一 大致过程
1、初始化地图、蛇身
2、食物随机产生(在keil5上的如果单纯调用随机函数那么它每次随机的位置是固定的,比如说第一次产生的事物在(x1,y1)处,第二次在(x2,y2)处,程序再次运行,第一次仍然在(x1,y1),所以我就用了adc采样值作为随机种子)
3、蛇的移动(按键)
4、存活条件设置
二 程序设计
蛇身、食物的产生用单链表结构
struct snack
{
char x;
char y;
struct snack*next;
}*head,*food,*pnew;
蛇初始化
屏幕分辨率是800×600,如果将一个点当作一个坐标那么蛇在运行吃食物时,吃没吃到有点难分的清楚,所以我就用5×5的块作为一个节点
void Init_snack()
{
struct snack* ptail;
char i;
ptail=(struct snack*)malloc(sizeof(struct snack));
ptail->x=50;
ptail->y=15;
ptail->next=NULL;
for(i=1;i<=3;i++) //蛇身长度为3
{
head=(struct snack*)malloc(sizeof(struct snack));
head->next=ptail;
head->x=50+i*5; //5*5作为一个结点
head->y=15;
ptail=head;
}
while(ptail!=NULL)
{
LCD_Fill(ptail->x,ptail->y,ptail->x+5,ptail->y+5,RED);
ptail=ptail->next;
}
}
食物随机产生在地图里
void rand_food()
{ u8 seed; //设置随机种子
struct snack*food_tb=(struct snack*)malloc(sizeof(struct snack));
if(food!=NULL)
{
return;
}
seed=(u8)Get_Adc_Average(ADC_Channel_5,20)<<5; //adc采样值作为随机种子
srand(seed);
food_tb->x=(rand()%37)*5+5; //食物坐标产生在地图里
food_tb->y=(rand()%39)*5;
pnew=head;
while(pnew!=NULL)
{
if(food_tb->x==pnew->x&&food_tb->y==pnew->y)
{
free(food_tb);
rand_food();
break;
}
pnew=pnew->next;
}
food=food_tb;
LCD_Fill(food->x,food->y,food->x+5,food->y+5,RED);
}
整体程序
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "lcd.h"
#include "adc.h"
#include "key.h"
#include <stdlib.h>
#include <time.h>
u8 ch=1,direction;
static int count;
void draw(char x,char y);
struct snack
{
char x;
char y;
struct snack*next;
}*head,*food,*pnew;
static int aa[]={0,33808,63488,1024,31,63634,65152,33792,65472}; //É«²Ê±ä»¯
void Init_snack()
{
struct snack* ptail;
char i;
ptail=(struct snack*)malloc(sizeof(struct snack));
ptail->x=50;
ptail->y=15;
ptail->next=NULL;
for(i=1;i<=3;i++) //ÉßÉí³¤¶ÈΪ3£»
{
head=(struct snack*)malloc(sizeof(struct snack));
head->next=ptail;
head->x=50+i*5;
head->y=15;
ptail=head;
}
while(ptail!=NULL)
{
LCD_Fill(ptail->x,ptail->y,ptail->x+5,ptail->y+5,RED);
ptail=ptail->next;
}
}
void Init_map() //³õʼ»¯µØͼ
{
u8 i;
POINT_COLOR=BLACK;
LCD_DrawRectangle(1,1,204,204);
LCD_DrawRectangle(2,2,203,203);
LCD_DrawRectangle(3,3,202,202);
LCD_DrawRectangle(4,4,201,201);
LCD_DrawRectangle(5,5,200,200);
}
void rand_food()
{ u8 seed;
struct snack*food_tb=(struct snack*)malloc(sizeof(struct snack));
if(food!=NULL)
{
return;
}
seed=(u8)Get_Adc_Average(ADC_Channel_5,20)<<5; //adc²ÉÑùÖµ×÷ΪËæ»úÖÖ×Ó
srand(seed);
food_tb->x=(rand()%37)*5+5;
food_tb->y=(rand()%39)*5;
pnew=head;
while(pnew!=NULL)
{
if(food_tb->x==pnew->x&&food_tb->y==pnew->y)
{
free(food_tb);
rand_food();
break;
}
pnew=pnew->next;
}
food=food_tb;
LCD_Fill(food->x,food->y,food->x+5,food->y+5,RED);
}
void snack_move()
{
u8 key;
struct snack*nextnode;
nextnode=(struct snack*)malloc(sizeof(struct snack));
key=KEY_Scan(1); //通过按键来移动蛇
if(key)
ch=key;
if (ch==4 && direction != 2) //·为了防止蛇能以相反的方向移动
{
direction = 4;
}
else if (ch==2 && direction != 4)
{
direction = 2;
}
else if (ch==3 && direction !=1)
{
direction = 3;
}
else if (ch==1 && direction != 3)
{
direction = 1;
}
switch(direction)
{
case 4:
{
nextnode->x=head->x;
nextnode->y=head->y-5; //向上移动
break;
}
case 2:
{
nextnode->x=head->x;
nextnode->y=head->y+5; //向下移动
break;
}
case 3:
{
nextnode->x=head->x-5; //向左移动
nextnode->y=head->y;
break;
}
case 1:
{
nextnode->x=head->x+5; //向右移动
nextnode->y=head->y;
break;
}
}
nextnode->next=head;
head=nextnode;
pnew=head;
if(nextnode->x==food->x&&nextnode->y==food->y)
{
while(pnew!=NULL)
{
LCD_Fill(pnew->x,pnew->y,pnew->x+5,pnew->y+5,aa[rand()%8]);
pnew=pnew->next;
}
free(food);
food=NULL;
rand_food();
count++;
}
else
{
while(pnew->next->next!=NULL)
{
LCD_Fill(pnew->x,pnew->y,pnew->x+5,pnew->y+5,aa[rand()%8]);
pnew=pnew->next;
}
LCD_Fill(pnew->next->x,pnew->next->y,pnew->next->x+5,pnew->next->y+5,GRAYBLUE );//µ¹ÊýµÚ¶þ¸ö±ðÍüÁË
free(pnew->next);
pnew->next=NULL;
}
}
u8 alive() //设置存活条件
{
struct snack *self=head->next;
while(self!=NULL)
{
if(self->x==head->x&&self->y==head->y)
{
return 0;
}
if(head->x==5||head->x==200||head->y==5||head->y==200)
return 0;
self=self->next;
}
return 1;
}
int main(void)
{
u16 adcx,apple,bird;
u8 key,flag;
float temp,temp2,res0,resx,t;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
delay_init(168);
uart_init(115200);
LED_Init();
LCD_Init();
Adc_Init();
KEY_Init();
LCD_Clear(GREEN);
LCD_Fill(5,5,200,200,GRAYBLUE);
LCD_Fill(205,0,400,205,LGRAY);
Init_map();
Init_snack();
rand_food();
while(1)
{
flag=alive();
LCD_ShowString(252,50,48,20,16,"SCORE:");
LCD_ShowString(252,90,48,20,16,"LEVEL:");
switch(count)
{
case 0:
{
POINT_COLOR=aa[rand()%8];
LCD_ShowString(300,90,120,20,16,"SLOW");
break;
}
case 1:
{
POINT_COLOR=aa[rand()%8];
LCD_ShowString(300,90,80,20,16," ");
LCD_ShowString(300,90,120,20,16,"SO SO");
break;
}
case 2:
{
POINT_COLOR=aa[rand()%8];
LCD_ShowString(300,90,80,20,16," ");
LCD_ShowString(300,90,120,20,16,"SO SO");
break;
}
case 3:
{
POINT_COLOR=aa[rand()%8];
LCD_ShowString(300,90,80,20,16," ");
LCD_ShowString(300,90,120,20,16,"FAST");}
break;
case 4:
{
POINT_COLOR=aa[rand()%8];
LCD_ShowString(300,90,80,20,16," ");
LCD_ShowString(300,90,120,20,16,"VERY FAST");
break;
}
case 5:
{
POINT_COLOR=aa[rand()%8];
LCD_ShowString(300,90,80,20,16," ");
LCD_ShowString(300,90,120,20,16,"AMAZING");
break;
}
case 6:
{
POINT_COLOR=aa[rand()%8];
LCD_ShowString(300,90,80,20,16," ");
LCD_ShowString(300,90,120,20,16,"SCARY");
break;
}
case 7:
{
POINT_COLOR=aa[rand()%8];
LCD_ShowString(300,90,80,20,16," ");
LCD_ShowString(300,90,120,20,16,"MIRACLE");
break;
}
case 8:
{
POINT_COLOR=aa[rand()%8];
LCD_ShowString(300,90,80,20,16," ");
LCD_ShowString(300,90,120,20,16,"SSSSSSSSS");
break;
}
case 9:
{
POINT_COLOR=aa[rand()%8];
LCD_ShowString(300,90,80,20,16," ");
LCD_ShowString(300,90,120,20,16,"GOD");
break;
}
}
LCD_ShowNum(300,50 ,count*100,8,16);
if(flag)
{
delay_ms(50-count*5);
snack_move();
}
else
{
POINT_COLOR=RED;
LCD_ShowString(252,110,120,20,16,"GAME OVER!!!!!!");
break;
}
}
}