【问题标题】:Unity Snake Game, how to make the body follow the head?Unity Snake Game,如何让身体跟随头部?
【发布时间】:2020-04-29 21:30:39
【问题描述】:

所以我一直在制作一个与 Snake 相关的小游戏,我正在努力研究如何让 Snake 的身体出现并在蛇的头部接触到苹果时跟随头部的位置。我已经设法让 Snake 的身体产卵,但我无法让它正确地跟随头部。谁能帮助我并告诉我该怎么做?谢谢!

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

public class Snake_Move : MonoBehaviour
{
    // variables
    public Vector2 pos;
    private Vector2 moveDirection;
    private float moveTimer;
    private float timerSeconds;

    //Function which runs once when the program starts
    void Start()
    {
        timerSeconds = 0.0167f;
        moveTimer = timerSeconds;
        moveDirection = new Vector2(0.1f, 0);
    }

    //Function which updates itself based on your refresh rate
    public void Update()
    {
        AutoMove();
        ChangeDirection();
        transform.position = new Vector2(pos.x, pos.y);
        transform.eulerAngles = new Vector3(0, 0, AngleCalculator(moveDirection) - 90);
    }

    //Moves the snake 60 units each second
    private void AutoMove()
    {
        moveTimer += Time.deltaTime;

        if (moveTimer > timerSeconds)
        {
            pos += moveDirection;
            moveTimer -= timerSeconds;
        }
    }

    //Changes direction of the snake based on arrow key pressed
    private void ChangeDirection()
    {
        if (Input.GetKeyDown(KeyCode.UpArrow))
        {
            if (moveDirection.y != -0.1f)
            {
                moveDirection.x = 0;
                moveDirection.y = 0.1f;
            }
        }
        else if (Input.GetKeyDown(KeyCode.DownArrow))
        {
            if (moveDirection.y != 0.1f)
            {
                moveDirection.x = 0;
                moveDirection.y = -0.1f;
            }
        }
        else if (Input.GetKeyDown(KeyCode.RightArrow))
        {
            if (moveDirection.x != -0.1f)
            {
                moveDirection.y = 0;
                moveDirection.x = 0.1f;
            }
        }
        else if (Input.GetKeyDown(KeyCode.LeftArrow))
        {
            if (moveDirection.x != 0.1f)
            {
                moveDirection.y = 0;
                moveDirection.x = -0.1f;
            }
        }
    }

    //Calculates the angle at which the snake is moving; used to calculate rotation of sprite
    private float AngleCalculator(Vector2 direction)
    {
        float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
        return angle;
    }

    private void SnakeBodySprite()
    {
        GameObject snakeApple = GameObject.Find("SnakeApple");
        Apple_RandomSpawn appleScript = snakeApple.GetComponent<Apple_RandomSpawn>();

        //something here?????
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Apple_RandomSpawn : MonoBehaviour
{
    private Vector2 foodPos;

    void Start()
    {
        SpawnApple();
    }

    void Update()
    {
        transform.position = new Vector2(foodPos.x, foodPos.y);
        SnakeAte();
    }

    public void SpawnApple()
    {
        foodPos = new Vector2(Random.Range(-17, 17), Random.Range(-9, 9));
    }

    public void SnakeAte()
    {
        GameObject snakeBody = GameObject.Find("SnakeBody");
        GameObject snakeHead = GameObject.Find("SnakeHead");
        Snake_Move snakeMove = snakeHead.GetComponent<Snake_Move>();

        if (foodPos.x <= snakeMove.pos.x + 1 &&
            foodPos.x >= snakeMove.pos.x - 1 &&
            foodPos.y <= snakeMove.pos.y + 1 &&
            foodPos.y >= snakeMove.pos.y -1)
        {
            SpawnApple();
            Instantiate(snakeBody);
        }
    }

}   

【问题讨论】:

标签: c# unity3d


【解决方案1】:

这是一个宽泛的问题,因此很难完全回答。我想到的想法是使用移动向量队列作为头部,然后将这些动作应用于身体。您需要对蛇体对象的引用,并且需要知道头部从身体移动了多少次。你的情况看起来可能是 60。

我将在本节中添加队列:

Queue<Vector2> moveDirections = new Queue<Vector2>();
SnakeBody snakeBody; // Reference to 1st snake body element
float offset = 60; // ?

private void AutoMove()
{
    moveTimer += Time.deltaTime;
    // enqueue the most recent moveDirection
    moveDirections.Enqueue(moveDirection);

    if (moveTimer > timerSeconds)
    {
        pos += moveDirection;
        moveTimer -= timerSeconds;

        // Get oldest moveDirection from the head to apply to the body
        Vector2 bodyMovement = moveDirections.Dequeue();
        snakeBody.transform.Translate(bodyMovement);
    }

    // If the queue count is greater than how far ahead the head should be from the
    // first body element, remove one from queue.
    if (moveDirections.Count > offset) {
        moveDirections.Dequeue();
    }
}

这仅适用于第一个 body 元素,因此您可以为每个 body 元素添加一个脚本来跟踪其子 body 元素。使用与上述相同的逻辑定位子元素。

注意:我没有对此进行测试,我只是想给出一个关于如何解决这个问题的高级概述。

【讨论】:

    猜你喜欢
    • 2021-01-23
    • 1970-01-01
    • 2015-06-30
    • 1970-01-01
    • 1970-01-01
    • 2012-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多