Vanilla JS | Who ate my fish?

heelieben·2021년 11월 13일
0

프로젝트

목록 보기
3/3
post-thumbnail

Who ate my fish?

🔗 프로젝트 링크

🚩 프로젝트 소개

접속한 사용자들이 실시간 소통을 통해서 “생선을 훔쳐 간” 고양이를 찾는 컨셉의 채팅 기반 웹 게임입니다. 사용자들은 실시간으로 대화하면서 생선을 훔쳐 간 마피아 고양이를 찾아야 합니다. 이를 위해서 사용자에게 재미있는 게임 요소를 주어 사용자들이 투표를 통해서 마피아를 찾을 수 있는 게임 입니다.

🖥 프로젝트 시연 영상

Who ate my fish? 시연 영상


필자가 구현한 기능

1. 채팅영역

소켓 통신을 이용한 사용자간 양방향 채팅 기능입니다. 백엔드 express 서버와 socket.io
API를 사용해서 클라이언트간의 실시간 채팅 기능을 구현했습니다.

// client
import io from 'socket.io-client';

const socket = io('http://localhost:3000');

socket.on('chat message', ([curUser, img, , msg, id]) => {
  // ...
  // 소켓에서 받은 메세지를 렌더링
}
          
document.querySelector('.chat-form').addEventListener('submit', e => {
  // ...
  
  // 메세지를 소켓에게 전송
  socket.emit('chat message', $input.value);
  
  // ...
});          
// server
const app = require('express')();
const server = require('http').createServer(app);
const { Server } = require('socket.io');

// CORS 처리
const io = new Server(server, {
  cors: {
    origin: 'http://localhost:8080',
    methods: ['GET', 'POST'],
  },
});


// client가 연결되었을 경우
io.on('connection', socket => {
  
  // ...
  
  // chat message 이벤트가 발생하면, 모든 클라이언트에게 chat message 이벤트를 발생시키고 메세지 정보를 전송
     socket.on('chat message', msg => {
      io.emit('chat message', [nickName, catImageUrl, jailCatImageUrl, msg, socket.id]);
    });
  }
      
  // ...
)

2. 플레이어의 상태를 관리

플레이어의 상태를 클로저를 사용해 안전하게 관리하였습니다.

const player = (() => {
  let name = '';
  let isAlive = true;
  let isCitizen = true;
  return {
    get name() {
      return name;
    },
    set name(newName) {
      name = newName;
    },
    get isAlive() {
      return isAlive;
    },
    set isAlive(newIsAlive) {
      isAlive = newIsAlive;
    },
    get isCitizen() {
      return isCitizen;
    },
    set isCitizen(newIsCitizen) {
      isCitizen = newIsCitizen;
    },
  };
})();

3. 게임 상태에 맞는 sound 처리

게임 상태에 맞춰서 효과음을 재생하는 기능을 구현하였습니다.

const sound = (() => {
  const SOUND = {
    pending: new Audio('./sound/pending.mp3'),
    beginning: new Audio('./sound/pending.mp3'),
    day: new Audio('./sound/day.mp3'),
    night: new Audio('./sound/night.mp3'),
    voteFin: new Audio('./sound/voteFin.mp3'),
    voteUser: new Audio('./sound/voteUser.m4a'),
  };
  return {
    play(state) {
      SOUND[state].play();
    },
    pause() {
      Object.keys(SOUND).forEach(state => SOUND[state].pause());
    },
  };
})();
profile
🎨그림을 좋아하는 FE 개발자👩🏻‍💻

0개의 댓글