forked from noxious/client
Started working on zone editor and tile loading & selecting for it
This commit is contained in:
parent
d0cd073b95
commit
0903bbfb19
@ -23,12 +23,23 @@
|
|||||||
</div>
|
</div>
|
||||||
<audio ref="bgm" id="bgm" src="/assets/music/bgm.mp3" loop autoplay></audio>
|
<audio ref="bgm" id="bgm" src="/assets/music/bgm.mp3" loop autoplay></audio>
|
||||||
<img draggable="false" src="/assets/bglogin.png" id="bg-img" alt="New Quest login background" />
|
<img draggable="false" src="/assets/bglogin.png" id="bg-img" alt="New Quest login background" />
|
||||||
|
|
||||||
|
<Modal :isModalOpen="true">
|
||||||
|
<template #modal-header>
|
||||||
|
<h1>Zone Editor</h1>
|
||||||
|
</template>
|
||||||
|
<template #modal-body>
|
||||||
|
<ZoneEditor />
|
||||||
|
</template>
|
||||||
|
</Modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { login, register } from '@/services/authentication'
|
import { login, register } from '@/services/authentication'
|
||||||
import { useNotificationStore } from '@/stores/notifications'
|
import { useNotificationStore } from '@/stores/notifications'
|
||||||
|
import ZoneEditor from '@/components/utilities/zoneEditor/ZoneEditor.vue'
|
||||||
|
import Modal from '@/components/utilities/Modal.vue'
|
||||||
|
|
||||||
const bgm = ref('bgm')
|
const bgm = ref('bgm')
|
||||||
if (bgm.value.paused) {
|
if (bgm.value.paused) {
|
||||||
|
@ -138,6 +138,8 @@ onUnmounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.modal-body {
|
.modal-body {
|
||||||
|
max-height: 80vh;
|
||||||
|
overflow: auto;
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
|
|
||||||
.submit {
|
.submit {
|
||||||
|
100
src/components/utilities/zoneEditor/ZoneEditor.vue
Normal file
100
src/components/utilities/zoneEditor/ZoneEditor.vue
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
<template>
|
||||||
|
<input type="file" @change="onFileChange" accept="image/*" />
|
||||||
|
<canvas ref="tileCanvas" :width="tileWidth" :height="tileHeight" style="display: none;"></canvas>
|
||||||
|
<div class="tiles">
|
||||||
|
<img
|
||||||
|
v-for="(tile, index) in tiles"
|
||||||
|
:key="index"
|
||||||
|
:src="tile"
|
||||||
|
alt="Tile"
|
||||||
|
@click="selectTile(index)"
|
||||||
|
:class="{ selected: selectedTile === index }"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
|
||||||
|
const tileWidth = 64;
|
||||||
|
const tileHeight = 32;
|
||||||
|
const tiles = ref([]);
|
||||||
|
const selectedTile = ref(null);
|
||||||
|
const tileCanvas = ref(null);
|
||||||
|
|
||||||
|
const onFileChange = (event) => {
|
||||||
|
const file = event.target.files[0];
|
||||||
|
if (file) {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = (e) => {
|
||||||
|
const img = new Image();
|
||||||
|
img.onload = () => {
|
||||||
|
splitTiles(img);
|
||||||
|
};
|
||||||
|
img.src = e.target.result;
|
||||||
|
};
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const splitTiles = (img) => {
|
||||||
|
const canvas = tileCanvas.value;
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
|
const tilesetWidth = img.width;
|
||||||
|
const tilesetHeight = img.height;
|
||||||
|
const columns = Math.floor(tilesetWidth / tileWidth);
|
||||||
|
const rows = Math.floor(tilesetHeight / tileHeight);
|
||||||
|
|
||||||
|
tiles.value = [];
|
||||||
|
selectedTile.value = null;
|
||||||
|
|
||||||
|
for (let row = 0; row < rows; row++) {
|
||||||
|
for (let col = 0; col < columns; col++) {
|
||||||
|
const x = col * tileWidth;
|
||||||
|
const y = row * tileHeight;
|
||||||
|
|
||||||
|
ctx.clearRect(0, 0, tileWidth, tileHeight);
|
||||||
|
ctx.drawImage(img, x, y, tileWidth, tileHeight, 0, 0, tileWidth, tileHeight);
|
||||||
|
|
||||||
|
const tileDataURL = canvas.toDataURL();
|
||||||
|
tiles.value.push(tileDataURL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const selectTile = (index) => {
|
||||||
|
selectedTile.value = index;
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// Any additional setup if needed
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resources:
|
||||||
|
* https://codepen.io/Xymota/pen/gOOyxWB
|
||||||
|
* https://www.dynetisgames.com/2022/06/09/update-how-to-manage-big-isometric-maps-with-phaser-3-5/
|
||||||
|
* https://stackoverflow.com/questions/11533606/javascript-splitting-a-tileset-image-to-be-stored-in-2d-image-array
|
||||||
|
*/
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.tiles {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tiles img {
|
||||||
|
width: 64px;
|
||||||
|
height: 32px;
|
||||||
|
cursor: pointer;
|
||||||
|
border: 2px solid transparent;
|
||||||
|
transition: border 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tiles img.selected {
|
||||||
|
border: 2px solid #ff0000;
|
||||||
|
}
|
||||||
|
</style>
|
Loading…
x
Reference in New Issue
Block a user