포시코딩

[Javascript] Snake game (2) 본문

개인프로젝트/snake 게임

[Javascript] Snake game (2)

포시 2022. 8. 23. 14:18
728x90
document.addEventListener('keydown', (e)=>{

이벤트리스너로 방향키가 눌릴때마다

    ctx.clearRect(0, 0, canvas.width, canvas.height);

캔버스를 깨끗이 지워준다음 다시 그리게 할거임

if(e.code == 'ArrowLeft'){

왼쪽키가 눌릴때 왼쪽으로 50 만큼 이동하게 할건데 0 아래로 이동하면 화면 밖으로 나가버리니

if(snakeHead.x > 0){
            snakeHead.x -= 50;

조건을 달아준 후 이동되게 한다.

다른 방향키들에도 각각 조건에 맞게 입력하면

document.addEventListener('keydown', (e)=>{
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    if(e.code == 'ArrowLeft'){
        if(snakeHead.x > 0){
            snakeHead.x -= 50;
        }
    }else if(e.code == 'ArrowRight'){
        if(snakeHead.x < (field.width - snakeHead.width) ){
            snakeHead.x += 50;
        }
    }else if(e.code == 'ArrowDown'){
        if(snakeHead.y < (field.height - snakeHead.height) ){
            snakeHead.y += 50;
        }
    }else if(e.code == 'ArrowUp'){
        if(snakeHead.y > 0 ){
            snakeHead.y -= 50;
        }
    }
	allDraw();
})

이제 한칸짜리 뱀머리가 자유롭게 움직일거임

 

움직이다 rat 과 부딪히면 (rat 의 x, y 좌표와 snakeHead 의 x, y 좌표가 같을 때)

rat을 랜덤위치에 재생성하면서 snakeBody 의 길이 하나가 늘어나게 한다. 물론 키다운 이벤트리스너 안에다

if(snakeHead.x == rat.x && snakeHead.y == rat.y){
    rat = new Rat();
    snakeHead.body += 1;
}

이제 snakeBody 가 생겼으므로 움직일때 뱀머리 뒤에 몸통개수만큼 따라와야하는데

body 가 1일땐 1개만, 2개일땐 2개만 따라와야해서 이렇게 구현해봤다.

if(snakeBodyArr.length > snakeHead.body){
    snakeBodyArr.splice(0, 1);
}

최종적으로 아래와 같은 코드가 됨

const canvas = document.querySelector('#canvas');
const ctx = canvas.getContext('2d');

canvas.width = 500;
canvas.height = 500;

let field = {
    x: 0, 
    y: 0, 
    width: 500, 
    height: 500, 
    draw(){
        ctx.fillStyle = 'black';
        ctx.fillRect(this.x, this.y, this.width, this.height);
    }
}

let snakeHead = {
    x: 0, 
    y: 0, 
    width: 50, 
    height: 50, 
    body: 0, 
    draw(){
        ctx.fillStyle = 'white';
        ctx.fillRect(this.x, this.y, this.width, this.height);
    }
}

class SnakeBody {
    constructor(x, y){
        this.x = x;
        this.y = y;
        this.width = 50;
        this.height = 50;
    }
    draw(){
        ctx.fillStyle = 'white';
        ctx.fillRect(this.x, this.y, this.width, this.height);
    }
}

class Rat {
    constructor(){
        this.x = 50 * getRandomInt(0, 10);
        this.y = 50 * getRandomInt(0, 10);
        this.width = 50
        this.height = 50
    }
    draw(){
        ctx.fillStyle = 'red';
        ctx.fillRect(this.x, this.y, this.width, this.height);
    }
}

let snakeBodyArr = [];
let rat;
do{
    rat = new Rat();
}while(rat.x == snakeHead.x && rat.y == snakeHead.y)

allDraw();

document.addEventListener('keydown', (e)=>{
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    if(e.code == 'ArrowLeft'){
        if(snakeHead.x > 0){
            snakeHead.x -= 50;
            if(snakeHead.body > 0){
                let snakeBody = new SnakeBody(snakeHead.x+50, snakeHead.y);
                snakeBodyArr.push(snakeBody);
            }
        }
    }else if(e.code == 'ArrowRight'){
        if(snakeHead.x < (field.width - snakeHead.width) ){
            snakeHead.x += 50;
            if(snakeHead.body > 0){
                let snakeBody = new SnakeBody(snakeHead.x-50, snakeHead.y);
                snakeBodyArr.push(snakeBody);
            }
        }
    }else if(e.code == 'ArrowDown'){
        if(snakeHead.y < (field.height - snakeHead.height) ){
            snakeHead.y += 50;
            if(snakeHead.body > 0){
                let snakeBody = new SnakeBody(snakeHead.x, snakeHead.y-50);
                snakeBodyArr.push(snakeBody);
            }
        }
    }else if(e.code == 'ArrowUp'){
        if(snakeHead.y > 0 ){
            snakeHead.y -= 50;
            if(snakeHead.body > 0){
                let snakeBody = new SnakeBody(snakeHead.x, snakeHead.y+50);
                snakeBodyArr.push(snakeBody);
            }
        }
    }

    if(snakeBodyArr.length > snakeHead.body){
        snakeBodyArr.splice(0, 1);
    }

    if(snakeHead.x == rat.x && snakeHead.y == rat.y){
        rat = new Rat();
        snakeHead.body += 1;
    }
    
    allDraw();
})

function allDraw(){
    field.draw();
    snakeHead.draw();
    if(snakeBodyArr.length > 0){
        snakeBodyArr.forEach((a, i, o)=>{
            a.draw();
        })
    }
    rat.draw();
}

function getRandomInt(min, max){
    min = Math.ceil(min);
    max = Math.floor(max);
    return Math.floor(Math.random() * (max-min)) + min;
}

 

https://github.com/cchoseonghun/game_snake

 

GitHub - cchoseonghun/game_snake

Contribute to cchoseonghun/game_snake development by creating an account on GitHub.

github.com

 

문제가 있는데 

1. 뱀몸통이 길어짐에 따라 rat이 랜덤생성되는 위치가 뱀몸통 위일 경우가 생긴다. 

처음시작 뱀머리 피하기처럼 하기엔 뱀몸통 Array를 다 돌며 확인해야 되는 상황이라 추후 개선 필요

2. 방향키 누르는건 말그대로 '방향'만 움직이게 하고 자동으로 앞으로 가게끔 만들기

 

위 두가지는 차차 진행할 예정

728x90

'개인프로젝트 > snake 게임' 카테고리의 다른 글

[Javascript] Snake game (1)  (0) 2022.08.23