Skip to content

Survivor 은 바닐라 자바스크립트와 Phaser 3 를 활용하여 만든 웹 서바이벌 라이크 게임 입니다.

Notifications You must be signed in to change notification settings

pieceofcakey/Survivor

Repository files navigation

Survivor

스크린샷 2024-04-13 오전 12 35 56

Survivor 은 바닐라 자바스크립트와 Phaser 3 를 활용하여 만든 웹 서바이벌 라이크 게임 입니다.

📒 Contents


🔧 Tech Stacks

JavaScript Phaser 3

Deployment

Netlify


🙋🏻‍♂️ Introduction

바닐라 코딩 부트캠프에서 3주간 진행한 개인 프로젝트로, 웹에서 플레이 할 수 있는 2d 탑다운 액션 게임을 만들어 보았습니다. 보다 다양한 게임적 요소 구현 및 성능 최적화를 위해 Phaser 3 라이브러리를 활용하여 WebGL, Canvas API 를 활용하여 웹 게임을 만들어 보았습니다.


💪 Motivation

저는 게임을 굉장히 좋아합니다. 사실, 비전공자인 제가 개발에 관심을 가지게 된 큰 계기 중 하나가 바로 게임이었습니다. 보다 많은 것을 만들 수 있는 웹 개발 공부를 선택 하였지만, 마음 한켠에는 언젠가 내가 배운 내용으로 웹에서 플레이 할 수 있는 게임을 만들어 보고 싶은 마음이 항상 존재 하였습니다. 개인 프로젝트는 부트캠프의 마지막 관문이자 혼자만의 힘으로 무언가를 만들어 내야하는 기간이었고, 이 기간은 제가 웹 게임을 만들어 볼 수 있는 아주 좋은 기회였습니다. 어떤 게임을 만들어 볼까 고민 중, 2022년 출시한 Vampire Survivors 라는 게임이 자바스크립트로 만들어졌다는 사실을 알게 되었고, 이 게임을 직접 Scratch 부터 만들어 보았습니다.


🔍 Proof Of Concept

어쩌면 당연한 얘기지만, 저는 웹 개발에 대해 그동안 공부를 해왔기 때문에 게임 플랫폼으로 웹을 선택하는것은 매우 당연한 이야기일지도 모릅니다. 하지만, 개발은 서비스의 특성에 맞는 플랫폼을 정하는것 또한 굉장히 중요하고, 웹 개발을 공부 했지만 자바스크립트를 활용하여 스마트폰 앱, 데스크톱 앱 등 다양한 플랫폼에서의 개발이 가능하다는 것을 알고 있고, 제가 주로 즐기는 게임들 또한 웹 게임이 아니기에, 결국 웹 게임을 만들게 되더라도 게임을 만들고 구동할 수 있는 다양한 제작 툴에 대해 조사하고 비교 분석 해보는 과정이 꼭 필요하다고 생각하여 프로젝트 시작 전 POC를 진행하였습니다.

1. 적절한 게임 툴 찾기


주어진 개발기간이 3주 정도 되었기에 모든 플랫폼을 조사할 수는 없었습니다. 따라서 저는 제가 기존에 알고있던 유니티, 언리얼 엔진, 그리고 웹 3가지 플랫폼에 대해 조사를 해봤습니다.

1.1 유니티

유니티는 C# 언어를 사용하는 게임 엔진입니다. 현재 시장에 존재하는 많은 게임, 그중 특히 모바일 게임들이 해당 엔진을 사용하고 있습니다. 모바일 게임 제작 툴로 유니티 게임 엔진이 가장 많은 선택을 받은 큰 이유중 하나는 하나의 프로그램으로 간편하고 다양한 빌드를 제공한다는 것입니다. 이를 통해 유니티 게임엔진으로 만든 게임은 한번의 작업으로 다양한 플랫폼으로서의 배포를 가능하게 합니다. 이러한 점은 저의 현 상황과 잘 맞는 개발 툴이라고 생각 하였지만, 새로운 언어 및 툴 학습 기간에 대해 고려했을 때 적절하지 않다고 판단하여 제외하게 되었습니다.

1.2 언리얼 엔진

