This project is a top-down shooter made in Typescript. It was made as a school assignment with the purpose of learning OOP Design patterns and principles.
I really like games with smooth mechanics so I've put extra attention on that in this game. For example, if you pay close attention the bullets and gunshot effect actually originate from the gun barrels and the enemy AI's vision comes from their heads. If they can't see you, they won't shoot you. Next to that I've also added blood, bullet trace and bullet impact particles, because it looks nice.
The goal of the game is to kill all the enemies and complete all levels. Some enemies move vertically or horizontally and some have a better gun than others. Plan your moves carefully and try to expose yourself as less as possible. The levels become harder as you complete them and if you die you need to start at level 1.
You can play the game on these Github Docs.
- Clone / Fork the project
- Install using NPM
npm install
- Edit code & build using Typescript compiler of Visual Studio Code with
ctrl+b
- Start express web server
- You can also create levels yourself by installing *Tiled and using the .tsx files in
docs/maps/*
as examples. (However, currently the levels are hard-coded inInit.ts
andMapLoader.ts
. So you would need your custom levels there too, you'll figure it out.)
node app
- Local game can be played at
localhost
Onderstaand de Klassendiagram (UML), klik voor groter scherm.
De class Game
is een singleton omdat er maar 1 instantie van kan bestaan in het spel. Door de private constructor kan hij niet ge-instantiate worden vanuit andere classes dan zichzelf.
Polymorfisme word op vele plekken toegepast. Zo zijn Player
en EnemySoldier
een extension van een abstract Entity
, en een Entity
een extension van een abstract GameObject
. Ook is heeft een Entity
een Gun
, welke zowel een Pistol
als een Machinegun
kan zijn. Deze Gun
weet wie zijn subject
(eigenaar is) en roept bijvoorbeeld de ReloadBar
en AmmoBar
van zijn subject
aan als de Gun
schiet.
Ook heeft Game
een Array met gameObjects[]
, dit kunnen zowel Entity
's zijn (Player
en EnemyPlayer
) als Item
's (pickups), want die zijn allemaal gameObject
.
Een Entity
kan een Gun
hebben. Er zijn 2 soorten Gun's in het spel: Pistol
en MachineGun
, deze extenden de abstracte class Gun
. Als een entity zijn shoot()
method word aangeroepen word de Gun.shoot()
aangeroepen. Deze verschilt per Gun
want een Pistol
heeft bijvoorbeeld minder kogels dan een MachineGun
en kan sneller achter elkaar schieten, maar heeft ook een grotere fire spread (minder accuraat).
Ook kan de speler d.m.v pickups Item
's oppakken. Hierdoor kan hij zowel een Pistol
als een MachineGun
oppakken en veranderd de speler (en EnemySoldier's) zijn Gun
property.
Een Entity
heeft meerdere classes die afhankelijk van hem zijn. Daarop heeft de Entity
een Subject interface
en heeft hij meerdere Observers[]
. Elke keer als een Entity
zijn update()
method uitvoerd, voert hij ook de Observer.update()
uit voor elke observer.
De game bevat meerdere game componenten.
Ik gebruik PixiJS om de game te renderen. WebGL zorgt ervoor dat de browser de GPU kan gebruiken om betere resultaten te leveren.
Ik gebruik de TiledMap, Bump en Pixi-Particles libraries. Tiledmap zorgt ervoor dat ik *Tiled levels kan maken vanuit een spritesheet. Deze levels zijn .tsx
bestanden welke automatisch ingeladen worden door de game en zorgt ervoor dat alle tiles (vanuit de spritesheet) als game objecten door Pixi
worden gezien. Dit werkt ook met verschillende layers van tiles, hierdoor kan ik onderscheid maken tussen muren en vloeren. Muren worden namelijk automatisch herkent als muur waardoor de collision scripts hier rekening mee houden.
Bump gebruik ik voor de collision tussen bullets
, players
en walls
.
Pixi-particles gebuik ik voor alle particles die te zien zijn: bloed, bullet traces, bullet impact en een gunshot animation. Dit zijn allemaal particle emitters waarvoor ik een speciale class heb gemaakt: Emitter
De enemies zijn "slim", ze kunnen lopen en detecteren wanneer ze zicht hebben op de speler.
Gebruik van spritesheet, dus consistent en ook meerdere particle effect. Ook zijn er UI's, zoals Startscherm, eindscherm, level complete scherm, etc.
De game heeft meerdere geluiden.
Er zijn een aantal levels in het spel die moeilijker worden per level.
Pull request Week 4 for Milan's game: Link Code review Week 6 for Imani's game: Link