본문 바로가기

메모장/스네이크 게임

스네이크 게임 - 스네이크 길이 증가

 

스네이크 이미지와 기본적인 코드는 아래 링크를 참고하여 작성하였다.
https://noobtuts.com/unity/2d-snake-game

위 링크에 있는 코드를 토대로 작성하였더니
스네이크 머리가 음식과 만나더라도
스네이크 길이가 증가하지 않는 문제가 발생하였다.
이는 약간의 구글링과 개인적인 코드 분석을 통해 해결하였다.

또한 스네이크가 벽에 닿았을 경우 반대 방향으로 돌아가는 코드와
스네이크가 현재 이동하는 방향의 반대 방향으로 입력이 들어올 경우
이동 방향이 바뀌지 않는 코드도 개인적으로 추가해보았다.

Snake Inspector
Food Inspector

 

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public class SnakeMove : MonoBehaviour
{
    // Snake Movement Var
    Vector2 dir = 1 * Vector2.right;
    Vector2 dirTemp = 1 * Vector2.right;
    private float size = 1;

    // Snake Direction Var
    float h;	// Horziontal
    float v;	// Vertical
    bool isHorizonMove;

    // Mobile Key Var
    int up_Value;
    int down_Value;
    int left_Value;
    int right_Value;
    bool up_Down;
    bool down_Down;
    bool left_Down;
    bool right_Down;
    bool up_Up;
    bool down_Up;
    bool left_Up;
    bool right_Up;

    // Snake Tail Var & Prefab
    List<Transform> tail = new List<Transform>();
    public GameObject tailPrefab;

    // for Check that Snake Eat
    bool ate = false;

    // for Check of Border
    bool isBorder = false;

    void Start()
    {
        InvokeRepeating("Move", 0.1f, 0.1f);
    }

    void Update()
    {
        // Move Value (PC + Mobile)
        h = Input.GetAxisRaw("Horizontal") + (right_Value + left_Value);
        v = Input.GetAxisRaw("Vertical") + (up_Value + down_Value);

        // Check Button Down & Up (PC || Mobile)
        bool hDown = Input.GetButtonDown("Horizontal") || right_Down || left_Down;
        bool vDown = Input.GetButtonDown("Vertical") || up_Down || down_Down;
        bool hUp = Input.GetButtonUp("Horizontal") || right_Up || left_Up;
        bool vUp = Input.GetButtonUp("Vertical") || up_Up || down_Up;

        // Check Horizontal Move
        if (hDown)
            isHorizonMove = true;
        else if (vDown)
            isHorizonMove = false;
        else if (hUp || vUp)
            isHorizonMove = (h != 0);

        // Determine Direction
        if (h != 0 || v != 0)
        {
            dirTemp = dir;
            dir = (isHorizonMove ? new Vector2(h, 0) : new Vector2(0, v));

            // Check Snake Direction (Reverse)
            if (dir == -dirTemp)
            {
                dir = dirTemp;
            }
        }

        // Mobile Var Init
        up_Down = false;
        down_Down = false;
        left_Down = false;
        right_Down = false;
        up_Up = false;
        down_Up = false;
        left_Up = false;
        right_Up = false;
    }

    void Move()
    {
        // Check whether Front is Border or Not
        if (isBorder)
        {
            // Go Same Way
            dir = -dir;
            transform.Translate(size * dir);

            isBorder = false;
        }
        else
        {
            transform.Translate(size * dir);
        }

        // Store Present Position
        Vector2 v = transform.position;

        // Check whether Snake Eats Food or Not
        if (ate)
        {
            // Copy the Tail in Present Position
            GameObject g = (GameObject)Instantiate(tailPrefab, v, Quaternion.identity);

            // Store the Tail
            tail.Insert(0, g.transform);

            ate = false;
        }
        // Move the Tail to the Head
        else if (tail.Count > 0)
        {
            tail.Last().position = v;

            tail.Insert(0, tail.Last());
            tail.RemoveAt(tail.Count - 1);
        }
    }

    // Button Down (Mobile)
    public void ButtonDown(string type)
    {
        switch (type)
        {
            case "U":
                up_Value = 1;
                up_Down = true;
                break;
            case "D":
                down_Value = -1;
                down_Down = true;
                break;
            case "L":
                left_Value = -1;
                left_Down = true;
                break;
            case "R":
                right_Value = 1;
                right_Down = true;
                break;
        }
    }

    // Button Up (Mobile)
    public void ButtonUp(string type)
    {
        switch (type)
        {
            case "U":
                up_Value = 0;
                up_Up = true;
                break;
            case "D":
                down_Value = 0;
                down_Up = true;
                break;
            case "L":
                left_Value = 0;
                left_Up = true;
                break;
            case "R":
                right_Value = 0;
                right_Up = true;
                break;
        }
    }

    void OnTriggerEnter2D(Collider2D col)
    {
        // Eat Food
        if (col.name.StartsWith("FoodPrefab"))
        {
            ate = true;
            
            Destroy(col.gameObject);
        }
        else
        {

        }

        // Check Border
        if (col.name.StartsWith("Border"))
        {
            isBorder = true;
        }
    }
}

 

궁금하신 점은 밑에 댓글 바랍니다