언리얼 엔진은 에픽게임즈에서 개발하고 c++언어를 사용하는 게임 엔진 입니다. 현존하는 대부분의 3D 게임 제작 툴로서 사용돼고 있습니다. 3D 게임들이 해당 엔진을 선택하는 선택하는 가장 큰 이유는 성능입니다. 타 게임 엔진들과 비교하여 언리얼 엔진으로 구현 할 수 있는 그래픽의 수준은 다른 게임 엔진들을 압도합니다. 가장 최근에 나온 언리얼 엔진 5는 정말 실사와도 같은 그래픽의 게임을 제작 할 수 있도록 기능을 제공합니다. 하지만, 제가 만들고자 하는 게임은 2D게임이었기에 해당 엔진은 저에게 적합하지 않은 선택지였습니다.

1.3 자바스크립트

자바스크립트의 주요 목적은, 웹에 동적인 요소를 부여하는 것 입니다. 이는 위에서 설명한 다른 게임엔진들과는 프로그래밍 언어의 목적부터 아주 큰 차이가 있습니다. 하지만, HTML5 가 등장하고 Canvas의 등장 하고, 결국 게임 또한 여러가지 오브젝트 들의 상관관계를 프로그래밍 한다는 점에서 자바스크립트 또한 게임을 만드는 언어로서의 목적을 충분히 달성할 수 있다고 생각했습니다. 실제로 제가 동기 섹션에서 소개했던 Vampire Survivors 이라는 게임이 자바스크립트로 만들어졌습니다. 제가 그동안 공부해왔던 익숙한 언어이기도 하고, 그 가능성을 입증받았다는 점에서 제가 다른 엔진을 선택할 이유는 사실 크게 존재하지 않았기에 자바스크립트로 게임을 만들어 보기로 결정하게 되었습니다.


2. 게임 플랫폼으로서의 웹의 장점과 단점


게임을 구동할 수 있는 환경은 크게 데스크톱 앱, 모바일, 콘솔, 웹 등 다양한 플랫폼이 존재합니다. 각 플랫폼들의 장점과 단점이 존재하지만 제가 가장 주요하게 생각한 점은 접근성 이었습니다. 실제로 최근 등장하는 게임들 중 웹 게임이 아닌 게임들 또한 PC, 모바일, 콘솔 등 다양한 플랫폼에서 서로 함께 플레이 할 수 있는 크로스 플랫폼 방식을 많이 택하고 있습니다.

또한 웹 게임은 웹 자체에서 구동되는 프로그램이기에 별도의 다운로드가 필요하지 않습니다. 이는 동일한 웹 브라우저를 사용한다면 사용자의 컴퓨터 하드웨어 환경에 상관 없이 동일한 경험을 제공할 수 있다는 큰 장점을 가집니다.

종합하자면 저는 다음과 같은 이유를 종합하여 게임 플랫폼으로 웹을 선택하게 되었습니다.

  • 제가 지금껏 공부한 언어 자바스크립트를 활용하여 게임을 만들 수 있다.
  • 접근성이 가장 높다.
  • 동일한 웹 브라우저를 사용한다는 가정하에, 유저의 컴퓨터 하드웨어와 상관없이 개발자가 설계한 그대로의 게임을 모두에게 동일하게 제공할 수 있다.

🕹 Features

1. 플레이 방법

  • 게임 시작 버튼을 눌러서 시작합니다.
  • 상하좌우 방향키 조작만으로 플레이 가능합니다.
  • 사방에서 몰려오는 몬스터를 피해 최대한 오랜 시간동안 살아남는 게임 입니다.

2. 적

  • 시간에 따라 등장하는 적의 종류 및 조합이 변합니다.
  • 적의 종류 별 체력, 경험치, 아이템 드롭률이 상이합니다.
  1. 적 종류
  • 각 몬스터 종류에 따라 상이한 몬스터 스펙을 표로 나타냈습니다.
  • 몬스터 스펙에 영향을 끼친 요소에는 플레이 타임, 무기 공격력, 플레이어 레벨 총 3가지 입니다.
  • 각 스펙은 해당 몬스터가 출현하는 시간대에 플레이어가 어느정도 수치의 공격을 평균적으로 가할 수 있는지를 고려하여 조정하였습니다.

