Started working on zone editor and tile loading & selecting for it

This commit is contained in:
Dennis Postma 2024-06-08 14:29:34 +02:00
parent d0cd073b95
commit 0903bbfb19
3 changed files with 113 additions and 0 deletions

View File

@ -23,12 +23,23 @@
</div>
<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" />
<Modal :isModalOpen="true">
<template #modal-header>
<h1>Zone Editor</h1>
</template>
<template #modal-body>
<ZoneEditor />
</template>
</Modal>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { login, register } from '@/services/authentication'
import { useNotificationStore } from '@/stores/notifications'
import ZoneEditor from '@/components/utilities/zoneEditor/ZoneEditor.vue'
import Modal from '@/components/utilities/Modal.vue'
const bgm = ref('bgm')
if (bgm.value.paused) {

View File

@ -138,6 +138,8 @@ onUnmounted(() => {
}
.modal-body {
max-height: 80vh;
overflow: auto;
padding: 15px;
.submit {

View 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>