diff --git a/frontend/index.html b/frontend/index.html index 9708b6f..cf3d648 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -1,13 +1,21 @@ - - - - SleepyWoods - - - -
- - - + + + + + + + SleepyWoods + + + +
+ + + + \ No newline at end of file diff --git a/frontend/src/component/Game/Phaser/Player/myPlayer.ts b/frontend/src/component/Game/Phaser/Player/myPlayer.ts index 5005917..d748d32 100644 --- a/frontend/src/component/Game/Phaser/Player/myPlayer.ts +++ b/frontend/src/component/Game/Phaser/Player/myPlayer.ts @@ -47,6 +47,7 @@ export class MyPlayer extends Player { update() { const prevState = this.state; + const prevPos = { x: this.x, y: this.y }; if (!this.isCanMove) { this.state = 'wait'; @@ -112,12 +113,15 @@ export class MyPlayer extends Player { if (prevState !== this.state) changeState(this); if (prevState !== this.state || this.heldDirection.length) { - this.socket.emit('move', { - state: this.state, - direction: this.direction, - x: this.x, - y: this.y, - }); + this.socket.emit( + prevPos.x !== this.x || prevPos.y !== this.y ? 'move' : 'motion', + { + state: this.state, + direction: this.direction, + x: this.x, + y: this.y, + } + ); } } } diff --git a/frontend/src/component/Game/Scene/maze.ts b/frontend/src/component/Game/Scene/maze.ts index e61df72..0c5de8c 100644 --- a/frontend/src/component/Game/Scene/maze.ts +++ b/frontend/src/component/Game/Scene/maze.ts @@ -1,11 +1,19 @@ +import { Socket } from 'socket.io-client'; import { MyPlayer } from '../Phaser/Player/myPlayer'; import { OtherPlayer } from '../Phaser/Player/otherPlayer'; +import { emitter } from '../util'; + +const backToTown = { x: 1000, y: 1580 }; export default class Maze extends Phaser.Scene { + socket?: Socket; + autoPlay?: boolean; background?: Phaser.Tilemaps.TilemapLayer; otherLayer?: Phaser.Tilemaps.TilemapLayer; myPlayer?: MyPlayer; otherPlayer: { [key: string]: OtherPlayer }; + gameEntry?: any; + isEnterGameZone?: any; constructor() { super('Maze'); @@ -14,6 +22,8 @@ export default class Maze extends Phaser.Scene { } init(data: any) { + this.socket = data.socket; + this.autoPlay = data.autoPlay; this.myPlayer = new MyPlayer( this, 1000, @@ -25,6 +35,54 @@ export default class Maze extends Phaser.Scene { ); this.myPlayer.fixState(true, 'swimming', 1); + + this.gameEntry = this.physics.add.staticGroup({ + key: 'portal', + frameQuantity: 1, + }); + + this.gameEntry + .getChildren()[0] + .setPosition(backToTown.x, backToTown.y) + .setDepth(3); + + this.gameEntry.refresh(); + + const keyG = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.G); + + this.physics.add.overlap(this.myPlayer, this.gameEntry, () => { + const { x, y } = backToTown; + const text: ( + | Phaser.GameObjects.Graphics + | Phaser.GameObjects.Text + | undefined + )[] = []; + + if (!this.isEnterGameZone) { + text.push( + this.add + .graphics() + .fillStyle(0xffffff, 50) + .fillRoundedRect(x - 140, y - 70, 265, 40, 20), + this.add.text(x - 130, y - 60, 'push G key for back to Town!', { + color: '#000', + font: '700 18px Arial', + }) + ); + + this.isEnterGameZone = true; + + setTimeout(() => { + text[0]?.destroy(); + text[1]?.destroy(); + this.isEnterGameZone = false; + }, 500); + } + + if (Phaser.Input.Keyboard.JustDown(keyG)) { + this.changeScene('Town'); + } + }); } create() { @@ -59,4 +117,15 @@ export default class Maze extends Phaser.Scene { update() { this.myPlayer?.update(); } + + changeScene = (gameName: string) => { + emitter.emit('closeContent'); + + this.scene.pause(); + this.scene.start(gameName, { + socket: this.socket, + myPlayer: this.myPlayer, + autoPlay: this.autoPlay, + }); + }; } diff --git a/frontend/src/component/Game/Scene/sprint.ts b/frontend/src/component/Game/Scene/sprint.ts index f737e98..dc5d244 100644 --- a/frontend/src/component/Game/Scene/sprint.ts +++ b/frontend/src/component/Game/Scene/sprint.ts @@ -1,11 +1,19 @@ +import { Socket } from 'socket.io-client'; import { MyPlayer } from '../Phaser/Player/myPlayer'; import { OtherPlayer } from '../Phaser/Player/otherPlayer'; +import { emitter } from '../util'; + +const backToTown = { x: 1600, y: 1900 }; export default class Sprint extends Phaser.Scene { + socket?: Socket; + autoPlay?: boolean; background?: Phaser.Tilemaps.TilemapLayer; otherLayer?: Phaser.Tilemaps.TilemapLayer; myPlayer?: MyPlayer; otherPlayer: { [key: string]: OtherPlayer }; + gameEntry?: any; + isEnterGameZone?: any; constructor() { super('Sprint'); @@ -23,6 +31,54 @@ export default class Sprint extends Phaser.Scene { data.myPlayer.nickname, data.socket ); + + this.gameEntry = this.physics.add.staticGroup({ + key: 'portal', + frameQuantity: 1, + }); + + this.gameEntry + .getChildren()[0] + .setPosition(backToTown.x, backToTown.y) + .setDepth(3); + + this.gameEntry.refresh(); + + const keyG = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.G); + + this.physics.add.overlap(this.myPlayer, this.gameEntry, () => { + const { x, y } = backToTown; + const text: ( + | Phaser.GameObjects.Graphics + | Phaser.GameObjects.Text + | undefined + )[] = []; + + if (!this.isEnterGameZone) { + text.push( + this.add + .graphics() + .fillStyle(0xffffff, 50) + .fillRoundedRect(x - 140, y - 70, 265, 40, 20), + this.add.text(x - 130, y - 60, 'push G key for back to Town!', { + color: '#000', + font: '700 18px Arial', + }) + ); + + this.isEnterGameZone = true; + + setTimeout(() => { + text[0]?.destroy(); + text[1]?.destroy(); + this.isEnterGameZone = false; + }, 500); + } + + if (Phaser.Input.Keyboard.JustDown(keyG)) { + this.changeScene('Town'); + } + }); } create() { @@ -52,4 +108,15 @@ export default class Sprint extends Phaser.Scene { update() { this.myPlayer?.update(); } + + changeScene = (gameName: string) => { + emitter.emit('closeContent'); + + this.scene.pause(); + this.scene.start(gameName, { + socket: this.socket, + myPlayer: this.myPlayer, + autoPlay: this.autoPlay, + }); + }; } diff --git a/frontend/src/component/Game/Scene/town.ts b/frontend/src/component/Game/Scene/town.ts index 22e1be2..4689126 100644 --- a/frontend/src/component/Game/Scene/town.ts +++ b/frontend/src/component/Game/Scene/town.ts @@ -27,7 +27,6 @@ export default class Town extends Phaser.Scene { init() { emitter.on('gameStart', (data: any) => { - console.log(data.userList); this.changeScene(data.gameName); }); @@ -136,13 +135,24 @@ export default class Town extends Phaser.Scene { } changeScene = (gameName: string) => { - console.log(gameName); + emitter.emit('closeContent'); + this.scene.pause(); this.scene.start(gameName, { socket: this.socket, myPlayer: this.myPlayer, autoPlay: this.autoPlay, }); + + // 자신의 캐릭터 지워주기 + this.myPlayer?.delete(); + delete this.myPlayer; + + // emitter 이벤트 지워주기 + emitter.removeListener('init'); + emitter.removeListener('updateNickname'); + emitter.removeListener('updateHair'); + emitter.removeListener('gameStart'); }; create() { @@ -250,6 +260,14 @@ export default class Town extends Phaser.Scene { this.otherPlayer[id].update(state, x, y, direction); }); + this.socket.on('motion', (data: userType) => { + const id = data.id.toString().trim(); + + if (!this.otherPlayer[id]) return; + const { state, x, y, direction } = data; + this.otherPlayer[id].update(state, x, y, direction); + }); + this.socket.on('userLeaved', (data: userType) => { const id = data.id.toString().trim(); this.otherPlayer[id].delete(); diff --git a/frontend/src/component/Game/Scene/zombie.ts b/frontend/src/component/Game/Scene/zombie.ts index 6934187..6a7d18d 100644 --- a/frontend/src/component/Game/Scene/zombie.ts +++ b/frontend/src/component/Game/Scene/zombie.ts @@ -1,11 +1,19 @@ +import { Socket } from 'socket.io-client'; import { MyPlayer } from '../Phaser/Player/myPlayer'; import { OtherPlayer } from '../Phaser/Player/otherPlayer'; +import { emitter } from '../util'; + +const backToTown = { x: 1000, y: 1580 }; export default class Zombie extends Phaser.Scene { + socket?: Socket; + autoPlay?: boolean; background?: Phaser.Tilemaps.TilemapLayer; otherLayer?: Phaser.Tilemaps.TilemapLayer; myPlayer?: MyPlayer; otherPlayer: { [key: string]: OtherPlayer }; + gameEntry?: any; + isEnterGameZone?: any; constructor() { super('Zombie'); @@ -23,6 +31,54 @@ export default class Zombie extends Phaser.Scene { data.myPlayer.nickname, data.socket ); + + this.gameEntry = this.physics.add.staticGroup({ + key: 'portal', + frameQuantity: 1, + }); + + this.gameEntry + .getChildren()[0] + .setPosition(backToTown.x, backToTown.y) + .setDepth(3); + + this.gameEntry.refresh(); + + const keyG = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.G); + + this.physics.add.overlap(this.myPlayer, this.gameEntry, () => { + const { x, y } = backToTown; + const text: ( + | Phaser.GameObjects.Graphics + | Phaser.GameObjects.Text + | undefined + )[] = []; + + if (!this.isEnterGameZone) { + text.push( + this.add + .graphics() + .fillStyle(0xffffff, 50) + .fillRoundedRect(x - 140, y - 70, 265, 40, 20), + this.add.text(x - 130, y - 60, 'push G key for back to Town!', { + color: '#000', + font: '700 18px Arial', + }) + ); + + this.isEnterGameZone = true; + + setTimeout(() => { + text[0]?.destroy(); + text[1]?.destroy(); + this.isEnterGameZone = false; + }, 500); + } + + if (Phaser.Input.Keyboard.JustDown(keyG)) { + this.changeScene('Town'); + } + }); } create() { @@ -56,4 +112,15 @@ export default class Zombie extends Phaser.Scene { update() { this.myPlayer?.update(); } + + changeScene = (gameName: string) => { + emitter.emit('closeContent'); + + this.scene.pause(); + this.scene.start(gameName, { + socket: this.socket, + myPlayer: this.myPlayer, + autoPlay: this.autoPlay, + }); + }; } diff --git a/frontend/src/component/MiniGame/index.tsx b/frontend/src/component/MiniGame/index.tsx index 645f957..23d5d60 100644 --- a/frontend/src/component/MiniGame/index.tsx +++ b/frontend/src/component/MiniGame/index.tsx @@ -31,7 +31,13 @@ const MiniGame = () => { setSelectGame(gameName); }); + emitter.on('closeContent', () => { + setIsShowModal(false); + initGame(); + }); + return () => { + emitter.removeListener('closeContent'); emitter.removeListener('game'); }; }, []); diff --git a/frontend/src/component/Sidebar/index.tsx b/frontend/src/component/Sidebar/index.tsx index 97f9a37..8d76dfc 100644 --- a/frontend/src/component/Sidebar/index.tsx +++ b/frontend/src/component/Sidebar/index.tsx @@ -16,6 +16,7 @@ import Setting from './Setting'; import Chat from './Chat'; import { useRecoilState } from 'recoil'; import { sidebarState } from '../../store/atom/sidebar'; +import { emitter } from '../Game/util'; type componentType = { [key: string]: EmotionJSX.Element; @@ -49,6 +50,16 @@ const Sidebar = () => { }); }; + useEffect(() => { + emitter.on('closeContent', () => { + setOpen(false); + }); + + return () => { + emitter.removeListener('closeContent'); + }; + }, []); + return (