tilegame/src/player.js

115 lines
3.0 KiB
JavaScript

import { ctx } from './canvas'
import { PhysicsEntity, ItemEntity } from './entity'
import { ItemStack } from './items'
import { Inventory } from './inventory'
import Input from './input'
class Player extends PhysicsEntity {
constructor (x, y, w, h) {
super(x, y, w, h)
this.speed = 4
this.gravity = 0.5
this.jumpPower = 10
this.inv = new Inventory(9)
this.itemPickUpDistance = 40
}
handleTool (dt, 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 (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)
}
}
}
}
handleMovement (dt, vp, world) {
this.mY += this.gravity
if (Input.isDown('a')) {
this.mX = -this.speed
} else if (Input.isDown('d')) {
this.mX = this.speed
} else {
this.mX = 0
}
if (this.grounded && (Input.isDown('w') || Input.isDown('space'))) {
this.mY = -this.jumpPower
}
this.moveAndSlide(world)
vp.x = parseInt(this.x - vp.width / 2)
vp.y = parseInt(this.y - vp.height / 2)
}
handleInventory () {
for (let i = 0; i < this.inv.size; i++) {
let pressed = Input.isPressed(i + 1)
if (pressed) {
this.inv.selected = i
break
}
}
}
pickUp (itemEntity) {
let istr = itemEntity.istr
let istack = ItemStack.new(istr)
this.inv.addItem(istack)
itemEntity.dead = true
}
handleWorldEntities (dt, vp, world) {
let entities = world.getLayer('ents')
if (!entities) return
let active = entities.getActiveEntities(vp, world)
for (let i in active) {
let ent = active[i]
if (!(ent instanceof ItemEntity)) continue
if (ent.distance(this) > this.itemPickUpDistance) continue
this.pickUp(ent)
}
}
update (dt, vp, world) {
this.handleTool(dt, vp, world)
this.handleWorldEntities(dt, vp, world)
this.handleInventory()
this.handleMovement(dt, vp, world)
}
draw (vp) {
ctx.fillStyle = '#f00'
ctx.fillRect(this.x - vp.x, this.y - vp.y, this.width, this.height)
this.inv.draw()
}
}
export default Player