modifyable tiles
This commit is contained in:
parent
395d69d2c1
commit
4eed971735
16
src/debug.js
16
src/debug.js
@ -1,4 +1,5 @@
|
|||||||
import { ctx } from './canvas'
|
import { ctx } from './canvas'
|
||||||
|
import Input from './input'
|
||||||
|
|
||||||
class Debugging {
|
class Debugging {
|
||||||
constructor () {
|
constructor () {
|
||||||
@ -6,9 +7,12 @@ class Debugging {
|
|||||||
this.overlay.style = 'color:#fff;position:absolute;top:15px;right:15px;background-color:hsla(0,0%,47%,0.5);padding:10px;display:flex;flex-direction:column;'
|
this.overlay.style = 'color:#fff;position:absolute;top:15px;right:15px;background-color:hsla(0,0%,47%,0.5);padding:10px;display:flex;flex-direction:column;'
|
||||||
document.body.appendChild(this.overlay)
|
document.body.appendChild(this.overlay)
|
||||||
this.drawGrid = false
|
this.drawGrid = false
|
||||||
|
this.infotext = true
|
||||||
|
this.addCheckbox(this, 'infotext')
|
||||||
}
|
}
|
||||||
|
|
||||||
draw (vp, world, fps) {
|
draw (vp, world, fps) {
|
||||||
|
if (!this.infotext) return
|
||||||
let p = vp.chunkIn(world.chunkSize * world.tileSize)
|
let p = vp.chunkIn(world.chunkSize * world.tileSize)
|
||||||
ctx.fillStyle = '#fff'
|
ctx.fillStyle = '#fff'
|
||||||
ctx.fillText(fps + ' fps', 4, 16)
|
ctx.fillText(fps + ' fps', 4, 16)
|
||||||
@ -17,6 +21,14 @@ class Debugging {
|
|||||||
ctx.fillText('loaded ' + world.chunks.length, 4, 16 * 4)
|
ctx.fillText('loaded ' + world.chunks.length, 4, 16 * 4)
|
||||||
ctx.fillText('drawn ' + world._lastDrawCount, 4, 16 * 5)
|
ctx.fillText('drawn ' + world._lastDrawCount, 4, 16 * 5)
|
||||||
ctx.fillText('updates ' + world._lastUpdateCount, 4, 16 * 6)
|
ctx.fillText('updates ' + world._lastUpdateCount, 4, 16 * 6)
|
||||||
|
// Mouse
|
||||||
|
let mpos = Input.mouse.pos
|
||||||
|
let mpin = world.pickMouse(vp, mpos)
|
||||||
|
ctx.fillText('mouse (x: ' + mpos.x + '; y: ' + mpos.y + ')', 4, 16 * 8)
|
||||||
|
if (mpin.chunk) {
|
||||||
|
ctx.fillText('mouse-in-chunk (x: ' + mpin.chunk.x + '; y: ' + mpin.chunk.y + ')', 4, 16 * 9)
|
||||||
|
ctx.fillText('mouse-in-tile (x: ' + mpin.tile.x + '; y: ' + mpin.tile.y + ')', 4, 16 * 10)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
createSliders (obj, args, fn) {
|
createSliders (obj, args, fn) {
|
||||||
@ -40,7 +52,7 @@ class Debugging {
|
|||||||
slider.addEventListener('input', function (e) {
|
slider.addEventListener('input', function (e) {
|
||||||
obj[a] = parseFloat(slider.value)
|
obj[a] = parseFloat(slider.value)
|
||||||
value.innerHTML = slider.value
|
value.innerHTML = slider.value
|
||||||
fn(a, slider.value)
|
fn && fn(a, slider.value)
|
||||||
})
|
})
|
||||||
div.appendChild(name)
|
div.appendChild(name)
|
||||||
div.appendChild(slider)
|
div.appendChild(slider)
|
||||||
@ -60,7 +72,7 @@ class Debugging {
|
|||||||
checkbox.checked = obj[arg] === true
|
checkbox.checked = obj[arg] === true
|
||||||
checkbox.addEventListener('change', function (e) {
|
checkbox.addEventListener('change', function (e) {
|
||||||
obj[arg] = checkbox.checked
|
obj[arg] = checkbox.checked
|
||||||
fn(arg, obj[arg])
|
fn && fn(arg, obj[arg])
|
||||||
})
|
})
|
||||||
div.appendChild(checkbox)
|
div.appendChild(checkbox)
|
||||||
div.appendChild(name)
|
div.appendChild(name)
|
||||||
|
14
src/index.js
14
src/index.js
@ -12,7 +12,7 @@ let frameTime = 0
|
|||||||
let frameCount = 0
|
let frameCount = 0
|
||||||
let fps = 0
|
let fps = 0
|
||||||
|
|
||||||
let vp = new Viewport(0, 0)
|
let vp = new Viewport(1111, 900)
|
||||||
|
|
||||||
let height = new HeightMap(0, 32, 16, 0)
|
let height = new HeightMap(0, 32, 16, 0)
|
||||||
let map = new TileMap('assets/ground.png', 32)
|
let map = new TileMap('assets/ground.png', 32)
|
||||||
@ -87,6 +87,18 @@ function update (dt) {
|
|||||||
} else if (vp.y + vp.height > world.height * full) {
|
} else if (vp.y + vp.height > world.height * full) {
|
||||||
vp.y = (full * world.height) - vp.height
|
vp.y = (full * world.height) - vp.height
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Input.mouse['btn0']) {
|
||||||
|
let mpin = world.pickMouse(vp, Input.mouse.pos)
|
||||||
|
if (mpin.chunk) {
|
||||||
|
mpin.chunk.setTile('fg', mpin.tile, map.indexOf('DIRT'))
|
||||||
|
}
|
||||||
|
} else if (Input.mouse['btn2']) {
|
||||||
|
let mpin = world.pickMouse(vp, Input.mouse.pos)
|
||||||
|
if (mpin.chunk) {
|
||||||
|
mpin.chunk.setTile('fg', mpin.tile, map.indexOf('AIR'))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function draw () {
|
function draw () {
|
||||||
|
10
src/input.js
10
src/input.js
@ -73,7 +73,6 @@ class Input {
|
|||||||
|
|
||||||
this.mouse = {
|
this.mouse = {
|
||||||
pos: { x: 0, y: 0 },
|
pos: { x: 0, y: 0 },
|
||||||
frame: { x: 0, y: 0 },
|
|
||||||
previous: { x: 0, y: 0 }
|
previous: { x: 0, y: 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,8 +102,8 @@ class Input {
|
|||||||
x -= canvas.offsetLeft
|
x -= canvas.offsetLeft
|
||||||
y -= canvas.offsetTop
|
y -= canvas.offsetTop
|
||||||
|
|
||||||
this.mouse.frame.x = x
|
this.mouse.pos.x = x
|
||||||
this.mouse.frame.y = y
|
this.mouse.pos.y = y
|
||||||
}, false)
|
}, false)
|
||||||
|
|
||||||
canvas.addEventListener('mousedown', (e) => {
|
canvas.addEventListener('mousedown', (e) => {
|
||||||
@ -212,11 +211,6 @@ class Input {
|
|||||||
// Mouse positions in the previous frame
|
// Mouse positions in the previous frame
|
||||||
this.mouse.previous.x = this.mouse.pos.x
|
this.mouse.previous.x = this.mouse.pos.x
|
||||||
this.mouse.previous.y = this.mouse.pos.y
|
this.mouse.previous.y = this.mouse.pos.y
|
||||||
|
|
||||||
// Mouse positions in the current frame
|
|
||||||
// Convert to OpenGL coordinate system
|
|
||||||
this.mouse.pos.x = this.mouse.frame.x / this.canvas.width * 2 - 1
|
|
||||||
this.mouse.pos.y = this.mouse.frame.y / this.canvas.height * 2 - 1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
61
src/tiles.js
61
src/tiles.js
@ -59,6 +59,18 @@ class TileLayer {
|
|||||||
this.tiles = []
|
this.tiles = []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setTile (x, y, i) {
|
||||||
|
if (typeof x === 'object') {
|
||||||
|
if (!i && y) i = y
|
||||||
|
y = x.y
|
||||||
|
x = x.x
|
||||||
|
}
|
||||||
|
let t = this.tileAtXY(x, y)
|
||||||
|
if (!t || t === i) return false
|
||||||
|
this.tiles[x + this.size * y] = i
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
tileAt (i) {
|
tileAt (i) {
|
||||||
return this.tiles[i]
|
return this.tiles[i]
|
||||||
}
|
}
|
||||||
@ -95,6 +107,7 @@ class Chunk {
|
|||||||
this.tile = tileSize
|
this.tile = tileSize
|
||||||
this.layers = []
|
this.layers = []
|
||||||
this.dirty = true
|
this.dirty = true
|
||||||
|
this.modified = false
|
||||||
this.img = null
|
this.img = null
|
||||||
this._updated = false
|
this._updated = false
|
||||||
}
|
}
|
||||||
@ -128,6 +141,28 @@ class Chunk {
|
|||||||
this.dirty = true
|
this.dirty = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getLayer (name) {
|
||||||
|
for (let i in this.layers) {
|
||||||
|
let layer = this.layers[i]
|
||||||
|
if (layer.name === name) return layer
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
setTile (layer, x, y, tile) {
|
||||||
|
if (!tile && typeof x !== 'object') {
|
||||||
|
tile = y
|
||||||
|
y = x.y
|
||||||
|
x = x.x
|
||||||
|
}
|
||||||
|
let l = this.getLayer(layer)
|
||||||
|
if (!l) return false
|
||||||
|
if (!l.setTile(x, y, tile)) return false
|
||||||
|
this.dirty = true
|
||||||
|
this.modified = true
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
toAbs (x, y) {
|
toAbs (x, y) {
|
||||||
if (typeof x === 'object') {
|
if (typeof x === 'object') {
|
||||||
y = x.y
|
y = x.y
|
||||||
@ -145,6 +180,12 @@ class Chunk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
draw (view, map) {
|
draw (view, map) {
|
||||||
|
if (this.img) {
|
||||||
|
// Draw the cached image
|
||||||
|
let p = this.absPos
|
||||||
|
ctx.drawImage(this.img, p.x - view.x, p.y - view.y)
|
||||||
|
}
|
||||||
|
|
||||||
// Create a cached image of the chunk
|
// Create a cached image of the chunk
|
||||||
if (this.dirty || !this.img) {
|
if (this.dirty || !this.img) {
|
||||||
cacheFactory.prepare(this.size * this.tile, this.size * this.tile)
|
cacheFactory.prepare(this.size * this.tile, this.size * this.tile)
|
||||||
@ -163,11 +204,7 @@ class Chunk {
|
|||||||
// Don't update again next tick
|
// Don't update again next tick
|
||||||
this.dirty = false
|
this.dirty = false
|
||||||
this._updated = true
|
this._updated = true
|
||||||
return
|
|
||||||
}
|
}
|
||||||
// Draw the cached image
|
|
||||||
let p = this.absPos
|
|
||||||
ctx.drawImage(this.img, p.x - view.x, p.y - view.y)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
update (dt) {
|
update (dt) {
|
||||||
@ -241,15 +278,25 @@ class World {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pickMouse (vp, mousePos) {
|
||||||
|
let a = this.chunkSize * this.tileSize
|
||||||
|
let abs = { x: mousePos.x + vp.x, y: mousePos.y + vp.y }
|
||||||
|
let chunk = { x: Math.floor(abs.x / a), y: Math.floor(abs.y / a) }
|
||||||
|
let tile = {
|
||||||
|
x: Math.floor(abs.x / this.tileSize - chunk.x * this.chunkSize),
|
||||||
|
y: Math.floor(abs.y / this.tileSize - chunk.y * this.chunkSize)
|
||||||
|
}
|
||||||
|
return { chunk: this.getChunk(chunk.x, chunk.y), tile }
|
||||||
|
}
|
||||||
|
|
||||||
draw (vp) {
|
draw (vp) {
|
||||||
this._lastDrawCount = 0
|
this._lastDrawCount = 0
|
||||||
this._lastUpdateCount = 0
|
this._lastUpdateCount = 0
|
||||||
const adj = this.tileSize
|
|
||||||
for (let i in this.chunks) {
|
for (let i in this.chunks) {
|
||||||
let chunk = this.chunks[i]
|
let chunk = this.chunks[i]
|
||||||
let absPos = chunk.absPos
|
let absPos = chunk.absPos
|
||||||
if (absPos.x > vp.x + vp.width + adj || absPos.x + chunk.fullSize < vp.x - adj ||
|
if (absPos.x > vp.x + vp.width + this.tileSize || absPos.x + chunk.fullSize < vp.x - this.tileSize ||
|
||||||
absPos.y > vp.y + vp.height + adj || absPos.y + chunk.fullSize < vp.y - adj) continue
|
absPos.y > vp.y + vp.height + this.tileSize || absPos.y + chunk.fullSize < vp.y - this.tileSize) continue
|
||||||
chunk._updated = false
|
chunk._updated = false
|
||||||
chunk.draw(vp, this.tileMaps.GROUND)
|
chunk.draw(vp, this.tileMaps.GROUND)
|
||||||
if (chunk._updated) this._lastUpdateCount++
|
if (chunk._updated) this._lastUpdateCount++
|
||||||
|
Loading…
Reference in New Issue
Block a user