You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

94 lines
2.4 KiB
Vue

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { BLOCK_SIZE, STAGE_WIDTH, STAGE_HEIGHT } from './level/def'
import createLevel from './level'
import useTime from './util/useTime'
import useInput from './util/useInput'
import usePlayer from './util/usePlayer'
const { updateTime, timeOfDay, clock } = useTime()
const { player, direction, dx, dy } = usePlayer()
const { inputX, inputY, digging, paused } = useInput(player)
const level = createLevel(STAGE_WIDTH + 2, STAGE_HEIGHT + 2)
let animationFrame = 0
let lastTick = 0
let x = ref(0)
let y = ref(12)
const floorX = computed(() => Math.floor(x.value))
const floorY = computed(() => Math.floor(y.value))
const tx = computed(() => (x.value - floorX.value) * -BLOCK_SIZE)
const ty = computed(() => (y.value - floorY.value) * -BLOCK_SIZE)
const rows = computed(() => level.grid(floorX.value, floorY.value))
// TODO: mock
const blocked = {
left: false,
right: false,
up: false,
down: false,
}
function dig() {
console.warn('digging not yet implemented')
}
function move(thisTick) {
animationFrame = requestAnimationFrame(move)
// do nothing when paused, otherwise keep roughly 20 fps
if (paused.value || thisTick - lastTick < 50) return
updateTime()
player.vx = inputX.value
player.vy = inputY.value
if (inputX.value) player.lastDir = inputX.value
let dx_ = dx.value
let dy_ = dy.value
if (dx > 0 && blocked.right) dx_ = 0
else if (dx < 0 && blocked.left) dx_ = 0
if (dy > 0 && blocked.down) dy_ = 0
else if (dy < 0 && blocked.up) dy_ = 0
if (!inputY.value && digging.value) {
dx_ = 0
dig()
}
x.value += dx_ * 32
y.value += dy_ * 32
lastTick = thisTick
}
onMounted(() => {
lastTick = performance.now()
move(lastTick)
})
</script>
<template>
<div id="field" :class="timeOfDay">
<div id="blocks" :style="{transform: `translate(${tx}px, ${ty}px)`}">
<template v-for="(row, y) in rows">
<div v-for="(block, x) in row" class="block" :class="[block.type]" />
</template>
</div>
<div id="player" :class="direction" />
<div id="level-indicator">
x:{{ floorX }}, y:{{ floorY }}
<template v-if="paused">(PAUSED)</template>
<template v-else>({{ clock }})</template>
<div>{{ inputX }}, {{ inputY }}, {{ player.lastDir }}</div>
<div>{{ dx }}, {{ dy }}, {{ direction }}</div>
</div>
</div>
</template>