몬스터 종류 체력 공격력 이동속도 경험치
LV1 2 5% fast 10
LV2 8 10% medium 20
LV3 20 20% medium 40
LV4 38 25% medium 70
LV5 62 33% slow 110
BOSS 1000 50% slow 1000

  1. 시간별 몬스터 웨이브
  • 플레이 타임 별 각 몬스터의 구성 비율을 표로 나타냈습니다.
  • 1분 별로 전체 몬스터 수를 100%라고 했을 때, 각 몬스터의 비율을 표시했습니다.
  • 시간이 지날수록 더 강한 몬스터들의 비율이 늘어나고, 약한 몬스터들의 비율이 줄어듭니다.
  • 몬스터 비율은 개발 완료 후 플레이 테스트를 통해 조정하였습니다.

플레이 타임 LV1 LV2 LV3 LV4 LV5 BOSS
0 ~ 1분 100%
1 ~ 2분 80% 20%
2 ~ 3분 30% 40% 30%
3 ~ 4분 10% 40% 30% 20%
4 ~ 5분 20% 20% 30% 30%
5 ~ 6분 20% 30% 40%
6 ~ 7분 30% 60% 10%

3. 레벨업

  • 경험치가 100% 가 되면 레벨업을 합니다.
  • 레벨업 시 새로운 무기가 자동으로 추가됩니다.
  • 기존에 있던 무기가 강화 될 수 있습니다.

4. 무기

  • 6가지 무기가 존재합니다
    • 화살
    • 화염구
    • 던지는 칼
    • 번개
    • 채찍
    • 쉴드
  • 레벨업 시 무기가 추가되거나 기존 무기가 강화됩니다.
  • 해당 무기를 보유한 시점에 따라 플레이어가 가할 수 있는 초당 공격력이 변동됩니다. 몬스터의 스펙, 플레이 타임에 따른 몬스터 종류의 변경등을 고려하여 적절한 게임 난이도를 유지하기 위한 공격력 및 공격 주기를 설정하였습니다.

무기 종류 공격력 공격방식 공격 주기
채찍 1 플레이어가 바라보는 방향 앞 뒤 2초
화살 1 플레이어 기준 가장 가까운 적 2초
단검 1 플레이어가 바라보는 방향 앞 2초
갑옷 1 플레이어 주변 빙빙 돌아감 x
화염구 3 플레이어 기준 랜덤 적 4초
번개 5 플레이어 기준 랜덤 적 4초

5. 게임오버

  • 플레이어가 적에게 접촉 시, hp가 감소합니다.
  • hp가 0이 되면 게임 오버가 됩니다.
  • 게임 오버 시 처치한 적 수 , 플레이 타임, 달성 레벨이 표시됩니다.
  • 재시작 버튼 및 메인화면으로 돌아가는 버튼이 존재합니다.

⛰️ Challenges

제 프로젝트는 2d 액션 게임으로, 맵 이라는 공간 위의 다양한 오브젝트(플레이어, 몹, 무기, 아이템) 들이 서로 상호작용 하며 진행되는 로직의 게임을 구현하고자 했습니다. 이 섹션에서는 제가 게임을 구현하며 정의해본 문제들과, 그 문제를 해결하기 위한 방법들, 선정한 방법에 대한 설명들을 서술해보았습니다.

1. Phaser3 프레임워크 채택 이유

Phaser3 는 웹에서 플레이 가능한 게임을 만들기 위한 자바스크립트 프레임 워크입니다. 이번 섹션에서는 제 프로젝트에 Phaser3를 사용하게 된 계기에 대해 설명 해 보겠습니다.

1.1 웹 게임은 어떻게 만들 수 있을까?


