mining drill and tile damage

This commit is contained in:
Evert Prants 2020-01-14 21:33:17 +02:00
parent 8eb371c090
commit 4b7f58dfab
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
7 changed files with 136 additions and 59 deletions

BIN
assets/item_drill.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 553 B

View File

@ -25,6 +25,8 @@ const tileSize = 16
let world = new World(height, { GROUND: map }, chunkSize, tileSize, 32, 64) let world = new World(height, { GROUND: map }, chunkSize, tileSize, 32, 64)
p.inv.addItem('drill')
function update (dt) { function update (dt) {
world.update(dt, vp) world.update(dt, vp)
p.update(dt, vp, world) p.update(dt, vp, world)
@ -82,7 +84,7 @@ function start () {
async function loadAll () { async function loadAll () {
let images = ['assets/ground.png', 'assets/item_grass.png', let images = ['assets/ground.png', 'assets/item_grass.png',
'assets/item_dirt.png', 'assets/item_stone.png'] 'assets/item_dirt.png', 'assets/item_stone.png', 'assets/item_drill.png']
for (let i in images) { for (let i in images) {
await RES.loadImage(images[i]) await RES.loadImage(images[i])
} }

View File

@ -1,5 +1,5 @@
import { canvas, ctx } from './canvas' import { canvas, ctx } from './canvas'
import { Item, ItemStack, MAX_STACK_SIZE } from './items' import { Item, ItemTool, ItemStack, MAX_STACK_SIZE } from './items'
const SLOT_SIZE = 32 const SLOT_SIZE = 32
@ -76,6 +76,7 @@ class Inventory {
ctx.fillRect(x, 16, SLOT_SIZE, SLOT_SIZE) ctx.fillRect(x, 16, SLOT_SIZE, SLOT_SIZE)
if (!stack || stack.isEmpty()) continue if (!stack || stack.isEmpty()) continue
ctx.drawImage(stack.item.image, x, 16, SLOT_SIZE, SLOT_SIZE) ctx.drawImage(stack.item.image, x, 16, SLOT_SIZE, SLOT_SIZE)
if (stack.item instanceof ItemTool) continue
ctx.font = '16px sans' ctx.font = '16px sans'
let measure = ctx.measureText(stack.count) let measure = ctx.measureText(stack.count)
ctx.fillStyle = '#000' ctx.fillStyle = '#000'

View File

@ -1,4 +1,6 @@
import RES from './resource' import RES from './resource'
import { ItemEntity } from './entity'
import Input from './input'
const MAX_STACK_SIZE = 999 const MAX_STACK_SIZE = 999
@ -37,9 +39,43 @@ class ItemPlaceable extends Item {
} }
class ItemTool extends Item { class ItemTool extends Item {
use (dt, world, player) {} use (dt, vp, world, player) {}
useSecondary (dt, world, player) {} useSecondary (dt, vp, world, player) {}
}
class ItemMiningTool extends ItemTool {
constructor (name, img, power, description) {
super(name, img, description)
this.power = power
}
mine (l, dt, vp, world, player) {
let mabs = { x: Input.mouse.pos.x + vp.x, y: Input.mouse.pos.y + vp.y }
let mpin = world.gridPosition(mabs)
if (!mpin.chunk) return false
let layer = mpin.chunk.getLayer(l)
let tile = layer.tileAtXY(mpin.tile.x, mpin.tile.y)
if (tile === -1) return false
let broken = layer.damageTileAtXY(mpin.tile.x, mpin.tile.y, this.power)
if (!broken) return false
let itile = layer.map.getTileByID(tile)
let success = mpin.chunk.setTile(l, mpin.tile, layer.map.indexOf('AIR'))
if (success) {
let e = ItemEntity.new(ItemStack.new(itile.item, 1), mabs.x - 8, mabs.y - 8)
let p = world.getLayer('ents')
p.entities.push(e)
return true
}
}
use (dt, vp, world, player) {
return this.mine('fg', dt, vp, world, player)
}
useSecondary (dt, vp, world, player) {
return this.mine('bg', dt, vp, world, player)
}
} }
class ItemStack { class ItemStack {
@ -94,4 +130,4 @@ class ItemStack {
} }
} }
export { Item, ItemPlaceable, ItemTool, ItemStack, ItemRegistry, MAX_STACK_SIZE } export { Item, ItemPlaceable, ItemTool, ItemMiningTool, ItemStack, ItemRegistry, MAX_STACK_SIZE }

View File

@ -16,38 +16,37 @@ class Player extends PhysicsEntity {
this.itemPickUpDistance = 40 this.itemPickUpDistance = 40
} }
handleTool (dt, vp, world) { place (layer, vp, world) {
let mabs = { x: Input.mouse.pos.x + vp.x, y: Input.mouse.pos.y + vp.y } let mabs = { x: Input.mouse.pos.x + vp.x, y: Input.mouse.pos.y + vp.y }
let mpin = world.gridPosition(mabs) let mpin = world.gridPosition(mabs)
if (Input.mouse['btn0']) { if (mpin.chunk) {
if (mpin.chunk) { if (this.inv.isEmpty(this.inv.selected)) return
if (this.inv.isEmpty(this.inv.selected)) return let tile = mpin.chunk.getTile(layer, mpin.tile)
let tile = mpin.chunk.getTile('fg', mpin.tile) if (tile !== -1) return
if (tile !== -1) return let itm = this.inv.getItem(this.inv.selected)
let itm = this.inv.getItem(this.inv.selected) if (itm && itm.item.placeable) {
if (itm && itm.item.placeable) { let success = mpin.chunk.setTile(layer, mpin.tile, itm.item.placeable.id)
let success = mpin.chunk.setTile('fg', mpin.tile, itm.item.placeable.id)
if (success) {
this.inv.takeItem(this.inv.selected, 1)
}
}
}
} else if (Input.mouse['btn2']) {
if (mpin.chunk) {
let layer = mpin.chunk.getLayer('fg')
let tile = layer.tileAtXY(mpin.tile.x, mpin.tile.y)
if (tile === -1) return
let itile = layer.map.getTileByID(tile)
let success = mpin.chunk.setTile('fg', mpin.tile, layer.map.indexOf('AIR'))
if (success) { if (success) {
let e = ItemEntity.new(ItemStack.new(itile.item, 1), mabs.x - 8, mabs.y - 8) this.inv.takeItem(this.inv.selected, 1)
let p = world.getLayer('ents')
p.entities.push(e)
} }
} }
} }
} }
handleTool (dt, vp, world) {
if (!Input.mouse['btn0'] && !Input.mouse['btn2']) return
let item = this.inv.getItem(this.inv.selected)
if (item) item = item.item
if (!item) return
if (Input.mouse['btn0']) {
if (item.use) return item.use(dt, vp, world, this)
if (item.placeable) return this.place('fg', vp, world)
} else if (Input.mouse['btn2']) {
if (item.useSecondary) return item.useSecondary(dt, vp, world, this)
if (item.placeable) return this.place('bg', vp, world)
}
}
handleMovement (dt, vp, world) { handleMovement (dt, vp, world) {
this.mY += this.gravity this.mY += this.gravity
if (Input.isDown('a')) { if (Input.isDown('a')) {

View File

@ -1,17 +1,20 @@
import { Tile, TileMap } from './tiles' import { Tile, TileMap } from './tiles'
import { ItemPlaceable } from './items' import { ItemPlaceable, ItemMiningTool } from './items'
const map = new TileMap('assets/ground.png', 32) const map = new TileMap('assets/ground.png', 32)
const dirtStrength = 2
// Basic tiles // Basic tiles
const dirtTile = new Tile('DIRT', 33) const dirtTile = new Tile('DIRT', 33, true, null, dirtStrength)
const grassTile = new Tile('GRASS_TOP', 6) const grassTile = new Tile('GRASS_TOP', 6, true, null, dirtStrength)
const stoneTile = new Tile('STONE', 10) const stoneTile = new Tile('STONE', 10, true, null, 10)
// Items for basic tiles // Items for basic tiles
const dirtItem = new ItemPlaceable(dirtTile, 'dirt', 'assets/item_dirt.png') const dirtItem = new ItemPlaceable(dirtTile, 'dirt', 'assets/item_dirt.png')
const grassItem = new ItemPlaceable(grassTile, 'dirt_with_grass', 'assets/item_grass.png') const grassItem = new ItemPlaceable(grassTile, 'dirt_with_grass', 'assets/item_grass.png')
const stoneItem = new ItemPlaceable(stoneTile, 'stone', 'assets/item_stone.png') const stoneItem = new ItemPlaceable(stoneTile, 'stone', 'assets/item_stone.png')
const drill = new ItemMiningTool('drill', 'assets/item_drill.png', 0.5)
// Set the items // Set the items
dirtTile.item = dirtItem dirtTile.item = dirtItem
@ -20,35 +23,35 @@ stoneTile.item = stoneItem
// Register dirt tiles // Register dirt tiles
map.register([ map.register([
new Tile('DIRT_CORNER_TOP_LEFT', 0, true, dirtItem), new Tile('DIRT_CORNER_TOP_LEFT', 0, true, dirtItem, dirtStrength),
new Tile('DIRT_TOP', 1, true, dirtItem), new Tile('DIRT_TOP', 1, true, dirtItem, dirtStrength),
new Tile('DIRT_CORNER_TOP_RIGHT', 2, true, dirtItem), new Tile('DIRT_CORNER_TOP_RIGHT', 2, true, dirtItem, dirtStrength),
new Tile('DIRT_INNER_BOTTOM_RIGHT', 3, true, dirtItem), new Tile('DIRT_INNER_BOTTOM_RIGHT', 3, true, dirtItem, dirtStrength),
new Tile('DIRT_INNER_BOTTOM_LEFT', 4, true, dirtItem), new Tile('DIRT_INNER_BOTTOM_LEFT', 4, true, dirtItem, dirtStrength),
new Tile('DIRT_LEFT', 32, true, dirtItem), new Tile('DIRT_LEFT', 32, true, dirtItem, dirtStrength),
dirtTile, dirtTile,
new Tile('DIRT_RIGHT', 34, true, dirtItem), new Tile('DIRT_RIGHT', 34, true, dirtItem, dirtStrength),
new Tile('DIRT_INNER_TOP_RIGHT', 35, true, dirtItem), new Tile('DIRT_INNER_TOP_RIGHT', 35, true, dirtItem, dirtStrength),
new Tile('DIRT_INNER_TOP_LEFT', 36, true, dirtItem), new Tile('DIRT_INNER_TOP_LEFT', 36, true, dirtItem, dirtStrength),
new Tile('DIRT_CORNER_BOTTOM_LEFT', 64, true, dirtItem), new Tile('DIRT_CORNER_BOTTOM_LEFT', 64, true, dirtItem, dirtStrength),
new Tile('DIRT_BOTTOM', 65, true, dirtItem), new Tile('DIRT_BOTTOM', 65, true, dirtItem, dirtStrength),
new Tile('DIRT_CORNER_BOTTOM_RIGHT', 66, true, dirtItem) new Tile('DIRT_CORNER_BOTTOM_RIGHT', 66, true, dirtItem, dirtStrength)
]) ])
// Register grass tiles // Register grass tiles
map.register([ map.register([
new Tile('GRASS_CORNER_TOP_LEFT', 5, true, grassItem), new Tile('GRASS_CORNER_TOP_LEFT', 5, true, grassItem, dirtStrength),
grassTile, grassTile,
new Tile('GRASS_CORNER_TOP_RIGHT', 7, true, grassItem), new Tile('GRASS_CORNER_TOP_RIGHT', 7, true, grassItem, dirtStrength),
new Tile('GRASS_INNER_BOTTOM_RIGHT', 8, true, grassItem), new Tile('GRASS_INNER_BOTTOM_RIGHT', 8, true, grassItem, dirtStrength),
new Tile('GRASS_INNER_BOTTOM_LEFT', 9, true, grassItem), new Tile('GRASS_INNER_BOTTOM_LEFT', 9, true, grassItem, dirtStrength),
new Tile('GRASS_LEFT', 37, true, grassItem), new Tile('GRASS_LEFT', 37, true, grassItem, dirtStrength),
new Tile('GRASS_RIGHT', 39, true, grassItem), new Tile('GRASS_RIGHT', 39, true, grassItem, dirtStrength),
new Tile('GRASS_INNER_TOP_RIGHT', 40, true, grassItem), new Tile('GRASS_INNER_TOP_RIGHT', 40, true, grassItem, dirtStrength),
new Tile('GRASS_INNER_TOP_LEFT', 41, true, grassItem), new Tile('GRASS_INNER_TOP_LEFT', 41, true, grassItem, dirtStrength),
new Tile('GRASS_CORNER_BOTTOM_LEFT', 69, true, grassItem), new Tile('GRASS_CORNER_BOTTOM_LEFT', 69, true, grassItem, dirtStrength),
new Tile('GRASS_BOTTOM', 70, true, grassItem), new Tile('GRASS_BOTTOM', 70, true, grassItem, dirtStrength),
new Tile('GRASS_CORNER_BOTTOM_RIGHT', 71, true, grassItem) new Tile('GRASS_CORNER_BOTTOM_RIGHT', 71, true, grassItem, dirtStrength)
]) ])
// Register other tiles // Register other tiles

View File

@ -8,11 +8,12 @@ const cacheFactory = new ResourceCacheFactory()
const UPDATE_RADIUS = 6 const UPDATE_RADIUS = 6
class Tile { class Tile {
constructor (name, index, solid = true, item) { constructor (name, index, solid = true, item, hardness = 0) {
this.name = name this.name = name
this.id = index this.id = index
this.solid = solid this.solid = solid
this.item = item this.item = item
this.hardness = hardness
} }
} }
@ -92,6 +93,7 @@ class TileLayer {
this.size = size this.size = size
this.tile = tileSize this.tile = tileSize
this.tiles = [] this.tiles = []
this.damage = {}
} }
setTile (x, y, i) { setTile (x, y, i) {
@ -116,7 +118,11 @@ class TileLayer {
tileAtXY (x, y) { tileAtXY (x, y) {
if (x < 0 || x >= this.size || y < 0 || y >= this.size) return null if (x < 0 || x >= this.size || y < 0 || y >= this.size) return null
return this.tileAt(x + this.size * y) return this.tileAt(this.toI(x, y))
}
toI (x, y) {
return x + this.size * y
} }
toXY (i) { toXY (i) {
@ -147,8 +153,38 @@ class TileLayer {
} }
} }
update (dt) { damageTileAt (i, dmg) {
let tile = this.tiles[i]
let tparams = this.map.getTileByID(tile)
if (tile === -1 || !tparams) return false
if (tparams.hardness < 0) return false
if (!this.damage[i]) this.damage[i] = tparams.hardness
this.damage[i] -= dmg
if (this.damage[i] <= 0) return true
return false
}
damageTileAtXY (x, y, dmg) {
return this.damageTileAt(this.toI(x, y), dmg)
}
update (dt) {
for (let index in this.damage) {
let damage = this.damage[index]
let tilei = parseInt(this.tiles[index])
let tparams = this.map.getTileByID(tilei)
if (tilei === -1 || !tparams) {
delete this.damage[index]
continue
}
if (damage < tparams.hardness) {
this.damage[index] += 10 * dt
continue
}
delete this.damage[index]
}
} }
} }