注:此代码只测试于正点原子stm32F407探索者,其他情况请自行修改
snake.c
//snake.c
//注:此代码只测试于正点原子F407探索者,其他情况请自行修改
#include “snake.h”
#define LEFT 1 //上下左右
#define RIGHT 2
#define UP 3
#define DOWN 4
u8 snake_pos = RIGHT; //开始时snake的运动方向
u8 key;
short snake_live = 0; //snake生命,用于判断是否游戏结束
u16 snake_x[100];
u16 snake_y[100];
u16 snake_speed; //snake速度
u16 snake_shape; //snake体型,请匹配与lcd屏的公因子
short i; //用于计数,按键间隔每 i * 10ms 为snake移动一次的时间
u16 apple_x;
u16 apple_y;
short apple = 0; //用于判断是否有apple,如若要一次显示多个apple请修改下面标注代码)=
u16 snake_length = 1; //snake长度
short m; //用于计数,等于snake的长度(即snake_length)
void snake_scan(void){ //按键获取及方向改变
key=KEY_Scan(0);
if(key){
switch(key){
case WKUP_PRES:
snake_pos = UP;
break;
case KEY0_PRES:
snake_pos = RIGHT;
break;
case KEY1_PRES:
snake_pos = DOWN;
break;
case KEY2_PRES:
snake_pos = LEFT;
break;
}
}
}
void apple_init(void){ //apple的生成及RNG的初始化
while(!apple && !RNG_Init()){
apple_x=RNG_Get_RandomRange(1,(lcddev.width - snake_shape * 2) / snake_shape / 2) * snake_shape * 2; //与lcd分辨率相适应
delay_ms(10);
apple_y=RNG_Get_RandomRange(1,(lcddev.height - snake_shape * 2) / snake_shape / 2) * snake_shape * 2; //与lcd分辨率相适应
delay_ms(10);
apple++;
for(m = snake_length;m 》= 0;m--){ //判断是否与snake重叠
if(apple_x == snake_x[m] && apple_y == snake_y[m]) {apple--;break;}
}
}
}
void snake_eat(void){ //与snake坐标相同时表明get到
if(snake_x[0] == apple_x && snake_y[0] == apple_y){
apple--;
snake_length++;
snake_x[snake_length] = snake_x[snake_length - 1]; //用数组来增加snake长度,
snake_y[snake_length] = snake_y[snake_length - 1]; //也可用链表
}
}
void snake_move(void){ //snake的移动(修改坐标实现移动)
switch(snake_pos){
case UP:snake_y[0] -= snake_shape * 2;break;
case DOWN:snake_y[0] += snake_shape * 2;break;
case LEFT:snake_x[0] -= snake_shape * 2;break;
case RIGHT:snake_x[0] += snake_shape * 2;break;
}
}
void snake_init(u16 x,u16 y,u16 speed,u16 shape){ //主函数
if(x % shape != 0) snake_x[0]=shape * 2; //略显鸡肋的判断
else snake_x[0]=x;
if(y % shape != 0) snake_y[0]=shape * 2;
else snake_y[0]=y;
snake_speed = speed;snake_shape = shape;
i = 0;
while(!snake_live){ //判断是否游戏结束
POINT_COLOR=BLACK;
snake_scan();
if(i《snake_speed){ //运动延时
delay_ms(10);
i++;
}
else{
delay_ms(10);
i = 0;
snake_eat();
snake_move();
if(snake_y[0] 《 snake_shape * 2 || snake_y[0] 》 lcddev.height - snake_shape || snake_x[0] 《 snake_shape * 2 || snake_x[0] 》 lcddev.width - snake_shape) snake_live = 1; //判断是否超出方框,因为画圆的bug,
LCD_Clear(WHITE); //如果超出则显示不全,可缩小方框来
apple_init(); //实现穿越或等我修改下画圆函数
while(snake_live) {
LCD_ShowString(lcddev.width / 2 - 40,lcddev.height / 2 - 16,200,16,16,“Game Over!”);
LCD_ShowString(lcddev.width / 2 - 100,lcddev.height / 2,200,16,16,“Press KEY0 To Play Again!”);
if(KEY_Scan(0) == KEY0_PRES) {
snake_live=0;
snake_pos = RIGHT;
if(x % shape != 0) snake_x[0]=shape * 2;
else snake_x[0]=x;
if(y % shape != 0) snake_y[0]=shape * 2;
else snake_y[0]=y;
LCD_Clear(WHITE);
}
}
if(apple 》 0){ //以下均为画图显示到lcd上
POINT_COLOR=RED;
LCD_Draw_ALLCircle(apple_x,apple_y,snake_shape);
}
POINT_COLOR=BLACK;
LCD_DrawRectangle(snake_shape - 1,snake_shape - 1,lcddev.width - snake_shape + 1,lcddev.height - snake_shape + 1);
for(m = snake_length;m 》= 0;m--) {
if(m 》 0){
snake_x[m] = snake_x[m-1];snake_y[m] = snake_y[m-1];
}
LCD_Draw_ALLCircle(snake_x[m],snake_y[m],snake_shape);
}
}
}
}
snake.h
#ifndef __SNAKE_H
#define __SNAKE_H
#include “lcd.h”
#include “key.h”
#include “delay.h”
#include “rng.h”
void snake_init(u16 x,u16 y,u16 speed,u16 shape);
#endif
main.c
#include “sys.h”
#include “delay.h”
#include “usart.h”
#include “led.h”
#include “lcd.h”
#include “snake.h”
#include “key.h”
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
delay_init(168);
uart_init(115200);
LCD_Init();
KEY_Init();
snake_init(30,30,100,20); //参数为x坐标、y坐标、延时间隔(100为1s,即10ms * 100)、体型
delay_ms(1000);
}
可能被忽视的几个头文件
注:此代码只测试于正点原子stm32F407探索者,其他情况请自行修改
snake.c
//snake.c
//注:此代码只测试于正点原子F407探索者,其他情况请自行修改
#include “snake.h”
#define LEFT 1 //上下左右
#define RIGHT 2
#define UP 3
#define DOWN 4
u8 snake_pos = RIGHT; //开始时snake的运动方向
u8 key;
short snake_live = 0; //snake生命,用于判断是否游戏结束
u16 snake_x[100];
u16 snake_y[100];
u16 snake_speed; //snake速度
u16 snake_shape; //snake体型,请匹配与lcd屏的公因子
short i; //用于计数,按键间隔每 i * 10ms 为snake移动一次的时间
u16 apple_x;
u16 apple_y;
short apple = 0; //用于判断是否有apple,如若要一次显示多个apple请修改下面标注代码)=
u16 snake_length = 1; //snake长度
short m; //用于计数,等于snake的长度(即snake_length)
void snake_scan(void){ //按键获取及方向改变
key=KEY_Scan(0);
if(key){
switch(key){
case WKUP_PRES:
snake_pos = UP;
break;
case KEY0_PRES:
snake_pos = RIGHT;
break;
case KEY1_PRES:
snake_pos = DOWN;
break;
case KEY2_PRES:
snake_pos = LEFT;
break;
}
}
}
void apple_init(void){ //apple的生成及RNG的初始化
while(!apple && !RNG_Init()){
apple_x=RNG_Get_RandomRange(1,(lcddev.width - snake_shape * 2) / snake_shape / 2) * snake_shape * 2; //与lcd分辨率相适应
delay_ms(10);
apple_y=RNG_Get_RandomRange(1,(lcddev.height - snake_shape * 2) / snake_shape / 2) * snake_shape * 2; //与lcd分辨率相适应
delay_ms(10);
apple++;
for(m = snake_length;m 》= 0;m--){ //判断是否与snake重叠
if(apple_x == snake_x[m] && apple_y == snake_y[m]) {apple--;break;}
}
}
}
void snake_eat(void){ //与snake坐标相同时表明get到
if(snake_x[0] == apple_x && snake_y[0] == apple_y){
apple--;
snake_length++;
snake_x[snake_length] = snake_x[snake_length - 1]; //用数组来增加snake长度,
snake_y[snake_length] = snake_y[snake_length - 1]; //也可用链表
}
}
void snake_move(void){ //snake的移动(修改坐标实现移动)
switch(snake_pos){
case UP:snake_y[0] -= snake_shape * 2;break;
case DOWN:snake_y[0] += snake_shape * 2;break;
case LEFT:snake_x[0] -= snake_shape * 2;break;
case RIGHT:snake_x[0] += snake_shape * 2;break;
}
}
void snake_init(u16 x,u16 y,u16 speed,u16 shape){ //主函数
if(x % shape != 0) snake_x[0]=shape * 2; //略显鸡肋的判断
else snake_x[0]=x;
if(y % shape != 0) snake_y[0]=shape * 2;
else snake_y[0]=y;
snake_speed = speed;snake_shape = shape;
i = 0;
while(!snake_live){ //判断是否游戏结束
POINT_COLOR=BLACK;
snake_scan();
if(i《snake_speed){ //运动延时
delay_ms(10);
i++;
}
else{
delay_ms(10);
i = 0;
snake_eat();
snake_move();
if(snake_y[0] 《 snake_shape * 2 || snake_y[0] 》 lcddev.height - snake_shape || snake_x[0] 《 snake_shape * 2 || snake_x[0] 》 lcddev.width - snake_shape) snake_live = 1; //判断是否超出方框,因为画圆的bug,
LCD_Clear(WHITE); //如果超出则显示不全,可缩小方框来
apple_init(); //实现穿越或等我修改下画圆函数
while(snake_live) {
LCD_ShowString(lcddev.width / 2 - 40,lcddev.height / 2 - 16,200,16,16,“Game Over!”);
LCD_ShowString(lcddev.width / 2 - 100,lcddev.height / 2,200,16,16,“Press KEY0 To Play Again!”);
if(KEY_Scan(0) == KEY0_PRES) {
snake_live=0;
snake_pos = RIGHT;
if(x % shape != 0) snake_x[0]=shape * 2;
else snake_x[0]=x;
if(y % shape != 0) snake_y[0]=shape * 2;
else snake_y[0]=y;
LCD_Clear(WHITE);
}
}
if(apple 》 0){ //以下均为画图显示到lcd上
POINT_COLOR=RED;
LCD_Draw_ALLCircle(apple_x,apple_y,snake_shape);
}
POINT_COLOR=BLACK;
LCD_DrawRectangle(snake_shape - 1,snake_shape - 1,lcddev.width - snake_shape + 1,lcddev.height - snake_shape + 1);
for(m = snake_length;m 》= 0;m--) {
if(m 》 0){
snake_x[m] = snake_x[m-1];snake_y[m] = snake_y[m-1];
}
LCD_Draw_ALLCircle(snake_x[m],snake_y[m],snake_shape);
}
}
}
}
snake.h
#ifndef __SNAKE_H
#define __SNAKE_H
#include “lcd.h”
#include “key.h”
#include “delay.h”
#include “rng.h”
void snake_init(u16 x,u16 y,u16 speed,u16 shape);
#endif
main.c
#include “sys.h”
#include “delay.h”
#include “usart.h”
#include “led.h”
#include “lcd.h”
#include “snake.h”
#include “key.h”
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
delay_init(168);
uart_init(115200);
LCD_Init();
KEY_Init();
snake_init(30,30,100,20); //参数为x坐标、y坐标、延时间隔(100为1s,即10ms * 100)、体型
delay_ms(1000);
}
可能被忽视的几个头文件
举报