MonoGame Worms – Del 3

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

Tank.cs
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
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; }

        private float _canonAngle = 0;

        public float CanonAngle
        {
            get {
                return _canonAngle;
            }
            set
            {
                _canonAngle = value;
                if (_canonAngle > 0)
                    _canonAngle = 0;
                if (_canonAngle < -MathHelper.Pi)
                    _canonAngle = -MathHelper.Pi;
            }
        }

        public float CannonTransformedAngle => Angle + CanonAngle + MathHelper.PiOver2;

        public Vector2 CannonPosition => Position + new Vector2(
            Height / 1.5f * (float)Math.Sin(Angle), 
            -Height / 1.5f * (float)Math.Cos(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.

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 Texture2D tankCannonTexture2D;
        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");
            tankCannonTexture2D = content.Load<Texture2D>("Tank_Cannon");

            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);
            if (kbState.IsKeyDown(Keys.Q))
                player1.CanonAngle -= 0.07f;
            if (kbState.IsKeyDown(Keys.E))
                player1.CanonAngle += 0.07f;

            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(tankCannonTexture2D, tank.CannonPosition, null, Color.White, tank.CannonTransformedAngle,
                    new Vector2(tankCannonTexture2D.Width / 2, tankCannonTexture2D.Height), 1.0f, SpriteEffects.None, 0);
                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);
        }
    }
}
Scroll to top