put/build blocks
This commit is contained in:
parent
d1d2b3fbf0
commit
cc2b787421
3 changed files with 77 additions and 21 deletions
65
src/App.vue
65
src/App.vue
|
@ -3,26 +3,26 @@ import { ref, computed, onMounted } from 'vue'
|
||||||
import Help from './screens/help.vue'
|
import Help from './screens/help.vue'
|
||||||
import Inventory from './screens/inventory.vue'
|
import Inventory from './screens/inventory.vue'
|
||||||
|
|
||||||
import { BLOCK_SIZE, STAGE_WIDTH, STAGE_HEIGHT, type Block, blockTypes } from './level/def'
|
import { BLOCK_SIZE, STAGE_WIDTH, STAGE_HEIGHT, type Block } from './level/def'
|
||||||
import { getItem, getItemClass } from './level/items'
|
import { getItem, getItemClass } from './level/items'
|
||||||
import createLevel from './level'
|
import createLevel from './level'
|
||||||
|
|
||||||
import useTime from './util/useTime'
|
import useTime from './util/useTime'
|
||||||
import useInput from './util/useInput'
|
import useInput from './util/useInput'
|
||||||
import usePlayer from './util/usePlayer'
|
import usePlayer, { type InventoryItem } from './util/usePlayer'
|
||||||
import useLightMap from './util/useLightMap'
|
import useLightMap from './util/useLightMap'
|
||||||
|
|
||||||
const { updateTime, time, timeOfDay, clock } = useTime()
|
const { updateTime, time, timeOfDay, clock } = useTime()
|
||||||
const { player, direction, dx, dy, pocket } = usePlayer()
|
const { player, direction, dx, dy, pocket, unpocket } = usePlayer()
|
||||||
const { inputX, inputY, running, paused, help, inventory } = useInput()
|
const { inputX, inputY, running, paused, help, inventory } = useInput()
|
||||||
const level = createLevel(STAGE_WIDTH + 2, STAGE_HEIGHT + 2)
|
const level = createLevel(STAGE_WIDTH + 2, STAGE_HEIGHT + 2)
|
||||||
|
|
||||||
const lightMapEl = ref<HTMLCanvasElement | undefined>(undefined)
|
const lightMapEl = ref<HTMLCanvasElement | undefined>(undefined)
|
||||||
let updateLightMap: ReturnType<typeof useLightMap>
|
let updateLightMap: ReturnType<typeof useLightMap>
|
||||||
|
|
||||||
pocket({ name: 'Shovel', type: 'tool', icon: 'shovel', quality: 'bronze' })
|
pocket({ name: 'Shovel', type: 'tool', icon: 'shovel', quality: 'wood' })
|
||||||
pocket({ name: 'Sword', type: 'weapon', icon: 'sword', quality: 'bronze' })
|
pocket({ name: 'Sword', type: 'weapon', icon: 'sword', quality: 'wood' })
|
||||||
pocket({ name: 'Pick Axe', type: 'tool', icon: 'pick', quality: 'bronze' })
|
pocket({ name: 'Pick Axe', type: 'tool', icon: 'pick', quality: 'wood' })
|
||||||
|
|
||||||
let animationFrame = 0
|
let animationFrame = 0
|
||||||
let lastTick = 0
|
let lastTick = 0
|
||||||
|
@ -74,18 +74,55 @@ const blocked = computed(() => {
|
||||||
const damagedBlocks = ref([])
|
const damagedBlocks = ref([])
|
||||||
|
|
||||||
function dig(blockX: number, blockY: number, block: Block) {
|
function dig(blockX: number, blockY: number, block: Block) {
|
||||||
// § 4 ArbZG
|
|
||||||
if (paused.value) return
|
|
||||||
|
|
||||||
// air cannot be digged, I guess
|
|
||||||
if (block.type === 'air' || block.type === 'cave') return
|
|
||||||
// can only dig in player proximity
|
// can only dig in player proximity
|
||||||
if (Math.abs(player.x - blockX) > 2 || Math.abs(player.y - blockY) > 2) return
|
if (Math.abs(player.x - blockX) > 2 || Math.abs(player.y - blockY) > 2) return
|
||||||
// finally dig that block
|
// finally dig that block
|
||||||
// TODO: damage blocks first
|
// TODO: damage blocks first
|
||||||
level.change({ type: 'exchange', x: floorX.value + blockX, y: floorY.value + blockY, newType: 'air' })
|
level.change({
|
||||||
|
type: 'exchange',
|
||||||
|
x: floorX.value + blockX,
|
||||||
|
y: floorY.value + blockY,
|
||||||
|
newType: 'air'
|
||||||
|
})
|
||||||
|
|
||||||
if (block.drops) pocket(getItem(block.drops))
|
// anything to pick up?
|
||||||
|
if (block.drops) {
|
||||||
|
const dropItem = getItem(block.drops)
|
||||||
|
if (dropItem) pocket(dropItem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function build(blockX: number, blockY: number, block: InventoryItem) {
|
||||||
|
const blockToBuild = block.builds
|
||||||
|
// the block doesn't do anything
|
||||||
|
if (!blockToBuild) return
|
||||||
|
|
||||||
|
level.change({
|
||||||
|
type: 'exchange',
|
||||||
|
x: floorX.value + blockX,
|
||||||
|
y: floorY.value + blockY,
|
||||||
|
newType: blockToBuild
|
||||||
|
})
|
||||||
|
|
||||||
|
const newAmount = unpocket(block)
|
||||||
|
if (newAmount < 1) inventorySelection.value = player.inventory[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
function interactWith(blockX: number, blockY: number, block: Block) {
|
||||||
|
// § 4 ArbZG
|
||||||
|
if (paused.value) return
|
||||||
|
|
||||||
|
const blockInHand = inventorySelection.value.type === 'block'
|
||||||
|
const toolInHand = inventorySelection.value.type === 'tool'
|
||||||
|
const emptyBlock = block.type === 'air' || block.type === 'cave'
|
||||||
|
|
||||||
|
// put the selected block
|
||||||
|
if (blockInHand && emptyBlock) {
|
||||||
|
build(blockX, blockY, inventorySelection.value)
|
||||||
|
// dig a block with shovel or pick axe
|
||||||
|
} else if (toolInHand && !emptyBlock) {
|
||||||
|
dig(blockX, blockY, block)
|
||||||
|
}
|
||||||
|
|
||||||
// This feels like cheating, but it makes Vue recalculate floorX
|
// This feels like cheating, but it makes Vue recalculate floorX
|
||||||
// which then recalculates the blocks, so that the changes are
|
// which then recalculates the blocks, so that the changes are
|
||||||
|
@ -194,7 +231,7 @@ onMounted(() => {
|
||||||
<template v-for="(row, y) in rows">
|
<template v-for="(row, y) in rows">
|
||||||
<div v-for="(block, x) in row"
|
<div v-for="(block, x) in row"
|
||||||
:class="['block', block.type]"
|
:class="['block', block.type]"
|
||||||
@click="dig(x, y, block)"
|
@click="interactWith(x, y, block)"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.item.tool-shovel-bronze { background-image: url("/Items/shovel_bronze.png"); }
|
.item.tool-shovel-wood { background-image: url("/Items/shovel_bronze.png"); }
|
||||||
.item.weapon-sword-bronze { background-image: url("/Items/sword_bronze.png"); }
|
.item.weapon-sword-wood { background-image: url("/Items/sword_bronze.png"); }
|
||||||
.item.tool-pick-bronze { background-image: url("/Items/pick_bronze.png"); }
|
.item.tool-pick-wood { background-image: url("/Items/pick_bronze.png"); }
|
||||||
|
|
||||||
.item.block-wood { background-image: url("/Tiles/wood.png"); }
|
.item.block-wood { background-image: url("/Tiles/wood.png"); }
|
||||||
.item.block-dirt { background-image: url("/Tiles/dirt.png"); }
|
.item.block-dirt { background-image: url("/Tiles/dirt.png"); }
|
||||||
|
|
|
@ -20,15 +20,34 @@ const player = reactive<Player>({
|
||||||
inventory: [], // not yet in use
|
inventory: [], // not yet in use
|
||||||
})
|
})
|
||||||
|
|
||||||
const pocket = (newItem: InventoryItem) => {
|
const pocket = (newItem: Item) => {
|
||||||
const existing = player.inventory.find(item => item.name === newItem.name)
|
const existing = player.inventory.find(item => item.name === newItem.name)
|
||||||
|
|
||||||
if (existing) existing.amount += 1
|
if (existing) {
|
||||||
else player.inventory.push({
|
existing.amount += 1
|
||||||
|
return existing.amount
|
||||||
|
}
|
||||||
|
player.inventory.push({
|
||||||
quality: null,
|
quality: null,
|
||||||
amount: 1,
|
amount: 1,
|
||||||
...newItem
|
...newItem
|
||||||
})
|
})
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
const unpocket = (oldItem: Item) => {
|
||||||
|
const existingIndex = player.inventory.findIndex(item => item.name === oldItem.name)
|
||||||
|
|
||||||
|
if (existingIndex < 0) return 0
|
||||||
|
|
||||||
|
const existing = player.inventory[existingIndex]
|
||||||
|
|
||||||
|
if (existing.amount > 1) {
|
||||||
|
existing.amount -= 1
|
||||||
|
return existing.amount
|
||||||
|
}
|
||||||
|
player.inventory.splice(existingIndex, 1)
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function usePlayer() {
|
export default function usePlayer() {
|
||||||
|
@ -36,5 +55,5 @@ export default function usePlayer() {
|
||||||
const dy = computed(() => player.vy * RECIPROCAL)
|
const dy = computed(() => player.vy * RECIPROCAL)
|
||||||
const direction = computed(() => (player.lastDir < 0 ? 'left' : 'right'))
|
const direction = computed(() => (player.lastDir < 0 ? 'left' : 'right'))
|
||||||
|
|
||||||
return { player, direction, dx, dy, pocket }
|
return { player, direction, dx, dy, pocket, unpocket }
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue