I'm working on a snake game and I'm running into a problem where if I hit my inputs (up, down, left, right) too fast, my snake runs into itself. I've tried to create a timer under Update() to regulate my movements but I find my snake to still be running into itself from time to time.
I use InvokeRepeating() to move my snake every 0.05 seconds and I have 2 methods of inputs: 1) Update to listen for keyboard inputs (up, down, left, right arrows) and 2) a Gamepad UI (up, down, left, right buttons). Any suggestions to how I could regulate my directional changes?
void Start () {
Screen.orientation = ScreenOrientation.Portrait;
isPaused = false;
InvokeRepeating("TimerInvoke", 0, deltaTimer);
}
void TimerInvoke() {
Movement();
StartCoroutine(checkVisible());
if (currentSize == maxSize)
TailFunction();
else
currentSize++;
}
void Update () {
CompDirectionControl();
PauseCMD();
}
void CompDirectionControl() {
if (direction != Direction.South && Input.GetKeyDown(KeyCode.UpArrow))
direction = Direction.North;
if (direction != Direction.West && Input.GetKeyDown(KeyCode.RightArrow))
direction = Direction.East;
if (direction != Direction.North && Input.GetKeyDown(KeyCode.DownArrow))
direction = Direction.South;
if (direction != Direction.East && Input.GetKeyDown(KeyCode.LeftArrow))
direction = Direction.West;
}
public void MPadDirectionControl(int numDirection)
{
if (direction != Direction.South && numDirection == 0)
direction = Direction.North;
if (direction != Direction.West && numDirection == 1)
direction = Direction.East;
if (direction != Direction.North && numDirection == 2)
direction = Direction.South;
if (direction != Direction.East && numDirection == 3)
direction = Direction.West;
}
I tried creating something like this but the delay is very inconsistent
if (Time.time >= timeStamp)
{
CompDirectionControl();
timeStamp = Time.time + moveInterval;
}
UPDATE I was able to add a delay to my keyboard inputs by using a coroutine. However, I have not figured out how to do the same with my button UI inputs. If I create a public IEnumerator GamePadDirControl(int direction), how do I pass my button's parameter to my IEnumator? Even though I set my GamePadDirControl to public, I don't see it in my Inspector so I can't link my button to it
IEnumerator DirControl() {
if (direction != Direction.South && Input.GetKeyDown(KeyCode.UpArrow))
{
yield return new WaitForSeconds(deltaTimer);
direction = Direction.North;
}
else if (direction != Direction.West && Input.GetKeyDown(KeyCode.RightArrow))
{
yield return new WaitForSeconds(deltaTimer);
direction = Direction.East;
}
else if (direction != Direction.North && Input.GetKeyDown(KeyCode.DownArrow))
{
yield return new WaitForSeconds(deltaTimer);
direction = Direction.South;
}
else if (direction != Direction.East && Input.GetKeyDown(KeyCode.LeftArrow))
{
yield return new WaitForSeconds(deltaTimer);
direction = Direction.West;
}
}
UPDATE 2 For my buttons UI - Since it isn't possible for my button to link up with IEnumator functions, I decided to create individual coroutines for each direction and call on them from my public void MPadDirectionControl(int numDirection) function.
updated code on button ui input
public void MPadDirectionControl(int numDirection)
{
if (direction != Direction.South && numDirection == 0)
{
StartCoroutine(IntervalN());
//direction = Direction.North;
}
else if (direction != Direction.West && numDirection == 1)
{
StartCoroutine(IntervalE());
//direction = Direction.East;
}
else if (direction != Direction.North && numDirection == 2)
{
StartCoroutine(IntervalS());
//direction = Direction.South;
}
else if (direction != Direction.East && numDirection == 3)
{
StartCoroutine(IntervalW());
//direction = Direction.West;
}
}
IEnumerator IntervalN() {
yield return new WaitForSeconds(deltaTimer);
direction = Direction.North;
}
IEnumerator IntervalE()
{
yield return new WaitForSeconds(deltaTimer);
direction = Direction.East;
}
IEnumerator IntervalS()
{
yield return new WaitForSeconds(deltaTimer);
direction = Direction.South;
}
IEnumerator IntervalW()
{
yield return new WaitForSeconds(deltaTimer);
direction = Direction.West;
}