JavaScript로 Slither.io를 만드는 법 : Part 7 - Food & Conclusion


이것은 JavaScript 및 Phaser로 Slither.io를 만드는 튜토리얼 시리즈의 일곱 번째 파트입니다! Part 1을 처음 보시거나 Part 6으로 돌아 가시면됩니다.

예제를 살펴보고 이 부분의 소스 코드를 살펴보십시오.

음식 개념

이 시리즈의 마지막 부분에서는 뱀이 먹을 수 있는 음식을 추가 할 것입니다. 이것이 우리의 마지막 부분이기 때문에 데모는 완성 된 버전입니다!

우리의 음식 스프라이트는 작은 육각형 일 것입니다. 이 스프라이트에는 원형 물리바디가 있습니다. 음식 스프라이트가 뱀 머리와 충돌 할 때, 음식이 머리 중심을 향해 중력을 가하는 것처럼 보이는 구속 조건이 만들어집니다. 음식이 뱀 머리의 중심에 있으면 파괴되고 뱀의 크기가 커집니다. 육각 이미지는 흰색이므로 hex.png에서 볼 수 있듯이 어떤 색상의 음식이라도 만들 수 있습니다.

음식

food.js의 Food 함수를 살펴보십시오.
Food = function(game, x, y) {
    this.game = game;
    this.debug = false;
    this.sprite = this.game.add.sprite(x, y, 'food');
    this.sprite.tint = 0xff0000;

    this.game.physics.p2.enable(this.sprite, this.debug);
    this.sprite.body.clearShapes();
    this.sprite.body.addCircle(this.sprite.width * 0.5);
    // 무언가가 음식에 부딪 칠 때 콜백을 설정합니다.
    this.sprite.body.onBeginContact.add(this.onBeginContact, this);

    this.sprite.food = this;

    this.head = null;
    this.constraint = null;
}
여기서는 음식 스프라이트를 만들고, 원형 물리 바디를 만들고,이 몸체가 뱀 머리와 접촉하기 시작할 때 콜백을 설정하고, 마지막으로 음식 머리를 만질 때 사용할 속성 머리와 구속 조건을 만듭니다.

처음 접촉

음식이 뭔가를 만졌을 때 콜백을 보자.
onBeginContact: function(phaserBody, p2Body) {
    if (phaserBody && phaserBody.sprite.name == "head" && this.constraint === null) {
        this.sprite.body.collides([]);
        // 음식과 충돌 한 뱀 머리 사이의 제약 조건을 만듭니다.
        // 음식은 머리 스프라이트의 중심으로 가져옵니다.
        this.constraint = this.game.physics.p2.createRevoluteConstraint(
            this.sprite.body, [0,0], phaserBody, [0,0]
        );
        this.head = phaserBody.sprite;
        this.head.snake.food.push(this);
    }
}
먼저 음식이 충돌 한 뱀 머리인지 확인합니다. 그렇다면 우리는 이 음식에 대한 모든 충돌을 차단합니다. 우리는 실제로 그것이 닿았 던 뱀 머리쪽으로 음식을 끌어 당기는 회전 제한을 만듭니다. 우리는 음식이 충돌 한 뱀 머리에 머리 속성을 설정하고, 우리는 잠시 후에 설명 할 뱀의 음식 배열에 이 음식을 밀어 넣습니다.

업데이트

업데이트 방법을 살펴보십시오.
update: function() {
    // 일단 음식이 뱀 머리의 중심에 도달하면, 그것을 파괴하고 뱀의 크기를 증가시킵니다.
    if (this.head && Math.round(this.head.body.x) == Math.round(this.sprite.body.x) &&
    Math.round(this.head.body.y) == Math.round(this.sprite.body.y)) {
        this.head.snake.incrementSize();
        this.destroy();
    }
}
여기서 우리는 음식이 대략 머리 중심에 있는지 확인합니다. 그것이되면, 우리는 뱀 크기를 증가시키고 이 음식을 파괴합니다.

파괴

우리 게임에서 그 밖의 모든 것과 마찬가지로, 음식에는 파괴 방법이 필요합니다.
destroy: function() {
    if (this.head) {
        this.game.physics.p2.removeConstraint(this.constraint);
        this.sprite.destroy();
        this.head.snake.food.splice(this.head.snake.food.indexOf(this), 1);
        this.head = null;
    }
}
일단 머리에 부딪치더라도 우리는 단지 그것을 파괴 할뿐입니다. 그런 다음 제약 조건을 제거하고 스프라이트를 제거한 다음 이전에 언급 한 뱀의 해당 배열에서 음식을 제거합니다.

