aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Stendahl <jakob.stendahl@outlook.com>2017-11-12 19:34:12 +0100
committerJakob Stendahl <jakob.stendahl@outlook.com>2017-11-12 19:34:12 +0100
commit91f2f03605f8fc2e3555e18826662754e1ee91a0 (patch)
tree5670c129372692fc7951d5770287115e0a5e4afa
parent4bc687ddbc5f262bcee09bc606fff8f98a10ac0f (diff)
downloadSpace-Invaders-CS-Console-91f2f03605f8fc2e3555e18826662754e1ee91a0.tar.gz
Space-Invaders-CS-Console-91f2f03605f8fc2e3555e18826662754e1ee91a0.zip
[a] Added sick shit!
-rw-r--r--Space Invaders/GameEngine/GameEngine.cs167
-rw-r--r--Space Invaders/GameEngine/Graphics.cs65
-rw-r--r--Space Invaders/GameObjects.cs147
-rw-r--r--Space Invaders/Program.cs50
-rw-r--r--Space Invaders/Space Invaders.csproj3
5 files changed, 431 insertions, 1 deletions
diff --git a/Space Invaders/GameEngine/GameEngine.cs b/Space Invaders/GameEngine/GameEngine.cs
new file mode 100644
index 0000000..6c5c5b0
--- /dev/null
+++ b/Space Invaders/GameEngine/GameEngine.cs
@@ -0,0 +1,167 @@
+using System;
+using System.Collections.Generic;
+using System.Threading;
+
+namespace GameEngine {
+
+ abstract class Game {
+
+ virtual public int ConsoleHeight { get; set; }
+ virtual public int ConsoleWidth { get; set; }
+
+ public List<GameObject> GameObjects = new List<GameObject>();
+ public Thread _listnerThread = new Thread(Input.Listner);
+
+ private Graphics _graphics;
+ private bool _running;
+
+ abstract public void Setup();
+
+ virtual public void Start() {
+ // Do initialization
+ _graphics = new Graphics(ConsoleHeight, ConsoleWidth);
+
+ // Run start thing in all GameObjects
+ for (int i = 0; i < GameObjects.Count; i++) {
+ GameObjects[i].Start();
+ }
+
+ // Start loop and other threads
+ _running = true; // This is a notifier to every thread, that will help us close the app
+ _listnerThread.Start();
+ GameLoop();
+ }
+
+ private void GameLoop() {
+ while (_running) {
+
+ // Run the Update method in each GameObject in the scene
+ for (int i = 0; i < GameObjects.Count; i++) {
+ GameObjects[i].Update();
+ }
+
+ // Scale every GameObject
+ for (int i = 0; i < GameObjects.Count; i++) {
+ GameObjects[i].ScaleSprite();
+ }
+
+ // Last thing to do each time. Render the frame and display it!
+ Frame nextFrame = new Frame();
+ nextFrame.Buffer = RenderGameObjects(); // Make buffer, remove dead objects
+ _graphics.DrawFrame(nextFrame);
+
+ // Run lateUpdate on each gameObject
+ for (int i = 0; i < GameObjects.Count; i++) {
+ GameObjects[i].LateUpdate(nextFrame);
+ }
+ }
+ }
+
+ private char[,] RenderGameObjects() {
+ // This will make a buffer of all gameObjects on Screen
+ char[,] buffer = new char[ConsoleHeight, ConsoleWidth];
+
+ for (int i = 0; i < GameObjects.Count; i++) {
+ GameObject gameObject = GameObjects[i];
+ char[,] sprite = gameObject.Sprite;
+
+ if (gameObject.isDead) {
+ GameObjects.RemoveAt(i);
+ continue;
+ }
+ if (gameObject.Sprite == null) { continue; }
+
+ for (int y = 0; y < sprite.GetLength(0); y++) {
+ for (int x = 0; x < sprite.GetLength(1); x++) {
+ try {
+ buffer[gameObject.yPos + y, gameObject.xPos + x] = sprite[y, x];
+ } catch { }
+ }
+ }
+ }
+
+ return buffer;
+ }
+
+ }
+
+ static class Input {
+
+ static List<ConsoleKey> KeyList = new List<ConsoleKey>();
+
+ static public void Listner() {
+ while (true) {
+ if (Console.KeyAvailable) {
+ KeyList.Add(Console.ReadKey().Key);
+ }
+ }
+ }
+
+ static public bool KeyPressed(ConsoleKey keyCode) {
+ for (int i = 0; i < KeyList.Count; i++) {
+ if (KeyList[i] == keyCode) {
+ KeyList.RemoveAt(i);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ }
+
+ abstract class GameObject {
+ public Game Parent;
+ virtual public bool isDead { get; set; }
+ virtual public String Tag { get; set; }
+ virtual public int Scale { get; set; }
+ virtual public int xPos { get; set; }
+ virtual public int yPos { get; set; }
+ virtual public Char[,] Sprite { get; set; }
+
+ private Char[,] RenderedSprite;
+
+ virtual public void Start() {
+ // This method is called once before the game actually starts
+ }
+
+ virtual public void Update() {
+ // This method is called right before the frame is rendered
+ }
+
+ virtual public void LateUpdate(Frame thisFrame) {
+ // This method is called after the frame is rendered
+ }
+
+ public void ScaleSprite() {
+ // This is called after the Update method, and scales the sprite if it has changed
+ if (RenderedSprite == Sprite) { return; }
+
+ RenderedSprite = new Char[Sprite.GetLength(0) * Scale, Sprite.GetLength(1) * Scale * 2];
+
+ for (int y = 0; y < Sprite.GetLength(0); y++) {
+ for (int x = 0; x < Sprite.GetLength(1); x++) {
+
+ for (int y1 = 0; y1 < Scale; y1++) {
+ for (int x1 = 0; x1 < (Scale * 2); x1++) { // The *2 is because a char is twice as high as wide
+
+ try {
+ int xOffset = x1 + ((Scale + Scale) * x) - x;
+ int yOffset = y1 + (Scale * y) - y;
+ int xPos = xOffset + x;
+ int yPos = yOffset + y;
+ char cChar = Sprite[y, x];
+ RenderedSprite[yPos, xPos] = cChar;
+ } catch { }
+
+ }
+ }
+
+
+ }
+ }
+ Sprite = RenderedSprite;
+ }
+
+ }
+
+}
diff --git a/Space Invaders/GameEngine/Graphics.cs b/Space Invaders/GameEngine/Graphics.cs
new file mode 100644
index 0000000..1c15199
--- /dev/null
+++ b/Space Invaders/GameEngine/Graphics.cs
@@ -0,0 +1,65 @@
+using System;
+using System.Diagnostics;
+
+namespace GameEngine {
+
+ class Graphics {
+ /* This class is made for drawing frame by frame in the console.
+ * It is designed to be used from a while loop, where the draw-frame method is called at the end of the loop */
+
+ // IMPORTANT! You might have to change the console font size, depending on how many rows and columns you want to have!
+
+ public int Rows { get; } // This should not be editable
+ public int Columns { get; } // Neither should this
+ public int FrameNum; // How many frames have been drawn
+
+ private Char[,] _consoleBuffer; // This stores how the screen looked last frame
+ private Stopwatch _stopWatch; // This is used to calculate time between frames
+
+ public Graphics(int columns, int rows) {
+ Rows = rows;
+ Columns = columns;
+ _consoleBuffer = new Char[Columns, Rows];
+
+ Console.CursorVisible = false;
+ Console.WindowHeight = Columns;
+ Console.WindowWidth = Rows;
+ Console.SetBufferSize(rows, columns);
+
+ _stopWatch = Stopwatch.StartNew();
+ FrameNum = 0;
+ }
+
+ public void DrawFrame(Frame newFrame) {
+ /* Method that draws all changes from last frame to the screen */
+ FrameNum++;
+ //Console.Clear();
+ //Console.SetCursorPosition(0, 0);
+ for (int y = 0; y < _consoleBuffer.GetLength(0); y++) {
+ for (int x = 0; x < _consoleBuffer.GetLength(1); x++) {
+
+ if (newFrame.Buffer[y, x] != _consoleBuffer[y, x]) {
+ _consoleBuffer[y, x] = newFrame.Buffer[y, x];
+ Console.SetCursorPosition(x, y);
+ Console.Write(newFrame.Buffer[y, x]);
+ }
+
+ }
+ }
+
+ _stopWatch.Reset();
+ }
+
+ public long DeltaTime() {
+ /* Method that returns time since last frame */
+ return _stopWatch.ElapsedMilliseconds;
+ }
+
+
+ }
+
+ class Frame {
+ public char[,] Buffer;
+ }
+
+}
diff --git a/Space Invaders/GameObjects.cs b/Space Invaders/GameObjects.cs
new file mode 100644
index 0000000..f7297a1
--- /dev/null
+++ b/Space Invaders/GameObjects.cs
@@ -0,0 +1,147 @@
+using System;
+using GameEngine;
+
+namespace SpaceInvaders {
+
+ class GameLogic : GameObject {
+
+ public override void Update() {
+
+ if (Input.KeyPressed(ConsoleKey.Escape)) {
+ Environment.Exit(0);
+ }
+
+ }
+ }
+
+ class Bullet : GameObject {
+
+ int moveTimer = 10;
+
+ public override void Start() {
+ Tag = "Projectile";
+ Scale = 1;
+ Sprite = new char[1, 1] { { '\u2588' } };
+ }
+
+ public override void Update() {
+
+ moveTimer--;
+ if (moveTimer <= 0) {
+ yPos = yPos - 1;
+ moveTimer = 10;
+ }
+
+
+ if (yPos <= 0) {
+ isDead = true;
+ }
+
+ }
+
+ public override void LateUpdate(Frame thisFrame) {
+ for (int i = 0; i < Parent.GameObjects.Count; i++) {
+ GameObject other = Parent.GameObjects[i];
+
+ if (other.Tag == "Enemy") {
+ int x1 = other.xPos;
+ int x2 = other.xPos + other.Sprite.GetLength(1);
+ int y1 = other.yPos;
+ int y2 = other.yPos + other.Sprite.GetLength(0);
+ if (x1 <= xPos && xPos <= x2 && y1 <= yPos && yPos <= y2) {
+ other.isDead = true;
+ isDead = true;
+ }
+ }
+
+ if (other.Tag == "Obstacle") {
+ int x1 = other.xPos;
+ int x2 = other.xPos + other.Sprite.GetLength(1);
+ int y1 = other.yPos;
+ int y2 = other.yPos + other.Sprite.GetLength(0);
+ if (x1 <= xPos && xPos <= x2 && y1 <= yPos && yPos <= y2) {
+ isDead = true;
+ }
+ }
+ }
+ }
+
+ }
+
+ class Player : GameObject {
+
+ public override void Start() {
+ Tag = "Player";
+ Sprite = new char[4, 9] {
+ {'\0', '\0', '\0', '\0', '\u2588', '\0', '\0', '\0', '\0'},
+ {'\0', '\0', '\0', '\0', '\u2588', '\0', '\0', '\0', '\0'},
+ {'\u2588', '\u2588', '\u2588', '\u2588', '\u2588', '\u2588', '\u2588', '\u2588', '\u2588'},
+ {'\u2588', '\u2588', '\u2588', '\u2588', '\u2588', '\u2588', '\u2588', '\u2588', '\u2588'}
+ };
+ }
+
+ public override void Update() {
+
+ if (Input.KeyPressed(ConsoleKey.RightArrow)) {
+ xPos = xPos + 2;
+
+ }
+
+ if (Input.KeyPressed(ConsoleKey.LeftArrow)) {
+ xPos = xPos - 2;
+ }
+
+ if (Input.KeyPressed(ConsoleKey.Spacebar)) {
+ GameObject tmpBullet = new Bullet();
+ tmpBullet.Parent = Parent;
+ tmpBullet.xPos = xPos + 8;
+ tmpBullet.yPos = yPos - 1;
+ tmpBullet.Start();
+ Parent.GameObjects.Add(tmpBullet);
+ }
+
+ }
+
+ }
+
+ class Obstacle : GameObject {
+
+ public override void Start() {
+ Tag = "Obstacle";
+ Scale = 4;
+
+ Sprite = new char[2, 5] {
+ {'\u2588', '\u2588', '\u2588', '\u2588', '\u2588'},
+ {'\u2588', '\0', '\0', '\0', '\u2588'}
+ };
+ }
+
+ }
+
+ class Monster : GameObject {
+
+ public override void Start() {
+ Tag = "Enemy";
+ xPos = 10;
+ yPos = 10;
+ Scale = 1;
+
+ Sprite = new char[8, 11] {
+ {'\0', '\0', '\u2588', '\0', '\0', '\0', '\0', '\0', '\u2588', '\0', '\0'},
+ {'\0', '\0', '\0', '\u2588', '\0', '\0', '\0', '\u2588', '\0', '\0', '\0'},
+ {'\0', '\0', '\u2588', '\u2588', '\u2588', '\u2588', '\u2588', '\u2588', '\u2588', '\0', '\0'},
+ {'\0', '\u2588', '\u2588', '\0', '\u2588', '\u2588', '\u2588', '\0', '\u2588', '\u2588', '\0'},
+ {'\u2588', '\u2588', '\u2588', '\u2588', '\u2588', '\u2588', '\u2588', '\u2588', '\u2588', '\u2588', '\u2588'},
+ {'\u2588', '\0', '\u2588', '\u2588', '\u2588', '\u2588', '\u2588', '\u2588', '\u2588', '\0', '\u2588'},
+ {'\u2588', '\0', '\u2588', '\0', '\0', '\0', '\0', '\0', '\u2588', '\0', '\u2588'},
+ {'\0', '\0', '\0', '\u2588', '\u2588', '\0', '\u2588', '\u2588', '\0', '\0', '\0'}
+ };
+
+ }
+
+ public override void Update() {
+ }
+
+ }
+
+}
diff --git a/Space Invaders/Program.cs b/Space Invaders/Program.cs
index 49244b1..bf9751d 100644
--- a/Space Invaders/Program.cs
+++ b/Space Invaders/Program.cs
@@ -3,10 +3,58 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using GameEngine;
+
+namespace SpaceInvaders {
-namespace Space_Invaders {
class Program {
static void Main(string[] args) {
+ Game SpaceInvaders = new SpaceInvaders();
+ SpaceInvaders.Setup();
+ SpaceInvaders.Start();
}
}
+
+ class SpaceInvaders : Game {
+
+ public override void Setup() {
+ // This sub is meant for setting the properties of the GameEngine. DO NOT MAKE NEW ONES HERE
+ // IMPORTANT! You might have to change the console font size, depending on how many rows and columns you want to have!
+ ConsoleWidth = 600; // Bigger than 15
+ ConsoleHeight = 120; // Bigger than 15
+ }
+
+ public override void Start() {
+ // Initialize all gameobjects here
+ GameObject gameLogic = new GameLogic();
+ gameLogic.Parent = this;
+ GameObjects.Add(gameLogic);
+
+ // Initialize the player
+ GameObject player = new Player();
+ player.Parent = this;
+ player.xPos = ConsoleWidth / 2 - 10;
+ player.yPos = 115;
+ player.Scale = 1;
+ GameObjects.Add(player);
+
+ // Init a monster
+ GameObject monster1 = new Monster();
+ GameObjects.Add(monster1);
+
+ // Init Obstacles
+
+ for (int i = 0; i < 6; i++) {
+ GameObject obstacle = new Obstacle();
+ player.Parent = this;
+ obstacle.xPos = 50 + (i * 90);
+ obstacle.yPos = 90;
+ GameObjects.Add(obstacle);
+ }
+
+ base.Start(); // Do start from inherited class, Required for the engine to actually start
+ }
+
+ }
+
}
diff --git a/Space Invaders/Space Invaders.csproj b/Space Invaders/Space Invaders.csproj
index 8762d4b..e636c8c 100644
--- a/Space Invaders/Space Invaders.csproj
+++ b/Space Invaders/Space Invaders.csproj
@@ -42,6 +42,9 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
+ <Compile Include="GameEngine\Graphics.cs" />
+ <Compile Include="GameObjects.cs" />
+ <Compile Include="GameEngine\GameEngine.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>