add inventory screen and cleanup assets

main
Norman Köhring 1 year ago
parent 193d991d0b
commit b18cc37b77

@ -49,7 +49,7 @@
right: 0;
color: white;
}
#help {
.screen {
position: absolute;
top: 0;
left: 0;
@ -57,14 +57,8 @@
padding: 1em;
background: transparent;
color: white;
column-count: 2;
column-gap: 40px;
column-rule: 1px dotted gray;
backdrop-filter: blur(5px) sepia(.8) brightness(0.4);
}
header {
column-span: all;
}
h2 {
font-size: 1rem;
font-weight: bold;

@ -1,5 +1,8 @@
<script setup lang="ts">
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 createLevel from './level'
@ -9,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 } = useInput()
const { inputX, inputY, running, digging, paused, help, inventory } = useInput()
const level = createLevel(STAGE_WIDTH + 2, STAGE_HEIGHT + 2)
let animationFrame = 0
@ -123,40 +126,9 @@ onMounted(() => {
x:{{ floorX }}, y:{{ floorY }}
<template v-if="paused">(PAUSED)</template>
<template v-else>({{ clock }})</template>
<div>{{ player.vx }}, {{ player.vy }}</div>
</div>
<div id="help" v-if="help">
<header>
<h1>How to play</h1>
</header>
<section>
<h2>Walk around: WASD or Arrow Keys</h2>
<p>A / Left: walk left</p>
<p>D / Right: walk right</p>
<p>W / Up: jump or climb up</p>
<p>S / Down: climb down</p>
<p>Hold Shift, to run.</p>
</section>
<section>
<h2>Dig Blocks: Left Mouse Key</h2>
<p>To dig a block, click on it with your left mouse key. Only adjacent blocks can be digged.</p>
<p><i>(not implemented, yet)</i></p>
</section>
<section>
<h2>Build / Set Blocks: Right Mouse Key</h2>
<p>To set a block, right click an empty position close to you.</p>
<p><i>(not implemented, yet)</i></p>
</section>
<section>
<h2>Inventory: I</h2>
<p>Press I to open the inventory and use the mouse to select an item. This item can then be put into the world with a right click.</p>
<p><i>(not implemented, yet)</i></p>
</section>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
</div>
<Inventory :shown="inventory" :player="player" />
<Help v-show="help" />
</div>
</template>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Before

Width:  |  Height:  |  Size: 554 B

After

Width:  |  Height:  |  Size: 554 B

Before

Width:  |  Height:  |  Size: 564 B

After

Width:  |  Height:  |  Size: 564 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Before

Width:  |  Height:  |  Size: 460 B

After

Width:  |  Height:  |  Size: 460 B

Before

Width:  |  Height:  |  Size: 448 B

After

Width:  |  Height:  |  Size: 448 B

Before

Width:  |  Height:  |  Size: 595 B

After

Width:  |  Height:  |  Size: 595 B

Before

Width:  |  Height:  |  Size: 620 B

After

Width:  |  Height:  |  Size: 620 B

Before

Width:  |  Height:  |  Size: 540 B

After

Width:  |  Height:  |  Size: 540 B

Before

Width:  |  Height:  |  Size: 537 B

After

Width:  |  Height:  |  Size: 537 B

Before

Width:  |  Height:  |  Size: 344 B

After

Width:  |  Height:  |  Size: 344 B

Before

Width:  |  Height:  |  Size: 329 B

After

Width:  |  Height:  |  Size: 329 B

Before

Width:  |  Height:  |  Size: 567 B

After

Width:  |  Height:  |  Size: 567 B

Before

Width:  |  Height:  |  Size: 551 B

After

Width:  |  Height:  |  Size: 551 B

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><defs><linearGradient x1="0" x2="0" y1="0" y2="1" id="lorc-spade-gradient-1"><stop offset="0%" stop-color="#ffffff" stop-opacity="1"></stop><stop offset="100%" stop-color="#e3b2b2" stop-opacity="1"></stop></linearGradient></defs><g class="" style="" transform="translate(0,0)"><path d="M173.844 15.563v.03l52.22 192.157c7.035-3.16 14.752-6.03 22.686-8.406 8.894-2.663 18.006-4.683 26.72-5.72L227 15.565l-53.156-.002zm240.03 183.968c-13.045 15.41-48.86 31.746-91.874 45.845 1.64 16.418 2.707 35.075 2.72 53.344.01 18.658-1.105 36.594-4.25 51.155-1.574 7.28-3.61 13.75-6.75 19.28-3.143 5.53-7.815 10.59-14.564 12.376-6.75 1.786-13.316-.275-18.812-3.5-5.497-3.223-10.55-7.79-15.594-13.31-10.087-11.045-20.125-26.058-29.563-42.22-9.477-16.23-18.235-33.37-25.218-48.688-45.532 8.43-85.193 11.69-102.126 6.313 27.59 101.65 71.632 175.738 120.312 216.094H388.75c47.247-52.587 62.203-160.075 25.125-296.69zm-127.843 12.064c-.745.007-1.525.022-2.31.062-8.694.44-19.32 2.508-29.626 5.594-10.308 3.086-20.344 7.183-28.063 11.313-5.254 2.81-8.667 5.522-10.905 7.53 5.213 15.886 19.636 48.602 36.22 77 9.044 15.492 18.7 29.674 27.218 39 4.258 4.664 8.254 8.075 11.218 9.813 2.965 1.74 4.307 1.64 4.595 1.563.288-.077 1.42-.62 3.094-3.564 1.67-2.944 3.424-7.837 4.75-13.97 2.648-12.262 3.823-29.34 3.81-47.217-.02-33.398-4.27-69.712-7.842-85.564-2.73-.895-6.933-1.61-12.157-1.562z" fill="url(#lorc-spade-gradient-1)" stroke="#000000" stroke-opacity="1" stroke-width="8"></path></g></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><defs><linearGradient x1="0" x2="0" y1="0" y2="1" id="lorc-pointy-sword-gradient-1"><stop offset="0%" stop-color="#ffffff" stop-opacity="1"></stop><stop offset="100%" stop-color="#e3b2b2" stop-opacity="1"></stop></linearGradient></defs><g class="" style="" transform="translate(0,0)"><path d="M45.95 14.553c-19.38.81-30.594 11.357-30.282 30.283l19.768 30.78c4.43-1.213 9.36-3.838 14.248-7.335l42.474 59.935c-17.018 20.83-31.258 44.44-42.71 70.836l26.55 26.552c11.275-23.6 24.634-44.826 39.918-63.864l210.82 297.475 166.807 33.213L460.33 325.62 162.78 114.745c19.907-16.108 41.842-29.91 65.652-41.578l-26.553-26.55c-27.206 11.803-51.442 26.576-72.735 44.292L69.39 48.56c3.443-4.823 6.062-9.735 7.342-14.242l-30.78-19.765zm400.84 86.933v.008l.003-.008h-.002zm0 .008l-28.028 124.97-25.116-80.593-18.105 70.667-26.862-49.64-.584 57.818 128.484 91.69 15.184 87.017-1.168-186.885-34.457 39.713-9.346-154.756zm-300.95 27.98l222.224 196.368 25.645 66.75-66.75-25.645L130.6 144.734c4.91-5.278 9.995-10.36 15.238-15.26zm32.305 196.274v.004h.005l-.005-.004zm.005.004l28.028 22.775-36.21 4.088 57.82 19.272-105.706 4.09 115.05 27.45L136.1 422.114l127.316 25.696-67.164 43.803 208.494 1.752-87.017-15.185-104.54-150.676-35.037-1.752z" fill="url(#lorc-pointy-sword-gradient-1)" stroke="#000000" stroke-opacity="1" stroke-width="8"></path></g></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

@ -0,0 +1,45 @@
<template>
<section id="help" class="screen">
<header>
<h1>How to play</h1>
</header>
<section>
<h2>Walk around: WASD or Arrow Keys</h2>
<p>A / Left: walk left</p>
<p>D / Right: walk right</p>
<p>W / Up: jump or climb up</p>
<p>S / Down: climb down</p>
<p>Hold Shift, to run.</p>
</section>
<section>
<h2>Dig Blocks: Left Mouse Key</h2>
<p>To dig a block, click on it with your left mouse key. Only adjacent blocks can be digged.</p>
<p><i>(not implemented, yet)</i></p>
</section>
<section>
<h2>Build / Set Blocks: Right Mouse Key</h2>
<p>To set a block, right click an empty position close to you.</p>
<p><i>(not implemented, yet)</i></p>
</section>
<section>
<h2>Inventory: I</h2>
<p>Press I or click your character to open the inventory and use the mouse to select an item. This item can then be put into the world with a right click.</p>
<p><i>(not implemented, yet)</i></p>
</section>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
</section>
</template>
<style scoped>
#help {
column-count: 2;
column-gap: 40px;
column-rule: 1px dotted gray;
}
header {
column-span: all;
}
</style>

@ -0,0 +1,90 @@
<script setup lang="ts">
import { ref } from 'vue'
export interface Props {
player: Player
shown: boolean
}
defineProps<Props>();
// inventory size is 12, and it is so empty
const slots = ref([
{ name: 'Spade', type: 'tool', icon: 'spade' },
{ name: 'Sword', type: 'weapon', icon: 'sword' },
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
])
</script>
<template>
<section id="inventory" class="screen" :class="{ shown }">
<header>
<h1>Inventory</h1>
</header>
<ol>
<li v-for="item in slots"
:class="[item?.type, item?.icon]"
>
<i v-if="item === null">(empty)</i>
<template v-else>
<b>{{ item.name }}</b>
</template>
</li>
</ol>
</section>
</template>
<style scoped>
#inventory {
width: 346px;
transition: transform .3s ease-out;
transform: translate(-50vw);
}
#inventory.shown {
transform: translate(0px);
}
ol {
list-style: none;
display: flex;
flex-flow: row wrap;
gap: 1em;
margin: 0;
padding: 0;
}
li {
position: relative;
display: inline-block;
width: 100px;
height: 100px;
text-align: center;
border: 2px solid white;
border-radius: 6px;
background: transparent center no-repeat;
background-size: contain;
}
li > i, li > b {
position: absolute;
bottom: 0;
right: 1px;
padding: .25em .5em;
background: black;
font-size: .8em;
}
.tool.spade {
background-image: url("../assets/tools/spade.svg");
}
.weapon.sword {
background-image: url("../assets/weapons/sword.svg");
}
</style>

