add inventory screen and cleanup assets
|
@ -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;
|
||||
|
|
40
src/App.vue
|
@ -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> </p>
|
||||
<p> </p>
|
||||
<p> </p>
|
||||
</div>
|
||||
<Inventory :shown="inventory" :player="player" />
|
||||
<Help v-show="help" />
|
||||
</div>
|
||||
</template>
|
||||
|
|
Before ![]() (image error) Size: 156 KiB |
BIN
src/assets/npcs/bossbeetle.png
Normal file
After ![]() (image error) Size: 2.5 KiB |
BIN
src/assets/npcs/bosswasp.png
Normal file
After ![]() (image error) Size: 13 KiB |
BIN
src/assets/npcs/centipede_0.png
Normal file
After ![]() (image error) Size: 16 KiB |
BIN
src/assets/npcs/crawler_0.png
Normal file
After ![]() (image error) Size: 16 KiB |
Before ![]() (image error) Size: 554 B After ![]() (image error) Size: 554 B ![]() ![]() |
Before ![]() (image error) Size: 564 B After ![]() (image error) Size: 564 B ![]() ![]() |
BIN
src/assets/npcs/flyer_0.png
Normal file
After ![]() (image error) Size: 17 KiB |
Before ![]() (image error) Size: 460 B After ![]() (image error) Size: 460 B ![]() ![]() |
Before ![]() (image error) Size: 448 B After ![]() (image error) Size: 448 B ![]() ![]() |
Before ![]() (image error) Size: 595 B After ![]() (image error) Size: 595 B ![]() ![]() |
Before ![]() (image error) Size: 620 B After ![]() (image error) Size: 620 B ![]() ![]() |
Before ![]() (image error) Size: 540 B After ![]() (image error) Size: 540 B ![]() ![]() |
Before ![]() (image error) Size: 537 B After ![]() (image error) Size: 537 B ![]() ![]() |
Before ![]() (image error) Size: 344 B After ![]() (image error) Size: 344 B ![]() ![]() |
Before ![]() (image error) Size: 329 B After ![]() (image error) Size: 329 B ![]() ![]() |
Before ![]() (image error) Size: 567 B After ![]() (image error) Size: 567 B ![]() ![]() |
Before ![]() (image error) Size: 551 B After ![]() (image error) Size: 551 B ![]() ![]() |
1
src/assets/tools/spade.svg
Normal file
|
@ -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 (image error) Size: 1.5 KiB |
1
src/assets/weapons/sword.svg
Normal file
|
@ -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 (image error) Size: 1.4 KiB |
45
src/screens/help.vue
Normal file
|
@ -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> </p>
|
||||
<p> </p>
|
||||
<p> </p>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
#help {
|
||||
column-count: 2;
|
||||
column-gap: 40px;
|
||||
column-rule: 1px dotted gray;
|
||||
}
|
||||
header {
|
||||
column-span: all;
|
||||
}
|
||||
</style>
|
90
src/screens/inventory.vue
Normal file
|
@ -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 {}
|
||||
|
|