From 44c1454eed3a2710bbf087c721cc4bd7c56fe1b4 Mon Sep 17 00:00:00 2001
From: GeorgeAbbott <57576261+GeorgeAbbott@users.noreply.github.com>
Date: Sun, 6 Sep 2020 18:09:11 +0100
Subject: Add files via upload
---
Class War.csproj | 78 +++++++++
Constants.cs | 36 ++++
Enemy.cs | 218 +++++++++++++++++++++++
Game1.cs | 512 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
Icon.ico | Bin 0 -> 147541 bytes
InputHandler.cs | 97 +++++++++++
MainChara.cs | 65 +++++++
Menu.cs | 137 +++++++++++++++
Program.cs | 22 +++
Sprite.cs | 14 ++
Timer.cs | 47 +++++
app.manifest | 42 +++++
12 files changed, 1268 insertions(+)
create mode 100644 Class War.csproj
create mode 100644 Constants.cs
create mode 100644 Enemy.cs
create mode 100644 Game1.cs
create mode 100644 Icon.ico
create mode 100644 InputHandler.cs
create mode 100644 MainChara.cs
create mode 100644 Menu.cs
create mode 100644 Program.cs
create mode 100644 Sprite.cs
create mode 100644 Timer.cs
create mode 100644 app.manifest
diff --git a/Class War.csproj b/Class War.csproj
new file mode 100644
index 0000000..86a108d
--- /dev/null
+++ b/Class War.csproj
@@ -0,0 +1,78 @@
+
+
+
+
+ Debug
+ x86
+ 8.0.30703
+ 2.0
+ {C1D2D54B-62BF-43AE-B0AC-970731BA20D9}
+ WinExe
+ Properties
+ Class_War
+ Class War
+ 512
+ Windows
+ v4.5
+
+
+ x86
+ true
+ full
+ false
+ bin\$(MonoGamePlatform)\$(Platform)\$(Configuration)\
+ DEBUG;TRACE;WINDOWS
+ prompt
+ 4
+
+
+ x86
+ pdbonly
+ true
+ bin\$(MonoGamePlatform)\$(Platform)\$(Configuration)\
+ TRACE;WINDOWS
+ prompt
+ 4
+
+
+ Icon.ico
+
+
+ app.manifest
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(MonoGameInstallDirectory)\MonoGame\v3.0\Assemblies\Windows\MonoGame.Framework.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Constants.cs b/Constants.cs
new file mode 100644
index 0000000..f46874d
--- /dev/null
+++ b/Constants.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+
+namespace Class_War
+{
+ public static class Constants
+ {
+ public const string Consolas12 = "Consolas12";
+
+ public const string DefaultFont = Consolas12;
+
+ public const int Level1MaxEnemyCount = 10;
+ public const int Level1EnemyHealth = 100;
+
+ public const string MainCharacterSpriteImage = "maincharaimage";
+ public static readonly Vector2 MainCharacterStartingPosition;
+
+ public const int LifeLostScreenDuration = 3;
+ public const int AfterLifeLostImmunityTime = LifeLostScreenDuration + 5;
+
+ public const int RightMostEdge = 800;
+ public const int BottomMostEdge = 500;
+
+
+ static Constants ()
+ {
+ MainCharacterStartingPosition = new Vector2(330, 375); // TODO: add
+ }
+
+ }
+}
diff --git a/Enemy.cs b/Enemy.cs
new file mode 100644
index 0000000..5e343b2
--- /dev/null
+++ b/Enemy.cs
@@ -0,0 +1,218 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using Microsoft.Xna.Framework.Graphics;
+using Microsoft.Xna.Framework.Design;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Content;
+
+using static Class_War.Constants;
+
+namespace Class_War
+{
+
+ enum Direction
+ {
+ Left,
+ Right,
+ Up,
+ Down
+ }
+
+
+ class Enemy : Sprite
+ {
+ bool OutOfBounds
+ {
+ get
+ {
+ // OutOfBounds is where
+ /*
+ * -> The TopLeft X is beyond the screen's RIGHT edge, or ...
+ * -> The TopRight X is beyond the screen's LEFT edge, or ...
+ * -> The Bottom Y is beyond the screen's TOPMOST edge, or ...
+ * -> The Top Y is beyond the screen's BOTTOMMOST edge
+ */
+
+ if (position.X > RightMostEdge+12) return true; //
+ else if (Vector2.Add(position, sizeOfString).X < 0) return true;
+ else if (Vector2.Add(position, sizeOfString).Y < 0) return true;
+ else if (position.Y > BottomMostEdge+12) return true; //
+ else return false;
+ }
+ }
+
+ public List Borders
+ {
+ get
+ {
+ Vector2 bottomright = new Vector2();
+ bottomright.X = (position.X + sizeOfString.X);
+ bottomright.Y = (position.Y + sizeOfString.Y);
+ return new List() { position, bottomright };
+ }
+ }
+
+ ContentManager Content;
+ int hp;
+ string keyword;
+ public Vector2 position;
+ SpriteFont font;
+ public int points;
+ Color color;
+ Vector2 sizeOfString;
+ float speed;
+ public Direction direction;
+ bool isDestroyed = false;
+ public bool IsDestroyed { get => isDestroyed; set => isDestroyed = value; }
+ Random random = new Random();
+
+ DateTime timeOfLastBullet = DateTime.Now;
+
+
+
+
+ public Enemy
+ (ContentManager Content, int hp, string keyword,
+ string font, Color color, double speed, int level,
+ bool isException, Vector2 position, Direction direction)
+ {
+ this.Content = Content;
+ this.hp = hp * (isException ? 2 : 1);
+ this.keyword = keyword;
+ this.font = Content.Load(font);
+ this.color = color;
+ this.sizeOfString = this.font.MeasureString(keyword);
+ this.points = Convert.ToInt32(Convert.ToDouble(level) * speed);
+ this.speed = (float)speed;
+ this.direction = direction;
+ this.position = position;
+ }
+
+ public void Update(ref List bullets)
+ // containingList is the list containing this object, to allow for it to destroy itself when out of bounds.
+ {
+ Move();
+ if (OutOfBounds)
+ IsDestroyed = true;
+
+ // Create bullets
+ if (DateTime.Now - timeOfLastBullet > TimeSpan.FromSeconds(
+ (((15*random.NextDouble()) - (0.4*speed) + 1) > 0.1) ? ((15*random.NextDouble()) - (0.4 * speed) + 1) : 0.05))
+ {
+ timeOfLastBullet = DateTime.Now;
+ bullets.Add(new Bullet(Content, position,
+ ((direction == Direction.Left || direction == Direction.Right) ? Direction.Down : new List() { Direction.Left, Direction.Right }[random.Next(0,1)])
+ , 5, false));
+ }
+
+ }
+
+ public void Move()
+ {
+ if (direction == Direction.Left)
+ {
+ this.position.X -= speed;
+ }
+ if (direction == Direction.Right)
+ {
+ this.position.X += speed;
+ }
+ if (direction == Direction.Up)
+ {
+ this.position.Y -= speed;
+ }
+ if (direction == Direction.Down)
+ {
+ this.position.Y += speed;
+ }
+ }
+
+ public void Draw(SpriteBatch sb)
+ {
+ sb.DrawString(font, keyword, position, color);
+ }
+
+ }
+
+ class Bullet
+ {
+ bool OutOfBounds
+ {
+ get
+ {
+ // OutOfBounds is where
+ /*
+ * -> The TopLeft X is beyond the screen's RIGHT edge, or ...
+ * -> The TopRight X is beyond the screen's LEFT edge, or ...
+ * -> The Bottom Y is beyond the screen's TOPMOST edge, or ...
+ * -> The Top Y is beyond the screen's BOTTOMMOST edge
+ */
+
+ if (position.X > GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width) return true;
+ else if ((position).X < 0) return true;
+ else if ((position).Y < 0) return true;
+ else if (position.Y > GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height) return true;
+ else return false;
+ }
+ }
+
+
+
+ public Vector2 position;
+ public bool isPlayersBullet;
+ Direction direction;
+ int speed;
+
+ Texture2D image;
+
+ bool isDestroyed = false;
+ public bool IsDestroyed { get => isDestroyed ; set => isDestroyed = value; }
+
+ public void Move(bool autoUpdate = true)
+ {
+ if (direction == Direction.Left)
+ {
+ this.position.X -= speed;
+ }
+ if (direction == Direction.Right)
+ {
+ this.position.X += speed;
+ }
+ if (direction == Direction.Up)
+ {
+ this.position.Y -= speed;
+ }
+ if (direction == Direction.Down)
+ {
+ this.position.Y += speed;
+ }
+
+ if (autoUpdate)
+ Update();
+ }
+
+ public void Update()
+ {
+ if (OutOfBounds)
+ IsDestroyed = true;
+ }
+
+ public void Draw(SpriteBatch sb)
+ {
+ sb.Draw(image, position, Color.White);
+ }
+
+ public Bullet(ContentManager Content, Vector2 position, Direction direction, int speed, bool isPlayersBullet)
+ {
+ this.position = position;
+ this.direction = direction;
+ this.speed = speed;
+ this.isPlayersBullet = isPlayersBullet;
+ this.image = Content.Load("bullet");
+ }
+ } // End of Class Bracket
+}
diff --git a/Game1.cs b/Game1.cs
new file mode 100644
index 0000000..a6f96b0
--- /dev/null
+++ b/Game1.cs
@@ -0,0 +1,512 @@
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+using Microsoft.Xna.Framework.Input;
+using static Class_War.Constants;
+using System.Diagnostics;
+using System.Collections.Generic;
+using System;
+
+
+namespace Class_War
+{
+ ///
+ /// This is the main type for your game.
+ ///
+ public class Game1 : Game
+ {
+ GraphicsDeviceManager graphics;
+ SpriteBatch spriteBatch;
+
+ SpriteFont Consolas12SF;
+
+ Random random = new Random();
+
+ InputHandler inputHandler;
+
+ int score;
+ byte level;
+ int enemiesSpawnedForLevel;
+ int maxEnemiesForCurrLevel;
+ bool isPaused;
+ DateTime startTime;
+ bool newLevel;
+ bool beginNewLevel = false;
+ int lives = 3;
+ bool lifeLost; // TODO: initialize these
+ bool inMenu = false;
+ bool isShill = false;
+ bool usesBackgroundImage = false;
+
+ Texture2D codeBackgroundImage;
+ Texture2D shillBackgroundImage;
+
+
+ DateTime lifeLostTime;
+
+ Timer collisionTimer = new Timer();
+
+ Menu menu;
+
+ MainChara mainchara;
+ List enemies;
+ List bullets;
+
+
+ List csharpKeywords;
+ List assemblyKeywords;
+ List cppKeywords;
+ List keywords;
+ List exceptions;
+
+ public bool IsCollision(List borders, Vector2 point)
+ {
+ // If point within the borders, return true.
+ if (point.X >= borders[0].X && point.X <= borders[1].X && point.Y >= borders[0].Y && point.Y <= borders[1].Y) return true;
+ else return false;
+
+ } // TODO: add
+
+
+ public Game1()
+ {
+ graphics = new GraphicsDeviceManager(this);
+ Content.RootDirectory = "Content";
+ }
+
+ ///
+ /// Allows the game to perform any initialization it needs to before starting to run.
+ /// This is where it can query for any required services and load any non-graphic
+ /// related content. Calling base.Initialize will enumerate through any components
+ /// and initialize them as well.
+ ///
+ protected override void Initialize()
+ {
+ // TODO: Add your initialization logic here
+
+ isPaused = false;
+ mainchara = new MainChara(Content, MainCharacterSpriteImage, MainCharacterStartingPosition);
+
+ enemies = new List();
+ bullets = new List();
+
+ menu = new Menu(Content, Consolas12);
+
+ // Level and Enemy loading logic
+ newLevel = true;
+ startTime = DateTime.Now;
+ level = 1;
+ score = 0;
+ maxEnemiesForCurrLevel = Level1MaxEnemyCount;
+
+ inputHandler = new InputHandler();
+
+ shillBackgroundImage = Content.Load("shillbg");
+ codeBackgroundImage = Content.Load("codebg");
+
+ lifeLost = false;
+ lifeLostTime = DateTime.Now.Subtract(new TimeSpan(0, 0, AfterLifeLostImmunityTime));
+
+ // TODO: actually add keyword loading mechanism
+ csharpKeywords = new List()
+ { "abstract", "base", "bool", "break", "byte", "case", "catch",
+ "char", "checked", "class", "const", "continue", "decimal", "default",
+ "delegate", "do", "double", "else", "enum", "event", "explicit",
+ "extern", "false", "finally", "fixed", "float", "for", "foreach",
+ "goto", "if", "implicit", "in", "int", "interface", "internal",
+ "is", "lock", "long", "namespace", "new", "null", "object", "operator",
+ "out", "override", "params", "private", "protected", "public",
+ "readonly", "ref", "return", "sbyte", "sealed", "short", "sizeof",
+ "stackalloc", "static", "string", "struct", "switch", "this",
+ "throw", "true", "try", "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort",
+ "using", "virtual", "void", "volatile", "while"};
+ assemblyKeywords = new List()
+ {
+ "aaa", "aad", "aam", "aas", "adc", "add", "and", "call", "cbw",
+ "clc", "cld", "cli", "cmc", "cmp", "cmpsb", "cmpsw", "cwd", "daa",
+ "das", "dec", "div", "esc", "hlt", "idiv", "imul", "in", "inc",
+ "int", "into", "iret", "ja", "jae", "jb", "jbe", "jc", "je", "jg",
+ "jge", "jl", "jle", "jna", "jnae", "jnb", "jnbe", "jnc", "jne", "jng",
+ "jnge", "jnl", "jnle", "jno", "jnp", "jns", "jnz", "jo", "jp", "jpe",
+ "jpo", "js", "jz", "jcxz", "jmp", "lahf", "lds", "lea", "les", "lock",
+ "lodsb", "lodsw", "loop", "mov", "movsb", "movsw", "mul", "neg",
+ "nop", "not", "or", "out", "pop", "popf", "push", "pushf", "rcl",
+ "rcr", "rep", "repe", "repne", "repnz", "repz", "retn", "retf",
+ "ret", "rol", "ror", "sahf", "sal", "sar", "sbb", "scasb", "scasw",
+ "shl", "shr", "stc", "std", "sti", "stosb", "stosw", "sub",
+ "test", "wait", "xchg", "xlat", "xor"
+ };
+ cppKeywords = new List() { "alignas", "alignof", "and",
+ "and_eq", "asm", "atomic_cancel", "atomic_commit", "atomic_noexcept",
+ "auto", "bitand", "bitor", "bool", "break", "case", "catch", "char",
+ "char8_t", "char16_t", "char32_t", "class", "compl", "concept",
+ "const", "consteval", "constexpr", "constinit", "const_cast",
+ "continue", "co_await", "co_return", "co_yield", "decltype",
+ "default", "delete", "do", "double", "dynamic_cast", "else",
+ "enum", "explicit","export", "extern", "false", "float",
+ "for", "friend", "goto", "if", "inline", "int", "long",
+ "mutable", "namespace", "new", "noexcept", "not", "not_eq",
+ "nullptr", "operator", "or", "or_eq", "private", "protected",
+ "register", "reinterpret_cast", "requires", "return", "short",
+ "signed", "sizeof", "static", "static_assert", "static_cast",
+ "struct", "switch", "this", "template", "thread_local", "throw",
+ "true", "try", "typedef", "typeid", "typename", "union", "unsigned",
+ "using", "virtual", "void", "volatile", "wchar_t", "while",
+ "xor", "xor_eq", "final", "override", "ifdef", "elif", "endif", "pragma",
+ "undef", "define", "error", "line", "include", "export", "import",
+ "module"};
+
+ keywords = csharpKeywords;
+
+
+
+ exceptions = new List();
+ exceptions.Add("NullReferenceException");
+
+
+ // Add Level One enemies
+
+
+
+ base.Initialize();
+ }
+
+ ///
+ /// LoadContent will be called once per game and is the place to load
+ /// all of your content.
+ ///
+ protected override void LoadContent()
+ {
+ // Create a new SpriteBatch, which can be used to draw textures.
+ spriteBatch = new SpriteBatch(GraphicsDevice);
+ Consolas12SF = Content.Load(DefaultFont);
+
+ // TODO: use this.Content to load your game content here
+ }
+
+ ///
+ /// UnloadContent will be called once per game and is the place to unload
+ /// game-specific content.
+ ///
+ protected override void UnloadContent()
+ {
+ // TODO: Unload any non ContentManager content here
+ }
+
+ ///
+ /// Allows the game to run logic such as updating the world,
+ /// checking for collisions, gathering input, and playing audio.
+ ///
+ /// Provides a snapshot of timing values.
+ protected override void Update(GameTime gameTime)
+ {
+ if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
+ Exit();
+
+ if (newLevel)
+ { // If newLevel begin the timer process, to regularly spawn the new enemies.
+ if ((DateTime.Now - startTime) > TimeSpan.FromSeconds(30d / maxEnemiesForCurrLevel))// SystemOverFlowexception here.
+ {
+ // Adequate time has passed, so spawn in a new enemy
+ string text = keywords[random.Next(keywords.Count)];
+ bool isException = false;
+
+ // Generate position and is left to right (or up and down)
+ Vector2 position = new Vector2(2,2); // Just to stop the error basically, position is overridden later
+ Direction direction;
+
+ // Testing for Random number gen
+ /*Debug.WriteLine(new string('\n', 20));
+ for (int amountoftimestodebugforwiththisthing = 0; amountoftimestodebugforwiththisthing < 150; amountoftimestodebugforwiththisthing++)
+ {
+ Debug.Write($"{(Direction)random.Next(0, 4)} - ");
+ }
+ Debug.WriteLine(new string('\n', 10));*/
+
+ if (level <= 5)
+ { // Can only declare left to right positions.
+ direction = (Direction)random.Next(0, 2); // Only generating 1
+ }
+ else
+ direction = (Direction)random.Next(0, 4); // Only generating 3
+
+ Debug.WriteLine($"\t\t\t\tCreated new Direction -> {direction.ToString()}");
+
+ if (direction == Direction.Left)
+ {
+ position = new Vector2(RightMostEdge+10f,
+ random.Next(0, BottomMostEdge-75));
+ }
+ else if (direction == Direction.Right)
+ {
+ position = new Vector2(-10f, random.Next(0, BottomMostEdge-75));
+ }
+ else if (direction == Direction.Down)
+ {
+ position = new Vector2(random.Next(0, GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width), -10f);
+ }
+ else if (direction == Direction.Up)
+ {
+ position = new Vector2(random.Next(0, RightMostEdge-5),
+ BottomMostEdge + 10f);
+ }
+
+
+
+
+ if (exceptions.Contains(text)) isException = true;
+ enemies.Add(new Enemy(Content, Level1EnemyHealth * level, text,
+ Consolas12,
+ Color.White,
+ random.NextDouble() + 0.3 + (level*0.15),
+ level, isException, position, direction));
+
+ enemiesSpawnedForLevel++;
+ if (enemiesSpawnedForLevel == maxEnemiesForCurrLevel) newLevel = false; // Once everything is spawned, no longer new level
+ }
+
+ }
+ // Begin the New Level once all Enemies down
+ if (!newLevel && (enemies.Count == 0)) // If all for this level spawned and disappeared out of list
+ {
+ beginNewLevel = true;
+ }
+
+
+ // Updating spawning logic for the next level
+ if (enemiesSpawnedForLevel >= maxEnemiesForCurrLevel && beginNewLevel)
+ { // Time for each spawning wave will be 30 seconds
+ level++;
+ newLevel = true;
+ beginNewLevel = false; // the level is begun-- this is set to true again once all enemies are gone
+ startTime = DateTime.Now;
+ enemiesSpawnedForLevel = 0;
+ maxEnemiesForCurrLevel = ((Level1MaxEnemyCount) + maxEnemiesForCurrLevel);
+ }
+
+
+
+ // Handle Input
+ inputHandler.ReadInput();
+ Debug.WriteLine("Jello"); // This is working every loop
+
+ /*if (inputHandler.IsKeyDown(Keys.P, 0.5))
+ { // Toggle Pausing with TAB
+ if (isPaused) isPaused = false;
+ else isPaused = true;
+ }*/
+
+ Debug.WriteLine("---- ABOUT TO CHECK FOR IF TAB PRESSED ----");
+ bool menuCodeExecuted = false;
+ if (isPaused && inMenu)
+ {
+ menu.HandleInput(inputHandler);
+
+ // TODO: handle states
+ // ....
+ if (menu.outValue == 0) {
+ isPaused = inMenu = false;
+ menu.outValue = 328;
+ }
+ else if (menu.outValue == 3) // C# Language
+ { keywords = csharpKeywords; }
+ else if (menu.outValue == 4) // Assembly
+ { keywords = assemblyKeywords; }
+ else if (menu.outValue == 5)
+ { keywords = cppKeywords; }
+ else if (menu.outValue == 6) // BLACK
+ { isShill = usesBackgroundImage = false; }
+ else if (menu.outValue == 7) // CODE
+ { usesBackgroundImage = true; isShill = false; }
+ else if (menu.outValue == 8) // SHILL
+ { usesBackgroundImage = isShill = true; }
+
+
+ else if (false) { } // TODO: add
+
+
+ if (inputHandler.OnKeyPress(Keys.Tab)) isPaused = inMenu = false;
+
+ menuCodeExecuted = true;
+ }
+
+ if (inputHandler.OnKeyPress(Keys.Tab) && menuCodeExecuted == false)
+ {
+ Debug.WriteLine("NOW IN MENU");
+ isPaused = true;
+ inMenu = true;
+ }
+
+ // If In Menu
+
+
+ if (!isPaused)
+ {
+ if (inputHandler.IsKeyDown(Keys.W) || inputHandler.IsKeyDown(Keys.Up))
+ mainchara.GoUp();
+ else if (inputHandler.IsKeyDown(Keys.S) || inputHandler.IsKeyDown(Keys.Down))
+ mainchara.GoDown();
+ else if (inputHandler.IsKeyDown(Keys.D) || inputHandler.IsKeyDown(Keys.Right))
+ mainchara.GoRight();
+ else if (inputHandler.IsKeyDown(Keys.A) || inputHandler.IsKeyDown(Keys.Left))
+ mainchara.GoLeft();
+ if (inputHandler.IsKeyDown(Keys.Enter))
+ mainchara.Fire(ref bullets);
+ }
+
+ // Update Enemys and Bullets, e.g. deleting them where necessary
+ /*List toBeRemoved = new List();
+ foreach (Enemy e in enemies)
+ {
+ e.Update(ref bullets);
+ if (e.IsDestroyed) toBeRemoved.Add(e);
+ }
+ enemies.RemoveAll(e => toBeRemoved.Contains(e));*/
+ if (!isPaused)
+ {
+ List bulletsToBeRemoved = new List();
+ foreach (Bullet b in bullets)
+ {
+ b.Move();
+ if (b.IsDestroyed) bulletsToBeRemoved.Add(b);
+ }
+ bullets.RemoveAll(b => bulletsToBeRemoved.Contains(b));
+
+ // Handling Collisions
+ /* If the Word Enemys collide with the bullet, they are destroyed.
+ * If the Word Enemys or their Bullets collide with the player, a life is lost.
+ * */
+ collisionTimer.StartTime();
+
+ foreach (Bullet bullet in bullets)
+ {
+ if (bullet.isPlayersBullet)
+ {
+ foreach (Enemy enemy in enemies)
+ {
+ if (IsCollision(enemy.Borders, bullet.position))
+ {
+ enemy.IsDestroyed = true;
+ bullet.IsDestroyed = true;
+ score += enemy.points;
+ }
+ }
+ }
+ else
+ {
+ if (IsCollision(mainchara.Borders, bullet.position))
+ {
+ if (DateTime.Now - lifeLostTime > TimeSpan.FromSeconds(AfterLifeLostImmunityTime))
+ {
+ Debug.WriteLine("Player loses life!");
+ lives--;
+ lifeLost = true;
+ lifeLostTime = DateTime.Now;
+ isPaused = true;
+ mainchara.topleft.X = -10000; // Just to prevent loss of lives
+ mainchara.topleft.Y = -10000;
+ break;
+ }
+ else { } // Do nothing if still in regeneratory period
+
+ }
+ }
+ }
+ // Remove The
+ List tbr = new List();
+ foreach (Enemy e in enemies)
+ {
+ e.Update(ref bullets);
+ if (e.IsDestroyed) tbr.Add(e);
+ }
+ enemies.RemoveAll(e => tbr.Contains(e));
+
+ collisionTimer.EndTime();
+ Debug.WriteLine($"Collision Detection -> Time This Run {collisionTimer.GetLastDuration()}");
+ Debug.WriteLine($"Collision Detection -> Average Time {collisionTimer.GetAverageDuration()}");
+ }
+
+ if (isPaused && lifeLost)
+ {
+ if (DateTime.Now - lifeLostTime > TimeSpan.FromSeconds(LifeLostScreenDuration))
+ {
+ isPaused = lifeLost = false;
+ mainchara.topleft = MainCharacterStartingPosition;
+ }
+ }
+
+ base.Update(gameTime);
+ }
+
+ ///
+ /// This is called when the game should draw itself.
+ ///
+ /// Provides a snapshot of timing values.
+ protected override void Draw(GameTime gameTime)
+ {
+ GraphicsDevice.Clear(Color.Black);
+
+
+ spriteBatch.Begin();
+
+ if (usesBackgroundImage && !isPaused)
+ {
+ if (isShill)
+ spriteBatch.Draw(shillBackgroundImage, new Vector2(0, 0), Color.White);
+ else spriteBatch.Draw(codeBackgroundImage, new Vector2(0, 0), Color.White);
+ }
+
+
+
+ Debug.WriteLine("In Draw() -- spriteBatch begun");
+ Debug.WriteLine($"In Draw() -> enemies.Count = {enemies.Count}");
+ Debug.WriteLine($"In Draw() -> bullets.Count = {bullets.Count}");
+ Debug.WriteLine($"In Draw() -> player coords = ({mainchara.Borders[0].X}, {mainchara.Borders[0].Y})");
+ Debug.WriteLine("Enemy coordinates as follows: ");
+ foreach (Enemy enemy in enemies)
+ {
+ Debug.WriteLine($"\t{enemy.position}\t{enemy.direction}");
+ }
+
+ if (inMenu && isPaused) menu.Draw(spriteBatch, isShill);
+
+
+ // TODO: Add your drawing code here
+ if (lives == 0) // if game over
+ {
+ spriteBatch.DrawString(Consolas12SF, "GAME OVER!", new Vector2(250, 200), Color.White);
+ spriteBatch.DrawString(Consolas12SF, $"Points: {score}", new Vector2(250, 220), Color.Red);
+ spriteBatch.DrawString(Consolas12SF, $"Level: {level}", new Vector2(250, 240), Color.Red);
+
+ isPaused = true; // Otherwise score count can change
+ }
+ else
+ {
+ if (isPaused && !lifeLost)
+ {
+ Debug.WriteLine("In Draw -> isPaused");
+ spriteBatch.DrawString(Consolas12SF, "PAUSED", new Vector2(GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height / 2,
+ GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width / 2), Color.White);
+ }
+ else if (isPaused && lifeLost)
+ {
+ spriteBatch.DrawString(Consolas12SF, "YOU DIED", new Vector2(250, 250), Color.White);
+ spriteBatch.DrawString(Consolas12SF, $"{lives} lives left", new Vector2(250, 270), Color.White);
+ }
+ else
+ {
+ Debug.WriteLine("In Draw -> isNotPaused");
+ mainchara.Draw(spriteBatch);
+ foreach (Enemy enemy in enemies) enemy.Draw(spriteBatch);
+ foreach (Bullet bullet in bullets) bullet.Draw(spriteBatch);
+ }
+
+ spriteBatch.DrawString(Consolas12SF, $"Score: {score.ToString("X8")}", new Vector2(10, 10), Color.Red);
+ //spriteBatch.DrawString(Consolas12SF, $"n. Enemies {enemies.Count}", new Vector2(10, 50), Color.Red);
+ spriteBatch.DrawString(Consolas12SF, $"Level {Convert.ToString(level, 2).PadLeft(8, '0')}", new Vector2(10, 30), Color.Red);
+ }
+
+ spriteBatch.End();
+ base.Draw(gameTime);
+ }
+ }
+}
diff --git a/Icon.ico b/Icon.ico
new file mode 100644
index 0000000..7d9dec1
Binary files /dev/null and b/Icon.ico differ
diff --git a/InputHandler.cs b/InputHandler.cs
new file mode 100644
index 0000000..1c74993
--- /dev/null
+++ b/InputHandler.cs
@@ -0,0 +1,97 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.Xna.Framework.Input;
+
+namespace Class_War
+{
+ class InputHandler
+ {
+ private KeyboardState _prevState;
+ public KeyboardState PreviousState { get => _prevState; set => _prevState = value; }
+
+ private KeyboardState _currentState;
+ public KeyboardState CurrentState { get => _currentState; set => _currentState = value; }
+
+ public void ReadInput ()
+ {
+ PreviousState = CurrentState;
+ CurrentState = Keyboard.GetState();
+ }
+
+ public bool IsKeyDown (Keys key)
+ {
+ if (CurrentState[key] == KeyState.Down) return true;
+ else return false;
+ }
+
+
+ private DateTime _isKeyDownLastCheck = DateTime.Now;
+ public DateTime KeyDownLastCheck
+ {
+ get { return _isKeyDownLastCheck; }
+ private set { _isKeyDownLastCheck = DateTime.Now; }
+ }
+
+
+
+ ///
+ /// Checks if a key is down, and will return false if the last keypress was earlier than
+ /// the timegap parameter. Keep changeKeyDownLastCheckIfFalse as false,
+ /// otherwise calling this function will interrupt the checking process.
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool IsKeyDown (Keys key, double timegap, bool changeKeyDownLastCheckIfFalse = false)
+ {
+ // Takes a DateTime, will return false if the DateTime is not after the last check.
+ // If enough time has passed, it will perform the check and return either true or false.
+ // Will not change KeyDownLastCheck unless true returned, except if changeKeyDownLastCheckIfFalse is true.
+
+ if (!((DateTime.Now - KeyDownLastCheck).TotalSeconds > timegap))
+ { // if not enough time has passed since last check
+ if (changeKeyDownLastCheckIfFalse) KeyDownLastCheck = DateTime.Now;
+ return false;
+ }
+ else // enough time has passed
+ {
+ if (CurrentState[key] == KeyState.Down)
+ { // Key has been pressed
+ KeyDownLastCheck = DateTime.Now;
+ return true;
+ }
+ else
+ { // Key has not been pressed
+ if (changeKeyDownLastCheckIfFalse)
+ {
+ KeyDownLastCheck = DateTime.Now;
+ return false;
+ }
+ else return false;
+ }
+ }
+
+
+
+
+
+ }
+
+ public bool OnKeyPress (Keys key)
+ {
+ if (CurrentState[key] == KeyState.Down && PreviousState[key] == KeyState.Up) return true;
+ else return false;
+ }
+
+ public bool OnKeyRelease (Keys key)
+ {
+ if (CurrentState[key] == KeyState.Up && PreviousState[key] == KeyState.Down) return true;
+ else return false;
+ }
+
+ }
+}
diff --git a/MainChara.cs b/MainChara.cs
new file mode 100644
index 0000000..018f19a
--- /dev/null
+++ b/MainChara.cs
@@ -0,0 +1,65 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.Xna.Framework.Graphics;
+using Microsoft.Xna.Framework.Content;
+using Microsoft.Xna.Framework;
+
+namespace Class_War
+{
+ class MainChara : Sprite
+ {
+ Texture2D image;
+ public Vector2 topleft;
+ ContentManager Content;
+ Vector2 size = new Vector2(50, 50);
+
+ public List Borders
+ {
+ get
+ {
+ Vector2 bottomright = new Vector2();
+ bottomright.X = (topleft.X + size.X);
+ bottomright.Y = (topleft.Y + size.Y);
+ return new List() { topleft, bottomright };
+ }
+ }
+
+ public void GoUp(int speed = 5)
+ {
+ topleft.Y -= speed;
+ }
+ public void GoDown(int speed = 5)
+ {
+ topleft.Y += speed;
+ }
+ public void GoLeft(int speed = 5)
+ {
+ topleft.X -= speed;
+ }
+ public void GoRight(int speed = 5)
+ {
+ topleft.X += speed;
+ }
+ public void Fire(ref List bullets, int speed = 5)
+ {
+ bullets.Add(new Bullet(Content, topleft, Direction.Up, speed, true));
+ }
+
+
+
+ public MainChara (ContentManager Content, string spriteImage, Vector2 position)
+ {
+ this.Content = Content;
+ image = Content.Load(spriteImage);
+ this.topleft = position;
+ }
+
+ public void Draw(SpriteBatch sb)
+ {
+ sb.Draw(image, topleft, Color.White);
+ }
+ }
+}
diff --git a/Menu.cs b/Menu.cs
new file mode 100644
index 0000000..22feee0
--- /dev/null
+++ b/Menu.cs
@@ -0,0 +1,137 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+using Microsoft.Xna.Framework.Design;
+using Microsoft.Xna.Framework.Content;
+using Microsoft.Xna.Framework.Input;
+
+namespace Class_War
+{
+ class Menu
+ {
+ ContentManager Content;
+ SpriteFont font;
+ bool indented = false; // on the zeroth indentation level
+ int currentSelection = 0;
+ int indentedCurrSel = 0;
+ int maxSelection = 2;
+ public int outValue = 328;
+
+ public void HandleInput (InputHandler ih)
+ {
+ if (!indented)
+ {
+ if (ih.OnKeyRelease(Keys.W) || ih.OnKeyRelease(Keys.Up))
+ {
+ currentSelection--;
+ if (currentSelection < 0) currentSelection = maxSelection;
+ }
+ else if (ih.OnKeyRelease(Keys.S) || ih.OnKeyRelease(Keys.Down))
+ {
+ currentSelection++;
+ if (currentSelection > maxSelection) currentSelection = 0;
+ }
+ else if (ih.OnKeyRelease(Keys.Enter))
+ {
+ if (currentSelection == 2) outValue = 0;
+ else
+ {
+ indented = true;
+ }
+ }
+ }
+ else
+ {
+ if (ih.OnKeyRelease(Keys.W) || ih.OnKeyRelease(Keys.Up))
+ {
+ indentedCurrSel--;
+ if (indentedCurrSel < 0) indentedCurrSel = maxSelection;
+ }
+ else if (ih.OnKeyRelease(Keys.S) || ih.OnKeyRelease(Keys.Down))
+ {
+ indentedCurrSel++;
+ if (indentedCurrSel > maxSelection) indentedCurrSel = 0;
+ }
+ else if (ih.OnKeyRelease(Keys.Back))
+ {
+ indentedCurrSel = 0;
+ indented = false;
+ }
+ else if (ih.OnKeyRelease(Keys.Enter))
+ {
+ // Select options, by setting outValue to appropriate setting.
+ switch (currentSelection)
+ {
+ case 0 when (indentedCurrSel == 0): outValue = 3; break; // C#
+ case 0 when (indentedCurrSel == 1): outValue = 4; break; // Assembly
+ case 0 when (indentedCurrSel == 2): outValue = 5; break; // C++
+ case 1 when (indentedCurrSel == 0): outValue = 6; break; // Black
+ case 1 when (indentedCurrSel == 1): outValue = 7; break; // Code
+ case 1 when (indentedCurrSel == 2): outValue = 8; break; // Shill
+ }
+
+ indentedCurrSel = 0;
+ indented = false;
+ }
+ }
+ }
+
+ public Menu (ContentManager Content, string font)
+ {
+ this.Content = Content;
+ this.font = Content.Load(font);
+
+ }
+
+ public void Draw(SpriteBatch sb, bool isShill)
+ {
+ sb.DrawString(font, "Language", new Vector2(100, 100), Color.White);
+ sb.DrawString(font, "Background", new Vector2(100, 120), Color.White);
+ sb.DrawString(font, "Exit Menu", new Vector2(100, 140), Color.DarkRed);
+
+ if (indented && currentSelection == 0)
+ {
+ sb.DrawString(font, "C#", new Vector2(230, 100), Color.White);
+ sb.DrawString(font, "Assembly", new Vector2(230, 120), Color.White);
+ sb.DrawString(font, "C++", new Vector2(230, 140), Color.White);
+ }
+ else if (indented && currentSelection == 1)
+ {
+ sb.DrawString(font, "Black", new Vector2(230, 120), Color.White);
+ sb.DrawString(font, "Code", new Vector2(230, 140), Color.White);
+ sb.DrawString(font, "Sellout", new Vector2(230, 160), Color.White);
+ }
+
+ if (isShill) sb.DrawString(font, "Go subscribe to javidx9!!!", new Vector2(300, 300), Color.Green);
+
+ Vector2 position;
+ switch (currentSelection)
+ {
+ case 0 when (!indented): position = new Vector2(90, 100); break;
+ case 1 when (!indented): position = new Vector2(90, 120); break;
+ case 2 when (!indented): position = new Vector2(90, 140); break;
+
+
+ // Render Positions for when in LANGUAGE
+ case 0 when (indented && indentedCurrSel == 0): position = new Vector2(220, 100); break;
+ case 0 when (indented && indentedCurrSel == 1): position = new Vector2(220, 120); break;
+ case 0 when (indented && indentedCurrSel == 2): position = new Vector2(220, 140); break;
+
+ // Render Positions for when in BACKGROUND
+ case 1 when (indented && indentedCurrSel == 0): position = new Vector2(220, 120); break;
+ case 1 when (indented && indentedCurrSel == 1): position = new Vector2(220, 140); break;
+ case 1 when (indented && indentedCurrSel == 2): position = new Vector2(220, 160); break;
+
+ // Default: should never happen.
+ default: position = new Vector2(0, 0); break; // This should never happen.
+ };
+
+ sb.DrawString(font, ">", position, Color.White);
+ }
+ }
+}
diff --git a/Program.cs b/Program.cs
new file mode 100644
index 0000000..379e7ef
--- /dev/null
+++ b/Program.cs
@@ -0,0 +1,22 @@
+using System;
+
+namespace Class_War
+{
+#if WINDOWS || LINUX
+ ///
+ /// The main class.
+ ///
+ public static class Program
+ {
+ ///
+ /// The main entry point for the application.
+ ///
+ [STAThread]
+ static void Main()
+ {
+ using (var game = new Game1())
+ game.Run();
+ }
+ }
+#endif
+}
diff --git a/Sprite.cs b/Sprite.cs
new file mode 100644
index 0000000..14e1d50
--- /dev/null
+++ b/Sprite.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.Xna.Framework.Graphics;
+
+namespace Class_War
+{
+ interface Sprite
+ {
+ void Draw(SpriteBatch sb);
+ }
+}
diff --git a/Timer.cs b/Timer.cs
new file mode 100644
index 0000000..748e7b2
--- /dev/null
+++ b/Timer.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Class_War
+{
+ class Timer
+ {
+ TimeSpan avgDuration;
+ DateTime t1;
+ DateTime t2;
+ bool isTiming = false;
+ bool firstTiming = true;
+ int numTimings = 0;
+
+ public void StartTime()
+ {
+ t1 = DateTime.Now;
+ isTiming = true;
+ }
+
+ public void EndTime()
+ {
+ t2 = DateTime.Now;
+ isTiming = false;
+ if (firstTiming) firstTiming = false;
+ numTimings++;
+ avgDuration.Add(t2 - t1);
+ }
+
+ public TimeSpan GetLastDuration()
+ {
+ if (!isTiming) return t2 - t1;
+ else throw new InvalidOperationException("Cannot call GetDuration when currently timing");
+ }
+
+ public TimeSpan GetAverageDuration()
+ {
+ if (numTimings == 0) throw new InvalidOperationException("No average duration where no timing has completed yet");
+ return TimeSpan.FromTicks(avgDuration.Ticks / numTimings);
+ }
+
+
+ }
+}
diff --git a/app.manifest b/app.manifest
new file mode 100644
index 0000000..760ba86
--- /dev/null
+++ b/app.manifest
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true/pm
+
+
+
+
--
cgit v1.2.1