paint-brush
향수를 불러일으키기: HTML5의 Canvas API 및 JavaScript를 사용하여 뱀 게임 재현~에 의해@ssaurel
523 판독값
523 판독값

향수를 불러일으키기: HTML5의 Canvas API 및 JavaScript를 사용하여 뱀 게임 재현

~에 의해 Sylvain Saurel8m2024/01/21
Read on Terminal Reader

너무 오래; 읽다

스네이크 게임은 90년대 Nokia 모바일의 위대한 고전 중 하나입니다. 이 튜토리얼에서는 HTML5에서 다시 만드는 방법을 보여줍니다.
featured image - 향수를 불러일으키기: HTML5의 Canvas API 및 JavaScript를 사용하여 뱀 게임 재현
Sylvain Saurel HackerNoon profile picture
0-item
1-item

유명한 스네이크 게임을 한 번도 해본 적이 없다면 손을 들어보세요!


나는 그렇게 말하지만, 요즘 새로운 세대는 이 게임에 대해 들어본 적이 없을지도 모른다고 생각합니다. 이 게임은 오늘날의 컴퓨터와 웹이 제공하는 가능성을 고려할 때 다소 구식으로 보일 수 있습니다.


그럼에도 불구하고 스네이크 게임은 휴대폰 소유자라면 누구나 지나치게 많은 시간을 들여 플레이하던 시절이 있었다. 네, 그 당시에는 스마트폰이 아니라 전화만 이야기하고 있었습니다.


좋은 시절이었다는 말처럼 노키아는 벤치마크이기도 한 모바일 기기를 통해 게임을 대중화했다. 오늘날 모바일 세계와 스네이크 게임에 대한 노키아의 지배력은 별로 남아 있지 않습니다.


이 게임에 대한 향수를 갖고 있는 사람들을 위해(저도 그 중 한 명입니다. 인정해야겠습니다.) 이 튜토리얼에서는 이 게임을 웹용으로 재현하는 방법을 알려줄 것입니다. 이를 위해 HTML5의 Canvas API와 JavaScript를 사용하겠습니다.


또한 Javascript에서 클래스를 사용하는 방법과 웹 게임을 위한 효과적인 게임 루프를 만드는 방법을 배울 수 있는 기회이기도 합니다.

Snake 게임용 웹 페이지 만들기

우선, 이 튜토리얼에서 개발할 Snake 게임을 플레이할 수 있는 웹 페이지를 생성하겠습니다. 이 웹 페이지에는 아무런 어려움이 없다는 것을 곧 알게 될 것입니다. 두 개의 div, 하나는 페이지 제목용이고 다른 하나는 뱀이 이동할 영역을 표시합니다.


여기에 고정 너비를 적용하여 이러한 div를 중앙에 배치하는 약간의 CSS를 추가하겠습니다.

Snake 클래스의 디자인

이 튜토리얼의 소개 부분에서 설명한 것처럼 전용 Snake 클래스를 사용하여 게임을 모델링하겠습니다. 또한 이를 통해 JavaScript에서 클래스를 조작하는 방법을 발견할 수 있습니다.


우리 뱀은 다음과 같은 속성을 갖습니다.

  • bwbh는 각각 보드 크기를 너비와 높이로 나타냅니다.
  • nbxnby는 보드에 사용 가능한 셀 수를 나타냅니다.
  • eltwelth는 뱀 요소의 너비와 높이 크기를 나타냅니다.
  • 뱀의 변위 벡터를 나타내는 dirxdiry .
  • marginxmarginy는 플레이어가 각 뱀 요소 사이의 경계를 볼 수 있도록 뱀 요소의 너비와 높이에 작은 여백을 추가합니다.
  • keyup , keydown , keyleft , keyright 는 특정 순간에 움직이는 화살표의 상태를 저장합니다.
  • startftps는 게임 시작 시 뱀을 움직이는 데 필요한 초당 프레임 수를 저장합니다.


생성자의 마지막 부분에서는 게임 시작 시 스네이크를 초기화하기 위해 init 메서드가 호출됩니다. 새 게임을 시작하려면 이 init 메소드를 다시 호출하면 됩니다.


그러면 Snake 클래스에 대한 다음 코드가 제공됩니다.

init 메서드에서는 머리에 대한 포인터 및 꼬리에 대한 포인터와 같은 다른 뱀 속성을 정의할 수 있습니다. 요소 배열은 특정 순간에 뱀의 모든 요소를 저장합니다. points 속성은 현재 게임에 대한 포인트를 저장하는 데 사용되며, level 속성은 게임의 fps를 높이기 위해 누적되는 포인트 수를 정의하는 데 사용됩니다. fps 수가 높을수록 뱀이 더 빨리 움직입니다.


