[game] 스네이크 게임 만들기 #02

in hive-101145 •  4 years ago 

이전 글 : 스네이크 게임 만들기 #01

스네이크 게임 만들기

체험하기 (최근 개발 시점 기준) : https://game.wonsama.dev

단계별

  1. 게임 맵 만들기 - https://game.wonsama.dev/snake/1
  2. 뱀 추가 - https://game.wonsama.dev/snake/2
  3. 뱀을 움직이기 - https://game.wonsama.dev/snake/3
  4. 뱀 먹이 추가 - https://game.wonsama.dev/snake/4

스네이크 게임은 일명 지렁이 게임이라고도 불리우며 아이템을 먹으면 지렁이가 지속적으로 늘어나는 게임이며, 지렁이는 벽 또는 본인에 몸에 부딪치면 안되는 rule 을 포함하고 있습니다.

먹이감 추가 및 이동 처리 반영

// 설정 - 카붐
const k = kaboom({
  global: true, // 전역 함수 사용여부
  fullscreen: true, // 풀스크린
  scale: 2, // 스케일
  clearColor: [0, 0, 0, 1], // 배경색 - 검정
});

const block_size = 10;

const map_base = [
  "==============",
  "=            = ",
  "=            = ",
  "=            = ",
  "=            = ",
  "=            = ",
  "=            = ",
  "=            = ",
  "=            = ",
  "=            = ",
  "=            = ",
  "=            = ",
  "=            = ",
  "==============",
];

const map_base_opt = {
  width: block_size, // 블록 1개의 넓이
  height: block_size, // 블록 1개의 높이
  pos: vec2(0, 0), // 블록 시작 위치
  "=": [rect(block_size, block_size), color(255, 0, 0), "wall"], // 맵에서 = 로 표현된 텍스트를 치환한다. 크기, 색상, alias
};

// 방향설정
const directions = {
  UP: "up",
  DOWN: "down",
  LEFT: "left",
  RIGHT: "right",
};

let current_direction = directions.RIGHT;
let run_loop = false;
let snake_length = 3;
let snake_body = [];

// 뱀을 재생성 한다
function respawn_snake() {
  // snake 라고 태깅한 개체를 모두 제거한다
  destroyAll("snake");

  snake_body = [];
  snake_length = 3;

  // 분할된 뱀
  for (let i = 1; i <= snake_length; i++) {
    let segment = add([
      rect(block_size, block_size),
      pos(block_size, block_size * i),
      color(0, 0, 255),
      "snake",
    ]);
    snake_body.push(segment);
  }
  current_direction = directions.RIGHT;
}

// 모든 리스폰(부활) 함수 호출
function respawn_all() {
  run_loop = false;
  wait(0.5, function () {
    respawn_snake();
    respawn_food();
    run_loop = true;
  });
}

let food = null;

/// 음식을 리스폰(부활) 한다
function respawn_food() {
  let new_pos = rand(vec2(1, 1), vec2(13, 13));
  new_pos.x = Math.floor(new_pos.x);
  new_pos.y = Math.floor(new_pos.y);
  new_pos = new_pos.scale(block_size);

  if (food) {
    destroy(food);
  }

  // 새 음식 개체를 생성
  food = add([
    rect(block_size, block_size),
    color(0, 255, 0),
    pos(new_pos),
    "food",
  ]);
}

// 씬 설정 - 메인
scene("main", () => {
  const map = addLevel(map_base, map_base_opt); // 맵을 그려준다
  respawn_all();

  // scene 하위에서 사용, timer undefined occured
  // 이동처리 - 뒤집히는 것을 방지하기 위해 현재 진행방향의 반대 방향 이동을 금한다.
  // 키 감지 - 위
  keyPress("up", () => {
    if (current_direction != directions.DOWN) {
      current_direction = directions.UP;
    }
  });

  // 키 감지 - 아래
  keyPress("down", () => {
    if (current_direction != directions.UP) {
      current_direction = directions.DOWN;
    }
  });

  // 키 감지 - 왼쪽
  keyPress("left", () => {
    if (current_direction != directions.RIGHT) {
      current_direction = directions.LEFT;
    }
  });

  // 키 감지 - 오른쪽
  keyPress("right", () => {
    if (current_direction != directions.LEFT) {
      current_direction = directions.RIGHT;
    }
  });

  // 0.2 초의 딜레이를 주면서 아래 구역을 반복(loop) 수행한다
  // 특정 조건에서만(run_loop=true) 동작
  // scene 하위에서 사용, timer undefined occured
  loop(0.2, () => {
    if (!run_loop) return;

    let move_x = 0;
    let move_y = 0;

    switch (current_direction) {
      case directions.DOWN:
        move_x = 0;
        move_y = block_size;
        break;
      case directions.UP:
        move_x = 0;
        move_y = -1 * block_size;
        break;
      case directions.LEFT:
        move_x = -1 * block_size;
        move_y = 0;
        break;
      case directions.RIGHT:
        move_x = block_size;
        move_y = 0;
        break;
    }

    // 최종 요소를 가져온다.(뱀 머리)
    let snake_head = snake_body[snake_body.length - 1];

    // 이동하려는 방향에 분할된 머리(segment)를 추가한다
    snake_body.push(
      add([
        rect(block_size, block_size),
        pos(snake_head.pos.x + move_x, snake_head.pos.y + move_y),
        color(0, 0, 255),
        "snake",
      ])
    );

    if (snake_body.length > snake_length) {
      let tail = snake_body.shift(); // 맨 마지막 꼬리를 제거.
      destroy(tail);
    }
  });
});

// 시작 - 메인씬
start("main");

맺음말

슬슬 게임이 틀을 잡아가고 있습니다. 다음 시간에는 충돌과 지렁이 확장등을 보여 드릴 수 있을거 같네요 :)

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

@wonsama transfered 10 KRWP to @krwp.burn. voting percent : 21.83%, voting power : 36.72%, steem power : 1810756.95, STU KRW : 1200.
@wonsama staking status : 1605.929 KRWP
@wonsama limit for KRWP voting service : 1.605 KRWP (rate : 0.001)
What you sent : 10 KRWP
Refund balance : 8.395 KRWP [55646251 - 67fb0635bb6bbb58603a93b7c474ef15b0782db6]

이거 사용 엔진이 카붐이라는 건가요??

https://kaboomjs.com 에서 확인 하실 수 있습니다