按照我找到的这个教程,我一直在Unity(C#)中创建了一个简单的贪吃蛇游戏:
https://www.youtube.com/watch?v=U8gUnpeaMbQ
我发现这是一个非常好的教程,到最后我有一个完美的蛇游戏,但是,我想走得更远一点,使运动更加愉快,添加尾巴,Gameover等。
现在我的问题是,如果一个玩家快速连续按下两个可接受的方向试图抓住一些食物,蛇的头会跳过食物,完全错过它。
发生这种情况是由于以下代码位:
private void Update() //Gets Key Inputs and execute Commands
{
if (Input.GetKeyDown(KeyCode.UpArrow) )
{
while(tempPosition == _segments[0].position)
{
for (int i = _segments.Count - 1; i > 0; i--)
{
_segments[i].position = _segments[i - 1].position;
}
this.transform.position = new Vector3(
Mathf.Round(this.transform.position.x + _direction.x),
Mathf.Round(this.transform.position.y + _direction.y),
0.0f
);
}
if(_direction != Vector2.down)
{
_direction = Vector2.up;
tempPosition = _segments[0].position;
}
}
else if (Input.GetKeyDown(KeyCode.LeftArrow) )
{
while (tempPosition == _segments[0].position)
{
for (int i = _segments.Count - 1; i > 0; i--)
{
_segments[i].position = _segments[i - 1].position;
}
this.transform.position = new Vector3(
Mathf.Round(this.transform.position.x + _direction.x),
Mathf.Round(this.transform.position.y + _direction.y),
0.0f
);
}
if (_direction != Vector2.right)
{
_direction = Vector2.left;
tempPosition = _segments[0].position;
}
}
else if (Input.GetKeyDown(KeyCode.RightArrow) )
{
while (tempPosition == _segments[0].position)
{
for (int i = _segments.Count - 1; i > 0; i--)
{
_segments[i].position = _segments[i - 1].position;
}
this.transform.position = new Vector3(
Mathf.Round(this.transform.position.x + _direction.x),
Mathf.Round(this.transform.position.y + _direction.y),
0.0f
);
}
if (_direction != Vector2.left)
{
_direction = Vector2.right;
tempPosition = _segments[0].position;
}
}
else if (Input.GetKeyDown(KeyCode.DownArrow) )
{
while (tempPosition == _segments[0].position)
{
for(int i = _segments.Count -1; i>0; i--)
{
_segments[i].position = _segments[i - 1].position;
}
this.transform.position = new Vector3(
Mathf.Round(this.transform.position.x + _direction.x),
Mathf.Round(this.transform.position.y + _direction.y),
0.0f
);
}
if (_direction != Vector2.up)
{
_direction = Vector2.down;
tempPosition = _segments[0].position;
}
}
如您所见,按下一个键会立即移动蛇头,从而导致问题。
然而,如果没有像这样编码,快速连续地按2个键会导致蛇与自身碰撞(假设蛇正在向右移动,如果向上和向左快速连续地按压,蛇将开始向左移动,然后才能向上移动,与它的身体碰撞)。
以下是完整代码:
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class Snake : MonoBehaviour
{
private Vector2 _direction = Vector2.right;
public List<Transform> _segments = new List<Transform>();
public Transform segmentPrefab;
public Transform tail;
public int initialSize = 4;
public int score = 0;
private Vector3 tempPosition;
public GameObject food;
public Text gameOver;
private void Start()
{
ResetState();
}
private void Update() //Gets Key Inputs and execute Commands
{
if (Input.GetKeyDown(KeyCode.UpArrow) )
{
while(tempPosition == _segments[0].position)
{
for (int i = _segments.Count - 1; i > 0; i--)
{
_segments[i].position = _segments[i - 1].position;
}
this.transform.position = new Vector3(
Mathf.Round(this.transform.position.x + _direction.x),
Mathf.Round(this.transform.position.y + _direction.y),
0.0f
);
}
if(_direction != Vector2.down)
{
_direction = Vector2.up;
tempPosition = _segments[0].position;
}
}
else if (Input.GetKeyDown(KeyCode.LeftArrow) )
{
while (tempPosition == _segments[0].position)
{
for (int i = _segments.Count - 1; i > 0; i--)
{
_segments[i].position = _segments[i - 1].position;
}
this.transform.position = new Vector3(
Mathf.Round(this.transform.position.x + _direction.x),
Mathf.Round(this.transform.position.y + _direction.y),
0.0f
);
}
if (_direction != Vector2.right)
{
_direction = Vector2.left;
tempPosition = _segments[0].position;
}
}
else if (Input.GetKeyDown(KeyCode.RightArrow) )
{
while (tempPosition == _segments[0].position)
{
for (int i = _segments.Count - 1; i > 0; i--)
{
_segments[i].position = _segments[i - 1].position;
}
this.transform.position = new Vector3(
Mathf.Round(this.transform.position.x + _direction.x),
Mathf.Round(this.transform.position.y + _direction.y),
0.0f
);
}
if (_direction != Vector2.left)
{
_direction = Vector2.right;
tempPosition = _segments[0].position;
}
}
else if (Input.GetKeyDown(KeyCode.DownArrow) )
{
while (tempPosition == _segments[0].position)
{
for(int i = _segments.Count -1; i>0; i--)
{
_segments[i].position = _segments[i - 1].position;
}
this.transform.position = new Vector3(
Mathf.Round(this.transform.position.x + _direction.x),
Mathf.Round(this.transform.position.y + _direction.y),
0.0f
);
}
if (_direction != Vector2.up)
{
_direction = Vector2.down;
tempPosition = _segments[0].position;
}
}
if(Input.GetKeyDown(KeyCode.R))
{
ResetState();
}
}
private void FixedUpdate() //Handles moviment
{
if (gameOver.gameObject.activeSelf == false)
{
for (int i = _segments.Count - 1; i > 0; i--)
{
_segments[i].position = _segments[i - 1].position;
}
this.transform.position = new Vector3(
Mathf.Round(this.transform.position.x + _direction.x),
Mathf.Round(this.transform.position.y + _direction.y),
0.0f
);
}
}
/*Instantiates a new segment, sets it's position to tail position,
destroys tail from list and adds new segment in it's place, adds new tail at end*/
private void Grow()
{
Transform segment = Instantiate(this.segmentPrefab);
segment.position = _segments[_segments.Count - 1].position;
Destroy(_segments[_segments.Count - 1].gameObject);
_segments.Remove(_segments[_segments.Count - 1]);
_segments.Add(segment);
Transform segmenttail = Instantiate(this.tail);
segmenttail.position = _segments[_segments.Count - 1].position;
_segments.Add(segmenttail);
}
private void ResetState()
{
gameOver.gameObject.SetActive(false);
tempPosition.x = 1000;
score = 0;
for (int i = 1; i < _segments.Count; i++)
{
Destroy(_segments[i].gameObject);
}
_segments.Clear();
_segments.Add(this.transform);
for (int i = 1; i < initialSize; i++)
{
_segments.Add(Instantiate(this.segmentPrefab));
}
_segments.Add(Instantiate(this.tail));
this.transform.position = Vector3.zero;
this.GetComponent<SpriteRenderer>().enabled = (true);
food.GetComponent<Food>().RandomizePosition();
}
private void OnTriggerEnter2D(Collider2D other)
{
if (other.tag == "Food")
{
Grow();
score++;
}
else if(other.tag == "Obstacle")
{
for (int i = 1; i < _segments.Count; i++)
{
Destroy(_segments[i].gameObject);
}
this.GetComponent<SpriteRenderer>().enabled=(false);
_segments.Clear();
food.gameObject.SetActive(false);
gameOver.gameObject.SetActive(true);
}
}
}
tl;dr:在一个简单的蛇游戏中,当两个方向快速连续按下时,我如何确保蛇在转向第二个方向之前会朝第一个方向移动,而不会出现虫子。
谢谢!
做一个红色的立方体,控制蛇移动的方向,还有遇到食物和吃食物的功能,在Update()中,WSAD和方向键控制蛇头的移动方向,而蛇头向上移动时不能向下移动,蛇向左移动时不能向右移动。
void Update () {
if (Input.GetKey(KeyCode.W)||Input.GetKey("up")&&direction!=
Vector2.down)
{
direction = Vector2.up;
}
if (Input.GetKey(KeyCode.S) || Input.GetKey("down") && direction != Vector2.up)
{
direction = Vector2.down;
}
if (Input.GetKey(KeyCode.A) || Input.GetKey("left") && direction != Vector2.right)
{
direction = Vector2.left;
}
if (Input.GetKey(KeyCode.D) || Input.GetKey("right") && direction != Vector2.left)
{
direction = Vector2.right;
}
}
蛇与食物相撞后,身体会长出一段,在遇到食物时,会先破坏食物,然后增加自己身体的长度,此时设定的相撞位旗会变成真,身体长度会增加,但当它撞到自己时,撞到墙上时,它会死亡,此时,它会在开始时被导入场景。
void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag("Food"))
{
//Debug.Log("hit it!");
Destroy(other.gameObject);
flag = true;
}
else
{
//SceneManager.LoadScene(0)
Application.LoadLevel(1);
}
}
身体每次生长的算法是吃蛇的难度。互联网上的许多算法都是使用链表实现的。链表的节点表明增加或减少snake非常方便。移动时,只需添加头部节点并将其移除。尾部节点就足够了,要吃东西,只需要添加一个头部节点。这个算法绝对是巧妙的,但由于互联网上的蛇太多,下面是另一个通过链表实现的吃蛇算法。蛇头一动不动,身体的最后一部分向前移动,然后慢慢向后移动。下面的蓝色方块(身体部位的设置)一步一步地移动,您可以看到这种效果。蛇身体部位的代码发布在下面。如果食物被吃了,国旗是真的。这是将一个预制的立方体插入蛇的身体,蛇的身体会变长。当没有食物时,它会在此时查看身体的数量。当数字大于0时,最后一个将放在前面,循环将持续到结束。
void Move()
{
Vector3 VPosition = transform.position;
transform.Translate(direction);
if (flag)
{
GameObject bodyPrefab = (GameObject)Instantiate(gameObjecgtBody, VPosition, Quaternion.identity);
Body.Insert(0, bodyPrefab.transform);
flag = false;
}
else if (Body.Count > 0)
{
Body.Last().position = VPosition;
Body.Insert(0, Body.Last());
Body.RemoveAt(Body.Count - 1);
}
}
食物的出现是一个随机的过程。这时,食物出现在一个随机的位置。InvokeRepeating("ShowFood ",1,4);意味着四秒后将调用ShowFood()函数,此时它会随机出现在ShowFood中。食物。下面是ShowFood()函数的代码
void ShowFood()
{
int x = Random.Range(-30, 30);
int y = Random.Range(-22, 22);
Instantiate(SSFood, new Vector2(x,y), Quaternion.identity);
}
特别要注意的是,在制作蛇头和蛇体时,如果将碰撞体的体积设置为1单元,蛇体的侧面也会撞击食物,触发对撞机。所以把对撞机的体积设置为0.8,也略小于1.我也从网上找到了信息,希望能帮到你,这个链接就是源代码 https://github.com/xiaogeformax/Snake/tree/master/Snake5.2
本文向大家介绍python实现简单贪吃蛇游戏,包括了python实现简单贪吃蛇游戏的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了python实现贪吃蛇游戏的具体代码,供大家参考,具体内容如下 代码: 更多有趣的经典小游戏实现专题,分享给大家: C++经典小游戏汇总 python经典小游戏汇总 python俄罗斯方块游戏集合 JavaScript经典游戏 玩不停 java经典小游戏汇
本文向大家介绍js实现贪吃蛇游戏(简易版),包括了js实现贪吃蛇游戏(简易版)的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了js实现贪吃蛇游戏的具体代码,供大家参考,具体内容如下 直接开始 效果图: 项目结构:图片自己找的 1.html 2.area.js 3.config.js 4.food.js 5.init.js 6.move.js 7.score.js 8.snake.js
本文向大家介绍python实现贪吃蛇游戏,包括了python实现贪吃蛇游戏的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了python实现贪吃蛇游戏的具体代码,供大家参考,具体内容如下 本文稍作改动,修复一些bug,原文链接:python实现贪吃蛇游戏 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。
本文向大家介绍python贪吃蛇游戏代码,包括了python贪吃蛇游戏代码的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了python贪吃蛇游戏的具体代码,供大家参考,具体内容如下 贪吃蛇游戏截图: 首先安装pygame,可以使用pip安装pygame: pip install pygame 运行以下代码即可: 操作方法: 上下左右键或wsad键控制 ESC键退出游戏 下载代码:贪吃
本文向大家介绍Python写的贪吃蛇游戏例子,包括了Python写的贪吃蛇游戏例子的使用技巧和注意事项,需要的朋友参考一下 第一次用Python写这种比较实用且好玩的东西,权当练手吧 游戏说明: * P键控制“暂停/开始” * 方向键控制贪吃蛇的方向 源代码如下:
本文向大家介绍C语言单链表贪吃蛇小游戏,包括了C语言单链表贪吃蛇小游戏的使用技巧和注意事项,需要的朋友参考一下 C语言实现单链表控制台贪吃蛇小游戏,供大家参考。 编译环境:vs2019 需求: 统计游戏开始后的时间,控制贪吃蛇;吃到食物蛇身加长,得分加一;碰墙或蛇头碰到身体减一条生命;生命消耗完则结束游戏。 思路: 使用wasd键控制蛇的移动方向,蛇头碰到食物得分加一,并在地图上随机产生一个食物,