hook-miner/src/level.js

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
}
}