뱀 음식 배열
Snake 클래스에서 다음 줄을 추가했습니다.
this.food = [];

이 배열은 뱀이 현재 소비하고있는 모든 음식을 포함합니다. 즉, 뱀과 충돌했지만 아직 파괴되지 않은 음식을 의미합니다. 왜 우리가 이것을 필요로합니까? 뱀이 갑자기 파괴되면 음식이 뱀에게 강요되므로 뱀이 모두 파괴되어야합니다. 이것을 처리하지 않으면 오류가 발생합니다. 자 이제 이것을 뱀 파괴 방법에 추가해 봅시다.
// 뱀 머리에 구속 된 음식을 파괴하라.
for (var i = this.food.length - 1 ; i >= 0 ; i--) {
    this.food[i].destroy();
}

게임에 음식 추가하기

마지막으로 실제로 음식을 추가하고 올바르게 충돌해야합니다. game.js를 한번보세요. 우리는 Create 상태에 몇몇 그룹과 음식을 추가 할 것입니다 :
this.foodGroup = this.game.add.group();
this.snakeHeadCollisionGroup = this.game.physics.p2.createCollisionGroup();
this.foodCollisionGroup = this.game.physics.p2.createCollisionGroup();
// add food randomly
for (var i = 0 ; i < 100 ; i++) {
    this.initFood(Util.randomInt(-width, width), Util.randomInt(-height, height));
}

마지막 몇 라인은 임의의 위치에서 initFood 메소드를 호출합니다. 이 방법을 살펴보십시오.
initFood: function(x, y) {
    var f = new Food(this.game, x, y);
    f.sprite.body.setCollisionGroup(this.foodCollisionGroup);
    this.foodGroup.add(f.sprite);
    f.sprite.body.collides([this.snakeHeadCollisionGroup]);
    return f;
}

우리는 음식을 일부 그룹에 추가 한 다음 뱀 머리와 만 충돌하는지 확인합니다. create 메서드에 뱀을 추가 한 후에는 자신에게 충돌 그룹을 제공해야합니다.
// initialize snake groups and collision
for (var i = 0 ; i < this.game.snakes.length ; i++) {
    var snake = this.game.snakes[i];
    snake.head.body.setCollisionGroup(this.snakeHeadCollisionGroup);
    snake.head.body.collides([this.foodCollisionGroup]);
    //callback for when a snake is destroyed
    snake.addDestroyedCallback(this.snakeDestroyed, this);
}
우리는 뱀 머리를 음식과 충돌하도록 설정 한 다음 파괴 콜백을 추가합니다.

Dropping Food on Destruction

마지막으로, 우리 게임의 가장 중요한 부분 : 그들이 죽을 때 음식을 떨어지는 뱀! 뱀이 파괴되었을 때 game.js에서 콜백 메소드를 봅시다
snakeDestroyed: function(snake) {
    //place food where snake was destroyed
    for (var i = 0 ; i < snake.headPath.length ;
    i += Math.round(snake.headPath.length / snake.snakeLength) * 2) {
        this.initFood(
            snake.headPath[i].x + Util.randomInt(-10,10),
            snake.headPath[i].y + Util.randomInt(-10,10)
        );
    }
}
우리는 뱀의 경로 근처에서 무작위로 음식을 떨어 뜨려 음식물이 고르게 흩어 지도록 경로를 반복합니다. 그리고 그걸로 우리 게임이 완성되었습니다!

결론

Slither.io 여행이 끝났습니다. 이제 자신의 IO 게임을 만들거나 이 게임에 추가 할 시간입니다. 이 시리즈와 같은 다른 시리즈를보고 싶다면 알려주세요. 충분한 관심이 있다면이 게임 멀티 플레이어 제작에 대한 자습서를 작성하는 것을 고려할 것입니다.

이 시리즈는 Phaser의 지원 없이는 가능하지 않았습니다. 잠시 시간을내어 Twitter에서 나를 따라 가고이 튜토리얼 시리즈의 소스 코드에 Github의 별표를 올려주세요!

댓글 없음:

댓글 쓰기