179 lines
4.8 KiB
JavaScript
179 lines
4.8 KiB
JavaScript
/* global requestAnimationFrame */
|
|
import { canvas, ctx } from './canvas'
|
|
import { Tile, TileMap, World } from './tiles'
|
|
import { ItemPlaceable } from './items'
|
|
import { Inventory } from './inventory'
|
|
import { HeightMap } from './heightmap'
|
|
import Debug from './debug'
|
|
import Player from './player'
|
|
import Input from './input'
|
|
import Viewport from './viewport'
|
|
import RES from './resource'
|
|
|
|
let playing = false
|
|
let frameTime = 0
|
|
let frameCount = 0
|
|
let fps = 0
|
|
|
|
let vp = new Viewport(0, 0)
|
|
let p = new Player(800, 1200, 32, 64)
|
|
let inv = new Inventory(9)
|
|
|
|
let height = new HeightMap(0, 32, 16, 0)
|
|
let map = new TileMap('assets/ground.png', 32)
|
|
|
|
const chunkSize = 32
|
|
const tileSize = 16
|
|
|
|
const dirtTile = new Tile('DIRT', 33)
|
|
const grassTile = new Tile('GRASS_TOP', 6)
|
|
const stoneTile = new Tile('STONE', 10)
|
|
|
|
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')
|
|
|
|
dirtTile.item = dirtItem
|
|
grassTile.item = grassItem
|
|
stoneTile.item = stoneItem
|
|
|
|
// Define 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),
|
|
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)
|
|
])
|
|
|
|
// Define grass tiles
|
|
map.register([
|
|
new Tile('GRASS_CORNER_TOP_LEFT', 5, true, dirtItem),
|
|
grassTile,
|
|
new Tile('GRASS_CORNER_TOP_RIGHT', 7, true, dirtItem),
|
|
new Tile('GRASS_INNER_BOTTOM_RIGHT', 8, true, dirtItem),
|
|
new Tile('GRASS_INNER_BOTTOM_LEFT', 9, true, dirtItem),
|
|
new Tile('GRASS_LEFT', 37, true, dirtItem),
|
|
new Tile('GRASS_RIGHT', 39, true, dirtItem),
|
|
new Tile('GRASS_INNER_TOP_RIGHT', 40, true, dirtItem),
|
|
new Tile('GRASS_INNER_TOP_LEFT', 41, true, dirtItem),
|
|
new Tile('GRASS_CORNER_BOTTOM_LEFT', 69, true, dirtItem),
|
|
new Tile('GRASS_BOTTOM', 70, true, dirtItem),
|
|
new Tile('GRASS_CORNER_BOTTOM_RIGHT', 71, true, dirtItem)
|
|
])
|
|
|
|
// Define other tiles
|
|
map.register([
|
|
new Tile('AIR', -1, false),
|
|
stoneTile
|
|
])
|
|
|
|
let world = new World(height, { GROUND: map }, chunkSize, tileSize, 32, 64)
|
|
|
|
function update (dt) {
|
|
world.update(dt, vp)
|
|
p.update(dt, vp, world)
|
|
vp.update(dt, world)
|
|
|
|
for (let i = 0; i < inv.size; i++) {
|
|
let pressed = Input.isPressed(i + 1)
|
|
if (pressed) {
|
|
inv.selected = i
|
|
break
|
|
}
|
|
}
|
|
|
|
if (Input.mouse['btn0']) {
|
|
let mpin = world.pickMouse(vp, Input.mouse.pos)
|
|
if (mpin.chunk) {
|
|
if (inv.isEmpty(inv.selected)) return
|
|
let tile = mpin.chunk.getTile('fg', mpin.tile)
|
|
if (tile !== -1) return
|
|
let itm = inv.getItem(inv.selected)
|
|
if (itm && itm.item.placeable) {
|
|
let success = mpin.chunk.setTile('fg', mpin.tile, itm.item.placeable.id)
|
|
if (success) {
|
|
inv.takeItem(inv.selected, 1)
|
|
}
|
|
}
|
|
}
|
|
} else if (Input.mouse['btn2']) {
|
|
let mpin = world.pickMouse(vp, Input.mouse.pos)
|
|
if (mpin.chunk) {
|
|
let tile = mpin.chunk.getTile('fg', mpin.tile)
|
|
if (tile === -1) return
|
|
let itile = map.getTileByID(tile)
|
|
let success = mpin.chunk.setTile('fg', mpin.tile, map.indexOf('AIR'))
|
|
if (success) inv.addItem(itile.item)
|
|
}
|
|
}
|
|
}
|
|
|
|
function draw () {
|
|
world.draw(vp)
|
|
p.draw(vp)
|
|
Debug.draw(vp, world, fps)
|
|
inv.draw()
|
|
}
|
|
|
|
function step () {
|
|
draw()
|
|
|
|
let ts = window.performance.now()
|
|
let timeDiff = ts - frameTime // time difference in milliseconds
|
|
frameCount++
|
|
|
|
if (timeDiff > 0) {
|
|
fps = Math.floor(frameCount / timeDiff * 1000)
|
|
frameCount = 0
|
|
frameTime = ts
|
|
}
|
|
|
|
update(timeDiff / 1000)
|
|
}
|
|
|
|
function gameLoop () {
|
|
playing && requestAnimationFrame(gameLoop)
|
|
ctx.fillStyle = '#111'
|
|
ctx.fillRect(0, 0, canvas.width, canvas.height)
|
|
|
|
step()
|
|
|
|
Input.update()
|
|
}
|
|
|
|
function start () {
|
|
Debug.createSliders(height, {
|
|
amplitude: [0, 100, 1],
|
|
persistence: [0.1, 5, 0.1],
|
|
octaves: [1, 16, 1],
|
|
period: [1, 100, 1],
|
|
lacunarity: [1, 5, 1]
|
|
}, function (key, val) {
|
|
world.chunks = []
|
|
})
|
|
Debug.addCheckbox(Debug, 'drawGrid', function (argument) {
|
|
world.chunks = []
|
|
})
|
|
playing = true
|
|
gameLoop()
|
|
}
|
|
|
|
async function loadAll () {
|
|
let images = ['assets/ground.png', 'assets/item_grass.png',
|
|
'assets/item_dirt.png', 'assets/item_stone.png']
|
|
for (let i in images) {
|
|
await RES.loadImage(images[i])
|
|
}
|
|
}
|
|
|
|
loadAll().then(start)
|