import { canvas, ctx } from './canvas' import { Level, Rock, Gold, Diamond, Lootbag } from './level' import { randomi } from './utils' const MAP_CLEARANCE_PERCENTAGE = 80 const REWARD_TABLE = { rock: 16, gold: [129, 543, 2399], diamond: 599, lootbag: [5, 5000] } export class Game { constructor (time, player, oh, gw, gh) { this.currentLevel = 0 this.player = player this.roundTime = time this.time = time this.score = 0 this.lastGoal = 0 this.goal = 0 this.level = null this.oh = oh this.gh = gh this.gw = gw this.message = null this.state = 0 this.wait = 0 } static calculateScore (obj, skipLoot) { if (obj instanceof Rock) { return REWARD_TABLE.rock * obj.size } if (obj instanceof Gold) { return REWARD_TABLE.gold[obj.size - 1] } if (obj instanceof Diamond) { return REWARD_TABLE.diamond } if (skipLoot) return 0 if (obj instanceof Lootbag) { let ssChance = randomi(0, 3) if (ssChance === 1) { return 'special' } return randomi(REWARD_TABLE.lootbag[0], REWARD_TABLE.lootbag[1]) } return 0 } static calculateLevelScore (level) { let total = 0 for (let i in level.objects) { total += Game.calculateScore(level.objects[i], true) } return total } nextLevel () { this.player.superStrength = false this.currentLevel++ this.time = this.roundTime this.level = Level.create(this.currentLevel, this.oh, this.gw, this.gh) this.lastGoal = this.goal this.goal = Math.floor(this.lastGoal + Game.calculateLevelScore(this.level) * (MAP_CLEARANCE_PERCENTAGE / 100)) this.player.hook.clear() } displayMessage (msg, time = 60) { this.message = { text: msg, time: time, duration: time } } scoredItem (obj) { let scored = Game.calculateScore(obj) if (scored === 'special') { this.displayMessage('SUPER STRENGTH!') this.player.superStrength = true return } this.displayMessage('$' + scored) this.score += scored } update () { ctx.oX = (canvas.width - this.gw) / 2 ctx.oY = (canvas.height - this.gh) / 2 if (this.state === 0 && this.time === 0) { if (this.score > this.goal) { this.state = 1 this.wait = 160 this.nextLevel() } else { this.state = 2 } } if (this.state === 1) { if (this.wait > 0) { this.wait-- } else { this.state = 0 } return } if (this.state !== 0) return if (this.message) { if (this.message.time > 0) { this.message.time-- } else { this.message = null } return } this.player.update(this.level) } tick () { if (this.state === 0 && this.time > 0) { this.time -= 1 } } draw () { if (this.state === 2) { ctx.fillStyle = '#ff1111' ctx.font = '20px sans-serif' let t = 'Game Over!' let s = 'Score: $' + this.score ctx.fillText(t, ctx.oX + this.gw / 2 - ctx.measureText(t).width / 2, ctx.oY + this.gh / 2 - 15) ctx.fillText(s, ctx.oX + this.gw / 2 - ctx.measureText(s).width / 2, ctx.oY + this.gh / 2 + 15) if (ctx.mouse['btn0']) { setTimeout(() => { this.currentLevel = 0 this.score = 0 this.lastGoal = 0 this.nextLevel() this.state = 0 }, 500) } return } if (this.state === 1) { ctx.fillStyle = '#05ff05' ctx.font = '20px sans-serif' let t = 'Level Cleared!' let s = 'Next Goal: $' + this.goal ctx.fillText(t, ctx.oX + this.gw / 2 - ctx.measureText(t).width / 2, ctx.oY + this.gh / 2 - 15) ctx.fillText(s, ctx.oX + this.gw / 2 - ctx.measureText(s).width / 2, ctx.oY + this.gh / 2 + 15) return } // Underground ctx.fillStyle = '#3a2201' ctx.fillRect(ctx.oX, ctx.oY, this.gw, this.gh) // Room ctx.fillStyle = '#b26b08' ctx.fillRect(ctx.oX, ctx.oY, this.gw, 25 + this.player.h) // Floor ctx.fillStyle = '#2b1a02' ctx.fillRect(ctx.oX, ctx.oY + 25 + this.player.h, this.gw, 15) if (this.level) this.level.draw() this.player.draw() ctx.fillStyle = '#05ff05' ctx.font = '20px sans-serif' ctx.fillText('Money: $' + this.score, ctx.oX + 20, ctx.oY + 30) ctx.fillStyle = '#eabb4d' ctx.fillText('Goal: $' + this.goal, ctx.oX + 20, ctx.oY + 62) ctx.fillStyle = '#05ff05' let time = 'Time: ' + this.time let ftsize = ctx.measureText(time) ctx.fillText(time, ctx.oX + this.gw - ftsize.width - 5, ctx.oY + 30) let round = 'Level ' + this.currentLevel let frsize = ctx.measureText(round) ctx.fillText(round, ctx.oX + this.gw - frsize.width - 5, ctx.oY + 62) if (this.message && this.message.time > 0) { let tfloat = this.message.duration - this.message.time ctx.fillStyle = '#05ff05' ctx.font = '20px sans-serif' ctx.fillText(this.message.text, ctx.oX + this.player.x - this.player.w - tfloat, ctx.oY + this.player.y + this.player.h / 2 - tfloat / 2) } } }