2025-02-11 TIL
작업 결과
- 기존 서버 집약적 게임에서 몬스터의 이동 등은 클라이언트에서 어느 정도 위임을 하기로 하면서 추가적인 핸들러를 생성했다.
const monsterMoveNotificationHandler = async (socket, payload) => {
const {monsterId, targetId, x,y} = payload;
const game = RoomSession.findGameBySocket(socket);
const player = game.getPlayerBySocket(socket);
const monster = game.getMonster(monsterId);
//지정된 몬스터의 좌표를 변경시킨다.
monster.setPosition({x,y});
//일단 타임스탬프 용으로 작성
const now = Date.now();
const monsterPos = monster.getPosition();
const monsterMoverPayload = {
monsterId : monsterId,
targetId : player.id,
x : monsterPos.x,
y : monsterPos.y
}
const packet = makePacket(PACKET_TYPE.MONSTER_MOVE_NOTIFICATION, monsterMoverPayload);
//이런 식으로 게임에서 notification을 보내보도록 하자.
game.broadcastAllPlayer(packet,[socket]);
}
export const AttackByPlayerHandler = async (socket, payload) => {
try {
//몬스터가 플레이어를 때렸을 때 [1] : 우선 몬스터의 정보를 가져온다.
const { monsterId, targetId } = payload;
//몬스터가 플레이어를 때렸을 때 [2] : 같은 아이디를 가진 플레이어와 몬스터를 세션에서 찾는다.
const game = RoomSession.findGameBySocket(socket);
if (!game) {
throw new Error("game fail");
}
const player = game.getPlayerBySocket(socket);
if (!player || player.id !== player.targetId) {
throw new Error("player fail");
}
const monster = game.getMonster(monsterId);
//별개 : 해당 플레이어만 가지고 있던 몬스터가 있다면 동기화가 잘못된 것이므로 일단 오류 처리
if (!monster) {
//몬스터가 죽었다는 것을 별도로 보내주고 끝내도록 하자.
const alreadMonsterDead = {
monsterId: monsterId
}
const monsterDeadPacket = makePacket(PACKET_TYPE.MONSTER_DEATH_NOTIFICATION, alreadMonsterDead);
player.socket.write(monsterDeadPacket);
return;
}
let packet;
let monsterAttackPayload;
const remainPlayerHp = user.changePlayerHp(monster.getAttack());
//몬스터가 플레이어를 때렸을 때 [3] : 충격 처리
if (remainPlayerHp <= 0) {
//유저 사망 처리 먼저 하도록 하자.
player.isDead();
//플레이어가 살아날 위치를 지정해준다.
const deadPayload = { playerId: player.id };
packet = makePacket(PACKET_TYPE.PLAYER_DEATH_NOTIFICATION, deadPayload);
} else {
//동기화 패킷은 계속 보내지고 있을 터이니 그 쪽에서 처리하면 될 테고
monsterAttackPayload = { playerId: player.id, hp: player.hp };
packet = createResponse(PACKET_TYPE.PLAYER_UPDATE_HP_NOTIFICATION, monsterAttackPayload);
}
game.broadcastAllPlayer(packet, [socket]);
//몬스터가 플레이어를 때렸을 때 [4] : 동기화 처리
}
catch (err) {
switch (err) {
case "game fail":
break;
case "player fail":
break;
}
}
};
핸들러를 실행시키기 위해 monster 클래스나 game, room 쪽에서도 접근할 함수를 작업했다.