From cc2b78742178d14aa6b6b7391c4306565d5a9cfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Norman=20K=C3=B6hring?= Date: Sat, 4 Mar 2023 21:53:29 +0100 Subject: [PATCH] put/build blocks --- src/App.vue | 65 +++++++++++++++++++++++++++++++++---------- src/assets/items.css | 6 ++-- src/util/usePlayer.ts | 27 +++++++++++++++--- 3 files changed, 77 insertions(+), 21 deletions(-) diff --git a/src/App.vue b/src/App.vue index 22191ac..cad4a43 100644 --- a/src/App.vue +++ b/src/App.vue @@ -3,26 +3,26 @@ 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, blockTypes } from './level/def' +import { BLOCK_SIZE, STAGE_WIDTH, STAGE_HEIGHT, type Block } from './level/def' import { getItem, getItemClass } from './level/items' import createLevel from './level' import useTime from './util/useTime' import useInput from './util/useInput' -import usePlayer from './util/usePlayer' +import usePlayer, { type InventoryItem } from './util/usePlayer' import useLightMap from './util/useLightMap' 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 level = createLevel(STAGE_WIDTH + 2, STAGE_HEIGHT + 2) const lightMapEl = ref(undefined) let updateLightMap: ReturnType -pocket({ name: 'Shovel', type: 'tool', icon: 'shovel', quality: 'bronze' }) -pocket({ name: 'Sword', type: 'weapon', icon: 'sword', quality: 'bronze' }) -pocket({ name: 'Pick Axe', type: 'tool', icon: 'pick', quality: 'bronze' }) +pocket({ name: 'Shovel', type: 'tool', icon: 'shovel', quality: 'wood' }) +pocket({ name: 'Sword', type: 'weapon', icon: 'sword', quality: 'wood' }) +pocket({ name: 'Pick Axe', type: 'tool', icon: 'pick', quality: 'wood' }) let animationFrame = 0 let lastTick = 0 @@ -74,18 +74,55 @@ const blocked = computed(() => { const damagedBlocks = ref([]) 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 if (Math.abs(player.x - blockX) > 2 || Math.abs(player.y - blockY) > 2) return // finally dig that block // 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' + }) + + // 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 + }) - if (block.drops) pocket(getItem(block.drops)) + 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 // which then recalculates the blocks, so that the changes are @@ -194,7 +231,7 @@ onMounted(() => { diff --git a/src/assets/items.css b/src/assets/items.css index 9d82bee..a137329 100644 --- a/src/assets/items.css +++ b/src/assets/items.css @@ -1,6 +1,6 @@ -.item.tool-shovel-bronze { background-image: url("/Items/shovel_bronze.png"); } -.item.weapon-sword-bronze { background-image: url("/Items/sword_bronze.png"); } -.item.tool-pick-bronze { background-image: url("/Items/pick_bronze.png"); } +.item.tool-shovel-wood { background-image: url("/Items/shovel_bronze.png"); } +.item.weapon-sword-wood { background-image: url("/Items/sword_bronze.png"); } +.item.tool-pick-wood { background-image: url("/Items/pick_bronze.png"); } .item.block-wood { background-image: url("/Tiles/wood.png"); } .item.block-dirt { background-image: url("/Tiles/dirt.png"); } diff --git a/src/util/usePlayer.ts b/src/util/usePlayer.ts index d316d5c..b2cc59a 100644 --- a/src/util/usePlayer.ts +++ b/src/util/usePlayer.ts @@ -20,15 +20,34 @@ const player = reactive({ inventory: [], // not yet in use }) -const pocket = (newItem: InventoryItem) => { +const pocket = (newItem: Item) => { const existing = player.inventory.find(item => item.name === newItem.name) - if (existing) existing.amount += 1 - else player.inventory.push({ + if (existing) { + existing.amount += 1 + return existing.amount + } + player.inventory.push({ quality: null, amount: 1, ...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() { @@ -36,5 +55,5 @@ export default function usePlayer() { const dy = computed(() => player.vy * RECIPROCAL) const direction = computed(() => (player.lastDir < 0 ? 'left' : 'right')) - return { player, direction, dx, dy, pocket } + return { player, direction, dx, dy, pocket, unpocket } }