웹에서 게임을 만들 수 있다는 사실은 개발을 배우기 전 부터도 느낌적으로 알고 있었습니다. 어릴적 많이 플레이 했던 플래시 게임들이 그 반증들이었습니다. 게임은 사실 굉장히 많은 부분이 추상화 되어있다고 생각합니다. 이번에 제가 프로젝트를 진행하며 깨달은 것 중 하나는, 결국 게임은 어떤 오브젝트들을 그리고, 그 오브젝트들을 적절하게 움직이고, 각 오브젝트간의 상호작용에 대한 로직을 세우는 것이 모든 게임의 기본이란걸 알게 됐습니다. 웹에서 어떤 그래픽을 그리는 행위는 html의 canvas 요소에 브라우저에서 제공하는 Canvas API 및 WebGL을 통해 동적 그래픽을 구현하는 것이 일반적입니다. 저에게는 Canvas API, WebGL 두가지의 선택지가 생겼고, 이 둘에 대해 비교를 해보았습니다.

1.2 WebGL vs Canvas API


추상화 레벨 러닝커브 퍼포먼스
WebGL 고수준 낮음 낮음
Canvas API 저수준 높음 높음

많은 차이점이 있지만, 제가 가장크게 본 비교 포인트는 러닝 커브와 성능의 차이였습니다. 렌더링 파이프라인에 직접 접근 가능 여부에 따라 저수준, 고수준을 정의해 보았을 때, Canvas API는 추상화가 잘 되어있고, 고수준의 그래픽 API이기 때문에 사용자 친화적입니다. 이에 따라서 자연스럽게 러닝커브는 낮지만, 직접적으로 렌더링 파이프라인에 접근하는것은 어렵기 때문에 성능적으로는 열세입니다.

반대로 WebGL은 낮은 수준의 그래픽 api이기에 이를 제대로 활용하기 위해서 선행학습 되어야 하는 내용이 많기 때문에 러닝커브가 높지만, 직접적으로 렌더링 파이프라인에 접근하는것이 가능하기 때문에 성능적으로 우세합니다

1.3 Phaser3, WebGL 과 Canvas API 모두 활용 가능!


이런 비교를 하던 중, 제가 발견한 Javascript 라이브러리가 있습니다. 바로 Phaser3 입니다. Phaser는 웹에서 게임을 만들기 위해 필요한 기능들을 추상화 하여 제공하기 때문에 게임을 만들기에 매우 적합한 라이브러리 입니다. 또한, Phaser3는 프로젝트 초기 설정 시 어떤 렌더링 api를 사용할 지 정할 수 있습니다. 이는 즉, Phaser3 라이브러리를 사용하여 코드를 작성하면, 동일한 코드를 Canvas API 로 렌더링 할지, WebGL 렌더링 할지 정할 수 있다는 뜻입니다. 이에 저는 2주라는 시간내에 게임적인 요소가 충분히 들어간 게임을 만들고 싶었기에, 최종적으로 낮은 러닝커브와 높은 퍼포먼스 두마리 토끼를 동시에 잡을 수 있는 Phaser3를 적극적으로 사용하여 프로젝트를 만들게 되었습니다.

2. 무한 맵 구현하기

제 프로젝트에서의 플레이가 진행되는 공간을 의미합니다. 플레이가 이루어지는 공간은 크기, 확장 여부 등 그 성질에 따라 매우 다른 게임적 특성을 지니기에, 제가 구현하고자 하는 게임에 걸맞는 특성을 우선 정의해야 했습니다.

2.1 맵은 얼마나 커야 할까?


제가 만들고자 하는 게임은 플레이어 오브젝트를 조작하여 최대한 오랜 시간 버티는 게임이고, 지속적으로 몬스터를 피해 움직여야 하기에 맵의 크기가 일단 커야 한다고 생각했습니다. 하지만 맵의 크기가 얼마나 커야하는지, 움직임에 따라 확장되어야 하는지, 아무리 맵이 크더라도 결국 맵의 끝이 존재 할텐데 유저 경험을 해치진 않을지에 대한 고민이 생겼고, 위 방식들에 대해 성능, 구현 난이도, 유저 경험에 대해 비교해 보았습니다.

2.2 하나의 큰 맵 vs 무한히 흐르는 작은 맵


2.2.1 하나의 큰 맵

가장 기본적으로 생각 할 수 있는 방법입니다. 맵을 이루는 에셋을 그대로 렌더링 하고, 플레이 공간을 해당 에셋의 크기만큼 제한 하면 되고 가장 간단하게 구현 할 수 있었습니다. 하지만 해당 방식은 플레이 공간이 제한되고, 제가 구현하고자 하는 게임과는 어울리지 않는 방식 이었습니다.

스크린샷 2024-05-22 오후 6 22 16
2.2.2 임계치 좌표 설정 후 맵을 이어 붙이기

다음으로 생각 한 방식은, 하나의 큰 맵으로 끝나는 것이 아니라, 유저가 일정 x,y 좌표를 넘어가면 가로 혹은 세로로 동일한 맵 에셋을 이어 붙이는 방식 이었습니다. 이는 말 그대로 플레이어 이동 방향으로 무한히 맵을 생성해 나가는 방식이기에 제가 추구했던 목표와 잘 맞는 방식이었습니다. 하지만 이는 결국 한 방향으로 무한히 이동을 하면 맵 에셋 또한 무한히 생성되게 되므로 효율적인 리소스 관리 측면에서는 매우 좋지 못한 방식 이었습니다.

스크린샷 2024-05-22 오후 6 29 06
2.2.3 플레이어 이동 방향으로 맵 에셋의 좌표 이동

마지막으로 생각한 방식은 착시를 이용하는 방법 입니다. 만약, 유저가 이동하는 방향으로 맵 에셋이 똑같이 따라오게 만들 수 있다면 작은 맵으로도 무한한 맵과 동일한 효과를 줄 수 있다고 판단하였습니다. 이 방법이 성능적으로, 유저 경험적으로 가장 적합한 방식이라고 생각하였고 해당 방법을 채택하여 무한 맵을 구현 하였습니다.

스크린샷 2024-05-24 오전 10 36 24

2.3 착시를 이용한 무한 맵 구현을 해보자!


우선, 타일 형식의 맵 리소스를 유저가 바라보는 브라우저 뷰포트의 크기 만큼만 채우고, 플레이어 오브젝트를 화면 중앙에 고정 한 뒤, 플레이어 오브젝트가 이동하는 방향과 속도 만큼 타일 오브젝트는 반대로 움직이게 하고, 타일의 x y 좌표는 플레이어가 이동하는 방향대로 조정해주는 방식을 택했습니다. 이를 통해 마치 무한이 맵이 이어진 것과 같은 효과를 얻을 수 있었습니다.

구현 코드
// camera가 가는 곳으로 background가 따라 움직이도록 해줍니다.
this.m_background.setX(this.m_player.x - config.width / 2);
this.m_background.setY(this.m_player.y - config.height / 2);

// tilePosition을 player가 움직이는 만큼 이동시켜 마치 무한 맵인 것처럼 나타내 줍니다.
this.m_background.tilePositionX = this.m_player.x - config.width / 2;
this.m_background.tilePositionY = this.m_player.y - config.height / 2;

결과물

결과적으로 하나의 맵 에셋만을 사용하여 무한히 존재하는 듯 착시를 일으키는 매커니즘을 완성 할 수 있었고, 이러한 방법이 가장 리소스 관리 측면에서 효율적이면서 제가 초기에 기획한 게임의 의도와 가장 잘 맞는 방법이었습니다.

3. 몬스터 스폰 위치 정하기

스폰 이란, 몬스터가 등장하는 이벤트를 의미 합니다. 제가 기획한 게임은 사방에서 몰려오는 몬스터들을 피해가며 최대한 오래 살아남는 게임이기에, 유저 경험 및 게임의 난이도 측면에서 몬스터의 스폰 위치를 정하는 것은 매우 중요한 의사결정 중 하나 였습니다.

3.1 몬스터는 어느 장소에서 스폰해야 할까?


만약 몬스터의 스폰위치가 플레이어와 너무 가깝다면 몬스터를 인지하고 도망가기 위해 필요한 반응 시간이 짧아지기에 게임의 난이도가 너무 어려워지고, 또한 몬스터 스폰 위치가 플레이어의 이동 경로 바로 앞에 있다면 이동중에 갑자기 등장한 몬스터에 의해 피격당하는 일이 잦아지고, 플레이 경험을 크게 해칠 것이라고 생각 했습니다. 반대로 몬스터 스폰 위치가 너무 멀다면, 몬스터로부터 도망갈 시간이 너무 길어져서 게임의 난이도가 너무 쉬워질 것 이라고 판단하였습니다. 각 방법들에 대해 비교 해 보겠습니다.

3.2 정해진 위치 vs 완전 랜덤 위치 vs 일정 거리 이상 랜덤 위치


3.2.1 고정된 위치

첫번째로 생각해본 방식은 고정된 위치에서 몬스터가 스폰 되도록 하는 방식 입니다. 하지만 이러한 방식은 몬스터의 스폰 위치를 유저가 알게 된다면, 게임 난이도를 매우 낮추고, 반복적 플레이에 대한 유저의 흥미를 전혀 이끌어내지 못 할 것이라고 생각 했기에 다른 방법을 고안해 봤습니다.

스크린샷 2024-05-22 오후 6 41 36
3.2.2 완전 랜덤 위치

두번째로 생각해본 방식은, 완전히 랜덤한 x,y 좌표에서 몬스터가 스폰 되도록 하는 방법 이었습니다. 몬스터 스폰 로직에 랜덤한 x,y 좌표를 입력만 하면 되기 때문에 이 방식 또한 어렵지 않았습니다. 하지만, 완전히 랜덤한 위치에서 몬스터가 스폰을 하다보니 플레이어로부터 매우 멀리, 혹은 매우 가까이 몬스터가 스폰되는 경우가 발생 하였습니다. 두 케이스 모두 플레이 경험을 매우 해치는 상황이기에 다음 방법을 생각 했습니다.

스크린샷 2024-05-22 오후 6 44 39
3.2.3 일정 거리 이상 랜덤 위치

마지막으로 제가 생각한 방법은, 플레이어로부터 일정 거리 이상에서 몬스터가 등장하는 방식을 고안하게 됐습니다. 이 방법은 플레이어가 어느방향으로 얼만큼 이동햇는지와 상관 없이, 몬스터가 스폰되는 시점에 플레이어의 위치에 따라 몬스터 스폰이 결정되기 때문에 갑자기 생성되는 몬스터로 인해 겪는 불합리함을 없앨 수 있기 때문에 합리적인 방법이라고 선택했습니다.

스크린샷 2024-05-15 오후 7 38 58

3.3 일정 거리 이상 랜덤 위치에서 등장하게 해보자!


그렇다면 플레이어로부터 얼만큼의 거리를 둬야하는지에 대해서 생각해보았을 때, 플레이어 기준, 유저의 뷰포트 꼭지점까지의 거리를 반지름으로 두고, 그 반지름의 거리에서 몬스터가 등장하면 유저가 보기에는 화면 바깥에서 생성된 몹이 나를 향해 다가오는 것 처럼 느껴지고, 적당한 시간에 플레이어에게 도달할 속도를 설정하였습니다.


참고 수식 자료

구현 코드
function getRandomPosition(x, y) {
  const randomRadius = Math.random() * Math.PI * 2;
  const radius =
    Math.sqrt(config.width * config.width + config.height * config.height) / 2;
  const randomX = x + radius * Math.cos(randomRadius);
  const randomY = y + radius * Math.sin(randomRadius);

  return [randomX, randomY];
}
결과물

이번 챌린지는 성능적인 측면이나 개발 난이도적인 측면 보다는 어떤 방식이 가장 게임답게 유저 경험을 극대화 시킬 수 있는 방법인지에 대해 고민해본 챌린지였습니다. 결과적으로 유저는 몬스터가 갑자기 등장하는 것이 아닌 맵 밖의 미지의 공간에서 부터 나를 향해 다가오는듯한 느낌을 잘 살리게 됐으며 렌더링 되는 순간의 모습을 유저에게 숨김으로써 더 좋은 유저 경험을 제공 할 수 있도록 했습니다..

📚 What i learned

1. 추가 기능 기획

제한된 시간내에 프로젝트를 완성해야 했기에 아이디어 도출 당시 생각 했던 기능들이 많이 있지만 다 구현하지 못해 아쉬운 점 또한 존재했습니다. 추가적으로 구현하면 더 풍성한 게임이 될 수 있을 기능들에 대해 설명해보겠습니다.