fps 속성은 초당 프레임 수를 나타내기 때문에 1초(또는 1,000밀리초)를 원하는 fps 수로 나눈 결과 값을 갖는 fpsinterval 속성이 필요합니다.

스네이크 게임의 원리

스네이크 게임의 원리는 간단합니다. 네 개의 방향 화살표를 사용하여 뱀이 보드에 나타나는 사과를 최대한 많이 먹도록 유도해야 합니다. 사과를 먹을 때마다 뱀은 한 원소씩 자랍니다. 뱀이 자라면서 자신의 꼬리를 만지는 것을 피하는 것이 어렵다는 것을 알게 될 것입니다. 그렇지 않으면 패배하게 되며 점수는 0부터 다시 시작됩니다. 물론, 사과를 먹을 때마다 점수를 얻습니다.


우리가 구현할 Snake 버전은 보드 가장자리를 터치해도 잃지 않는 버전이라는 점을 지적할 가치가 있습니다. 그것은 단지 당신을 반대쪽으로 기울게 만듭니다. Snake 게임의 두 번째 버전은 Nokia에서 이러한 방식으로 구현했습니다.


뱀은 사과를 먹어야 하기 때문에 이 사과를 무작위 방식으로 보드에 표시해야 하며 뱀의 요소에 직접 사과가 생성되지 않도록 주의해야 합니다.


이는 Snake 클래스에 대해 다음과 같은 generatefood 메소드를 제공합니다.

뱀 화면 렌더링

Snake 클래스가 진행 중이므로 이제 화면에 뱀을 렌더링하는 메서드를 만들어야 합니다. 또한 주어진 시간에 플레이어의 포인트 수를 표시하고 마지막으로 먹을 사과를 표시해야 합니다. 사과의 위치는 Snake 클래스의 food 속성에 저장됩니다.


화면에 뱀을 렌더링하기 위해 HTML5의 Canvas API를 사용하고 있습니다.


나는 이 API의 그리기 기본 요소를 사용하여 먹을 사과와 뱀의 다양한 요소를 나타내는 직사각형을 그릴 것입니다. 플레이어가 구별할 수 있도록 사과와 뱀에 다른 색상을 적용하겠습니다.


이것은 Snake 클래스의 그리기 메소드에 대한 다음 코드를 제공합니다.

뱀 옮기기

이제 화면에 표시할 수 있는 뱀이 생겼습니다. 이것은 모두 매우 좋지만 뱀의 움직임에 대한 지원을 추가해야 합니다. 위에서 설명한 것처럼 뱀은 좌표 벡터(dirx, diry)를 따라 이동합니다. 따라서 여기서 정의할 move 메서드를 호출할 때마다 뱀은 같은 양만큼 움직일 것입니다.


이 이동 방법에서는 뱀의 머리 좌표가 먹려는 사과의 좌표와 일치하는지 확인합니다. 그렇다면 뱀은 방금 사과를 먹은 것입니다. 플레이어는 점수를 얻었지만 더 중요한 것은 다음 네 가지 조치를 취해야 한다는 것입니다.


  1. 뱀의 요소에 요소를 추가합니다. 이 요소는 새로운 꼬리가 됩니다.
  2. generatefood를 호출하여 새 사과를 생성합니다.
  3. 플레이어에 포인트를 추가합니다.
  4. 플레이어가 레벨을 통과하면 표시되는 초당 프레임 수를 업데이트하여 뱀의 움직임 속도를 높입니다.


그래도 이동 방법에서는 플레이어가 뱀의 요소를 머리로 건드리는 실수를 저지르지 않았는지 확인해야 합니다. 이 경우 게임은 패하고 새로 시작합니다! 이를 위해 위에 제시된 Snake 클래스의 init 메소드를 호출합니다.


이제 실제로 뱀을 움직여 이동 메소드를 완성해야 합니다. 이를 위해 뱀의 머리 좌표에 dirx와 diry를 추가합니다. 그러면 추가할 새 헤드가 제공됩니다. 또한 매번 꼬리를 제거하고 새 머리를 추가하여 뱀을 지능적으로 움직이는 것을 볼 수 있습니다. 이렇게 하면 모든 뱀 요소의 위치를 업데이트할 필요가 없습니다.


