212 lines
4.5 KiB
JavaScript
212 lines
4.5 KiB
JavaScript
import { ctx } from './canvas'
|
|
import { randomi, distanceTo } from './utils'
|
|
import RES from './resource'
|
|
|
|
const OFFSET = 50
|
|
const TNT_START = 5
|
|
const DIAMOND_START = 3
|
|
|
|
// Objects
|
|
|
|
export class GameObject {
|
|
constructor (x, y, w, h, img) {
|
|
this.x = x
|
|
this.y = y
|
|
this.w = w
|
|
this.h = h
|
|
this.img = img
|
|
this.physical = true
|
|
}
|
|
|
|
draw () {
|
|
if (!this.physical) return
|
|
if (this.img.indexOf('#') === 0) {
|
|
ctx.fillStyle = this.img
|
|
ctx.fillRect(ctx.oX + this.x, ctx.oY + this.y, this.w, this.h)
|
|
} else {
|
|
ctx.drawImage(RES.loadImage(this.img, true), ctx.oX + this.x, ctx.oY + this.y, this.w, this.h)
|
|
}
|
|
}
|
|
|
|
destroy () {
|
|
this.physical = false
|
|
}
|
|
|
|
get weight () {
|
|
return 0.1
|
|
}
|
|
}
|
|
|
|
export class Rock extends GameObject {
|
|
constructor (x, y, size) {
|
|
let o = size * 20
|
|
super(x, y, o, o, 'static/rock_' + size + '.png')
|
|
this.size = size
|
|
}
|
|
|
|
get weight () {
|
|
return Math.min(0.20 * this.size, 1)
|
|
}
|
|
}
|
|
|
|
export class Gold extends GameObject {
|
|
constructor (x, y, size) {
|
|
let o = size * 24
|
|
super(x, y, o, o, 'static/gold_' + size + '.png')
|
|
this.size = size
|
|
}
|
|
|
|
get weight () {
|
|
return Math.min(0.25 * this.size, 1)
|
|
}
|
|
}
|
|
|
|
export class Diamond extends GameObject {
|
|
constructor (x, y) {
|
|
super(x, y, 16, 16, 'static/diamond.png')
|
|
}
|
|
|
|
get weight () {
|
|
return 0.11
|
|
}
|
|
}
|
|
|
|
export class Lootbag extends GameObject {
|
|
constructor (x, y) {
|
|
super(x, y, 30, 30, 'static/loot.png')
|
|
}
|
|
|
|
get weight () {
|
|
return 0.45
|
|
}
|
|
}
|
|
|
|
export class BarrelPiece extends GameObject {
|
|
constructor (x, y) {
|
|
super(x, y, 30, 18, 'static/barrel_piece.png')
|
|
}
|
|
|
|
get weight () {
|
|
return 0.05
|
|
}
|
|
}
|
|
|
|
export class TNTBarrel extends GameObject {
|
|
constructor (x, y) {
|
|
super(x, y, 40, 55, 'static/tnt.png')
|
|
this.radius = 156
|
|
}
|
|
|
|
get weight () {
|
|
return 0.0
|
|
}
|
|
|
|
explode (level) {
|
|
for (let i in level.objects) {
|
|
let obj = level.objects[i]
|
|
if (distanceTo(obj, this) < this.radius) {
|
|
if (obj instanceof TNTBarrel && obj !== this && obj.physical) {
|
|
obj.explode(level)
|
|
continue
|
|
}
|
|
obj.destroy()
|
|
}
|
|
}
|
|
this.destroy()
|
|
level.placeExplosion(this.x, this.y, this.radius)
|
|
let b = new BarrelPiece(this.x, this.y)
|
|
level.objects.push(b)
|
|
return b
|
|
}
|
|
}
|
|
|
|
// Level
|
|
|
|
export class Level {
|
|
constructor (id, objects) {
|
|
this.id = id
|
|
this.objects = objects || []
|
|
this.explosions = []
|
|
}
|
|
|
|
placeExplosion (x, y, r) {
|
|
this.explosions.push({ x, y, time: 30, r })
|
|
}
|
|
|
|
draw () {
|
|
for (let i in this.objects) {
|
|
this.objects[i].draw()
|
|
}
|
|
|
|
let expl = RES.loadImage('static/explosion.png', true)
|
|
for (let i in this.explosions) {
|
|
let ex = this.explosions[i]
|
|
let r = ex.r * 1.5
|
|
ctx.drawImage(expl, ctx.oX + ex.x - r / 2, ctx.oY + ex.y - r / 2, r, r)
|
|
}
|
|
}
|
|
|
|
update () {
|
|
let toKeep = []
|
|
for (let i in this.explosions) {
|
|
let ex = this.explosions[i]
|
|
if (ex.time > 0) {
|
|
ex.time--
|
|
ex.r -= randomi(-10, 10)
|
|
toKeep.push(ex)
|
|
continue
|
|
}
|
|
}
|
|
this.explosions = toKeep
|
|
}
|
|
|
|
static create (index, my, width, height) {
|
|
let objects = []
|
|
let rocks = randomi(4, 12)
|
|
let gold = randomi(4, 12)
|
|
let diamond = index >= DIAMOND_START ? randomi(0, 2) : 0
|
|
let loot = randomi(0, 2)
|
|
let tnt = index >= TNT_START ? randomi(0, 4) : 0
|
|
|
|
// Add rocks
|
|
for (let r = 0; r < rocks; r++) {
|
|
let x = randomi(OFFSET, width - OFFSET)
|
|
let y = randomi(OFFSET + my, height - (OFFSET + my))
|
|
let size = randomi(1, 4)
|
|
objects.push(new Rock(x, y, size))
|
|
}
|
|
|
|
// Add gold
|
|
for (let r = 0; r < gold; r++) {
|
|
let x = randomi(OFFSET, width - OFFSET)
|
|
let y = randomi(OFFSET + my, height - (OFFSET + my))
|
|
let size = randomi(1, 4)
|
|
objects.push(new Gold(x, y, size))
|
|
}
|
|
|
|
// Add diamonds
|
|
for (let r = 0; r < diamond; r++) {
|
|
let x = randomi(OFFSET, width - OFFSET)
|
|
let y = randomi(OFFSET + my, height - (OFFSET + my))
|
|
objects.push(new Diamond(x, y))
|
|
}
|
|
|
|
// Add loot
|
|
for (let r = 0; r < loot; r++) {
|
|
let x = randomi(OFFSET, width - OFFSET)
|
|
let y = randomi(OFFSET + my, height - (OFFSET + my))
|
|
objects.push(new Lootbag(x, y))
|
|
}
|
|
|
|
// Add TNT
|
|
for (let r = 0; r < tnt; r++) {
|
|
let x = randomi(OFFSET, width - OFFSET)
|
|
let y = randomi(OFFSET + my + 10, height - (OFFSET + my) - 10)
|
|
objects.push(new TNTBarrel(x, y))
|
|
}
|
|
|
|
let n = new Level(index, objects)
|
|
return n
|
|
}
|
|
}
|