最近一直忙期末,好久没来论坛,今天发个论坛帖,庆祝一下本学期圆满结束。
前段时间在论坛上看有STM32的贪吃蛇,俄罗斯方块帖子,自己一直想研究研究,因为小时候真样的掌机都玩过吧,现在终于有能力一探究竟了。
,本想用Mini板子移植个程序算了,但是板子上按键不方便,于是正好手头有个5a60s2芯片,就准备做个小板子,液晶有12864,可是太笨重,
就用了5110,5110GRAM格式显示点不太好,就只有建了个BUF,可以实现点的显示,然后拓展出字符串,位图显示等,一些基本的显示没有用
BUF,程序基本是自己写的,可以用宏定义选择是否使用BUF。
板子本来计划自己用蓝油腐蚀出一块,但是期末时间有点紧,以前也没投过板,然后一时激动,就稍微改了改,发淘宝PCB打样去了,错误不足很多
,但完全能用,大家就别喷我了,,,(也没画原理图什么的,直接拿封装画的PCB,,,本来单层板就能实现,但是打样一个价,就。。。)
硬件不难,只算是最小系统加了按键,LCD,5V稳压电源,
然后重点主要放在程序上了,看到几个论坛上的帖子,里面程序有点乱,不方便移植,
我主要是将LCD驱动和游戏代码分开,实现只需移植一个画点函数,就基本可以在所有平台上移植了,同时还可以调节SNAKE蛇体node,以及游戏边框宽度
还有是否介意边界(就是撞墙不死,咬住自己才死,算是开挂了的。。。)
主要算法蛇体移动,参照了很多人的,自己也优化了一些,既然开源,大家也别在意版权了。呵呵。。
先给上个图
程序中还可以自定义关卡,升级分数等等,注释算是比较详细的,坑定会有bug?,希望指出,
另外这个板子完全可以加上蓝牙,无线模块,作为一个遥控器平台,按键的布局不算太好,只有几个接到了中断上,
反正是比手焊的漂亮点,
一共是10块,自己留两块,要是有需要的盆友,出个邮费,就送了,个人想法是把以前玩过的俄罗斯,坦克,推箱子什么的都试着一直一遍
反正自己通过这个程序,把结构体,枚举变量都熟悉了一遍
下面简单上点代码
#ifndef __SNAKE_H__
#define __SNAKE_H__
typedef unsigned char u8;
/*LCD相关宏定义*/
#define LCD_X 84 //X向 分辨率 但坐标是 0-83
#define LCD_Y 48 //Y向 分辨率 0-47
/*按键编码*/
#define LEFT 6
#define RIGHT 5
#define UP 7
#define DOWN 8
/**************************************************************************/
/*关于屏幕坐标以及游戏坐标的转换(蛇的每个节一般不会用屏幕最小点表示哈)*/
//以Node中心点为坐标点
/*此两宏定义为配置游戏显示的主要参数*/
#define Border_Pix 1//定义边界的像素宽度
#define Step_Length 3 //步长 每移动一次的距离 要以奇数点定义 1 3 5 7 ...算法原因 否则会出现特殊情况
/*此两宏定义为配置游戏显示的主要参数*/
#define Node_Length Step_Length
#define Game_X_Max (LCD_X-2*Border_Pix)/Step_Length-1 //84/3-1=26 ... 3 共27*15个可用点
#define Game_Y_Max (LCD_Y-2*Border_Pix)/Step_Length-1 //48/3-1=14 ... 3
#define OFFSET Step_Length/2 //计算坐标偏移
//经过屏幕坐标转换后剩余的无法利用的像素
/*用于游戏边界划分*/
#define Pix_Left_X (LCD_X-2*Border_Pix)%Step_Length
#define Pix_Left_Y (LCD_Y-2*Border_Pix)%Step_Length
/**************************************************************************/
/*蛇的一些宏定义*/
#define SNAKE_MAX_NODE 25 //蛇的最大长度
#define Initial_Node 6 //蛇的初始节数
#define Initial_Orientation right//蛇的初始方向
#define Initial_X 3 //蛇的初始坐标
#define Initial_Y 3
/*游戏规则的一些配置*/
#define Score_Over 3//超过此分数 升级
#define Level_Over 5//超过此等级 通关
#define SpeedAdd_PerLevel 45 //每一等级的速度增量 3*70 < 300
/*食物配置*/
#define Food_Initial_X 5 //食物的初始坐标
#define Food_Initial_Y 5
/*定义是否有边界 若定义0 则蛇接触到边界会从另一边对应位置出现 不会Dead*/
//允许穿越边界 但分数会 -1
#define border 1 //1 则介意边界
LCD部分
#ifdef USE_GRAM
void GRAM_Refresh(void);
void GRAM_Clear(uchar color);
void GRAM_DrawPoint(uchar x,uchar y,bit color);//x 0-83 y 0-47
void GRAM_DrawLine(uchar x1,uchar y1,uchar x2,uchar y2);
void GRAM_DrawRectangle(uchar x1,uchar y1,uchar x2,uchar y2);
//void GRAM_DrawCircle(uchar x0,uchar y0,uchar r);
//void GRAM_Fill(uchar x1,uchar y1,uchar x2,uchar y2,bit color);
//一下为在GRAM中实现Basic函数
void GRAM_DrawBitmap(uchar X,uchar Y,uchar *map,
uchar Pix_x,uchar Pix_y);
void GRAM_DrawChar(uchar x,uchar y,uchar c);
void GRAM_DrawStr(uchar x,uchar y,uchar *s);
void GRAM_Draw2Num(uchar x,uchar y,uchar num,uchar len);
#else
/*基本操作,不使用GRAM缓存*/
void LCD_Clear(uchar color);
void LCD_SetXY(uchar X, uchar Y);//X 0-83 Y 0-5
void LCD_ShowChar(uchar c);
void LCD_ShowNum(uchar x,uchar y,uchar num);//显示单个数字0-9
void LCD_Show2Num(uchar x,uchar y,uchar num,uchar len);
void LCD_ShowStr(uchar X,uchar Y,char *s);
void LCD_ShowBitmap(uchar X,uchar Y,uchar *map,
uchar Pix_x,uchar Pix_y);
void LCD_WriteByte(uchar dat, uchar dc);
#endif/*USE_GRAM*/
下面是工程文件,Keil4的,
视频
按键部分稍有问题,暂时是在循环中扫描,灵敏度会受贪吃蛇速度影响
|