196 lines
4.8 KiB
JavaScript
196 lines
4.8 KiB
JavaScript
import { canvas, ctx } from './canvas'
|
|
import { Level, Rock, Gold, Diamond, Lootbag } from './level'
|
|
import { randomi } from './utils'
|
|
|
|
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.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.goal = Math.floor(this.score / 2 + Game.calculateLevelScore(this.level) * 0.65)
|
|
}
|
|
|
|
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.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)
|
|
}
|
|
}
|
|
}
|