Overview:

Tank Wars is a top down shooter game designed in C#. It includes features such as local multiplayer gameplay using C#’s NetworkUtil library for communicating packets from the host and client. While also using Multithreading to optimize the communication of the game physics. The game was coded entirely using a Model-View-Controller (MVC) architecture.


How It Works

Controls

ArrowKeysMove.png

Move tank

MoveMouse.png

Move Turret

LeftClickShoot.png

Shoot Primary

RightClickBeam.png

Shoot Secondary

Multiplayer

Untitled

The application utilizes a server application to receive player requests(top left). Client applications (right) connects and displays the game. (Bottom left) json data representing game physics for each player


Class Diagram

classDiagram

class View{
drawingPanel
menuSize
leftPressed
downPressed
rightpRessed
upPressed
theWorld
viewHeight
viewWidth
-HandShakeUpdate void 
-CreateBeamAnimation(Beam b) void
-HandleKeyDown(sender:object , e:KeyEventArgs ) void
-HandleKeyUp(sender:Object, e:KeyEventArgs ) void
-HandleMouseDown(sender:Object, e:MouseEventArgs )
-HandleMouseUp(sender:object , e:MouseEventArgs )
-HandleMouseMove(sender:object , e:MouseEventArgs )
-connectButton_Click(sender:object , e:EventArgs )
-ConnectionErrorHandler() void
-ServerDiedHandler() void
-HandleWindowResize(sender:object , e:EventArgs ) void
}

class Beam{
+id : int
+owner : int
+Beam(Vector2d,Vector2d,int) void
+ToSTring() string
}

class ControlCommand{
+controlCommand() void 
+Direction:Vector2D 
+Fire:string
+Moving:string
}

class Powerup{
+Id : int
+died : bool 

+PowerUp(Vector2d) void
+ToString() string
}

class Projectile{
+Id : int
+loc : Vector2D
+dir : Vector2D
+died : bool
+owner : int

+Projectile(Vector2D,Vector2D,bool,int) void
+ToString() string
}

class Settings{
+Settings(string) void
}

class Wall{
+Id:int
+p1:Vector2D 
[JsonProperty]
+p2:Vector2D 

+lowerColBound:Vector2D 
+higherColBound:Vector2D 

+WallSize:int
-static int nextId = 0;
}

class World{
-Settings : Settings
+WorldSize : int
+walls : Dictionary<int, Wall>
+yoshi : Dictionary<int, Yoshi>
+projectiles : Dictionary<int, Projectiles>
+powerups : Dictionary<int, PowerUp>
+beams : Dictionary<int, Beams>
+nextPowerupSpawn : int 
+nextTankSpawn : int
+rand : Random

+world(Settings)
+world(int)
+Update() void
+Intersects(Vector2D,Vector2d,Vector2D,double) bool
+setRAndomLocation() Vector2D

}
Model<-- Wall

World --> Settings
World --> Model

class Yoshi{
+Id : int
+name : String
+loc : Vector2D <get, set> 
+bdir : Vector2D <get, set> 
+tdir : Vector2D <get, set> 
+score : int <get, set>
+hp : int <get, set>
+died : bool <get, set>
+dc : bool <get, set>
+join : bool <get, set>
+vel : Vector2D <get, set>
+shotCooldown : int; 
+canFire : bool ;
+nextRespawn : int <get, set>
+powerUpCollected : int <get, set>
-MaxHP : int;
+EnginePower : double; 
+YoshiSize : int <get, set>

+Yoshi(int,string,int,int,double,int,Vector2D )

}

class Controller{
-playerName:string
-WorldSize:int
+Id:int

-socketState:SocketStat
-cmd:ControlCommand

-fire:string
-turretDir:Vector2D 

-ServerUpdateHandler:delegate void 
-StartUpDataArrived:event ServerUpdateHandler 
-UpdateArrived:event ServerUpdateHandler 
-ServerDied:event ServerUpdateHandler 
-ConnectionError:event ServerUpdateHandler 

+BeamAnimator(b:Beam) delegate void 
+DeathAnimator(y:Yoshi) delegate void 
+BeamArrived:delegate void 
+DeathArrived:delegate void 
}
Controller --> Model
Model<-- Projectile
Model<-- Settings

View <--> Controller
Model<-- Yoshi
Model<-- Beam
Model<-- ControlCommand
Model <-- Powerup

View ..> Model : read Only