Worked on commands, notifications
This commit is contained in:
parent
b58df15ae0
commit
ef12c61ea9
44
env.d.ts
vendored
44
env.d.ts
vendored
@ -1,45 +1 @@
|
|||||||
/// <reference types="vite/client" />
|
/// <reference types="vite/client" />
|
||||||
export type User = {
|
|
||||||
id: number;
|
|
||||||
username: string;
|
|
||||||
password: string;
|
|
||||||
characters: Character[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Character = {
|
|
||||||
id: number;
|
|
||||||
userId: number;
|
|
||||||
user: User;
|
|
||||||
name: string;
|
|
||||||
hitpoints: number;
|
|
||||||
mana: number;
|
|
||||||
level: number;
|
|
||||||
experience: number;
|
|
||||||
role: string;
|
|
||||||
position_x: number;
|
|
||||||
position_y: number;
|
|
||||||
rotation: number;
|
|
||||||
zoneId: number;
|
|
||||||
zone: Zone;
|
|
||||||
chats: Chat[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Zone = {
|
|
||||||
id: number;
|
|
||||||
name: string;
|
|
||||||
width: number;
|
|
||||||
height: number;
|
|
||||||
tiles: Record<string, any>;
|
|
||||||
characters: Character[];
|
|
||||||
chats: Chat[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Chat = {
|
|
||||||
id: number;
|
|
||||||
characterId: number;
|
|
||||||
character: Character;
|
|
||||||
zoneId: number;
|
|
||||||
zone: Zone;
|
|
||||||
message: string;
|
|
||||||
createdAt: Date;
|
|
||||||
};
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<Notifications />
|
||||||
<Login v-if="screen === 'login'" />
|
<Login v-if="screen === 'login'" />
|
||||||
<Register v-if="screen === 'register'" />
|
<Register v-if="screen === 'register'" />
|
||||||
<Characters v-if="screen === 'characters'" />
|
<Characters v-if="screen === 'characters'" />
|
||||||
@ -8,6 +9,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { type Ref, ref } from 'vue'
|
import { type Ref, ref } from 'vue'
|
||||||
import { useSocketStore } from '@/stores/socket'
|
import { useSocketStore } from '@/stores/socket'
|
||||||
|
import Notifications from '@/components/utilities/Notifications.vue'
|
||||||
import Login from '@/components/screens/Login.vue'
|
import Login from '@/components/screens/Login.vue'
|
||||||
import Register from '@/components/screens/Register.vue'
|
import Register from '@/components/screens/Register.vue'
|
||||||
import Characters from '@/components/screens/Characters.vue'
|
import Characters from '@/components/screens/Characters.vue'
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<Notifications />
|
||||||
<div class="game-container">
|
<div class="game-container">
|
||||||
<div class="top-ui">
|
<div class="top-ui">
|
||||||
<Hud />
|
<Hud />
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<TilemapLayer v-if="zoneStore.isLoaded" :tilemap="tileMap" :tileset="zoneStore.getTiles" ref="tilemapLayer" :layerIndex="0" :cull-padding-x="10" :cull-padding-y="10" />
|
<TilemapLayer v-if="zoneStore.isLoaded" :tilemap="tileMap" :tileset="zoneStore.getTiles" ref="tilemapLayer" :layerIndex="0" :cull-padding-x="10" :cull-padding-y="10" />
|
||||||
<Controls :layer="layer" />
|
<Controls :layer="layer" />
|
||||||
<Player :layer="layer" />
|
<Character :layer="layer" />
|
||||||
<Container v-if="zoneStore.isLoaded && zoneStore.getPlayers.length > 0">
|
<Container v-if="zoneStore.isLoaded && zoneStore.getPlayers.length > 0">
|
||||||
<Character :layer="layer" v-for="player in zoneStore.getPlayers" :key="player.id" :player="player" />
|
<Character :layer="layer" v-for="player in zoneStore.getPlayers" :key="player.id" :player="player" />
|
||||||
</Container>
|
</Container>
|
||||||
|
@ -13,8 +13,9 @@
|
|||||||
|
|
||||||
<div class="buttons-wrapper">
|
<div class="buttons-wrapper">
|
||||||
<button @click="select_character()">Play</button>
|
<button @click="select_character()">Play</button>
|
||||||
<button @click="isModalOpen = true">Create New</button>
|
<button @click="isModalOpen = true">Create New</button>
|
||||||
<button @click="delete_character()">Delete</button>
|
<!-- @TODO : Add a confirmation dialog -->
|
||||||
|
<button v-if="selected_character" @click="delete_character()">Delete</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -58,17 +59,15 @@ 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) {
|
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) {
|
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
|
||||||
|
@ -25,11 +25,11 @@
|
|||||||
<img src="/assets/bglogin.png" id="bg-img" alt="New Quest login background" />
|
<img src="/assets/bglogin.png" id="bg-img" alt="New Quest login background" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup lang="ts">
|
||||||
import { onMounted, 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 { useCookies } from '@vueuse/integrations/useCookies'
|
import { useNotificationStore } from '@/stores/notifications'
|
||||||
|
|
||||||
const bgm = ref('bgm');
|
const bgm = ref('bgm');
|
||||||
if (bgm.value.paused) {
|
if (bgm.value.paused) {
|
||||||
@ -38,6 +38,7 @@ 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 socket = useSocketStore();
|
const socket = useSocketStore();
|
||||||
const username = ref('');
|
const username = ref('');
|
||||||
const password = ref('');
|
const password = ref('');
|
||||||
@ -45,7 +46,7 @@ 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 === '') {
|
||||||
alert('Please enter a valid username and password');
|
notifications.addNotification({ message: 'Please enter a valid username and password' });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,7 +54,7 @@ async function loginFunc() {
|
|||||||
const success = await login(username.value, password.value);
|
const success = await login(username.value, password.value);
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
alert('Invalid username or password');
|
notifications.addNotification({ message: 'Invalid username or password' });
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (success) {}
|
// if (success) {}
|
||||||
@ -62,7 +63,7 @@ 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 === '') {
|
||||||
alert('Please enter a valid username and password');
|
notifications.addNotification({ message: 'Please enter a valid username and password' });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,7 +71,7 @@ async function registerFunc() {
|
|||||||
const success = await register(username.value, password.value);
|
const success = await register(username.value, password.value);
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
alert('Username already exists');
|
notifications.addNotification({ message: 'Username already exists' });
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (success) {}
|
// if (success) {}
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
|
|
||||||
<Container>
|
<Container>
|
||||||
<Text
|
<Text
|
||||||
:text="'Hello world'"
|
:text="props.player?.name"
|
||||||
|
:x="position.x - 50"
|
||||||
|
:y="position.y - 80"
|
||||||
:style="{
|
:style="{
|
||||||
fontFamily: 'Helvetica, Arial',
|
fontFamily: 'Helvetica, Arial',
|
||||||
color: '#42B883',
|
color: '#42B883',
|
||||||
fontSize: '26px',
|
fontSize: '20px',
|
||||||
fontStyle: 'bold',
|
fontStyle: 'bold',
|
||||||
strokeThickness: 8,
|
strokeThickness: 8,
|
||||||
stroke: '#213547'
|
stroke: '#213547'
|
||||||
|
1
src/components/sprites/MapEntity.vue
Normal file
1
src/components/sprites/MapEntity.vue
Normal file
@ -0,0 +1 @@
|
|||||||
|
<template></template>
|
1
src/components/sprites/NPC.vue
Normal file
1
src/components/sprites/NPC.vue
Normal file
@ -0,0 +1 @@
|
|||||||
|
<template></template>
|
@ -42,6 +42,12 @@ 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
|
||||||
|
onMounted(() => {
|
||||||
|
x.value = (window.innerWidth / 2) - 150;
|
||||||
|
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;
|
||||||
|
28
src/components/utilities/Notifications.vue
Normal file
28
src/components/utilities/Notifications.vue
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<template>
|
||||||
|
<div class="notifications">
|
||||||
|
<Modal v-for="notification in notifications.getNotifications" :key="notification.id" :isModalOpen="true" @modal:close="closeNotification(notification.id)">
|
||||||
|
<template #modal-body>
|
||||||
|
<p>{{ notification.message }}</p>
|
||||||
|
</template>
|
||||||
|
</Modal>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useNotificationStore } from '@/stores/notifications'
|
||||||
|
import { useSocketStore } from '@/stores/socket'
|
||||||
|
import Modal from '@/components/utilities/Modal.vue'
|
||||||
|
|
||||||
|
const notifications = useNotificationStore();
|
||||||
|
const socket = useSocketStore();
|
||||||
|
|
||||||
|
if (socket.getConnection) {
|
||||||
|
socket.getConnection.on('notification', (data: any) => {
|
||||||
|
notifications.addNotification(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeNotification(id: string) {
|
||||||
|
notifications.removeNotification(id);
|
||||||
|
}
|
||||||
|
</script>
|
@ -1,6 +1,6 @@
|
|||||||
export default interface IPlayer {
|
export default interface IPlayer {
|
||||||
readonly id: number;
|
readonly id: number;
|
||||||
username: string;
|
name: string;
|
||||||
coords: {
|
coords: {
|
||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
|
@ -2,12 +2,12 @@ import type IPlayer from '@/engine/Player/IPlayer';
|
|||||||
|
|
||||||
export default class Player implements IPlayer {
|
export default class Player implements IPlayer {
|
||||||
id: number;
|
id: number;
|
||||||
username: string;
|
name: string;
|
||||||
coords: { x: number; y: number; };
|
coords: { x: number; y: number; };
|
||||||
|
|
||||||
constructor(id: number, username: string, coords: { x: number; y: number; }) {
|
constructor(id: number, name: string, coords: { x: number; y: number; }) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.username = username;
|
this.name = name;
|
||||||
this.coords = coords;
|
this.coords = coords;
|
||||||
}
|
}
|
||||||
}
|
}
|
19
src/stores/notifications.ts
Normal file
19
src/stores/notifications.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { defineStore, type StoreDefinition } from 'pinia'
|
||||||
|
import type { Notification } from '@/types'
|
||||||
|
|
||||||
|
export const useNotificationStore: StoreDefinition = defineStore('notifications', {
|
||||||
|
state: () => ({
|
||||||
|
notifications: [] as Notification[]
|
||||||
|
}),
|
||||||
|
getters: {
|
||||||
|
getNotifications: (state: any) => state.notifications
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
addNotification(notification: Notification) {
|
||||||
|
this.notifications.push(notification);
|
||||||
|
},
|
||||||
|
removeNotification(index: number) {
|
||||||
|
this.notifications.splice(index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
@ -2,9 +2,10 @@ 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 '../../env'
|
import type { Character, User } from '@/types'
|
||||||
|
import { useNotificationStore } from '@/stores/notifications'
|
||||||
|
|
||||||
export const useSocketStore: StoreDefinition<any> = defineStore('socket', {
|
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,
|
||||||
@ -36,12 +37,6 @@ export const useSocketStore: StoreDefinition<any> = defineStore('socket', {
|
|||||||
console.log("Reconnect failed")
|
console.log("Reconnect failed")
|
||||||
this.disconnectSocket();
|
this.disconnectSocket();
|
||||||
})
|
})
|
||||||
|
|
||||||
this.connection.on('notification', (data: any) => {
|
|
||||||
if(data.error) console.error(data.error);
|
|
||||||
if (data.success) console.log(data.success);
|
|
||||||
if (data.message) console.log(data.message);
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
disconnectSocket() {
|
disconnectSocket() {
|
||||||
if (!this.connection) return;
|
if (!this.connection) return;
|
||||||
|
50
src/types.ts
Normal file
50
src/types.ts
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
export type Notification = {
|
||||||
|
id?: number;
|
||||||
|
message: string;
|
||||||
|
type?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type User = {
|
||||||
|
id: number;
|
||||||
|
username: string;
|
||||||
|
password: string;
|
||||||
|
characters: Character[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Character = {
|
||||||
|
id: number;
|
||||||
|
userId: number;
|
||||||
|
user: User;
|
||||||
|
name: string;
|
||||||
|
hitpoints: number;
|
||||||
|
mana: number;
|
||||||
|
level: number;
|
||||||
|
experience: number;
|
||||||
|
role: string;
|
||||||
|
position_x: number;
|
||||||
|
position_y: number;
|
||||||
|
rotation: number;
|
||||||
|
zoneId: number;
|
||||||
|
zone: Zone;
|
||||||
|
chats: Chat[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Zone = {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
tiles: Record<string, any>;
|
||||||
|
characters: Character[];
|
||||||
|
chats: Chat[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Chat = {
|
||||||
|
id: number;
|
||||||
|
characterId: number;
|
||||||
|
character: Character;
|
||||||
|
zoneId: number;
|
||||||
|
zone: Zone;
|
||||||
|
message: string;
|
||||||
|
createdAt: Date;
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user