From 25fdc90968a14ffd44dae65d6fdb3d50e6df9082 Mon Sep 17 00:00:00 2001 From: BoredGuy Date: Fri, 27 Mar 2026 16:29:32 -0700 Subject: Initial Commit --- TankBattleCore/.config/dotnet-tools.json | 30 +++++++++ TankBattleCore/.mgstats | 1 + TankBattleCore/Content/Content.mgcb | 15 +++++ TankBattleCore/Game1.cs | 91 ++++++++++++++++++++++++++ TankBattleCore/Objects/Bullet.cs | 47 ++++++++++++++ TankBattleCore/Objects/Game.cs | 106 +++++++++++++++++++++++++++++++ TankBattleCore/Objects/Scene.cs | 9 +++ TankBattleCore/Objects/Tank.cs | 79 +++++++++++++++++++++++ TankBattleCore/TankBattleCore.csproj | 10 +++ 9 files changed, 388 insertions(+) create mode 100644 TankBattleCore/.config/dotnet-tools.json create mode 100644 TankBattleCore/.mgstats create mode 100644 TankBattleCore/Content/Content.mgcb create mode 100644 TankBattleCore/Game1.cs create mode 100644 TankBattleCore/Objects/Bullet.cs create mode 100644 TankBattleCore/Objects/Game.cs create mode 100644 TankBattleCore/Objects/Scene.cs create mode 100644 TankBattleCore/Objects/Tank.cs create mode 100644 TankBattleCore/TankBattleCore.csproj (limited to 'TankBattleCore') diff --git a/TankBattleCore/.config/dotnet-tools.json b/TankBattleCore/.config/dotnet-tools.json new file mode 100644 index 0000000..ec5d637 --- /dev/null +++ b/TankBattleCore/.config/dotnet-tools.json @@ -0,0 +1,30 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "dotnet-mgcb-editor": { + "version": "3.8.4.1", + "commands": [ + "mgcb-editor" + ] + }, + "dotnet-mgcb-editor-linux": { + "version": "3.8.4.1", + "commands": [ + "mgcb-editor-linux" + ] + }, + "dotnet-mgcb-editor-windows": { + "version": "3.8.4.1", + "commands": [ + "mgcb-editor-windows" + ] + }, + "dotnet-mgcb-editor-mac": { + "version": "3.8.4.1", + "commands": [ + "mgcb-editor-mac" + ] + } + } +} \ No newline at end of file diff --git a/TankBattleCore/.mgstats b/TankBattleCore/.mgstats new file mode 100644 index 0000000..eab26b3 --- /dev/null +++ b/TankBattleCore/.mgstats @@ -0,0 +1 @@ +Source File,Dest File,Processor Type,Content Type,Source File Size,Dest File Size,Build Seconds diff --git a/TankBattleCore/Content/Content.mgcb b/TankBattleCore/Content/Content.mgcb new file mode 100644 index 0000000..ddc4c36 --- /dev/null +++ b/TankBattleCore/Content/Content.mgcb @@ -0,0 +1,15 @@ + +#----------------------------- Global Properties ----------------------------# + +/outputDir:bin/$(Platform) +/intermediateDir:obj/$(Platform) +/platform:DesktopGL +/config: +/profile:Reach +/compress:False + +#-------------------------------- References --------------------------------# + + +#---------------------------------- Content ---------------------------------# + diff --git a/TankBattleCore/Game1.cs b/TankBattleCore/Game1.cs new file mode 100644 index 0000000..91a09b5 --- /dev/null +++ b/TankBattleCore/Game1.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; +using TankBattleCore.Objects; + +namespace TankBattleCore; + +internal enum TankColor +{ + Black +} + +public class Game1 : Game +{ + private static Game1 _instance; + + public static Game1 Instance + { + get + { + if (_instance == null) + { + _instance = new Game1(); + } + + return _instance; + } + } + + private GraphicsDeviceManager _graphics; + private SpriteBatch _spriteBatch; + internal Dictionary TankBodyTextures { get; private set; } + IScene _scene; + + public int WindowWidth + { + get => _graphics.PreferredBackBufferWidth; + } + + public int WindowHeight + { + get => _graphics.PreferredBackBufferHeight; + } + + private Game1() + { + _graphics = new GraphicsDeviceManager(this); + Content.RootDirectory = "Content"; + IsMouseVisible = true; + } + + protected override void Initialize() + { + base.Initialize(); + } + + protected override void LoadContent() + { + _spriteBatch = new SpriteBatch(GraphicsDevice); + + TankBodyTextures = new Dictionary() + { + {TankColor.Black, Content.Load("tankBlack_outline")} + }; + + _scene = new GameScene(); + } + + protected override void Update(GameTime gameTime) + { + if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape)) + Exit(); + + float dt = (float)gameTime.ElapsedGameTime.TotalSeconds; + + _scene.Update(dt); + + base.Update(gameTime); + } + + protected override void Draw(GameTime gameTime) + { + GraphicsDevice.Clear(Color.CornflowerBlue); + + _scene.Draw(_spriteBatch); + + base.Draw(gameTime); + } +} diff --git a/TankBattleCore/Objects/Bullet.cs b/TankBattleCore/Objects/Bullet.cs new file mode 100644 index 0000000..0775d22 --- /dev/null +++ b/TankBattleCore/Objects/Bullet.cs @@ -0,0 +1,47 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace TankBattleCore.Objects; + +struct BulletData +{ + public Vector2 Position; + public float Angle; + public float Speed; +} + +class Bullet +{ + public const float SlowSpeed = 250f; + public const float FastSpeed = 400f; + + private Vector2 _position; + private Texture2D _bulletTexture; + float _speed; + float _angle; + + public Vector2 Position { get => _position; } + + public Bullet(Vector2 position, Texture2D bulletTexture, float speed, float angle) + { + _position = position; + _bulletTexture = bulletTexture; + _speed = speed; + _angle = angle; + } + + public void Update(float dt) + { + _position += new Vector2(MathF.Cos(_angle), MathF.Sin(_angle)) * _speed * dt; + } + + public void Draw(SpriteBatch spriteBatch) + { + spriteBatch.Draw( + _bulletTexture, + _position, + Color.White + ); + } +} \ No newline at end of file diff --git a/TankBattleCore/Objects/Game.cs b/TankBattleCore/Objects/Game.cs new file mode 100644 index 0000000..75f25e5 --- /dev/null +++ b/TankBattleCore/Objects/Game.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; +using TankBattleCore; +using TankBattleCore.Objects; + +internal class GameScene : IScene +{ + private const int PlayAreaOffset = 100; + private static readonly Rectangle PlayArea = new Rectangle( + -PlayAreaOffset, + -PlayAreaOffset, + Game1.Instance.WindowWidth + PlayAreaOffset, + Game1.Instance.WindowHeight + PlayAreaOffset + ); + + private List tanks = []; + private List bullets = []; + private bool paused = false; + + public GameScene() + { + Clear(); + + AddTank( + new Tank( + Vector2.Zero, + Game1.Instance.TankBodyTextures[TankColor.Black] + ) + ); + } + + internal void Clear() + { + tanks.Clear(); + } + + public void Update(float dt) + { + if (paused) + { + return; + } + + var keyboardState = Keyboard.GetState(); + + foreach (Tank t in tanks) + { + t.Update(dt); + + if (keyboardState.IsKeyDown(Keys.Enter)) + { + ShootBullet(t.GetNextShot()); + } + } + + foreach (Bullet b in bullets) + { + b.Update(dt); + } + + bullets.RemoveAll(b => !PlayArea.Contains(b.Position)); + } + + public void Draw(SpriteBatch spriteBatch) + { + spriteBatch.Begin(); + + foreach (Tank t in tanks) + { + t.Draw(spriteBatch); + } + + foreach (Bullet b in bullets) + { + b.Draw(spriteBatch); + } + + spriteBatch.End(); + } + + private void AddTank(Tank tank) + { + tanks.Add(tank); + } + + private void AddBullet(Bullet bullet) + { + bullets.Add(bullet); + } + + public void ShootBullet(BulletData bulletData) + { + AddBullet( + new Bullet( + bulletData.Position, + Game1.Instance.TankBodyTextures[TankColor.Black], + bulletData.Speed, + bulletData.Angle + ) + ); + } +} \ No newline at end of file diff --git a/TankBattleCore/Objects/Scene.cs b/TankBattleCore/Objects/Scene.cs new file mode 100644 index 0000000..9fa5619 --- /dev/null +++ b/TankBattleCore/Objects/Scene.cs @@ -0,0 +1,9 @@ +using Microsoft.Xna.Framework.Graphics; + +namespace TankBattleCore.Objects; + +internal interface IScene +{ + internal void Update(float dt); + internal void Draw(SpriteBatch spriteBatch); +} \ No newline at end of file diff --git a/TankBattleCore/Objects/Tank.cs b/TankBattleCore/Objects/Tank.cs new file mode 100644 index 0000000..927d053 --- /dev/null +++ b/TankBattleCore/Objects/Tank.cs @@ -0,0 +1,79 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; + +namespace TankBattleCore.Objects; + +internal class Tank +{ + private const float Speed = 200; + private const float TurnSpeed = 2; //In Rad/Sec + private const float Scale = 0.6f; + private const int PoweredUpShotInterval = 4; + + private Vector2 _position; + private float _angle = 0; + private Texture2D _bodyTexture; + private int _numShots = 0; + private float ShotSpeed + { + get + { + if (_numShots % PoweredUpShotInterval == PoweredUpShotInterval - 1) + { + return Bullet.FastSpeed; + } else + { + return Bullet.SlowSpeed; + } + } + } + + public Tank(Vector2 postion, Texture2D bodyTexture) + { + _position = postion; + _bodyTexture = bodyTexture; + } + + public void Update(float dt) + { + _position += new Vector2(MathF.Cos(_angle), MathF.Sin(_angle)) * Speed * dt; + + var keyboardState = Keyboard.GetState(); + if (keyboardState.IsKeyDown(Keys.A)) + { + _angle -= TurnSpeed * dt; + } else if (keyboardState.IsKeyDown(Keys.D)) { + _angle += TurnSpeed * dt; + } + } + + public void Draw(SpriteBatch _spriteBatch) + { + _spriteBatch.Draw( + _bodyTexture, + _position, + null, + Color.White, + _angle - MathF.PI / 2, //Texture is rotated 90 degrees downwards + 0.5f * new Vector2(_bodyTexture.Width, _bodyTexture.Height), + Scale, + SpriteEffects.None, + 1.0f + ); + } + + public BulletData GetNextShot() + { + var shotSpeed = ShotSpeed; + _numShots++; + + return new BulletData + { + Position = _position, + Angle = _angle, + Speed = shotSpeed + }; + } +} \ No newline at end of file diff --git a/TankBattleCore/TankBattleCore.csproj b/TankBattleCore/TankBattleCore.csproj new file mode 100644 index 0000000..53d116f --- /dev/null +++ b/TankBattleCore/TankBattleCore.csproj @@ -0,0 +1,10 @@ + + + net9.0 + + + + All + + + \ No newline at end of file -- cgit v1.2.3