snake_game.c: resolved bug where the head gets bitten by itself
This commit is contained in:
parent
126c1d0c44
commit
967ab9a05e
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include "../../config.h"
|
#include "../../config.h"
|
||||||
#include "../../compat/pgmspace.h"
|
#include "../../compat/pgmspace.h"
|
||||||
#include "../../pixel.h"
|
#include "../../pixel.h"
|
||||||
|
@ -102,6 +103,8 @@ typedef struct snake_protagonist_s
|
||||||
uint8_t nHeadIndex; /**< Index of the head segment. */
|
uint8_t nHeadIndex; /**< Index of the head segment. */
|
||||||
uint8_t nTailIndex; /**< Index of the tail segment. */
|
uint8_t nTailIndex; /**< Index of the tail segment. */
|
||||||
snake_dir_t dir; /**< Direction of the snake. */
|
snake_dir_t dir; /**< Direction of the snake. */
|
||||||
|
bool bJoystickLocked; /**< Avoid double joytick queries
|
||||||
|
between movements. */
|
||||||
} snake_protagonist_t;
|
} snake_protagonist_t;
|
||||||
|
|
||||||
|
|
||||||
|
@ -213,6 +216,7 @@ static void snake_initGameProtagonist(snake_protagonist_t *pprotSnake)
|
||||||
#endif
|
#endif
|
||||||
pprotSnake->nTailIndex = 0;
|
pprotSnake->nTailIndex = 0;
|
||||||
pprotSnake->nHeadIndex = 1;
|
pprotSnake->nHeadIndex = 1;
|
||||||
|
pprotSnake->bJoystickLocked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef GAME_SNAKE
|
#ifdef GAME_SNAKE
|
||||||
|
@ -229,10 +233,14 @@ static void snake_userControl(snake_protagonist_t *pprotSnake,
|
||||||
if (dirJoystick != SNAKE_DIR_NONE)
|
if (dirJoystick != SNAKE_DIR_NONE)
|
||||||
{
|
{
|
||||||
// valid transitions can only be uneven
|
// valid transitions can only be uneven
|
||||||
if ((pprotSnake->dir + dirJoystick) & 0x01)
|
if (((pprotSnake->dir + dirJoystick) & 0x01) &&
|
||||||
|
!pprotSnake->bJoystickLocked)
|
||||||
{
|
{
|
||||||
pprotSnake->dir = dirJoystick;
|
pprotSnake->dir = dirJoystick;
|
||||||
}
|
}
|
||||||
|
// we query the joystick twice as fast as we move the snake, so we
|
||||||
|
// have to ensure that it does not bite its head with its head...uh
|
||||||
|
pprotSnake->bJoystickLocked = true;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if ((dirJoystick ^ *pdirLast) && (dirJoystick != SNAKE_DIR_NONE))
|
if ((dirJoystick ^ *pdirLast) && (dirJoystick != SNAKE_DIR_NONE))
|
||||||
|
@ -244,6 +252,9 @@ static void snake_userControl(snake_protagonist_t *pprotSnake,
|
||||||
pprotSnake->dir = (pprotSnake->dir +
|
pprotSnake->dir = (pprotSnake->dir +
|
||||||
(dirJoystick == SNAKE_DIR_LEFT ? 3 : 1)) % 4u;
|
(dirJoystick == SNAKE_DIR_LEFT ? 3 : 1)) % 4u;
|
||||||
}
|
}
|
||||||
|
// we query the joystick twice as fast as we move the snake, so we
|
||||||
|
// have to ensure that it does not bite its head with its head...uh
|
||||||
|
pprotSnake->bJoystickLocked = true;
|
||||||
}
|
}
|
||||||
*pdirLast = dirJoystick;
|
*pdirLast = dirJoystick;
|
||||||
#endif
|
#endif
|
||||||
|
@ -362,9 +373,9 @@ static void snake_initApples(snake_apples_t *pApples)
|
||||||
* Checks for an apple at a given position and removes it if there is one.
|
* Checks for an apple at a given position and removes it if there is one.
|
||||||
* @param pApples The set of apples which are lying on the playing field.
|
* @param pApples The set of apples which are lying on the playing field.
|
||||||
* @param pxHead The position to be tested.
|
* @param pxHead The position to be tested.
|
||||||
* @return 0 if no apples were found, 1 otherwise
|
* @return false if no apples were found, true otherwise
|
||||||
*/
|
*/
|
||||||
static uint8_t snake_checkForApple(snake_apples_t *pApples, pixel pxHead)
|
static bool snake_checkForApple(snake_apples_t *pApples, pixel pxHead)
|
||||||
{
|
{
|
||||||
for (uint8_t i = pApples->nAppleCount; i--;)
|
for (uint8_t i = pApples->nAppleCount; i--;)
|
||||||
{
|
{
|
||||||
|
@ -376,10 +387,10 @@ static uint8_t snake_checkForApple(snake_apples_t *pApples, pixel pxHead)
|
||||||
pApples->aApples[i] = pApples->aApples[i + 1];
|
pApples->aApples[i] = pApples->aApples[i + 1];
|
||||||
}
|
}
|
||||||
--pApples->nAppleCount;
|
--pApples->nAppleCount;
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -419,7 +430,7 @@ void snake_engine(uint8_t bDemoMode)
|
||||||
clear_screen(0);
|
clear_screen(0);
|
||||||
snake_drawBorder();
|
snake_drawBorder();
|
||||||
|
|
||||||
for (uint8_t nTick = 0; 1; nTick ^= SNAKE_COLOR_APPLE)
|
for (uint8_t nTick = 0; true; nTick ^= SNAKE_COLOR_APPLE)
|
||||||
{
|
{
|
||||||
// determine new direction
|
// determine new direction
|
||||||
#if defined ANIMATION_SNAKE && defined GAME_SNAKE
|
#if defined ANIMATION_SNAKE && defined GAME_SNAKE
|
||||||
|
@ -439,6 +450,8 @@ void snake_engine(uint8_t bDemoMode)
|
||||||
snake_userControl(&protSnake, &dirLast);
|
snake_userControl(&protSnake, &dirLast);
|
||||||
if (nTick) {
|
if (nTick) {
|
||||||
#endif
|
#endif
|
||||||
|
// release joystick lock
|
||||||
|
protSnake.bJoystickLocked = false;
|
||||||
|
|
||||||
// actually move head
|
// actually move head
|
||||||
pixel pxOldHead = protSnake.aSegments[protSnake.nHeadIndex];
|
pixel pxOldHead = protSnake.aSegments[protSnake.nHeadIndex];
|
||||||
|
|
Loading…
Reference in New Issue