새 헤드를 업데이트하는 것을 잊지 말고 마무리하세요. 덧붙여서, 뱀의 머리가 보드 경계를 넘을 때 뱀이 보드의 반대쪽으로 이동하게 한다는 점도 알아차렸을 것입니다. 이는 너비와 길이 모두에 적용됩니다.


그러면 move 메소드에 대한 다음 코드가 제공됩니다.

스네이크 게임의 GameLoop

우리 뱀은 화면에 표시될 수 있습니다. 뱀은 move 메소드를 호출하여 움직일 수 있습니다. 우리는 무엇을 놓치고 있나요?


게임의 GameLoop 구현이 누락되었습니다!


일정한 간격으로 이동 및 그리기 메서드를 호출하는 이 GameLoop이 없으면 Snake는 이동할 수 없습니다. 다음에서는 GameLoop를 JavaScript로 올바른 방식으로 구현하는 방법을 보여드리겠습니다. 게임 웹 페이지의 렌더링 스레드를 차단하지 않도록 적합하다고 판단될 때 이를 호출하도록 브라우저에 맡기는 것입니다.


이를 위해 표준 JavaScript 개체 창의 requestAnimationFrame 메서드를 사용합니다. 그런 다음 브라우저는 웹 페이지가 사용될 컴퓨터나 스마트폰에 지원할 수 있는 최대 fps를 조정합니다.


그런 다음 게임루프 방법 내에서 브라우저가 지원하는 fps 수와 뱀을 움직이려는 fps 수의 상관 관계를 해제합니다. 앞서 정의한 fps 범위 내에 있을 때만 이동 및 그리기 메서드를 호출합니다.


네 가지 방향 키(위, 아래, 왼쪽, 오른쪽)의 상태에 따라 뱀의 이동 벡터 좌표를 업데이트하는 것이 중요합니다.


마지막으로 GameLoop를 호출하여 최적의 순간을 선택하는 작업을 브라우저에 위임합니다. 그러면 GameLoop에 대한 다음 코드가 제공됩니다.

Snake와의 사용자 상호작용 처리

플레이어가 누른 방향 키에 따라 뱀이 움직일 수 있도록 하기 위해 keydown 및 keyup 이벤트를 사용합니다. 이러한 각 이벤트에 대해 Snake 클래스의 메서드를 호출합니다. 논리적으로 이것은 keydown 이벤트의 경우 pressdown이고 keyup 이벤트의 경우 pressup입니다.


플레이어가 이러한 키를 사용하여 수행하는 작업에 따라 연결된 Snake 클래스 속성의 값을 업데이트합니다. 보시다시피, 뱀의 위치를 직접 업데이트하여 게임을 차단하지 않습니다. 대신 정기적으로 호출되는 gameloop 메서드에서 상태를 업데이트합니다.

다양한 Snake 구성 요소 조립

이 스네이크 게임을 완성하려면 다양한 요소를 조합해야 합니다. ID를 통해 Canvas 객체를 검색합니다. 그런 다음 이 캔버스에 연결된 2D 컨텍스트를 얻습니다. 원하는 치수를 적용합니다. 보드의 셀 수를 포함하여 다양한 예상 값을 매개변수로 전달하여 Snake 개체를 만듭니다.


keydown 및 keyup 이벤트에 대한 이벤트 리스너를 추가합니다.


마지막으로 남은 일은 Snake의 게임루프를 한 번 호출하여 게임을 시작하는 것뿐입니다. 이는 Canvas API와 지옥 같은 HTML5/JavaScript 웹 커플을 사용하여 만든 유명한 Snake 게임에 대한 다음과 같은 완전한 코드를 제공합니다.

실제 뱀 게임

Snake가 완성되었습니다. 이제 Nokia가 모바일 세계를 엄청나게 지배했을 때 그랬던 것처럼 Snake 마법이 다시 작동하는지 확인하기 위해 웹 브라우저에서 테스트할 시간입니다.



이 Snake 게임을 통해 몇 가지 가능한 개선 사항을 상상할 수 있습니다. 예를 들어, 뱀이 사과를 먹을 때마다 소리를 추가할 수 있습니다. HTML5의 웹 저장소 API를 사용하여 플레이어의 로컬 최고 점수를 저장할 수 있습니다. 이렇게 하면 플레이어가 최고 점수를 달성했을 때 축하 메시지를 표시할 수 있습니다. 가능성은 무궁무진하며 프로그래밍에서 유일한 한계는 상상력입니다.


YouTube에서 이 튜토리얼을 시청하세요.

이 튜토리얼은 YouTube SSaurel 채널에서도 시청할 수 있습니다.


여기에도 게시되었습니다.