Skip to content

Commit

Permalink
Create sub-folders in src. Add scan stop shoot behaviour to tank.
Browse files Browse the repository at this point in the history
  • Loading branch information
twinprime committed Dec 25, 2020
1 parent bf3750b commit aee4e15
Show file tree
Hide file tree
Showing 30 changed files with 416 additions and 230 deletions.
3 changes: 2 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ node_modules
dist
# don't lint nyc coverage output
coverage
jest.config.js
jest.config.js
tests
76 changes: 38 additions & 38 deletions src/BlueForceControl.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,40 @@
import AAGunGameObject from "./AAGunGameObject"
import BarrackGameObject from "./BarrackGameObject"
import ChopperGameObject from "./ChopperGameObject"
import CivilianGameObject from "./CivilianGameObject"
import FactoryGameObject from "./FactoryGameObject"
import GameButton from "./GameButton"
import AAGunGameObject from "./static-objects/AAGunGameObject"
import BarrackGameObject from "./static-objects/BarrackGameObject"
import ChopperGameObject from "./mobile-objects/ChopperGameObject"
import CivilianGameObject from "./mobile-objects/CivilianGameObject"
import FactoryGameObject from "./static-objects/FactoryGameObject"
import ForceControl from "./ForceControl"
import GameButton from "./ui-objects/GameButton"
import GameScene from "./GameScene"
import HealthBarGameObject from "./HealthBarGameObject"
import HelipadGameObject from "./HelipadGameObject"
import HomeBuildingGameObject from "./HomeBuildingGameObject"
import SoldierGameObject from "./SoldierGameObject"
import TankGameObject from "./TankGameObject"
import VillageGameObject from "./VillageGameObject"

export default class BlueForceControl {
private scene: GameScene
import HealthBarGameObject from "./ui-objects/HealthBarGameObject"
import HelipadGameObject from "./static-objects/HelipadGameObject"
import HomeBuildingGameObject from "./static-objects/HomeBuildingGameObject"
import SoldierGameObject from "./mobile-objects/SoldierGameObject"
import TankGameObject from "./mobile-objects/TankGameObject"
import VillageGameObject from "./static-objects/VillageGameObject"

export default class BlueForceControl extends ForceControl {
private cash = 1000
private cashDelta = 100
private cashUpdateInterval = 5000
private lastCashUpdate = 0
private cashText: Phaser.GameObjects.Text
private factory: FactoryGameObject
private barrack: BarrackGameObject
private villages: VillageGameObject[] = []
private aaGunObjects: AAGunGameObject[] = []
private tankObjects: TankGameObject[] = []
private soliderObjects: SoldierGameObject[] = []

private liftableBodies: Phaser.Physics.Arcade.Group
private boardableBodies: Phaser.Physics.Arcade.Group
private villages = new Set<VillageGameObject>()
private aaGunObjects= new Set<AAGunGameObject>()

protected factory: FactoryGameObject
protected barrack: BarrackGameObject
protected tankObjects = new Set<TankGameObject>()
protected soliderObjects = new Set<SoldierGameObject>()
protected boardableBodies: Phaser.Physics.Arcade.Group

private _chopper: ChopperGameObject
get chopper(): ChopperGameObject { return this._chopper }

constructor(scene: GameScene) {
this.scene = scene
super(scene, 1)

const screenWidth = scene.sys.scale.gameSize.width

Expand Down Expand Up @@ -66,7 +68,7 @@ export default class BlueForceControl {
nextPos += 100
const aaGun = new AAGunGameObject(scene, 1, this.liftableBodies,
nextPos + 16, 3 * Math.PI / 4)
this.aaGunObjects.push(aaGun)
this.aaGunObjects.add(aaGun)
nextPos += 32 + 15

nextPos += 100
Expand All @@ -75,7 +77,7 @@ export default class BlueForceControl {
this.cashDelta += 100
this.adjustCash(0)
})
this.villages.push(village)
this.villages.add(village)
nextPos += 128 + 15

const healthBar = new HealthBarGameObject(scene, 10, 15, 100)
Expand Down Expand Up @@ -103,34 +105,32 @@ export default class BlueForceControl {
soldierOnBoardCountText.setText(`${humans.get(SoldierGameObject.TYPE)?.length ?? 0}`)
civilianOnBoardCountText.setText(`${humans.get(CivilianGameObject.TYPE)?.length ?? 0}`)
})
this.scene.gameMap.add(this._chopper)

const soldier = new SoldierGameObject(this.scene, this.owner, this.scene.worldWidth - 1000, this.boardableBodies)
soldier.move(10)
this.soliderObjects.add(soldier)
this.scene.gameMap.add(soldier)
soldier.destroyCallback = () => {
this.soliderObjects.delete(soldier)
this.scene.gameMap.remove(soldier)
}
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
update(time: number, delta: number): void {
this._chopper.update(time, delta)
this.villages.forEach(v => v.update(time, delta))
this.aaGunObjects.forEach(gun => gun.update(time))
this.soliderObjects.forEach(soldier => soldier.update(time, delta))
if ((time - this.lastCashUpdate) >= this.cashUpdateInterval) {
this.adjustCash(this.cashDelta)
this.lastCashUpdate = time
}
super.update(time, delta)
}

private adjustCash(amt: number) {
this.cash += amt
this.cashText.setText(`$${this.cash} +$${this.cashDelta}`)
}

private buildTank() {
const tank = new TankGameObject(this.scene, 1, this.factory.spawnX)
tank.move(50, false)
this.tankObjects.push(tank)
}

private buildSoldier() {
const soldier = new SoldierGameObject(this.scene, 1, this.barrack.spawnX, this.boardableBodies)
soldier.move(10, false)
this.soliderObjects.push(soldier)
}
}
43 changes: 43 additions & 0 deletions src/ForceControl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import BarrackGameObject from "./static-objects/BarrackGameObject"
import FactoryGameObject from "./static-objects/FactoryGameObject"
import GameScene from "./GameScene"
import SoldierGameObject from "./mobile-objects/SoldierGameObject"
import TankGameObject from "./mobile-objects/TankGameObject"

export default abstract class ForceControl {
protected abstract factory: FactoryGameObject
protected abstract barrack: BarrackGameObject
protected abstract boardableBodies: Phaser.Physics.Arcade.Group

protected tankObjects = new Set<TankGameObject>()
protected soliderObjects = new Set<SoldierGameObject>()

constructor(protected readonly scene: GameScene, protected readonly owner: number) {}

update(time: number, delta: number): void {
this.soliderObjects.forEach(soldier => soldier.update(time, delta))
this.tankObjects.forEach(tank => tank.update(time))
}

protected buildTank(): void {
const tank = new TankGameObject(this.scene, this.owner, this.factory.spawnX, 50)
tank.move(50 * this.owner, this.owner < 0)
this.tankObjects.add(tank)
this.scene.gameMap.add(tank)
tank.destroyCallback = () => {
this.tankObjects.delete(tank)
this.scene.gameMap.remove(tank)
}
}

protected buildSoldier(): void {
const soldier = new SoldierGameObject(this.scene, this.owner, this.barrack.spawnX, this.boardableBodies)
soldier.move(10 * this.owner, this.owner < 0)
this.soliderObjects.add(soldier)
this.scene.gameMap.add(soldier)
soldier.destroyCallback = () => {
this.soliderObjects.delete(soldier)
this.scene.gameMap.remove(soldier)
}
}
}
36 changes: 26 additions & 10 deletions src/GameMap.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import GameObject from "./GameObject"

export default class GameMap {
private static readonly updateInterval = 250
private static readonly updateInterval = 32

private readonly cellCount: number
private lastUpdate = 0
private gameObjects = new Map<number, Set<GameObject>[]>()
private gameObjectCells = new Map<GameObject, number[]>()

constructor(readonly mapSize: number, readonly cellWidth: number) {
const cells = Math.ceil(mapSize / cellWidth)
const redCells = new Array(cells)
const blueCells = new Array(cells)
for (let i = 0; i < cells; i++) {
this.cellCount = Math.ceil(mapSize / cellWidth)
const redCells = new Array(this.cellCount)
const blueCells = new Array(this.cellCount)
for (let i = 0; i < this.cellCount; i++) {
redCells[i] = new Set()
blueCells[i] = new Set()
}
Expand All @@ -23,7 +24,6 @@ export default class GameMap {
const objs = this.gameObjects.get(obj.owner)
if (objs) {
const cells = [this.getCell(obj.x1), this.getCell(obj.x2)]
console.log(`Add object in ${cells[0]} - ${cells[1]}`)
for (let i = cells[0]; i <= cells[1]; i++) objs[i].add(obj)
this.gameObjectCells.set(obj, cells)
}
Expand All @@ -41,21 +41,35 @@ export default class GameMap {
filter?: (obj: GameObject) => boolean): Set<GameObject> {
const c1 = this.getCell(x1)
const c2 = this.getCell(x2)
console.log(`get objects in ${c1} - ${c2}`)
const result = new Set<GameObject>()
const objs = this.gameObjects.get(owner)
for (let c = c1; c <= c2; c++) {
objs[c].forEach(o => {
if (this.overlaps(o.x1, o.x2, x1, x2) && (!filter || filter(o))) result.add(o)
if (this.overlaps(o.x1, o.x2, x1, x2) && (!filter || filter(o))) {
result.add(o)
}
})
}
return result
}

getObjectsFrom(thisObj: GameObject, thatOwner: number,
startOffset: number, distance: number,
filter?: (obj: GameObject) => boolean): Set<GameObject> {
if (thisObj.owner > 0) {
return this.getObjectsWithin(thatOwner, thisObj.x1 + startOffset,
thisObj.x1 + startOffset + distance, filter)
} else {
return this.getObjectsWithin(thatOwner, thisObj.x1 - startOffset - distance,
thisObj.x1 - startOffset, filter)
}
}

private overlaps(a1: number, a2: number, b1: number, b2: number) {
return !(b2 < a1 || b1 > a2)
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
update(time: number, delta: number): void {
if ((time - this.lastUpdate) >= GameMap.updateInterval) {
this.lastUpdate = time
Expand All @@ -76,5 +90,7 @@ export default class GameMap {
}
}

private getCell(x: number) { return Math.floor(x / this.cellWidth) }
private getCell(x: number) {
return Math.min(this.cellCount - 1, Math.max(0, Math.floor(x / this.cellWidth)))
}
}
9 changes: 8 additions & 1 deletion src/GameObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ interface WrappedPhaserGameObject {
}

export default abstract class GameObject {
constructor(readonly scene: GameScene, public owner: number) {}
protected _destroyCallback: () => void
set destroyCallback(cb: () => void) { this._destroyCallback = cb }

abstract readonly x1: number
abstract readonly x2: number
Expand All @@ -14,9 +15,15 @@ export default abstract class GameObject {
abstract readonly width: number
abstract readonly height: number

constructor(readonly scene: GameScene, public owner: number) {}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
moveTo(x: number, y: number): void { throw "object cannot be moved" }

abstract remove(): void

removed(): void { this._destroyCallback?.() }

addWrapperProperty(obj: Phaser.GameObjects.GameObject): void {
(obj as unknown as WrappedPhaserGameObject).wrapper = this
}
Expand Down
Loading

0 comments on commit aee4e15

Please sign in to comment.