1.1 보다 다양한 적 유형

현재 제 프로젝트의 몬스터는 텍스쳐, 속도, 체력, 공격력 등 정적인 요소에서만 차이가 있습니다. 이를 제가 구현한 무기들의 동작방식이 다 다른 것 처럼, 몬스터 또한 더 다양한 행동 방식에 대해 로직을 세우고 새로운 공격 유형의 몬스터들을 개발 할 예정입니다.

1.2 무기 융합 기능

개별 무기들이 최대 레벨에 도달하면, 그 이상의 효과는 존재하지 않습니다. 이를 유저에게 조금 더 다양한 게임 경험을 주기 위해, 특정 무기 2개가 최대 레벨에 도달한다면 두 무기를 하나의 업그레이드 된 새로운 무기로 융합하는 기능을 개발 할 예정입니다.

1.3 실시간 멀티 플레이 게임

제 게임은 로컬 환경에서 혼자 플레이 할 수 있는 싱글 게임입니다. 이를 단지 서버가 기록을 경쟁 할 수 있는 기능 외에, 실시간으로 두 명의 유저가 함께 플레이 할 수 있는 멀티 플레이 게임으로 리팩토링 할 예정입니다. 이는 꼭 처음부터 구현 하고 싶었던 기능이었습니다만, 하나의 캔버스 상에서 실시간으로 변경되는 매우 많은 수의 오브젝트들의 좌표, 오브젝트의 상태(존재, 파괴, 이동 방향)등을 두 명의 유저가 서로 교환한다는 것은 생각보다 매우 어려운 작업이었습니다. 실시간 멀티 플레이 게임으로의 업그레이드를 위해 네트워크 프로토콜(TCP/UDP), Web Socket 등 필요한 지식을 습득 한 뒤 개발 할 예정입니다.

2. 회고

프로젝트를 진행하며 처음 접해보는 기술을 사용했기 때문에 이런저런 어려움을 많이 겪었지만 제가 배운 지식 및 공부 방식을 통해 궁극적으로 제가 만들고 싶었던 '게임' 이라는 서비스를 개발했다는 점에서 굉장히 재미있었던 프로젝트 였습니다. 정말 막연하게 생각만 하고 있던 '게임' 이라는 크고 추상적인 문제 또한 논리적 사고를 통해 작은 문제들로 나누고, 프로그래밍적으로 표현하는 것이라는 점에서 다시 한번 논리적 사고의 중요성에 대해 생각하는 계기가 되었습니다. 이를 통해서 앞으로 어떤 도전을 하게 되던지 논리적으로 문제를 쪼갤 수 있는 영감을 많이 얻게 됐습니다.


⏰ Project timeline

프로젝트는 칸반 방식을 채택하였으며 모든 개별 태스크의 주기는 다음과 같은 프로세스를 따랐습니다

  1. 문제 정의
  2. POC(Proof Of Concept) 진행
  3. 해결 방법 비교
  4. 해결 방법 선정
  5. 실행
  6. 회고

👉🏻프로젝트 계획 노션 링크

1주차

  • 아이디어 수집, 선정
  • POC 및 주제 관련 조사
  • 기술 스택 결정
  • ESLint, Prettier, Husky 설정
    • 개인 프로젝트지만 린터, 포매터, 깃 훅을 사용하였습니다. 주어진 핵심 개발 기간은 3주였지만 추후 리팩토링시 코드 퀄리티 유지 및 프로젝트 확장을 염두에 두었을 때 코드를 읽을 새로운 팀원들을 위해 미리 신경 써두는 것이 좋다고 판단하였습니다.
  • 칸반 태스크 작성

2주차

  • Scenes 개발
  • 플레이어 구현
  • 적 구현
  • 무기 구현

3주차

  • 공격 구현
  • 피격 구현
  • 레벨업 구현
  • 아이템 구현
  • QA 및 게임 밸런싱

About

Survivor 은 바닐라 자바스크립트와 Phaser 3 를 활용하여 만든 웹 서바이벌 라이크 게임 입니다.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages