dig blocks, finally
This commit is contained in:
parent
811b6e5b78
commit
b2a4d2e547
4 changed files with 92 additions and 40 deletions
43
src/App.vue
43
src/App.vue
|
@ -3,7 +3,7 @@ import { ref, computed, onMounted } from 'vue'
|
|||
import Help from './screens/help.vue'
|
||||
import Inventory from './screens/inventory.vue'
|
||||
|
||||
import { BLOCK_SIZE, STAGE_WIDTH, STAGE_HEIGHT, type Block } from './level/def'
|
||||
import { BLOCK_SIZE, STAGE_WIDTH, STAGE_HEIGHT, type Block, blockTypes } from './level/def'
|
||||
import createLevel from './level'
|
||||
|
||||
import useTime from './util/useTime'
|
||||
|
@ -12,7 +12,7 @@ import usePlayer from './util/usePlayer'
|
|||
|
||||
const { updateTime, timeOfDay, clock } = useTime()
|
||||
const { player, direction, dx, dy } = usePlayer()
|
||||
const { inputX, inputY, running, digging, paused, help, inventory } = useInput()
|
||||
const { inputX, inputY, running, paused, help, inventory } = useInput()
|
||||
const level = createLevel(STAGE_WIDTH + 2, STAGE_HEIGHT + 2)
|
||||
|
||||
player.inventory.push(
|
||||
|
@ -67,8 +67,24 @@ const blocked = computed(() => {
|
|||
}
|
||||
})
|
||||
|
||||
function dig() {
|
||||
console.warn('digging not yet implemented')
|
||||
function dig(blockX: number, blockY: number, oldBlockType: BlockType) {
|
||||
// § 4 ArbZG
|
||||
if (paused.value) return
|
||||
|
||||
// TODO: temporary filter
|
||||
if (oldBlockType === 'air' || oldBlockType === 'cave') return
|
||||
|
||||
level.change({
|
||||
type: 'exchange',
|
||||
x: floorX.value + blockX,
|
||||
y: floorY.value + blockY,
|
||||
newType: 'air'
|
||||
})
|
||||
// This feels like cheating, but it makes Vue recalculate floorX
|
||||
// which then recalculates the blocks, so that the changes are
|
||||
// applied. Otherwise, they wouldn't be visible before moving
|
||||
x.value = x.value + 0.01
|
||||
x.value = x.value - 0.01
|
||||
}
|
||||
|
||||
let lastTimeUpdate = 0
|
||||
|
@ -107,13 +123,9 @@ const move = (thisTick: number): void => {
|
|||
if (dy_ > 0 && blocked.value.down) dy_ = 0
|
||||
else if (dy_ < 0 && blocked.value.up) dy_ = 0
|
||||
|
||||
if (!inputY.value && digging.value) {
|
||||
dx_ = 0
|
||||
dig()
|
||||
}
|
||||
|
||||
const optimal = 16 // 16ms per tick => 60 FPS
|
||||
const movementMultiplier = (tickDelta / optimal) * 2
|
||||
const fallMultiplier = movementMultiplier * 2 // TODO: accelerated fall?
|
||||
|
||||
if (arriving.value && dy_ === 0) {
|
||||
arriving.value = false
|
||||
|
@ -122,7 +134,12 @@ const move = (thisTick: number): void => {
|
|||
walking.value = !!dx_
|
||||
|
||||
x.value += dx_ * movementMultiplier
|
||||
y.value += dy_ * movementMultiplier
|
||||
|
||||
if (dy_ < 0 || arriving.value) {
|
||||
y.value += dy_ * movementMultiplier
|
||||
} else {
|
||||
y.value += dy_ * fallMultiplier
|
||||
}
|
||||
lastTick = thisTick
|
||||
}
|
||||
|
||||
|
@ -140,10 +157,6 @@ onMounted(() => {
|
|||
lastTick = performance.now()
|
||||
move(lastTick)
|
||||
})
|
||||
|
||||
function log(...args: any[]) {
|
||||
console.log(...args)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -153,7 +166,7 @@ function log(...args: any[]) {
|
|||
<template v-for="(row, y) in rows">
|
||||
<div v-for="(block, x) in row"
|
||||
:class="['block', block.type, calcBrightness(y, x)]"
|
||||
@click="log('block', x, y, block.type)"
|
||||
@click="dig(x, y, block.type)"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
|
|
|
@ -15,18 +15,24 @@ export type Block = {
|
|||
transparent?: boolean,
|
||||
}
|
||||
|
||||
export const blockTypes: Record<string, Block> = {
|
||||
export type BlockType =
|
||||
| 'air' | 'grass'
|
||||
| 'treeCrown' | 'treeLeaves' | 'treeTrunk' | 'treeRoot'
|
||||
| 'soil' | 'soilGravel' | 'stone' | 'stoneGravel'
|
||||
| 'bedrock' | 'cave'
|
||||
|
||||
export const blockTypes: Record<BlockType, Block> = {
|
||||
air: { type: 'air', hp: Infinity, walkable: true, transparent: true },
|
||||
grass: { type: 'grass', hp: 1, walkable: false },
|
||||
grass: { type: 'grass', hp: 5, walkable: false },
|
||||
|
||||
treeCrown: { type: 'treeCrown', hp: 5, walkable: true, transparent: true },
|
||||
treeLeaves: { type: 'treeLeaves', hp: 5, walkable: true, transparent: true },
|
||||
treeTrunk: { type: 'treeTrunk', hp: 15, walkable: true, climbable: true, transparent: true },
|
||||
treeRoot: { type: 'treeRoot', hp: 15, walkable: true, climbable: true },
|
||||
treeCrown: { type: 'treeCrown', hp: 1, walkable: true, transparent: true },
|
||||
treeLeaves: { type: 'treeLeaves', hp: 1, walkable: true, transparent: true },
|
||||
treeTrunk: { type: 'treeTrunk', hp: 10, walkable: true, climbable: true, transparent: true },
|
||||
treeRoot: { type: 'treeRoot', hp: 10, walkable: true, climbable: true },
|
||||
|
||||
soil: { type: 'soil', hp: 2, walkable: false },
|
||||
soil: { type: 'soil', hp: 5, walkable: false },
|
||||
soilGravel: { type: 'soilGravel', hp: 5, walkable: false },
|
||||
stoneGravel: { type: 'stoneGravel', hp: 5, walkable: false },
|
||||
stoneGravel: { type: 'stoneGravel', hp: 10, walkable: false },
|
||||
stone: { type: 'stone', hp: 10, walkable: false },
|
||||
bedrock: { type: 'bedrock', hp: 25, walkable: false },
|
||||
cave: { type: 'cave', hp: Infinity, walkable: true, transparent: true },
|
||||
|
|
|
@ -3,7 +3,22 @@ import { createNoise2D, type NoiseFunction2D } from 'simplex-noise'
|
|||
import createBlockGenerator from './blockGen'
|
||||
import createBlockExtender from './blockExt'
|
||||
|
||||
import {blockTypes as T, level as L, type Block} from './def'
|
||||
import {blockTypes, blockTypes as T, level as L, type Block, type BlockType} from './def'
|
||||
|
||||
// describes a changed block, eg digged or placed by the player
|
||||
type DamagedBlock = {
|
||||
type: 'damage'
|
||||
x: number
|
||||
y: number
|
||||
damage: number
|
||||
}
|
||||
type ChangedBlock = {
|
||||
type: 'exchange'
|
||||
x: number
|
||||
y: number
|
||||
newType: BlockType
|
||||
}
|
||||
type Change = DamagedBlock | ChangedBlock
|
||||
|
||||
const MAX_LIGHT = 100 // maximum level where light shines
|
||||
|
||||
|
@ -17,15 +32,34 @@ export default function createLevel(width: number, height: number, seed = 'extre
|
|||
// stores the limit to where light still shines,
|
||||
// for each column currently visible on the screen
|
||||
const _lightBarrier: number[] = [...new Array(width)].map(() => MAX_LIGHT)
|
||||
const _changes: Change[] = []
|
||||
|
||||
const blockGen = createBlockGenerator(rand)
|
||||
const blockExt = createBlockExtender(rand)
|
||||
|
||||
// Apply changes, coming from the player (tocktocktock-plopp!)
|
||||
function change (level: number, column: number, newBlock: Block) {
|
||||
// TODO
|
||||
function change(change: Change) {
|
||||
_changes.push(change)
|
||||
console.log(_changes)
|
||||
}
|
||||
|
||||
function applyPlayerChanges(columnOffset: number, levelOffset: number) {
|
||||
for (const change of _changes) {
|
||||
// ignore all changes outside of the current view
|
||||
if (change.x < columnOffset || change.x > columnOffset + width) continue
|
||||
if (change.y < levelOffset || change.y > levelOffset + height) continue
|
||||
|
||||
if (change.type === 'exchange') {
|
||||
_grid[change.y - levelOffset][change.x - columnOffset] = blockTypes[change.newType]
|
||||
} else if (change.type === 'damage') {
|
||||
console.warn('damaging blocks not yet supported')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// takes the current columnOffset and generates all blocks from the very top
|
||||
// until a block is generated that blocks light. The height of that block is
|
||||
// stored in the lightBarrier list
|
||||
function calcLightBarrier(columnOffset: number) {
|
||||
let previousBlock: Block = T.air
|
||||
|
||||
|
@ -33,6 +67,12 @@ export default function createLevel(width: number, height: number, seed = 'extre
|
|||
for (let level = 0; level < MAX_LIGHT; level++) {
|
||||
let block = blockGen.generateBlock(level, col + columnOffset)
|
||||
block = blockExt.extendBlock(level, col, columnOffset, block, previousBlock)
|
||||
|
||||
const change = _changes.find(change => {
|
||||
return change.x === columnOffset + col && change.y === level
|
||||
})
|
||||
if (change && change.type === 'exchange') block = blockTypes[change.newType]
|
||||
|
||||
previousBlock = block
|
||||
|
||||
if (!block.transparent) {
|
||||
|
@ -43,21 +83,22 @@ export default function createLevel(width: number, height: number, seed = 'extre
|
|||
}
|
||||
}
|
||||
|
||||
function generate(column: number, y: number) {
|
||||
function generate(columnOffset: number, levelOffset: number) {
|
||||
for (let i = 0; i < height; i++) {
|
||||
const level = y+i
|
||||
const level = levelOffset + i
|
||||
const row: Block[] = Array(width)
|
||||
const previousRow = i ? _grid[i-1] : [] as Block[]
|
||||
|
||||
blockGen.fillRow(level, column, row)
|
||||
blockExt.extendRow(level, column, row, previousRow)
|
||||
blockGen.fillRow(level, columnOffset, row)
|
||||
blockExt.extendRow(level, columnOffset, row, previousRow)
|
||||
|
||||
_grid[i] = row
|
||||
}
|
||||
applyPlayerChanges(columnOffset, levelOffset)
|
||||
}
|
||||
|
||||
function sunLight(x: number, y: number) {
|
||||
calcLightBarrier(x)
|
||||
function sunLight(columnOffset: number) {
|
||||
calcLightBarrier(columnOffset)
|
||||
return _lightBarrier
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ export default function useInput() {
|
|||
let inputX = ref(0)
|
||||
let inputY = ref(1)
|
||||
let running = ref(false)
|
||||
let digging = ref(false)
|
||||
let paused = ref(false)
|
||||
let help = ref(false)
|
||||
let inventory = ref(false)
|
||||
|
@ -32,9 +31,6 @@ export default function useInput() {
|
|||
if (!help.value) paused.value = !paused.value
|
||||
if (wasPaused && !paused.value) wasPaused = false
|
||||
break
|
||||
case ' ':
|
||||
digging.value = true
|
||||
break
|
||||
case '?':
|
||||
if (paused.value && !help.value) wasPaused = true
|
||||
help.value = !help.value
|
||||
|
@ -64,9 +60,6 @@ export default function useInput() {
|
|||
case 'ArrowLeft':
|
||||
inputX.value = inputX.value === -1 ? 0 : 1
|
||||
break
|
||||
case ' ':
|
||||
digging.value = false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,7 +73,6 @@ export default function useInput() {
|
|||
inputX,
|
||||
inputY,
|
||||
running,
|
||||
digging,
|
||||
paused,
|
||||
help,
|
||||
inventory,
|
||||
|
|
Loading…
Reference in a new issue