Skip to content

Commit

Permalink
Add bunker button and button enabling logic based on cost and last pr…
Browse files Browse the repository at this point in the history
…oduction
  • Loading branch information
twinprime committed Dec 31, 2020
1 parent b318396 commit 313cd91
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 42 deletions.
64 changes: 51 additions & 13 deletions src/BlueForceControl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,34 @@ import HomeBuildingGameObject from "./static-objects/HomeBuildingGameObject"
import SoldierGameObject from "./mobile-objects/SoldierGameObject"
import TankGameObject from "./mobile-objects/TankGameObject"
import VillageGameObject from "./static-objects/VillageGameObject"
import BunkerGameObject from "./static-objects/BunkerGameObject"

export default class BlueForceControl extends ForceControl {
private cash = 1000
private _cash = 1000
get cash(): number { return this._cash }
private cashDelta = 100
private cashUpdateInterval = 5000
private lastCashUpdate = 0
private cashText: Phaser.GameObjects.Text

private lastProduction = 0
private minProductionInterval = 3000
private productionEnabled = true
private ProductionButton = class extends GameButton {
constructor(control: BlueForceControl, readonly cost: number,
icon: Phaser.GameObjects.Sprite, onClick: () => void) {
super(control.scene, icon, () => {
if (control._cash >= cost) {
control.adjustCash(-cost)
control.lastProduction = control.scene.sys.game.getTime()
control.enableProduction(false)
onClick()
}
})
}
}
private productionButtons: GameButton[] = []

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

Expand All @@ -36,14 +56,13 @@ export default class BlueForceControl extends ForceControl {

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

new GameButton(scene, SoldierGameObject.createIcon(scene, screenWidth - 32, 32), () => {
this.adjustCash(-10)
this.buildSoldier()
})
new GameButton(scene, TankGameObject.createIcon(scene, screenWidth - 32, 69), () => {
this.adjustCash(-500)
this.buildTank()
})
this.productionButtons.push(new this.ProductionButton(this, 10,
SoldierGameObject.createIcon(scene, screenWidth - 32, 32), () => this.buildSoldier()))
this.productionButtons.push(new this.ProductionButton(this, 500,
TankGameObject.createIcon(scene, screenWidth - 32, 69), () => this.buildTank()))
this.productionButtons.push(new this.ProductionButton(this, 500,
BunkerGameObject.createIcon(scene, screenWidth- 32, 106),
() => this.buildBunker(this.factory.spawnX, this.liftableBodies)))

this.boardableBodies = scene.physics.add.group()

Expand Down Expand Up @@ -96,7 +115,7 @@ export default class BlueForceControl extends ForceControl {
const soldierOnBoardCountText = scene.add.text(onBoardCountX, 10, "0")
soldierOnBoardCountText.setScrollFactor(0, 0)

this.cashText = scene.add.text(10, healthBar.height + 20, `$${this.cash} +$${this.cashDelta}`)
this.cashText = scene.add.text(10, healthBar.height + 20, `$${this._cash} +$${this.cashDelta}`)
this.cashText.setScrollFactor(0, 0)

this._chopper = new ChopperGameObject(scene, 1, helipad, this.liftableBodies,
Expand All @@ -117,12 +136,31 @@ export default class BlueForceControl extends ForceControl {
this.adjustCash(this.cashDelta)
this.lastCashUpdate = time
}

if (!this.productionEnabled &&
(time - this.lastProduction) >= this.minProductionInterval) {
this.enableProduction(true)
}

super.update(time, delta)
}

private adjustCash(amt: number) {
this.cash += amt
this.cashText.setText(`$${this.cash} +$${this.cashDelta}`)
private enableProduction(enable: boolean) {
this.productionEnabled = enable
this.productionButtons.forEach(b => {
if (enable) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
const cost = (b as any).cost as number
if (b.enabled && cost > this._cash) b.enabled = false
else if (!b.enabled && cost <= this._cash) b.enabled = true
} else b.enabled = false
})
}

private adjustCash(amt: number): void {
this._cash += amt
this.cashText.setText(`$${this._cash} +$${this.cashDelta}`)
if (this.productionEnabled) this.enableProduction(true)
}

private buildVillage(x: number, homePos: number) {
Expand Down
3 changes: 1 addition & 2 deletions src/GameScene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ export default class GameScene extends Phaser.Scene {
constructor(readonly worldWidth: number, readonly worldHeight: number) {
super({
active: false,
visible: false,
key: 'Game',
visible: false
})
this.gameMap = new GameMap(worldWidth, 100)
}
Expand Down
19 changes: 17 additions & 2 deletions src/ReactGame.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import GameScene from './GameScene'

export class ReactGame extends React.Component {
private gameDivRef = React.createRef<HTMLDivElement>()
private game: Phaser.Game

render(): JSX.Element {
return <div id="game" ref={this.gameDivRef}></div>
}

componentDidMount(): void {
new Phaser.Game({
this.game = new Phaser.Game({
title: 'Sample',
type: Phaser.AUTO,

Expand All @@ -30,7 +31,21 @@ export class ReactGame extends React.Component {

parent: 'game',
backgroundColor: '#000000',
scene: new GameScene(1068 * 5, 600),
})
this.game.scene.add("main", new GameScene(1068 * 5, 600), true)
}

pause(): boolean {
if (this.game.scene.isPaused("main")) {
this.game.scene.resume("main")
return false
} else {
this.game.scene.pause("main")
return true
}
}

restart(): void {
this.game.scene.getScene("main").scene.restart()
}
}
49 changes: 33 additions & 16 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,42 @@ import './app.scss'
import Button from 'react-bootstrap/Button'
import { ReactGame } from './ReactGame'

function Example() {
// Declare a new state variable, which we'll call "count"
const [count, setCount] = React.useState(0);
function GameControl() {
const reactGame = React.createRef<ReactGame>()
const [paused, setPaused] = React.useState(false)

return (
<div>
<p>You clicked {count} times</p>
<Button onClick={() => setCount(count + 1)}>
Click me
</Button>
</div>
<div className="title"><img src="/logo.png"></img><span className="bigtext">Peace</span>{" "}<span className="smalltext">[is not an option]</span></div>
<ReactGame ref={reactGame} />
<div>
<Button onClick={() => setPaused(reactGame.current.pause())}>
{paused ? "Resume" : "Pause"}
</Button>
<Button onClick={() => reactGame.current.restart()}>
Restart
</Button>
</div>
<div>
<h3>Chopper Control</h3>
<p>Move chopper using W, S, A, D</p>
<p>If chopper is in the air and moving, hold Space to fire guns.</p>
<p>If chopper is in the air and stationary,</p>
<ul>
<li>Hold Space to lower lifting cables.</li>
<li>If lifting cables touches a liftable object, it will be attached to the chopper.</li>
<li>Lower the object on ground and press Space to release it.</li>
</ul>
<p>If chopper is on ground and stationary,</p>
<ul>
<li>Nearby civilians will run towards it to board</li>
<li>Soliders will not run towards it intentionally, but any soldier touching it will board</li>
<li>Press and hold Space any where except the helipad to alight any soldiers onboard</li>
<li>Press and hold Space on helipad to alight any civilians onboard</li>
</ul>
</div>
</div>
);
}

ReactDOM.render(
<div>
<div className="title"><img src="/logo.png"></img><span className="bigtext">Peace</span>{" "}<span className="smalltext">[is not an option]</span></div>
<ReactGame />
<Example />
</div>,
document.getElementById('root'),
)
ReactDOM.render(<GameControl />, document.getElementById('root'))
6 changes: 6 additions & 0 deletions src/static-objects/BunkerGameObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,10 @@ export default class BunkerGameObject extends SpriteGameObject {
static preload(scene: GameScene): void {
scene.load.image("bunker", "/images/bunker.png")
}

static createIcon(scene: GameScene, x: number, y: number): Phaser.GameObjects.Sprite {
const icon = scene.add.sprite(x, y, "bunker")
// icon.setScale(0.35, 0.35)
return icon
}
}
30 changes: 21 additions & 9 deletions src/ui-objects/GameButton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,35 @@ import GameScene from "../GameScene"

export default class GameButton {
private pointerDown = false
private _enabled = true
set enabled(enable: boolean) {
this._enabled = enable
if (this._enabled) this.icon.clearTint()
else this.icon.setTint(0x888888)
}

constructor(scene: GameScene, icon: Phaser.GameObjects.Sprite, onClick: () => void) {
constructor(scene: GameScene, private readonly icon: Phaser.GameObjects.Sprite, onClick: () => void) {
icon.setScrollFactor(0, 0)
icon.setInteractive()
icon.on("pointerdown", () => {
icon.setTint(0xff0000)
this.pointerDown = true
if (this._enabled) {
icon.setTint(0xff0000)
this.pointerDown = true
}
})
icon.on("pointerout", () => {
icon.clearTint()
this.pointerDown = false
if (this._enabled) {
icon.clearTint()
this.pointerDown = false
}
})
icon.on("pointerup", () => {
icon.clearTint()
if (this.pointerDown) {
this.pointerDown = false
onClick()
if (this._enabled) {
icon.clearTint()
if (this.pointerDown) {
this.pointerDown = false
onClick()
}
}
})
}
Expand Down

0 comments on commit 313cd91

Please sign in to comment.