@ -7,6 +7,7 @@ export default function useInput() {
let digging = ref(false)
let paused = ref(false)
let help = ref(false)
let inventory = ref(false)
let wasPaused = false
@ -39,6 +40,11 @@ export default function useInput() {
help.value = !help.value
paused.value = help.value || wasPaused
break
case 'i':
if (paused.value && !inventory.value) wasPaused = true
inventory.value = !inventory.value
paused.value = inventory.value || wasPaused
break
}
}
@ -77,5 +83,6 @@ export default function useInput() {
digging,
paused,
help,
inventory,
}
}

@ -1,20 +1,13 @@
import { computed, reactive } from 'vue'
import { RECIPROCAL, STAGE_WIDTH, STAGE_HEIGHT } from '../level/def'
export interface Moveable {
x: number, // position on x-axis (fixed for the player)
y: number, // position on y-axis (fixed for the player)
lastDir: number, // store last face direction
vx: number, // velocity on the x-axis
vy: number, // velocity on the y-axis
}
const player = reactive({
const player: Player = reactive({
x: (STAGE_WIDTH + 2) / 2,
y: (STAGE_HEIGHT + 2) / 2,
lastDir: 0,
vx: 0,
vy: 1, // always falling, because of gravity
inventory: {}, // not yet in use
})
export default function usePlayer() {

24
src/vite-env.d.ts vendored

@ -1 +1,25 @@
/// <reference types="vite/client" />
declare global {
interface Moveable {
x: number // position on x-axis (fixed for the player)
y: number // position on y-axis (fixed for the player)
lastDir: number // store last face direction
vx: number // velocity on the x-axis
vy: number // velocity on the y-axis
}
type Inventory = {
}
interface Player extends Moveable {
inventory: Inventory
}
interface Npc extends Moveable {
hostile: boolean
inventory: Inventory
}
}
export {}

Loading…
Cancel
Save