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)
p.inv.addItem('drill')
function update (dt) {
world.update(dt, vp)
p.update(dt, vp, world)
@ -82,7 +84,7 @@ function start () {
async function loadAll () {
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) {
await RES.loadImage(images[i])
}

View File

@ -1,5 +1,5 @@
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
@ -76,6 +76,7 @@ class Inventory {
ctx.fillRect(x, 16, SLOT_SIZE, SLOT_SIZE)
if (!stack || stack.isEmpty()) continue
ctx.drawImage(stack.item.image, x, 16, SLOT_SIZE, SLOT_SIZE)
if (stack.item instanceof ItemTool) continue
ctx.font = '16px sans'
let measure = ctx.measureText(stack.count)
ctx.fillStyle = '#000'

View File

@ -1,4 +1,6 @@
import RES from './resource'
import { ItemEntity } from './entity'
import Input from './input'
const MAX_STACK_SIZE = 999
@ -37,9 +39,43 @@ class ItemPlaceable 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 {
@ -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
}
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 mpin = world.gridPosition(mabs)
if (Input.mouse['btn0']) {
if (mpin.chunk) {
if (this.inv.isEmpty(this.inv.selected)) return
let tile = mpin.chunk.getTile('fg', mpin.tile)
if (tile !== -1) return
let itm = this.inv.getItem(this.inv.selected)
if (itm && itm.item.placeable) {
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 (mpin.chunk) {
if (this.inv.isEmpty(this.inv.selected)) return
let tile = mpin.chunk.getTile(layer, mpin.tile)
if (tile !== -1) return
let itm = this.inv.getItem(this.inv.selected)
if (itm && itm.item.placeable) {
let success = mpin.chunk.setTile(layer, mpin.tile, itm.item.placeable.id)
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)
this.inv.takeItem(this.inv.selected, 1)
}
}
}
}
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) {
this.mY += this.gravity
if (Input.isDown('a')) {

View File

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

View File

@ -8,11 +8,12 @@ const cacheFactory = new ResourceCacheFactory()
const UPDATE_RADIUS = 6
class Tile {
constructor (name, index, solid = true, item) {
constructor (name, index, solid = true, item, hardness = 0) {
this.name = name
this.id = index
this.solid = solid
this.item = item
this.hardness = hardness
}
}
@ -92,6 +93,7 @@ class TileLayer {
this.size = size
this.tile = tileSize
this.tiles = []
this.damage = {}
}
setTile (x, y, i) {
@ -116,7 +118,11 @@ class TileLayer {
tileAtXY (x, y) {
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) {
@ -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]
}
}
}