working snake basis, todo animation and gameplay

multi-mode
Ondřej Hruška 8 years ago
parent d49b10a802
commit e99ea3d0ec
  1. 5
      project/main.c
  2. 4
      project/main.h
  3. 4
      project/mode_audio.c
  4. 4
      project/mode_life.c
  5. 145
      project/mode_snake.c

@ -106,7 +106,10 @@ int main(void)
mode_life_init();
mode_snake_init();
mode_audio_start();
app_mode = MODE_SNAKE;
mode_snake_start();
//mode_audio_start();
ms_time_t last;
while (1) {

@ -15,4 +15,8 @@
#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)
// screen size
#define SCREEN_W 16
#define SCREEN_H 16
#endif // MAIN_H

@ -34,7 +34,7 @@ static void boot_animation(void)
dmtx_clear(dmtx);
// Boot animation (for FFT)
for (int i = 0; i < 16; i++) {
for (int i = 0; i < SCREEN_W; i++) {
dmtx_set(dmtx, i, 0, 1);
dmtx_show(dmtx);
delay_ms(20);
@ -149,7 +149,7 @@ static void audio_capture_done(void* unused)
dmtx_clear(dmtx);
float factor = (1.0f / bin_count) * 0.25f;
for (int i = 0; i < bin_count; i++) {
for (int i = 0; i < MIN(bin_count, SCREEN_W) + 1; i++) { // +1 because bin 0 is always 0
bins[i] *= factor;
for (int j = 0; j < 1 + floorf(bins[i]); j++) {

@ -9,8 +9,8 @@ static bool life_enabled = false;
static void show_board(bool do_show);
static void apply_paint(void);
#define BOARD_W 16
#define BOARD_H 16
#define BOARD_W SCREEN_W
#define BOARD_H SCREEN_H
#define SIZEOF_BOARD (BOARD_H*sizeof(uint32_t))

@ -1,13 +1,156 @@
#include "mode_snake.h"
#include "com/debug.h"
#include "dotmatrix.h"
#define BOARD_W SCREEN_W
#define BOARD_H SCREEN_H
/** Snake movement direction */
typedef enum {
NORTH,
SOUTH,
EAST,
WEST
} Direction;
typedef enum {
CELL_EMPTY,
CELL_BODY,
CELL_FOOD,
CELL_WALL
} CellType;
/** Board cell */
typedef struct __attribute__((packed)) {
CellType type : 2; // Cell type
Direction dir : 2; // direction the head moved to from this tile, if body = 1
} Cell;
/** Wall tile, invariant, used for out-of-screen coords */
static const Cell WALL_TILE = {CELL_WALL, 0};
static const Cell EMPTY_TILE = {CELL_EMPTY, 0};
/** Game board */
static Cell board[BOARD_H][BOARD_W];
typedef struct {
int x;
int y;
} Coord;
/** Snake coords */
static Coord head;
static Coord tail;
static Direction head_dir;
/** blinking to visually change 'color' */
static bool wall_pwm_on = 1;
static bool body_pwm_on = 1;
static bool head_pwm_on = 1;
static bool food_pwm_on = 1;
/** Get board cell at coord (x,y) */
static Cell *cell_at_xy(int x, int y)
{
if (x < 0 || x >= BOARD_W || y < 0 || y >= BOARD_H ) {
return &WALL_TILE; // discards const - OK
}
return &board[y][x];
}
/** Get board cell at coord */
static Cell *cell_at(Coord *coord)
{
return cell_at_xy(coord->x, coord->y);
}
/** Place food in a random empty tile */
static void place_food(void)
{
Coord food;
// 1000 tries - timeout in case board is full of snake (?)
for (int i = 0; i < 1000; i++) {
food.x = rand() % BOARD_W;
food.y = rand() % BOARD_H;
Cell *cell = cell_at(&food);
if (cell->type == CELL_EMPTY) {
cell->type = CELL_FOOD;
dbg("Food at [%d, %d]", food.x, food.y);
break;
}
}
}
/** Clear the board and prepare for a new game */
static void new_game(void)
{
// randomize (we can assume it takes random time before the user switches to the Snake mode)
srand(SysTick->VAL);
// Erase the board
memset(board, 0, sizeof(board));
// Place initial snake
tail.x = BOARD_W/2-5;
tail.y = BOARD_H/2;
head.x = tail.x + 4;
head.y = tail.y;
for (int x = tail.x; x < head.x; x++) {
board[tail.y][x].type = CELL_BODY;
}
place_food();
}
static void show_board(void)
{
dmtx_clear(dmtx);
for (int x = 0; x < BOARD_W; x++) {
for (int y = 0; y < BOARD_H; y++) {
Cell *cell = cell_at_xy(x, y);
bool set = 0;
switch (cell->type) {
case CELL_EMPTY: set = 0; break;
case CELL_BODY: set = body_pwm_on; break;
case CELL_FOOD:
dbg("Food found @ [%d, %d]", x, y);
set = food_pwm_on;
break;
case CELL_WALL: set = wall_pwm_on; break;
}
if (x == head.x && y == head.y) set = head_pwm_on;
dmtx_set(dmtx, x, y, set);
}
}
dmtx_show(dmtx);
}
void mode_snake_init(void)
{
//
}
void mode_snake_start(void)
{
//
new_game();
show_board();
}
void mode_snake_stop(void)

Loading…
Cancel
Save