npm run format
This commit is contained in:
parent
8329afe897
commit
86b80f8244
@ -3,6 +3,6 @@
|
|||||||
"semi": false,
|
"semi": false,
|
||||||
"tabWidth": 2,
|
"tabWidth": 2,
|
||||||
"singleQuote": true,
|
"singleQuote": true,
|
||||||
"printWidth": 100,
|
"printWidth": 300,
|
||||||
"trailingComma": "none"
|
"trailingComma": "none"
|
||||||
}
|
}
|
31
src/App.vue
31
src/App.vue
@ -15,20 +15,23 @@ import Register from '@/components/screens/Register.vue'
|
|||||||
import Characters from '@/components/screens/Characters.vue'
|
import Characters from '@/components/screens/Characters.vue'
|
||||||
import Game from '@/components/Game.vue'
|
import Game from '@/components/Game.vue'
|
||||||
|
|
||||||
const screen:Ref<string> = ref('login');
|
const screen: Ref<string> = ref('login')
|
||||||
const socket = useSocketStore();
|
const socket = useSocketStore()
|
||||||
|
|
||||||
socket.$subscribe((mutation, state) => {
|
socket.$subscribe(
|
||||||
if (!state.connection) {
|
(mutation, state) => {
|
||||||
screen.value = 'login';
|
if (!state.connection) {
|
||||||
}
|
screen.value = 'login'
|
||||||
|
|
||||||
if (state.connection){
|
|
||||||
screen.value = 'characters';
|
|
||||||
|
|
||||||
if (state.character) {
|
|
||||||
screen.value = 'game';
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}, { detached: true })
|
if (state.connection) {
|
||||||
|
screen.value = 'characters'
|
||||||
|
|
||||||
|
if (state.character) {
|
||||||
|
screen.value = 'game'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ detached: true }
|
||||||
|
)
|
||||||
</script>
|
</script>
|
@ -2,7 +2,7 @@
|
|||||||
$white: #fff;
|
$white: #fff;
|
||||||
$black: #000;
|
$black: #000;
|
||||||
$purple: #4741e6;
|
$purple: #4741e6;
|
||||||
$lilac: #7B76FF;
|
$lilac: #7b76ff;
|
||||||
$light-blue: #00c2ff;
|
$light-blue: #00c2ff;
|
||||||
$red: #ff0000;
|
$red: #ff0000;
|
||||||
$gray: #7f7f7f;
|
$gray: #7f7f7f;
|
||||||
|
@ -96,10 +96,17 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 3rem;
|
font-size: 3rem;
|
||||||
color: $white;
|
color: $white;
|
||||||
text-shadow: -1px -1px 0 $gray, 1px -1px 0 $gray, -1px 1px 0 $gray, 1px 1px 0 $gray;
|
text-shadow:
|
||||||
|
-1px -1px 0 $gray,
|
||||||
|
1px -1px 0 $gray,
|
||||||
|
-1px 1px 0 $gray,
|
||||||
|
1px 1px 0 $gray;
|
||||||
}
|
}
|
||||||
|
|
||||||
p, a, li, label {
|
p,
|
||||||
|
a,
|
||||||
|
li,
|
||||||
|
label {
|
||||||
font-family: Arial, sans-serif;
|
font-family: Arial, sans-serif;
|
||||||
color: $white;
|
color: $white;
|
||||||
}
|
}
|
||||||
|
@ -1,27 +1,32 @@
|
|||||||
@import "@/assets/scss/_variables";
|
@import '@/assets/scss/_variables';
|
||||||
|
|
||||||
// Fonts
|
// Fonts
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: GentiumPlus;
|
font-family: GentiumPlus;
|
||||||
src: url('@/assets/fonts/Gentium_plus.ttf');
|
src: url('@/assets/fonts/Gentium_plus.ttf');
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
-ms-overflow-style: none;
|
-ms-overflow-style: none;
|
||||||
scrollbar-width: none;
|
scrollbar-width: none;
|
||||||
background: $black;
|
background: $black;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
||||||
// Disable selection, might wanna comment when debugging
|
// Disable selection, might wanna comment when debugging
|
||||||
-webkit-user-select: none; /* Safari */
|
-webkit-user-select: none; /* Safari */
|
||||||
-ms-user-select: none; /* IE 10 and IE 11 */
|
-ms-user-select: none; /* IE 10 and IE 11 */
|
||||||
user-select: none; /* Standard syntax */
|
user-select: none; /* Standard syntax */
|
||||||
}
|
}
|
||||||
|
|
||||||
h1, h2, h3, h4, h5, h6 {
|
h1,
|
||||||
font-family: GentiumPlus, serif;
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6 {
|
||||||
|
font-family: GentiumPlus, serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar {
|
::-webkit-scrollbar {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
@ -7,55 +7,55 @@ import { ref } from 'vue'
|
|||||||
import config from '@/config'
|
import config from '@/config'
|
||||||
|
|
||||||
const scene = useScene()
|
const scene = useScene()
|
||||||
const pointer_tile = ref(undefined);
|
const pointer_tile = ref(undefined)
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
layer: Phaser.Tilemaps.TilemapLayer
|
layer: Phaser.Tilemaps.TilemapLayer
|
||||||
})
|
})
|
||||||
const waypoint = ref({
|
const waypoint = ref({
|
||||||
visible: false,
|
visible: false,
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0
|
||||||
})
|
})
|
||||||
|
|
||||||
function onPointerMove(pointer: Phaser.Input.Pointer) {
|
function onPointerMove(pointer: Phaser.Input.Pointer) {
|
||||||
const px = scene.cameras.main.worldView.x + pointer.x;
|
const px = scene.cameras.main.worldView.x + pointer.x
|
||||||
const py = scene.cameras.main.worldView.y + pointer.y;
|
const py = scene.cameras.main.worldView.y + pointer.y
|
||||||
|
|
||||||
pointer_tile.value = getTile(px, py, props.layer);
|
pointer_tile.value = getTile(px, py, props.layer)
|
||||||
if (pointer_tile.value) {
|
if (pointer_tile.value) {
|
||||||
waypoint.value.visible = true;
|
waypoint.value.visible = true
|
||||||
|
|
||||||
// Convert tile coordinates to world coordinates
|
// Convert tile coordinates to world coordinates
|
||||||
const worldPoint = props.layer.tileToWorldXY(pointer_tile.value.x, pointer_tile.value.y);
|
const worldPoint = props.layer.tileToWorldXY(pointer_tile.value.x, pointer_tile.value.y)
|
||||||
waypoint.value.x = worldPoint.x + config.tile_size.y;
|
waypoint.value.x = worldPoint.x + config.tile_size.y
|
||||||
waypoint.value.y = worldPoint.y + config.tile_size.y;
|
waypoint.value.y = worldPoint.y + config.tile_size.y
|
||||||
} else {
|
} else {
|
||||||
waypoint.value.visible = false;
|
waypoint.value.visible = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scene.input.on(Phaser.Input.Events.POINTER_MOVE, onPointerMove);
|
scene.input.on(Phaser.Input.Events.POINTER_MOVE, onPointerMove)
|
||||||
|
|
||||||
function getTile (x: number, y: number, layer: Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile | undefined {
|
function getTile(x: number, y: number, layer: Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile | undefined {
|
||||||
const tile: Phaser.Tilemaps.Tile = layer.getTileAtWorldXY(x, y);
|
const tile: Phaser.Tilemaps.Tile = layer.getTileAtWorldXY(x, y)
|
||||||
|
|
||||||
// console.log(x,y);
|
// console.log(x,y);
|
||||||
// console.log('tile', tile);
|
// console.log('tile', tile);
|
||||||
|
|
||||||
if (!tile) {
|
if (!tile) {
|
||||||
return undefined;
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
return tile;
|
return tile
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTileAt (iX: number, iY: number, layer: Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile | undefined {
|
function getTileAt(iX: number, iY: number, layer: Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile | undefined {
|
||||||
const tile: Phaser.Tilemaps.Tile = layer.getTileAt(iX, iY);
|
const tile: Phaser.Tilemaps.Tile = layer.getTileAt(iX, iY)
|
||||||
if (tile) return tile;
|
if (tile) return tile
|
||||||
else return undefined;
|
else return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDepth(tile: Phaser.Tilemaps.Tile): number {
|
function getDepth(tile: Phaser.Tilemaps.Tile): number {
|
||||||
return 32;
|
return 32
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
@ -18,7 +18,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import 'phaser';
|
import 'phaser'
|
||||||
import { Game, Scene } from 'phavuer'
|
import { Game, Scene } from 'phavuer'
|
||||||
import World from '@/components/World.vue'
|
import World from '@/components/World.vue'
|
||||||
import Pointer = Phaser.Input.Pointer
|
import Pointer = Phaser.Input.Pointer
|
||||||
@ -28,10 +28,10 @@ import Chat from '@/components/game/Chat.vue'
|
|||||||
import Menubar from '@/components/game/Menu.vue'
|
import Menubar from '@/components/game/Menu.vue'
|
||||||
import { onUnmounted } from 'vue'
|
import { onUnmounted } from 'vue'
|
||||||
|
|
||||||
const socket = useSocketStore();
|
const socket = useSocketStore()
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
socket.disconnectSocket();
|
socket.disconnectSocket()
|
||||||
})
|
})
|
||||||
|
|
||||||
const gameConfig = {
|
const gameConfig = {
|
||||||
@ -39,13 +39,13 @@ const gameConfig = {
|
|||||||
width: window.innerWidth,
|
width: window.innerWidth,
|
||||||
height: window.innerHeight,
|
height: window.innerHeight,
|
||||||
type: Phaser.WEBGL,
|
type: Phaser.WEBGL,
|
||||||
pixelArt: true,
|
pixelArt: true
|
||||||
}
|
}
|
||||||
|
|
||||||
const bootGame = (game: Phaser.Game) => {
|
const bootGame = (game: Phaser.Game) => {
|
||||||
window.addEventListener('resize', () => {
|
window.addEventListener('resize', () => {
|
||||||
game.scale.resize(window.innerWidth, window.innerHeight);
|
game.scale.resize(window.innerWidth, window.innerHeight)
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const preloadScene = (scene: Phaser.Scene) => {
|
const preloadScene = (scene: Phaser.Scene) => {
|
||||||
@ -54,19 +54,22 @@ const preloadScene = (scene: Phaser.Scene) => {
|
|||||||
* Write logic that downloads all assets from out websocket or http server in base64 format
|
* Write logic that downloads all assets from out websocket or http server in base64 format
|
||||||
* Don't forget to check how intensive that operation is with sockets for performance
|
* Don't forget to check how intensive that operation is with sockets for performance
|
||||||
*/
|
*/
|
||||||
scene.load.image('tiles', '/assets/tiles/default.png');
|
scene.load.image('tiles', '/assets/tiles/default.png')
|
||||||
scene.load.image('waypoint', '/assets/waypoint.png');
|
scene.load.image('waypoint', '/assets/waypoint.png')
|
||||||
scene.textures.addBase64('player', 'data:image/png;base64,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')
|
scene.textures.addBase64(
|
||||||
|
'player',
|
||||||
|
'data:image/png;base64,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'
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const bootScene = (scene: Phaser.Scene) => {
|
const bootScene = (scene: Phaser.Scene) => {
|
||||||
// Camera drag system
|
// Camera drag system
|
||||||
let cam = scene.cameras.main;
|
let cam = scene.cameras.main
|
||||||
scene.input.on("pointermove", function (pointer: Pointer) {
|
scene.input.on('pointermove', function (pointer: Pointer) {
|
||||||
if (!pointer.isDown) return;
|
if (!pointer.isDown) return
|
||||||
cam.scrollX -= (pointer.x - pointer.prevPosition.x) / cam.zoom;
|
cam.scrollX -= (pointer.x - pointer.prevPosition.x) / cam.zoom
|
||||||
cam.scrollY -= (pointer.y - pointer.prevPosition.y) / cam.zoom;
|
cam.scrollY -= (pointer.y - pointer.prevPosition.y) / cam.zoom
|
||||||
});
|
})
|
||||||
|
|
||||||
// const grid = scene.add.grid(0, 0, window.innerWidth, window.innerHeight, 64, 32, 0, 0, 0xff0000, 0.5).setOrigin(0, 0);
|
// const grid = scene.add.grid(0, 0, window.innerWidth, window.innerHeight, 64, 32, 0, 0, 0xff0000, 0.5).setOrigin(0, 0);
|
||||||
//
|
//
|
||||||
@ -82,10 +85,11 @@ const bootScene = (scene: Phaser.Scene) => {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
padding:30px;
|
padding: 30px;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
.top-ui, .bottom-ui {
|
.top-ui,
|
||||||
|
.bottom-ui {
|
||||||
display: flex;
|
display: flex;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
@ -19,18 +19,18 @@ import { useZoneStore } from '@/stores/zone'
|
|||||||
|
|
||||||
// Phavuer logic
|
// Phavuer logic
|
||||||
let scene = useScene()
|
let scene = useScene()
|
||||||
let tilemapLayer = ref();
|
let tilemapLayer = ref()
|
||||||
let zoneData = new Phaser.Tilemaps.MapData({
|
let zoneData = new Phaser.Tilemaps.MapData({
|
||||||
width: 10, // @TODO : get this from the server
|
width: 10, // @TODO : get this from the server
|
||||||
height: 10, // @TODO : get this from the server
|
height: 10, // @TODO : get this from the server
|
||||||
tileWidth: config.tile_size.x,
|
tileWidth: config.tile_size.x,
|
||||||
tileHeight: config.tile_size.y,
|
tileHeight: config.tile_size.y,
|
||||||
orientation: Phaser.Tilemaps.Orientation.ISOMETRIC,
|
orientation: Phaser.Tilemaps.Orientation.ISOMETRIC,
|
||||||
format: Phaser.Tilemaps.Formats.ARRAY_2D,
|
format: Phaser.Tilemaps.Formats.ARRAY_2D
|
||||||
});
|
})
|
||||||
let tileMap = new Phaser.Tilemaps.Tilemap(scene, zoneData);
|
let tileMap = new Phaser.Tilemaps.Tilemap(scene, zoneData)
|
||||||
let tileset: any = tileMap.addTilesetImage('default', 'tiles');
|
let tileset: any = tileMap.addTilesetImage('default', 'tiles')
|
||||||
let layer: (typeof TilemapLayer|null) = tileMap.createBlankLayer('layer', tileset, 0, config.tile_size.y);
|
let layer: typeof TilemapLayer | null = tileMap.createBlankLayer('layer', tileset, 0, config.tile_size.y)
|
||||||
|
|
||||||
// center camera
|
// center camera
|
||||||
const centerY = (tileMap.height * tileMap.tileHeight) / 2
|
const centerY = (tileMap.height * tileMap.tileHeight) / 2
|
||||||
@ -38,24 +38,28 @@ const centerX = (tileMap.width * tileMap.tileWidth) / 2
|
|||||||
scene.cameras.main.centerOn(centerX, centerY)
|
scene.cameras.main.centerOn(centerX, centerY)
|
||||||
|
|
||||||
// Multiplayer / server logics
|
// Multiplayer / server logics
|
||||||
const zoneStore = useZoneStore();
|
const zoneStore = useZoneStore()
|
||||||
const socket = useSocketStore();
|
const socket = useSocketStore()
|
||||||
|
|
||||||
// Watch for changes in the zoneStore and update the layer
|
// Watch for changes in the zoneStore and update the layer
|
||||||
watch (() => zoneStore.tiles, () => { // @TODO : change to tiles for when loading other maps
|
watch(
|
||||||
zoneStore.getTiles.forEach((row, y) => row.forEach((tile, x) => layer.putTileAt(tile, x, y)));
|
() => zoneStore.tiles,
|
||||||
}, { deep: true })
|
() => {
|
||||||
|
// @TODO : change to tiles for when loading other maps
|
||||||
|
zoneStore.getTiles.forEach((row, y) => row.forEach((tile, x) => layer.putTileAt(tile, x, y)))
|
||||||
|
},
|
||||||
|
{ deep: true }
|
||||||
|
)
|
||||||
|
|
||||||
// Load the zone from the server
|
// Load the zone from the server
|
||||||
onBeforeMount(() => {
|
onBeforeMount(() => {
|
||||||
socket.getConnection.emit('character:connect');
|
socket.getConnection.emit('character:connect')
|
||||||
socket.getConnection.emit('character:zone:load');
|
socket.getConnection.emit('character:zone:load')
|
||||||
})
|
})
|
||||||
|
|
||||||
// Listen for the zone event from the server and load the zone
|
// Listen for the zone event from the server and load the zone
|
||||||
socket.getConnection.on('character:zone:load', (data) => {
|
socket.getConnection.on('character:zone:load', (data) => {
|
||||||
console.log('character:zone:load', data);
|
console.log('character:zone:load', data)
|
||||||
zoneStore.loadTiles(data.zone.tiles)
|
zoneStore.loadTiles(data.zone.tiles)
|
||||||
/**
|
/**
|
||||||
* @TODO
|
* @TODO
|
||||||
@ -75,10 +79,10 @@ socket.getConnection.on('character:zone:load', (data) => {
|
|||||||
socket.getConnection.on('player_join', (data) => {
|
socket.getConnection.on('player_join', (data) => {
|
||||||
console.log('player_join', data)
|
console.log('player_join', data)
|
||||||
if (data.id === socket.getConnection.id) {
|
if (data.id === socket.getConnection.id) {
|
||||||
console.log('self');
|
console.log('self')
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
zoneStore.addPlayer(data);
|
zoneStore.addPlayer(data)
|
||||||
})
|
})
|
||||||
|
|
||||||
socket.getConnection.on('ping', (data) => {
|
socket.getConnection.on('ping', (data) => {
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="chat-wrapper">
|
<div class="chat-wrapper">
|
||||||
<input placeholder="Type something..." />
|
<input placeholder="Type something..." />
|
||||||
<img src="/assets/icons/submit-icon.svg">
|
<img src="/assets/icons/submit-icon.svg" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts"></script>
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import '@/assets/scss/main';
|
@import '@/assets/scss/main';
|
||||||
@ -29,7 +27,6 @@
|
|||||||
background-color: rgba($white, 0.85);
|
background-color: rgba($white, 0.85);
|
||||||
border: 2px solid $white;
|
border: 2px solid $white;
|
||||||
color: black;
|
color: black;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
img {
|
img {
|
||||||
@ -39,5 +36,4 @@
|
|||||||
height: 1.875rem;
|
height: 1.875rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
@ -1,54 +1,52 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="hud-wrapper">
|
<div class="hud-wrapper">
|
||||||
<div class="profile">
|
<div class="profile">
|
||||||
<img src="/assets/avatar/default/head.png">
|
<img src="/assets/avatar/default/head.png" />
|
||||||
</div>
|
|
||||||
<div class="hud">
|
|
||||||
<div class="stats"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="hud">
|
||||||
|
<div class="stats"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts"></script>
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import '@/assets/scss/main';
|
@import '@/assets/scss/main';
|
||||||
|
|
||||||
.hud-wrapper {
|
.hud-wrapper {
|
||||||
position: relative;
|
position: relative;
|
||||||
.profile {
|
.profile {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
width: 4rem;
|
width: 4rem;
|
||||||
height: 4rem;
|
height: 4rem;
|
||||||
background-color: rgba($white, 0.8);
|
background-color: rgba($white, 0.8);
|
||||||
border-radius: 100%;
|
border-radius: 100%;
|
||||||
border: 2px solid $white;
|
border: 2px solid $white;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
img {
|
img {
|
||||||
width: 2rem;
|
width: 2rem;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: calc(50% - 1rem);
|
left: calc(50% - 1rem);
|
||||||
top: 50%;
|
top: 50%;
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
}
|
|
||||||
}
|
|
||||||
.hud {
|
|
||||||
position: absolute;
|
|
||||||
left: 2rem;
|
|
||||||
top: 2rem;
|
|
||||||
width: 15rem;
|
|
||||||
height: 5rem;
|
|
||||||
background-image: url('/assets/clouds.png');
|
|
||||||
background-position: center;
|
|
||||||
background-size: cover;
|
|
||||||
// background-color: rgba(127, 127, 127, 0.7);
|
|
||||||
clip-path: ellipse(3rem 3rem at 0% 0%) invert;
|
|
||||||
border-radius: 1rem;
|
|
||||||
border: 2px solid $white;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
.hud {
|
||||||
|
position: absolute;
|
||||||
|
left: 2rem;
|
||||||
|
top: 2rem;
|
||||||
|
width: 15rem;
|
||||||
|
height: 5rem;
|
||||||
|
background-image: url('/assets/clouds.png');
|
||||||
|
background-position: center;
|
||||||
|
background-size: cover;
|
||||||
|
// background-color: rgba(127, 127, 127, 0.7);
|
||||||
|
clip-path: ellipse(3rem 3rem at 0% 0%) invert;
|
||||||
|
border-radius: 1rem;
|
||||||
|
border: 2px solid $white;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
@ -1,106 +1,104 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="menu-wrapper">
|
<div class="menu-wrapper">
|
||||||
<ul class="menu">
|
<ul class="menu">
|
||||||
<li class="menu-item">
|
<li class="menu-item">
|
||||||
<p>Chat</p>
|
<p>Chat</p>
|
||||||
<a>
|
<a>
|
||||||
<img src="/assets/icons/chat.png">
|
<img src="/assets/icons/chat.png" />
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="menu-item">
|
<li class="menu-item">
|
||||||
<p>World</p>
|
<p>World</p>
|
||||||
<a>
|
<a>
|
||||||
<img src="/assets/icons/world.png">
|
<img src="/assets/icons/world.png" />
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="menu-item">
|
<li class="menu-item">
|
||||||
<p>Users</p>
|
<p>Users</p>
|
||||||
<a>
|
<a>
|
||||||
<img src="/assets/icons/users.png">
|
<img src="/assets/icons/users.png" />
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="menu-item">
|
<li class="menu-item">
|
||||||
<p>Inventory</p>
|
<p>Inventory</p>
|
||||||
<a>
|
<a>
|
||||||
<img src="/assets/icons/treasure-chest.png">
|
<img src="/assets/icons/treasure-chest.png" />
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts"></script>
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import '@/assets/scss/main';
|
@import '@/assets/scss/main';
|
||||||
|
|
||||||
.menu-wrapper {
|
.menu-wrapper {
|
||||||
.menu {
|
.menu {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 1.25rem;
|
gap: 1.25rem;
|
||||||
|
|
||||||
.menu-item {
|
.menu-item {
|
||||||
position: relative;
|
position: relative;
|
||||||
p {
|
p {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 3.125rem;
|
bottom: 3.125rem;
|
||||||
width: 4rem;
|
width: 4rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background-color: #B1B2B5;
|
background-color: #b1b2b5;
|
||||||
border: 2px solid $white;
|
border: 2px solid $white;
|
||||||
border-radius: 1.5rem;
|
border-radius: 1.5rem;
|
||||||
height: 1.5rem;
|
height: 1.5rem;
|
||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
line-height: 1.5rem;
|
line-height: 1.5rem;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
display: none;
|
display: none;
|
||||||
|
|
||||||
&::after {
|
&::after {
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 100%;
|
top: 100%;
|
||||||
background-color: $white;
|
background-color: $white;
|
||||||
height: 0.5rem;
|
height: 0.5rem;
|
||||||
width: 0.875rem;
|
width: 0.875rem;
|
||||||
clip-path: polygon(100% 0, 0 0, 50% 100%);
|
clip-path: polygon(100% 0, 0 0, 50% 100%);
|
||||||
left: calc(50% - 0.4375rem);
|
left: calc(50% - 0.4375rem);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
padding: 0.5rem;
|
|
||||||
background-color: rgba(127, 127, 127, 0.7);
|
|
||||||
border: 2px solid $white;
|
|
||||||
border-radius: 100%;
|
|
||||||
display: block;
|
|
||||||
width: 1.875rem;
|
|
||||||
height: 1.875rem;
|
|
||||||
|
|
||||||
img {
|
|
||||||
width: inherit;
|
|
||||||
height: inherit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
p {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
background-image: url('/assets/galaxy.png');
|
|
||||||
background-position: center;
|
|
||||||
background-size: cover;
|
|
||||||
img {
|
|
||||||
-webkit-filter: drop-shadow(0px 3px 6px $black);
|
|
||||||
filter: drop-shadow(0px 3px 6px $black);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
padding: 0.5rem;
|
||||||
|
background-color: rgba(127, 127, 127, 0.7);
|
||||||
|
border: 2px solid $white;
|
||||||
|
border-radius: 100%;
|
||||||
|
display: block;
|
||||||
|
width: 1.875rem;
|
||||||
|
height: 1.875rem;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: inherit;
|
||||||
|
height: inherit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
p {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
background-image: url('/assets/galaxy.png');
|
||||||
|
background-position: center;
|
||||||
|
background-size: cover;
|
||||||
|
img {
|
||||||
|
-webkit-filter: drop-shadow(0px 3px 6px $black);
|
||||||
|
filter: drop-shadow(0px 3px 6px $black);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
@ -1,50 +1,50 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="character-select-screen">
|
<div class="character-select-screen">
|
||||||
<div class="ui-wrapper">
|
<div class="ui-wrapper">
|
||||||
<div class="characters-wrapper">
|
<div class="characters-wrapper">
|
||||||
<div v-for="character in characters" :key="character.id" class="character" :class="{active: selected_character == character.id}">
|
<div v-for="character in characters" :key="character.id" class="character" :class="{ active: selected_character == character.id }">
|
||||||
<input type="radio" :id="character.id" name="character" :value="character.id" v-model="selected_character" />
|
<input type="radio" :id="character.id" name="character" :value="character.id" v-model="selected_character" />
|
||||||
<label :for="character.id">{{ character.name }}</label>
|
<label :for="character.id">{{ character.name }}</label>
|
||||||
<div class="sprite-container">
|
<div class="sprite-container">
|
||||||
<img src="/assets/avatar/default/base_right_down.png" />
|
<img src="/assets/avatar/default/base_right_down.png" />
|
||||||
|
</div>
|
||||||
|
<span>Lvl. </span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="character new-character">
|
||||||
|
<button @click="isModalOpen = true">
|
||||||
|
<img src="/assets/icons/plus-icon.svg" />
|
||||||
|
<span>Create new</span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<span>Lvl. </span>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="character new-character">
|
<div class="buttons-wrapper">
|
||||||
<button @click="isModalOpen = true">
|
<button v-if="selected_character" @click="select_character()">Play</button>
|
||||||
<img src="/assets/icons/plus-icon.svg" />
|
<!-- @TODO : Add a confirmation dialog -->
|
||||||
<span>Create new</span>
|
<button v-if="selected_character" @click="delete_character()">Delete</button>
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="buttons-wrapper">
|
|
||||||
<button v-if="selected_character" @click="select_character()">Play</button>
|
|
||||||
<!-- @TODO : Add a confirmation dialog -->
|
|
||||||
<button v-if="selected_character" @click="delete_character()">Delete</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<Modal :isModalOpen="isModalOpen" @modal:close="isModalOpen = false">
|
<Modal :isModalOpen="isModalOpen" @modal:close="isModalOpen = false">
|
||||||
<template #modal-header>
|
<template #modal-header>
|
||||||
<h2 class="modal-title">Create your character</h2>
|
<h2 class="modal-title">Create your character</h2>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #modal-body>
|
<template #modal-body>
|
||||||
<form method="post" @submit.prevent="create" class="modal-form">
|
<form method="post" @submit.prevent="create" class="modal-form">
|
||||||
<div class="form-fields">
|
<div class="form-fields">
|
||||||
<label for="name">Name</label>
|
<label for="name">Name</label>
|
||||||
<input v-model="name" name="name" id="name">
|
<input v-model="name" name="name" id="name" />
|
||||||
</div>
|
</div>
|
||||||
<div class="submit">
|
<div class="submit">
|
||||||
<button @click="create">Create</button>
|
<button @click="create">Create</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<button @click="isModalOpen = false">Cancel</button>
|
<button @click="isModalOpen = false">Cancel</button>
|
||||||
</template>
|
</template>
|
||||||
</Modal>
|
</Modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@ -53,38 +53,38 @@ import { ref } from 'vue'
|
|||||||
import type { Character } from '../../../env'
|
import type { Character } from '../../../env'
|
||||||
import Modal from '@/components/utilities/Modal.vue'
|
import Modal from '@/components/utilities/Modal.vue'
|
||||||
|
|
||||||
const socket = useSocketStore();
|
const socket = useSocketStore()
|
||||||
|
|
||||||
// Fetch characters
|
// Fetch characters
|
||||||
socket.getConnection.emit('character:list');
|
socket.getConnection.emit('character:list')
|
||||||
socket.getConnection.on('character:list', (data: any) => {
|
socket.getConnection.on('character:list', (data: any) => {
|
||||||
console.log(data);
|
console.log(data)
|
||||||
characters.value = data;
|
characters.value = data
|
||||||
});
|
})
|
||||||
|
|
||||||
// Select character logics
|
// Select character logics
|
||||||
const characters = ref([]);
|
const characters = ref([])
|
||||||
const selected_character = ref(null);
|
const selected_character = ref(null)
|
||||||
function select_character() {
|
function select_character() {
|
||||||
console.log(selected_character.value);
|
console.log(selected_character.value)
|
||||||
if (!selected_character.value) return;
|
if (!selected_character.value) return
|
||||||
socket.getConnection.emit('character:connect', {character_id: selected_character.value});
|
socket.getConnection.emit('character:connect', { character_id: selected_character.value })
|
||||||
socket.getConnection.on('character:connect', (data: Character) => socket.setCharacter(data));
|
socket.getConnection.on('character:connect', (data: Character) => socket.setCharacter(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete character logics
|
// Delete character logics
|
||||||
function delete_character() {
|
function delete_character() {
|
||||||
if (!selected_character.value) return;
|
if (!selected_character.value) return
|
||||||
socket.getConnection.emit('character:delete', {character_id: selected_character.value});
|
socket.getConnection.emit('character:delete', { character_id: selected_character.value })
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create character logics
|
// Create character logics
|
||||||
const isModalOpen = ref(false);
|
const isModalOpen = ref(false)
|
||||||
let name: any = ref('');
|
let name: any = ref('')
|
||||||
function create() {
|
function create() {
|
||||||
socket.getConnection.emit('character:create', { name: name.value });
|
socket.getConnection.emit('character:create', { name: name.value })
|
||||||
name.value = '';
|
name.value = ''
|
||||||
isModalOpen.value = false;
|
isModalOpen.value = false
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ function create() {
|
|||||||
@import '@/assets/scss/main';
|
@import '@/assets/scss/main';
|
||||||
|
|
||||||
.character-select-screen {
|
.character-select-screen {
|
||||||
background-image: url("/assets/bglogin.png");
|
background-image: url('/assets/bglogin.png');
|
||||||
.ui-wrapper {
|
.ui-wrapper {
|
||||||
// vertical and vertical center
|
// vertical and vertical center
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
@ -104,7 +104,6 @@ function create() {
|
|||||||
padding: 0 5rem;
|
padding: 0 5rem;
|
||||||
&::before {
|
&::before {
|
||||||
content: '';
|
content: '';
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.characters-wrapper {
|
.characters-wrapper {
|
||||||
@ -139,7 +138,6 @@ function create() {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
&::before {
|
&::before {
|
||||||
content: '';
|
content: '';
|
||||||
|
|
||||||
}
|
}
|
||||||
img {
|
img {
|
||||||
width: 100px;
|
width: 100px;
|
||||||
@ -155,7 +153,8 @@ function create() {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&::before, &::after {
|
&::before,
|
||||||
|
&::after {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -181,12 +180,11 @@ function create() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// hide the radio buttons
|
// hide the radio buttons
|
||||||
input[type="radio"] {
|
input[type='radio'] {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
label {
|
label {
|
||||||
@ -251,7 +249,4 @@ function create() {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
@ -6,11 +6,11 @@
|
|||||||
<form method="post">
|
<form method="post">
|
||||||
<div class="form-field">
|
<div class="form-field">
|
||||||
<label for="username">Username</label>
|
<label for="username">Username</label>
|
||||||
<input id="username" v-model="username" type="text" name="username" required autofocus>
|
<input id="username" v-model="username" type="text" name="username" required autofocus />
|
||||||
</div>
|
</div>
|
||||||
<div class="form-field">
|
<div class="form-field">
|
||||||
<label for="password">Password</label>
|
<label for="password">Password</label>
|
||||||
<input id="password" v-model="password" type="password" name="password" required>
|
<input id="password" v-model="password" type="password" name="password" required />
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@ -28,10 +28,10 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { useSocketStore } from '@/stores/socket.ts'
|
import { useSocketStore } from '@/stores/socket.ts'
|
||||||
import {login, register} from '@/services/authentication.ts'
|
import { login, register } from '@/services/authentication.ts'
|
||||||
import { useNotificationStore } from '@/stores/notifications'
|
import { useNotificationStore } from '@/stores/notifications'
|
||||||
|
|
||||||
const bgm = ref('bgm');
|
const bgm = ref('bgm')
|
||||||
if (bgm.value.paused) {
|
if (bgm.value.paused) {
|
||||||
window.addEventListener('click', () => bgm.value.play())
|
window.addEventListener('click', () => bgm.value.play())
|
||||||
window.addEventListener('keydown', () => bgm.value.play())
|
window.addEventListener('keydown', () => bgm.value.play())
|
||||||
@ -39,22 +39,22 @@ if (bgm.value.paused) {
|
|||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
const notifications = useNotificationStore()
|
const notifications = useNotificationStore()
|
||||||
const socket = useSocketStore();
|
const socket = useSocketStore()
|
||||||
const username = ref('');
|
const username = ref('')
|
||||||
const password = ref('');
|
const password = ref('')
|
||||||
|
|
||||||
async function loginFunc() {
|
async function loginFunc() {
|
||||||
// check if username and password are valid
|
// check if username and password are valid
|
||||||
if (username.value === '' || password.value === '') {
|
if (username.value === '' || password.value === '') {
|
||||||
notifications.addNotification({ message: 'Please enter a valid username and password' });
|
notifications.addNotification({ message: 'Please enter a valid username and password' })
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// send login event to server
|
// send login event to server
|
||||||
const success = await login(username.value, password.value);
|
const success = await login(username.value, password.value)
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
notifications.addNotification({ message: 'Invalid username or password' });
|
notifications.addNotification({ message: 'Invalid username or password' })
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (success) {}
|
// if (success) {}
|
||||||
@ -63,15 +63,15 @@ async function loginFunc() {
|
|||||||
async function registerFunc() {
|
async function registerFunc() {
|
||||||
// check if username and password are valid
|
// check if username and password are valid
|
||||||
if (username.value === '' || password.value === '') {
|
if (username.value === '' || password.value === '') {
|
||||||
notifications.addNotification({ message: 'Please enter a valid username and password' });
|
notifications.addNotification({ message: 'Please enter a valid username and password' })
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// send register event to server
|
// send register event to server
|
||||||
const success = await register(username.value, password.value);
|
const success = await register(username.value, password.value)
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
notifications.addNotification({ message: 'Username already exists' });
|
notifications.addNotification({ message: 'Username already exists' })
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (success) {}
|
// if (success) {}
|
||||||
@ -79,5 +79,5 @@ async function registerFunc() {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@/assets/scss/login";
|
@import '@/assets/scss/login';
|
||||||
</style>
|
</style>
|
@ -1,3 +1 @@
|
|||||||
<template>
|
<template></template>
|
||||||
|
|
||||||
</template>
|
|
||||||
|
@ -11,7 +11,8 @@
|
|||||||
fontStyle: 'bold',
|
fontStyle: 'bold',
|
||||||
strokeThickness: 8,
|
strokeThickness: 8,
|
||||||
stroke: '#213547'
|
stroke: '#213547'
|
||||||
}" />
|
}"
|
||||||
|
/>
|
||||||
<Sprite ref="sprite" texture="player" :x="position.x" :y="position.y" />
|
<Sprite ref="sprite" texture="player" :x="position.x" :y="position.y" />
|
||||||
</Container>
|
</Container>
|
||||||
</template>
|
</template>
|
||||||
@ -22,14 +23,14 @@ import { reactive, type Ref, ref } from 'vue'
|
|||||||
import config from '@/config'
|
import config from '@/config'
|
||||||
import { useSocketStore } from '@/stores/socket'
|
import { useSocketStore } from '@/stores/socket'
|
||||||
|
|
||||||
const socket = useSocketStore();
|
const socket = useSocketStore()
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
layer: Phaser.Tilemaps.TilemapLayer,
|
layer: Phaser.Tilemaps.TilemapLayer,
|
||||||
player: {
|
player: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: undefined
|
default: undefined
|
||||||
},
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const scene = useScene()
|
const scene = useScene()
|
||||||
@ -38,64 +39,64 @@ const scene = useScene()
|
|||||||
// console.log(time, delta);
|
// console.log(time, delta);
|
||||||
// })
|
// })
|
||||||
|
|
||||||
const position = reactive({ x: 0, y: 0 });
|
const position = reactive({ x: 0, y: 0 })
|
||||||
|
|
||||||
if (props.player !== undefined) {
|
if (props.player !== undefined) {
|
||||||
console.log('player', props.player);
|
console.log('player', props.player)
|
||||||
position.x = props.player?.coords.x;
|
position.x = props.player?.coords.x
|
||||||
position.y = props.player?.coords.y;
|
position.y = props.player?.coords.y
|
||||||
}
|
}
|
||||||
|
|
||||||
const pointer_tile = ref(undefined);
|
const pointer_tile = ref(undefined)
|
||||||
|
|
||||||
function onPointerClick(pointer: Phaser.Input.Pointer) {
|
function onPointerClick(pointer: Phaser.Input.Pointer) {
|
||||||
const px = scene.cameras.main.worldView.x + pointer.x;
|
const px = scene.cameras.main.worldView.x + pointer.x
|
||||||
const py = scene.cameras.main.worldView.y + pointer.y;
|
const py = scene.cameras.main.worldView.y + pointer.y
|
||||||
|
|
||||||
pointer_tile.value = getTile(px, py, props.layer);
|
pointer_tile.value = getTile(px, py, props.layer)
|
||||||
if (pointer_tile.value) {
|
if (pointer_tile.value) {
|
||||||
const worldPoint = props.layer.tileToWorldXY(pointer_tile.value.x, pointer_tile.value.y);
|
const worldPoint = props.layer.tileToWorldXY(pointer_tile.value.x, pointer_tile.value.y)
|
||||||
position.x = worldPoint.x + config.tile_size.y;
|
position.x = worldPoint.x + config.tile_size.y
|
||||||
position.y = worldPoint.y;
|
position.y = worldPoint.y
|
||||||
|
|
||||||
socket.getConnection.emit('move', { x: position.x, y: position.y });
|
socket.getConnection.emit('move', { x: position.x, y: position.y })
|
||||||
}
|
}
|
||||||
|
|
||||||
//Directions for player sprites + animations
|
//Directions for player sprites + animations
|
||||||
if (px < 0 && py > 0) {
|
if (px < 0 && py > 0) {
|
||||||
console.log('down left');
|
console.log('down left')
|
||||||
} else if (px < 0 && py < 0) {
|
} else if (px < 0 && py < 0) {
|
||||||
console.log('top left');
|
console.log('top left')
|
||||||
} else if (px > 0 && py > 0) {
|
} else if (px > 0 && py > 0) {
|
||||||
console.log('down right');
|
console.log('down right')
|
||||||
} else if (px > 0 && py < 0) {
|
} else if (px > 0 && py < 0) {
|
||||||
console.log('top right');
|
console.log('top right')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!props.player) {
|
if (!props.player) {
|
||||||
scene.input.on(Phaser.Input.Events.POINTER_UP, onPointerClick);
|
scene.input.on(Phaser.Input.Events.POINTER_UP, onPointerClick)
|
||||||
}
|
}
|
||||||
|
|
||||||
socket.getConnection.on('player_moved', (data: any) => {
|
socket.getConnection.on('player_moved', (data: any) => {
|
||||||
console.log('player_moved', data);
|
console.log('player_moved', data)
|
||||||
|
|
||||||
if (data.id !== props.player?.id) {
|
if (data.id !== props.player?.id) {
|
||||||
console.log('not you');
|
console.log('not you')
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
position.x = data.coords.x;
|
position.x = data.coords.x
|
||||||
position.y = data.coords.y;
|
position.y = data.coords.y
|
||||||
})
|
})
|
||||||
|
|
||||||
function getTile (x: number, y: number, layer: Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile | undefined {
|
function getTile(x: number, y: number, layer: Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile | undefined {
|
||||||
const tile: Phaser.Tilemaps.Tile = layer.getTileAtWorldXY(x, y);
|
const tile: Phaser.Tilemaps.Tile = layer.getTileAtWorldXY(x, y)
|
||||||
|
|
||||||
if (!tile) {
|
if (!tile) {
|
||||||
return undefined;
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
return tile;
|
return tile
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
@ -1,14 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<Teleport to="body">
|
<Teleport to="body">
|
||||||
<div class="modal-container" :style="{ top: y + 'px', left: x + 'px' }" v-if="isModalOpenRef">
|
<div class="modal-container" :style="{ top: y + 'px', left: x + 'px' }" v-if="isModalOpenRef">
|
||||||
<div class="modal-header" @mousedown="startDrag">
|
<div class="modal-header" @mousedown="startDrag">
|
||||||
<slot name="modal-header"/>
|
<slot name="modal-header" />
|
||||||
<button @click="close"><img src="/assets/icons/close-button-white.svg"></button>
|
<button @click="close"><img src="/assets/icons/close-button-white.svg" /></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<slot name="modal-body" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
|
||||||
<slot name="modal-body"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Teleport>
|
</Teleport>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -20,64 +20,67 @@ const properties = defineProps({
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
watch(() => properties.isModalOpen, (value) => {
|
watch(
|
||||||
isModalOpenRef.value = value;
|
() => properties.isModalOpen,
|
||||||
});
|
(value) => {
|
||||||
|
isModalOpenRef.value = value
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
const isModalOpenRef = ref(properties.isModalOpen);
|
const isModalOpenRef = ref(properties.isModalOpen)
|
||||||
const emit = defineEmits(["modal:close", "character:create"]);
|
const emit = defineEmits(['modal:close', 'character:create'])
|
||||||
|
|
||||||
function close () {
|
function close() {
|
||||||
emit('modal:close');
|
emit('modal:close')
|
||||||
}
|
}
|
||||||
|
|
||||||
// make modal draggable
|
// make modal draggable
|
||||||
let startX = 0;
|
let startX = 0
|
||||||
let startY = 0;
|
let startY = 0
|
||||||
let initialX = 0;
|
let initialX = 0
|
||||||
let initialY = 0;
|
let initialY = 0
|
||||||
const x = ref(0);
|
const x = ref(0)
|
||||||
const y = ref(0);
|
const y = ref(0)
|
||||||
const isDragging = ref(false);
|
const isDragging = ref(false)
|
||||||
|
|
||||||
// set modal position center of the screen
|
// set modal position center of the screen
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
x.value = (window.innerWidth / 2) - 150;
|
x.value = window.innerWidth / 2 - 150
|
||||||
y.value = (window.innerHeight / 2) - 100;
|
y.value = window.innerHeight / 2 - 100
|
||||||
});
|
})
|
||||||
|
|
||||||
const startDrag = (event: MouseEvent) => {
|
const startDrag = (event: MouseEvent) => {
|
||||||
isDragging.value = true;
|
isDragging.value = true
|
||||||
startX = event.clientX;
|
startX = event.clientX
|
||||||
startY = event.clientY;
|
startY = event.clientY
|
||||||
initialX = x.value;
|
initialX = x.value
|
||||||
initialY = y.value;
|
initialY = y.value
|
||||||
event.preventDefault();
|
event.preventDefault()
|
||||||
};
|
}
|
||||||
|
|
||||||
const drag = (event: MouseEvent) => {
|
const drag = (event: MouseEvent) => {
|
||||||
if (!isDragging.value) return;
|
if (!isDragging.value) return
|
||||||
const dx = event.clientX - startX;
|
const dx = event.clientX - startX
|
||||||
const dy = event.clientY - startY;
|
const dy = event.clientY - startY
|
||||||
x.value = initialX + dx;
|
x.value = initialX + dx
|
||||||
y.value = initialY + dy;
|
y.value = initialY + dy
|
||||||
};
|
}
|
||||||
|
|
||||||
const stopDrag = () => {
|
const stopDrag = () => {
|
||||||
isDragging.value = false;
|
isDragging.value = false
|
||||||
};
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
addEventListener('mousemove', drag);
|
addEventListener('mousemove', drag)
|
||||||
addEventListener('mouseup', stopDrag);
|
addEventListener('mouseup', stopDrag)
|
||||||
});
|
})
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
removeEventListener('mousemove', drag);
|
removeEventListener('mousemove', drag)
|
||||||
removeEventListener('mouseup', stopDrag);
|
removeEventListener('mouseup', stopDrag)
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="notifications">
|
<div class="notifications">
|
||||||
<Modal v-for="notification in notifications.getNotifications"
|
<Modal v-for="notification in notifications.getNotifications" :key="notification.id" :isModalOpen="true" @modal:close="closeNotification(notification.id)">
|
||||||
:key="notification.id"
|
|
||||||
:isModalOpen="true"
|
|
||||||
@modal:close="closeNotification(notification.id)"
|
|
||||||
>
|
|
||||||
<template #modal-body>
|
<template #modal-body>
|
||||||
<p>{{ notification.message }}</p>
|
<p>{{ notification.message }}</p>
|
||||||
</template>
|
</template>
|
||||||
@ -30,7 +26,7 @@ function setupNotificationListener(connection: any) {
|
|||||||
notifications.addNotification({
|
notifications.addNotification({
|
||||||
id: Math.random().toString(16),
|
id: Math.random().toString(16),
|
||||||
message: data.message
|
message: data.message
|
||||||
});
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,7 +36,9 @@ onMounted(() => {
|
|||||||
setupNotificationListener(connection)
|
setupNotificationListener(connection)
|
||||||
} else {
|
} else {
|
||||||
// Watch for changes in the socket connection
|
// Watch for changes in the socket connection
|
||||||
watch(() => socket.getConnection, (newConnection) => {
|
watch(
|
||||||
|
() => socket.getConnection,
|
||||||
|
(newConnection) => {
|
||||||
if (newConnection) setupNotificationListener(newConnection)
|
if (newConnection) setupNotificationListener(newConnection)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import Player from '../Player/Player';
|
import Player from '../Player/Player'
|
||||||
|
|
||||||
export default interface IMap {
|
export default interface IMap {
|
||||||
readonly id: number;
|
readonly id: number
|
||||||
name: string;
|
name: string
|
||||||
width: number;
|
width: number
|
||||||
height: number;
|
height: number
|
||||||
data: any;
|
data: any
|
||||||
players: Array<Player>|[];
|
players: Array<Player> | []
|
||||||
}
|
}
|
@ -1,37 +1,37 @@
|
|||||||
import type IMap from '@/engine/Map/IMap';
|
import type IMap from '@/engine/Map/IMap'
|
||||||
import Player from '@/engine/Player/Player';
|
import Player from '@/engine/Player/Player'
|
||||||
|
|
||||||
export default class Map implements IMap {
|
export default class Map implements IMap {
|
||||||
id: number;
|
id: number
|
||||||
name: string;
|
name: string
|
||||||
width: number;
|
width: number
|
||||||
height: number;
|
height: number
|
||||||
data: any;
|
data: any
|
||||||
players: Array<Player>|[];
|
players: Array<Player> | []
|
||||||
|
|
||||||
constructor(id: number, name: string, width: number, height: number, data: any, players: Array<Player>|[]) {
|
constructor(id: number, name: string, width: number, height: number, data: any, players: Array<Player> | []) {
|
||||||
this.id = id;
|
this.id = id
|
||||||
this.name = name;
|
this.name = name
|
||||||
this.width = width;
|
this.width = width
|
||||||
this.height = height;
|
this.height = height
|
||||||
this.data = data;
|
this.data = data
|
||||||
this.players = players;
|
this.players = players
|
||||||
}
|
}
|
||||||
|
|
||||||
public addPlayer(player: Player) {
|
public addPlayer(player: Player) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
this.players.push(player);
|
this.players.push(player)
|
||||||
}
|
}
|
||||||
|
|
||||||
public removePlayer(player: Player) {
|
public removePlayer(player: Player) {
|
||||||
this.players = this.players.filter(p => p.id !== player.id);
|
this.players = this.players.filter((p) => p.id !== player.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
public movePlayer(player: Player, x: number, y: number) {
|
public movePlayer(player: Player, x: number, y: number) {
|
||||||
const playerIndex = this.players.findIndex(p => p.id === player.id);
|
const playerIndex = this.players.findIndex((p) => p.id === player.id)
|
||||||
if (playerIndex !== -1) {
|
if (playerIndex !== -1) {
|
||||||
this.players[playerIndex].coords.x = x;
|
this.players[playerIndex].coords.x = x
|
||||||
this.players[playerIndex].coords.y = y;
|
this.players[playerIndex].coords.y = y
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,8 +1,8 @@
|
|||||||
export default interface IPlayer {
|
export default interface IPlayer {
|
||||||
readonly id: number;
|
readonly id: number
|
||||||
name: string;
|
name: string
|
||||||
coords: {
|
coords: {
|
||||||
x: number;
|
x: number
|
||||||
y: number;
|
y: number
|
||||||
};
|
}
|
||||||
}
|
}
|
@ -1,13 +1,13 @@
|
|||||||
import type IPlayer from '@/engine/Player/IPlayer';
|
import type IPlayer from '@/engine/Player/IPlayer'
|
||||||
|
|
||||||
export default class Player implements IPlayer {
|
export default class Player implements IPlayer {
|
||||||
id: number;
|
id: number
|
||||||
name: string;
|
name: string
|
||||||
coords: { x: number; y: number; };
|
coords: { x: number; y: number }
|
||||||
|
|
||||||
constructor(id: number, name: string, coords: { x: number; y: number; }) {
|
constructor(id: number, name: string, coords: { x: number; y: number }) {
|
||||||
this.id = id;
|
this.id = id
|
||||||
this.name = name;
|
this.name = name
|
||||||
this.coords = coords;
|
this.coords = coords
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,32 +1,32 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios'
|
||||||
import config from '@/config';
|
import config from '@/config'
|
||||||
import { useSocketStore } from '@/stores/socket';
|
import { useSocketStore } from '@/stores/socket'
|
||||||
import { useCookies } from '@vueuse/integrations/useCookies'
|
import { useCookies } from '@vueuse/integrations/useCookies'
|
||||||
|
|
||||||
export async function register(username: string, password: string, socketStore = useSocketStore()) {
|
export async function register(username: string, password: string, socketStore = useSocketStore()) {
|
||||||
try {
|
try {
|
||||||
const response = await axios.post(`${config.server_endpoint}/register`, { username, password });
|
const response = await axios.post(`${config.server_endpoint}/register`, { username, password })
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
useCookies().set('token', response.data.token as string)
|
useCookies().set('token', response.data.token as string)
|
||||||
await socketStore.setupSocketConnection();
|
await socketStore.setupSocketConnection()
|
||||||
return true;
|
return true
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error registering user:', error);
|
console.error('Error registering user:', error)
|
||||||
return false;
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function login(username: string, password: string, socketStore = useSocketStore()) {
|
export async function login(username: string, password: string, socketStore = useSocketStore()) {
|
||||||
try {
|
try {
|
||||||
const response = await axios.post(`${config.server_endpoint}/login`, { username, password });
|
const response = await axios.post(`${config.server_endpoint}/login`, { username, password })
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
useCookies().set('token', response.data.token as string)
|
useCookies().set('token', response.data.token as string)
|
||||||
await socketStore.setupSocketConnection();
|
await socketStore.setupSocketConnection()
|
||||||
return true;
|
return true
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Login failed:', error);
|
console.error('Login failed:', error)
|
||||||
return false;
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -10,10 +10,10 @@ export const useNotificationStore: StoreDefinition = defineStore('notifications'
|
|||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
addNotification(notification: Notification) {
|
addNotification(notification: Notification) {
|
||||||
this.notifications.push(notification);
|
this.notifications.push(notification)
|
||||||
},
|
},
|
||||||
removeNotification(id: string) {
|
removeNotification(id: string) {
|
||||||
this.notifications = this.notifications.filter((notification: Notification) => notification.id !== id);
|
this.notifications = this.notifications.filter((notification: Notification) => notification.id !== id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { defineStore, type StoreDefinition } from 'pinia'
|
import { defineStore, type StoreDefinition } from 'pinia'
|
||||||
import { io, Socket } from 'socket.io-client';
|
import { io, Socket } from 'socket.io-client'
|
||||||
import {useCookies} from '@vueuse/integrations/useCookies'
|
import { useCookies } from '@vueuse/integrations/useCookies'
|
||||||
import config from '@/config';
|
import config from '@/config'
|
||||||
import type { Character, User } from '@/types'
|
import type { Character, User } from '@/types'
|
||||||
import { useNotificationStore } from '@/stores/notifications'
|
import { useNotificationStore } from '@/stores/notifications'
|
||||||
|
|
||||||
@ -9,54 +9,54 @@ export const useSocketStore: StoreDefinition = defineStore('socket', {
|
|||||||
state: () => ({
|
state: () => ({
|
||||||
connection: null as Socket | null,
|
connection: null as Socket | null,
|
||||||
user: null as User | null,
|
user: null as User | null,
|
||||||
character: null as Character | null,
|
character: null as Character | null
|
||||||
}),
|
}),
|
||||||
getters: {
|
getters: {
|
||||||
getConnection: (state: any) => state.connection as Socket,
|
getConnection: (state: any) => state.connection as Socket,
|
||||||
getUser: (state: any) => state.user as User,
|
getUser: (state: any) => state.user as User,
|
||||||
getCharacter: (state: any) => state.character as Character,
|
getCharacter: (state: any) => state.character as Character
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
setupSocketConnection() {
|
setupSocketConnection() {
|
||||||
this.connection = io(config.server_endpoint, {
|
this.connection = io(config.server_endpoint, {
|
||||||
withCredentials: true,
|
withCredentials: true,
|
||||||
transports: ['websocket'],
|
transports: ['websocket'],
|
||||||
reconnectionAttempts: 5,
|
reconnectionAttempts: 5
|
||||||
});
|
})
|
||||||
|
|
||||||
// Let the server know the user is logged in
|
// Let the server know the user is logged in
|
||||||
this.connection.emit('login');
|
this.connection.emit('login')
|
||||||
|
|
||||||
// set user
|
// set user
|
||||||
this.connection.on('login', (user: User) => {
|
this.connection.on('login', (user: User) => {
|
||||||
this.setUser(user);
|
this.setUser(user)
|
||||||
});
|
})
|
||||||
|
|
||||||
// When we can't reconnect, disconnect
|
// When we can't reconnect, disconnect
|
||||||
this.connection.on('reconnect_failed', () => {
|
this.connection.on('reconnect_failed', () => {
|
||||||
console.log("Reconnect failed")
|
console.log('Reconnect failed')
|
||||||
this.disconnectSocket();
|
this.disconnectSocket()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
disconnectSocket() {
|
disconnectSocket() {
|
||||||
if (!this.connection) return;
|
if (!this.connection) return
|
||||||
|
|
||||||
this.connection.disconnect();
|
this.connection.disconnect()
|
||||||
this.connection = null;
|
this.connection = null
|
||||||
|
|
||||||
this.user = null;
|
this.user = null
|
||||||
this.character = null;
|
this.character = null
|
||||||
|
|
||||||
useCookies().remove('token');
|
useCookies().remove('token')
|
||||||
},
|
},
|
||||||
setUser(user: User|null) {
|
setUser(user: User | null) {
|
||||||
this.user = user;
|
this.user = user
|
||||||
},
|
},
|
||||||
setCharacter(character: Character|null) {
|
setCharacter(character: Character | null) {
|
||||||
this.character = character;
|
this.character = character
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resources:
|
* Resources:
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
export const useZoneStore = defineStore('zone', {
|
export const useZoneStore = defineStore('zone', {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
@ -13,18 +13,18 @@ export const useZoneStore = defineStore('zone', {
|
|||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
loadTiles(tiles: any) {
|
loadTiles(tiles: any) {
|
||||||
this.tiles = tiles;
|
this.tiles = tiles
|
||||||
this.loaded = true;
|
this.loaded = true
|
||||||
},
|
},
|
||||||
addPlayers(player: any) {
|
addPlayers(player: any) {
|
||||||
this.players = player;
|
this.players = player
|
||||||
},
|
},
|
||||||
addPlayer(player: any) {
|
addPlayer(player: any) {
|
||||||
this.players[player.id] = player;
|
this.players[player.id] = player
|
||||||
console.log('Player added:', player);
|
console.log('Player added:', player)
|
||||||
},
|
},
|
||||||
removePlayer(playerId: any) {
|
removePlayer(playerId: any) {
|
||||||
delete this.players[playerId];
|
delete this.players[playerId]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
80
src/types.ts
80
src/types.ts
@ -1,49 +1,49 @@
|
|||||||
export type Notification = {
|
export type Notification = {
|
||||||
id: string;
|
id: string
|
||||||
message: string;
|
message: string
|
||||||
};
|
}
|
||||||
|
|
||||||
export type User = {
|
export type User = {
|
||||||
id: number;
|
id: number
|
||||||
username: string;
|
username: string
|
||||||
password: string;
|
password: string
|
||||||
characters: Character[];
|
characters: Character[]
|
||||||
};
|
}
|
||||||
|
|
||||||
export type Character = {
|
export type Character = {
|
||||||
id: number;
|
id: number
|
||||||
userId: number;
|
userId: number
|
||||||
user: User;
|
user: User
|
||||||
name: string;
|
name: string
|
||||||
hitpoints: number;
|
hitpoints: number
|
||||||
mana: number;
|
mana: number
|
||||||
level: number;
|
level: number
|
||||||
experience: number;
|
experience: number
|
||||||
role: string;
|
role: string
|
||||||
position_x: number;
|
position_x: number
|
||||||
position_y: number;
|
position_y: number
|
||||||
rotation: number;
|
rotation: number
|
||||||
zoneId: number;
|
zoneId: number
|
||||||
zone: Zone;
|
zone: Zone
|
||||||
chats: Chat[];
|
chats: Chat[]
|
||||||
};
|
}
|
||||||
|
|
||||||
export type Zone = {
|
export type Zone = {
|
||||||
id: number;
|
id: number
|
||||||
name: string;
|
name: string
|
||||||
width: number;
|
width: number
|
||||||
height: number;
|
height: number
|
||||||
tiles: Record<string, any>;
|
tiles: Record<string, any>
|
||||||
characters: Character[];
|
characters: Character[]
|
||||||
chats: Chat[];
|
chats: Chat[]
|
||||||
};
|
}
|
||||||
|
|
||||||
export type Chat = {
|
export type Chat = {
|
||||||
id: number;
|
id: number
|
||||||
characterId: number;
|
characterId: number
|
||||||
character: Character;
|
character: Character
|
||||||
zoneId: number;
|
zoneId: number
|
||||||
zone: Zone;
|
zone: Zone
|
||||||
message: string;
|
message: string
|
||||||
createdAt: Date;
|
createdAt: Date
|
||||||
};
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user