Add new/better snake.c from git://github.com/MascHman/r0ket.git
This commit is contained in:
parent
44f09ef804
commit
63f5536ccf
|
@ -186,6 +186,9 @@ void m_choose(){
|
||||||
case('r'):
|
case('r'):
|
||||||
strcpy(p,"r0type");
|
strcpy(p,"r0type");
|
||||||
break;
|
break;
|
||||||
|
case('s'):
|
||||||
|
strcpy(p,"Snake");
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
p[0]=*mm;
|
p[0]=*mm;
|
||||||
|
@ -233,6 +236,9 @@ void m_choose(){
|
||||||
case('r'):
|
case('r'):
|
||||||
strcpy(p,"r0type");
|
strcpy(p,"r0type");
|
||||||
break;
|
break;
|
||||||
|
case('s'):
|
||||||
|
strcpy(p,"Snake");
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
if(tmm[i]>='a' && tmm[i]<='z'){
|
if(tmm[i]>='a' && tmm[i]<='z'){
|
||||||
|
|
|
@ -0,0 +1,322 @@
|
||||||
|
/*
|
||||||
|
* snake
|
||||||
|
********
|
||||||
|
* a snake clone for the r0ket
|
||||||
|
* created by Flori4n (DrivenHoliday) & MascH (CCCHB tent)
|
||||||
|
***************************************/
|
||||||
|
|
||||||
|
#include <sysinit.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "basic/basic.h"
|
||||||
|
#include "basic/config.h"
|
||||||
|
#include "basic/random.h"
|
||||||
|
#include "lcd/render.h"
|
||||||
|
#include "lcd/display.h"
|
||||||
|
#include "lcd/fonts.h"
|
||||||
|
#include "lcd/fonts/invaders.h"
|
||||||
|
//#Include "lcd/lcd.h"
|
||||||
|
//#include "lcd/print.h"
|
||||||
|
#include "funk/mesh.h"
|
||||||
|
#include "usetable.h"
|
||||||
|
|
||||||
|
#define MAX_SNAKE_LEN (40)
|
||||||
|
#define SNAKE_DIM (3)
|
||||||
|
#define MIN_SPEED (25)
|
||||||
|
#define MAX_SPEED (3)
|
||||||
|
#define MIN_X 2
|
||||||
|
#define MAX_X (RESX-3)
|
||||||
|
#define MIN_Y 8
|
||||||
|
#define MAX_Y (RESY-2)
|
||||||
|
#define SIZE_X ((MAX_X-MIN_X)/SNAKE_DIM)
|
||||||
|
#define SIZE_Y ((MAX_Y-MIN_Y)/SNAKE_DIM)
|
||||||
|
|
||||||
|
#define RIGHT 0
|
||||||
|
#define LEFT 2
|
||||||
|
#define UP 3
|
||||||
|
#define DOWN 1
|
||||||
|
|
||||||
|
struct pos_s {
|
||||||
|
int x,y;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct snake_s {
|
||||||
|
struct pos_s *tail;
|
||||||
|
int len, dir, speed, t_start;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void reset();
|
||||||
|
static void next_level();
|
||||||
|
static void draw_block();
|
||||||
|
static void handle_input();
|
||||||
|
static void death_anim();
|
||||||
|
static struct pos_s getFood(void);
|
||||||
|
static int hitWall();
|
||||||
|
static int hitFood();
|
||||||
|
static int hitSelf();
|
||||||
|
static int showHighscore();
|
||||||
|
|
||||||
|
int points = 0;
|
||||||
|
struct snake_s snake = { NULL, 3, 0, MIN_SPEED, 2};
|
||||||
|
struct pos_s food;
|
||||||
|
|
||||||
|
void ram(void)
|
||||||
|
{
|
||||||
|
int c=0, pos=0,del=0;
|
||||||
|
|
||||||
|
struct pos_s tail[MAX_SNAKE_LEN];
|
||||||
|
snake.tail = tail;
|
||||||
|
|
||||||
|
// initially reset everything
|
||||||
|
reset();
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if(!(++c % snake.speed)) {
|
||||||
|
handle_input();
|
||||||
|
|
||||||
|
pos = (snake.t_start+1) % MAX_SNAKE_LEN;
|
||||||
|
snake.tail[pos].x = snake.tail[snake.t_start].x;
|
||||||
|
snake.tail[pos].y = snake.tail[snake.t_start].y;
|
||||||
|
|
||||||
|
if(snake.dir == 0)
|
||||||
|
snake.tail[pos].x++;
|
||||||
|
else if(snake.dir == 1)
|
||||||
|
snake.tail[pos].y++;
|
||||||
|
else if(snake.dir == 2)
|
||||||
|
snake.tail[pos].x--;
|
||||||
|
else if(snake.dir == 3)
|
||||||
|
snake.tail[pos].y--;
|
||||||
|
|
||||||
|
snake.t_start = pos;
|
||||||
|
|
||||||
|
if (pos < snake.len) {
|
||||||
|
del = MAX_SNAKE_LEN - (snake.len - pos);
|
||||||
|
} else
|
||||||
|
del = pos - snake.len;
|
||||||
|
|
||||||
|
// remove last, add first line
|
||||||
|
draw_block(snake.tail[del].x, snake.tail[del].y, 0);
|
||||||
|
draw_block(snake.tail[pos].x, snake.tail[pos].y, 1);
|
||||||
|
|
||||||
|
// check for obstacle hit..
|
||||||
|
if (hitWall() || hitSelf()) {
|
||||||
|
death_anim();
|
||||||
|
if (showHighscore())
|
||||||
|
break;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
else if (hitFood())
|
||||||
|
next_level();
|
||||||
|
|
||||||
|
lcdDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef SIMULATOR
|
||||||
|
delayms(50);
|
||||||
|
#else
|
||||||
|
delayms(3);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct pos_s getFood(void)
|
||||||
|
{
|
||||||
|
int i,pos;
|
||||||
|
struct pos_s res;
|
||||||
|
|
||||||
|
tryagain:
|
||||||
|
res.x = (getRandom() % (SIZE_X-1)) + 1;
|
||||||
|
res.y = (getRandom() % (SIZE_Y-3)) + 3;
|
||||||
|
|
||||||
|
for(i=0; i<snake.len; i++) {
|
||||||
|
pos = (snake.t_start < i) ? (MAX_SNAKE_LEN - (i-snake.t_start)) : (snake.t_start-i);
|
||||||
|
if (snake.tail[pos].x == res.x && snake.tail[pos].y == res.y) // no food to be spawn in snake plz
|
||||||
|
goto tryagain;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void reset()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// setup the screen
|
||||||
|
lcdClear();
|
||||||
|
for (i=MIN_X; i<MAX_X; i++) {
|
||||||
|
lcdSetPixel(i,MIN_Y,1);
|
||||||
|
lcdSetPixel(i,MAX_Y,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=MIN_Y; i<MAX_Y; i++) {
|
||||||
|
lcdSetPixel(MIN_X,i,1);
|
||||||
|
lcdSetPixel(MAX_X,i,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
snake.speed = MIN_SPEED;
|
||||||
|
snake.len = 3;
|
||||||
|
snake.dir = 0;
|
||||||
|
snake.t_start = 2;
|
||||||
|
|
||||||
|
points = 0;
|
||||||
|
|
||||||
|
// create snake in the middle of the field
|
||||||
|
snake.tail[0].x = SIZE_X/2;
|
||||||
|
snake.tail[0].y = SIZE_Y/2;
|
||||||
|
snake.tail[1].x = SIZE_X/2 +1;
|
||||||
|
snake.tail[1].y = SIZE_Y/2;
|
||||||
|
snake.tail[2].x = SIZE_X/2 +2;
|
||||||
|
snake.tail[2].y = SIZE_Y/2;
|
||||||
|
|
||||||
|
// print initail tail
|
||||||
|
draw_block(snake.tail[0].x, snake.tail[0].y, 1);
|
||||||
|
draw_block(snake.tail[1].x, snake.tail[1].y, 1);
|
||||||
|
draw_block(snake.tail[2].x, snake.tail[2].y, 1);
|
||||||
|
|
||||||
|
// switch to level one
|
||||||
|
next_level();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void draw_block(int x, int y, int set)
|
||||||
|
{
|
||||||
|
x *= SNAKE_DIM;
|
||||||
|
y *= SNAKE_DIM;
|
||||||
|
|
||||||
|
lcdSetPixel(x , y, set);
|
||||||
|
lcdSetPixel(x+1, y, set);
|
||||||
|
lcdSetPixel(x+2, y, set);
|
||||||
|
lcdSetPixel(x, y+1, set);
|
||||||
|
lcdSetPixel(x+1, y+1, set);
|
||||||
|
lcdSetPixel(x+2, y+1, set);
|
||||||
|
lcdSetPixel(x, y+2, set);
|
||||||
|
lcdSetPixel(x+1, y+2, set);
|
||||||
|
lcdSetPixel(x+2, y+2, set);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void next_level()
|
||||||
|
{
|
||||||
|
food = getFood();
|
||||||
|
draw_block( food.x, food.y, 1);
|
||||||
|
|
||||||
|
snake.len++;
|
||||||
|
snake.speed--;
|
||||||
|
DoInt(0,0,++points);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_input()
|
||||||
|
{
|
||||||
|
int key = getInputRaw(), dir_old = snake.dir;
|
||||||
|
|
||||||
|
if (key&BTN_UP && dir_old != 1)
|
||||||
|
snake.dir = 3;
|
||||||
|
else if (key&BTN_DOWN && dir_old != 3)
|
||||||
|
snake.dir = 1;
|
||||||
|
else if (key&BTN_LEFT && dir_old != 0)
|
||||||
|
snake.dir = 2;
|
||||||
|
else if (key&BTN_RIGHT && dir_old !=2)
|
||||||
|
snake.dir = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int hitWall()
|
||||||
|
{
|
||||||
|
return ( (snake.tail[snake.t_start].x*3 <= MIN_X)
|
||||||
|
|| (snake.tail[snake.t_start].x*3 >= MAX_X)
|
||||||
|
|| (snake.tail[snake.t_start].y*3 <= MIN_Y)
|
||||||
|
|| (snake.tail[snake.t_start].y*3 >= MAX_Y) ) ?
|
||||||
|
1 : 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int hitSelf()
|
||||||
|
{
|
||||||
|
int i, pos;
|
||||||
|
for (i=1; i<snake.len; i++) {
|
||||||
|
pos = (snake.t_start < i) ? (MAX_SNAKE_LEN - (i-snake.t_start)) : (snake.t_start-i);
|
||||||
|
if (snake.tail[pos].x == snake.tail[snake.t_start].x && snake.tail[pos].y == snake.tail[snake.t_start].y)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void death_anim()
|
||||||
|
{
|
||||||
|
int i,j, a=4;
|
||||||
|
|
||||||
|
while(a--) {
|
||||||
|
// lcdToggleFlag(LCD_INVERTED);
|
||||||
|
for (i=0; i<RESY; i++) {
|
||||||
|
for (j=0; j<RESX; j++) {
|
||||||
|
lcdSetPixel(j,i,!lcdGetPixel(j,i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lcdDisplay();
|
||||||
|
|
||||||
|
#ifdef SIMULATOR
|
||||||
|
delayms(5000);
|
||||||
|
#else
|
||||||
|
delayms(250);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
;// this is a stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool highscore_set(uint32_t score, char nick[]) {
|
||||||
|
MPKT * mpkt= meshGetMessage('s');
|
||||||
|
if(MO_TIME(mpkt->pkt)>score)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
MO_TIME_set(mpkt->pkt,score);
|
||||||
|
strcpy((char*)MO_BODY(mpkt->pkt),nick);
|
||||||
|
if(GLOBAL(privacy)==0){
|
||||||
|
uint32touint8p(GetUUID32(),mpkt->pkt+26);
|
||||||
|
mpkt->pkt[25]=0;
|
||||||
|
};
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t highscore_get(char nick[]){
|
||||||
|
MPKT * mpkt= meshGetMessage('s');
|
||||||
|
char * packet_nick = (char*)MO_BODY(mpkt->pkt);
|
||||||
|
// the packet crc end is already zeroed
|
||||||
|
if(MAXNICK<MESHPKTSIZE-2-6-1)
|
||||||
|
packet_nick[MAXNICK-1] = 0;
|
||||||
|
strcpy(nick, packet_nick);
|
||||||
|
return MO_TIME(mpkt->pkt);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int showHighscore()
|
||||||
|
{
|
||||||
|
int key = getInputRaw(); //throw away pending keypress
|
||||||
|
char nick[20];
|
||||||
|
uint32_t score = 0;
|
||||||
|
|
||||||
|
highscore_set(points,GLOBAL(nickname));
|
||||||
|
score = highscore_get(nick);
|
||||||
|
|
||||||
|
lcdClear();
|
||||||
|
DoString(0,RESY/2-33, " Your Score");
|
||||||
|
DoInt(RESX/2-4, RESY/2-25, points);
|
||||||
|
DoString(0,RESY/2-10, " Highscore");
|
||||||
|
DoInt(RESX/2-4, RESY/2-2, score);
|
||||||
|
DoString(0, RESY/2+18, " UP to play ");
|
||||||
|
DoString(0, RESY/2+26, "DOWN to quit ");
|
||||||
|
|
||||||
|
lcdDisplay();
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
key = getInputRaw();
|
||||||
|
if (key&BTN_DOWN) {
|
||||||
|
return 1;
|
||||||
|
} else if (key&BTN_UP) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int hitFood()
|
||||||
|
{
|
||||||
|
return ((snake.tail[snake.t_start].x == food.x) && (snake.tail[snake.t_start].y == food.y)) ? 1 : 0;
|
||||||
|
}
|
|
@ -1,194 +0,0 @@
|
||||||
#include <sysinit.h>
|
|
||||||
#include "basic/basic.h"
|
|
||||||
#include "basic/config.h"
|
|
||||||
|
|
||||||
#include "lcd/lcd.h"
|
|
||||||
#include "lcd/print.h"
|
|
||||||
#include "usetable.h"
|
|
||||||
|
|
||||||
struct elem
|
|
||||||
{
|
|
||||||
int x,y;
|
|
||||||
};
|
|
||||||
|
|
||||||
void reset(struct elem snake[],size_t *snake_size,int *dirc,
|
|
||||||
int*speed, int*points,int*point_s);
|
|
||||||
void o_rectangle (int x0, int y0, int width, int height);
|
|
||||||
struct elem rnd(void);
|
|
||||||
|
|
||||||
#define MAX_SNAKE_LEN (40)
|
|
||||||
#define SNAKE_DEM (3)
|
|
||||||
#define MIN_SPEED (25)
|
|
||||||
#define MAX_SPEED (3)
|
|
||||||
#define SIZE_X (RESX)
|
|
||||||
#define SIZE_Y (RESY)
|
|
||||||
|
|
||||||
void ram(void)
|
|
||||||
{
|
|
||||||
int inpt,dirc,c,grows = 0,dx,dy,points,point_s=1;
|
|
||||||
size_t n = 0, snake_size = 5, speed=MIN_SPEED;
|
|
||||||
struct elem snake[MAX_SNAKE_LEN], food;
|
|
||||||
char test[512]; /* scratch space */
|
|
||||||
o_init (test, sizeof(test));
|
|
||||||
|
|
||||||
reset(snake,&snake_size,&dirc,&speed,&points,&point_s);
|
|
||||||
|
|
||||||
food = rnd();
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
head:
|
|
||||||
if(!(++c % speed))
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
inpt = getInputRaw();
|
|
||||||
|
|
||||||
dx=DoString(0,0,IntToStrX(points,2));
|
|
||||||
dx=(SIZE_X-dx)/2;
|
|
||||||
if(dx<0)
|
|
||||||
dx=0;
|
|
||||||
dy=(SIZE_Y-getFontHeight())/2;
|
|
||||||
|
|
||||||
lcdFill(255);
|
|
||||||
o_rectangle(1,0,SIZE_X-2,SIZE_Y-2);
|
|
||||||
o_set_gray (0);
|
|
||||||
o_fill ();
|
|
||||||
|
|
||||||
//o_identity (); /* reset tranforms */
|
|
||||||
|
|
||||||
o_set_gray (50);
|
|
||||||
|
|
||||||
setExtFont("UBUNTU29");
|
|
||||||
|
|
||||||
lcdSetPixel(1,1,1);
|
|
||||||
DoString(dx,dy,IntToStrX(points,2));
|
|
||||||
|
|
||||||
o_set_gray (255);
|
|
||||||
|
|
||||||
|
|
||||||
for(n=0;n<snake_size;++n)
|
|
||||||
{
|
|
||||||
o_rectangle
|
|
||||||
(snake[n].x*SNAKE_DEM,snake[n].y*SNAKE_DEM,SNAKE_DEM,SNAKE_DEM); /*
|
|
||||||
fill background with black */
|
|
||||||
o_fill (); /* fill with 50% {
|
|
||||||
reset(snake,&snake_size);
|
|
||||||
goto head;
|
|
||||||
}gray */
|
|
||||||
}
|
|
||||||
o_rectangle
|
|
||||||
(food.x*SNAKE_DEM,food.y*SNAKE_DEM,SNAKE_DEM,SNAKE_DEM); /* fill
|
|
||||||
background with black */
|
|
||||||
o_fill ();
|
|
||||||
|
|
||||||
|
|
||||||
lcdDisplay();
|
|
||||||
|
|
||||||
if (inpt == BTN_UP && dirc != 1)
|
|
||||||
{
|
|
||||||
dirc = 3;
|
|
||||||
}
|
|
||||||
else if (inpt == BTN_DOWN && dirc != 3)
|
|
||||||
{
|
|
||||||
dirc = 1;
|
|
||||||
}
|
|
||||||
else if (inpt == BTN_LEFT && dirc != 0)
|
|
||||||
{
|
|
||||||
dirc = 2;
|
|
||||||
}
|
|
||||||
else if (inpt == BTN_RIGHT && dirc !=2)
|
|
||||||
{
|
|
||||||
dirc = 0;
|
|
||||||
}
|
|
||||||
//
|
|
||||||
|
|
||||||
struct elem t = snake[snake_size-1];
|
|
||||||
|
|
||||||
if(dirc == 0)
|
|
||||||
++t.x;
|
|
||||||
else if(dirc == 1)
|
|
||||||
++t.y;
|
|
||||||
else if(dirc == 2)
|
|
||||||
--t.x;
|
|
||||||
else if(dirc == 3)
|
|
||||||
--t.y;
|
|
||||||
|
|
||||||
if(t.x < 0 || t.y < 0 || t.y > SIZE_Y/SNAKE_DEM-1 ||
|
|
||||||
t.x > SIZE_X/SNAKE_DEM)
|
|
||||||
{
|
|
||||||
reset(snake,&snake_size,&dirc,&speed,&points,&point_s);
|
|
||||||
goto head;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(n=0;n<snake_size-1;++n)
|
|
||||||
{
|
|
||||||
if(snake[n].x == t.x && snake[n].y == t.y)
|
|
||||||
{
|
|
||||||
reset(snake,&snake_size,&dirc,&speed,&points,&point_s);
|
|
||||||
goto head;
|
|
||||||
}
|
|
||||||
else if(snake[n].x == food.x && snake[n].y == food.y)
|
|
||||||
{
|
|
||||||
grows = 1;
|
|
||||||
++snake_size;
|
|
||||||
++points;
|
|
||||||
if(speed > MAX_SPEED) --speed;
|
|
||||||
food = rnd();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!grows)
|
|
||||||
{
|
|
||||||
for(n=0;n<snake_size-1;++n)
|
|
||||||
{
|
|
||||||
snake[n] = snake[n+1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
grows = 0;
|
|
||||||
|
|
||||||
snake[snake_size-1] = t;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
delayms(3);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
struct elem rnd(void)
|
|
||||||
{
|
|
||||||
struct elem res;
|
|
||||||
res.x = getRandom() % (SIZE_X/SNAKE_DEM-1) +1;
|
|
||||||
res.y = getRandom() % (SIZE_Y/SNAKE_DEM-1) + 1;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset(struct elem snake[],size_t *snake_size,int *dirc,
|
|
||||||
int*speed, int*points,int* point_s)
|
|
||||||
{
|
|
||||||
size_t n = 0;
|
|
||||||
for(n=0;n<MAX_SNAKE_LEN;++n)
|
|
||||||
{ snake[n].x=5;snake[n].y=5; }
|
|
||||||
*snake_size = 5;
|
|
||||||
*dirc = 0;
|
|
||||||
*speed = MIN_SPEED;
|
|
||||||
*points=0;
|
|
||||||
*point_s=1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void o_rectangle (int x0, int y0, int width, int height)
|
|
||||||
{
|
|
||||||
o_path_new ();
|
|
||||||
o_move_to (x0, y0);
|
|
||||||
o_line_to (x0 + width, y0);
|
|
||||||
o_line_to (x0 + width, y0+height+1);
|
|
||||||
o_line_to (x0, y0+height+1);
|
|
||||||
o_close ();
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue