MonoGame Worms – Del 2

Denna serie är gjorde med MonoGame 3.8.1. Du hittar källkod och övrigt material länkat.

TankManager.cs
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WormsGame
{
    internal class TankManager
    {
        private Texture2D tankTexture2D;
        private List<Tank> tanks = new List<Tank>();

        private MapGenerator mapGenerator;
        public TankManager(MapGenerator mapGenerator)
        {
            this.mapGenerator = mapGenerator;
        }

        public  void LoadContent(ContentManager content)
        {
            tankTexture2D = content.Load<Texture2D>("Tank");

            tanks.Add(new Tank()
            {
                Position = new Vector2(300, 0),
                Width = tankTexture2D.Width,
                Height = tankTexture2D.Height
            });
        }

        public void Update()
        {
            var kbState = Keyboard.GetState();
            var player1 = tanks.First();

            if (kbState.IsKeyDown(Keys.Left))
                player1.Speed = new Vector2(-1, player1.Speed.Y);
            if (kbState.IsKeyDown(Keys.Right))
                player1.Speed = new Vector2(1, player1.Speed.Y);

            foreach(var tank in tanks)
            {
                var oldPos = player1.Position;
                var oldSpeed = player1.Speed;
                var oldAngle = player1.Angle;

                tank.Speed += new Vector2(0, 0.1f);
                tank.Position += tank.Speed;

                // kollision med kartan?
                var landPosition = FindLandPosition(tank.Position);
                if(landPosition.Item1.Y <= tank.Position.Y)
                {
                    tank.Speed = Vector2.Zero;
                    tank.Angle = landPosition.Item2;
                    tank.Position = landPosition.Item1;
                }

                if ((tank.Angle > 1.0f && oldSpeed.X < 0) || (tank.Angle < -1.0f && oldSpeed.X > 0))
                {
                    tank.Position = oldPos;
                    tank.Angle = oldAngle;
                }
            }
        }

        public void Draw(SpriteBatch spriteBatch)
        {
            foreach(var tank in tanks)
            {
                spriteBatch.Draw(tankTexture2D, tank.Position, null, Color.White, tank.Angle,
                        new Vector2(tankTexture2D.Width / 2, tankTexture2D.Height), 1.0f, SpriteEffects.None, 0);
            }
        }

        private Tuple<Vector2, float> FindLandPosition(Vector2 position)
        {
            int x1 = (int)position.X - tankTexture2D.Width / 2 + 4;
            int x2 = (int)position.X + tankTexture2D.Width / 2 - 4;
            int y1 = mapGenerator.FindLand(new Vector2(x1, position.Y));
            int y2 = mapGenerator.FindLand(new Vector2(x2, position.Y));

            var angle = (float)Math.Atan2(y2 - y1, x2 - x1);
            var pos = new Vector2(position.X, (y1 + y2) / 2);
            return new Tuple<Vector2, float>(pos, angle);
        }
    }
}
Tank.cs
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Text;

namespace WormsGame
{
    internal class Tank
    {
        public int Width { get; set; }
        public int Height { get; set; }
        public Vector2 Position { get; set; }
        public Vector2 Speed { get; set; }
        public float Angle { get; set; }
    }
}

Komplettera MapGenerator.cs med metoden FindLand.

MapGenerator.cs - FindLand
public int FindLand(Vector2 pos)
        {
            int x = (int)MathHelper.Clamp(pos.X, 0, Width - 1);
            int y = (int)MathHelper.Clamp(pos.Y, 0, Height - 1);

            if (colorData[x + y * Width] == Color.Transparent)
            {
                for (int i = y; i < Height; i++)
                    if (colorData[x + i * Width] != Color.Transparent)
                        return i;
                return Height;
            }
            else
            {
                for (int i = y; i >= 0; i--)
                    if (colorData[x + i * Width] == Color.Transparent)
                        return i;
                return 0;
            }
        }
Scroll to top