从硬件的底层开始,构建一个FlappyBird游戏
2017-07-01 22:14
330 查看
从硬件的底层开始,构建一个FlappyBird游戏
看了网上的很多FlappyBird的代码,大都是基于操作系统下的开发。近期学校的短学期课程中发了一个OLED显示屏,于是我花了一点时间设计了一个简易FlappyBird游戏,能在裸机上跑,最后大致的效果还行吧,下面介绍一下整个设计流程。
首先我们要知道FlappyBird这个游戏中最关键的两个对象:
{
1). 小鸟(Bird)
2). 水管(Pipe)
}
他们的共同特点是都是屏幕上的图像,所以我们可以把小鸟和水管看作为同一个类,而针对图像我们可以简单的提取出两个简单的要素:
{
1). 图像的中心坐标
2). 图像的边界
}
我们把小鸟和水管都视为简单的矩形,于是我们定义一下一个结构体类型:
typedef struct{
uinsigned char px;//position
uinsigned char py;
uinsigned char ox;//offset
uinsigned char oy;
}OBJ_t;
其中px和py表示矩形的中心点坐标,ox和oy表示矩形的边界距中心点的偏移量
因为水管是成对出现的,我们不妨把上下两个水管视为一体,用ox和oy表示水管中间的空隙。
因为一个屏幕中最多只会同时存在一只小鸟和两只(两对)水管,
所以我们定义以下三个变量:
OBJ_t Bird, Pipe_New, Pipe_Old;
由于水管是一直向左移动,当旧的水管移动到屏幕的左边缘时,便会消失,同时屏幕的右边缘又会生成一个新的水管。小鸟是上下移动,按下按键时小鸟上升一定格数,否则小鸟会下降一定的格数。
分析完这些,我们开始正式讲解程序
首先我们需要底层来提供OLED的接口函数:
1.OLED清屏函数,
2.OLED画框函数,
3.OLED缓存刷新函数
这里要说一下缓存刷新函数,我们一般操作OLED都是屏幕上哪些地方要改动就立刻通过总线向OLED发送数据
这样确实很方便,但是当我们写一个游戏是,变的地方太多了,如果我们该一点写一点改一点,操作起来很麻烦,而且我们不知道同一时刻OLED的屏幕上的数据,怎么去判断小鸟是否和水管相撞呢。
所以我们就在内存里分配了一些空间用来放OLED的屏幕数据(就是显存),当While(1)的循环每执行一遍,就一次性把显存里的数据发送到OLED,或者我们打开一个定时器,每隔一段时间刷新一次缓存。
void FlappyBird(void)
{
OLED_Clear();//清屏
BirdCreate();//创建一个小鸟
PipeCreate();//创建一个水管
while(1)
{
if(小鸟死亡)
{
break;
}
else
{
if(旧的水管没有到达屏幕边界)
{
//移动旧水管
if(屏幕中有两个水管)
{
//移动新水管
}
if(旧水管到了屏幕中央)
{
//用于统计水管数量的变量加一
//创建一个新的水管
}
}
else
{
//消除旧水管
}
KeyScanHandle();//扫描按键
if(没有按键按下)
{
if(RiseCnt == 0)//如果小鸟上升的计数值为零
{
BirdDown();//小鸟下降
}
else//否则小鸟上升,同时上升的计数值加一
{
RiseCnt--;
BirdRise();
}
}
else if(有按键按下)
{
BirdRise();//小鸟立刻上升
RiseCnt = 10;//上升的计数值为10
}
Delay_ms(15);//延时一段时间按,用来调节游戏速度
}
}
OLED_Clear();
}
大致思路就是这样,这里附上整个工程(FlappyBird()只是这个工程里的一小部分),代码写的比较仓促,结构上会有一些不同,仅供参考。
http://download.csdn.net/detail/chenqt123/9886370
看了网上的很多FlappyBird的代码,大都是基于操作系统下的开发。近期学校的短学期课程中发了一个OLED显示屏,于是我花了一点时间设计了一个简易FlappyBird游戏,能在裸机上跑,最后大致的效果还行吧,下面介绍一下整个设计流程。
首先我们要知道FlappyBird这个游戏中最关键的两个对象:
{
1). 小鸟(Bird)
2). 水管(Pipe)
}
他们的共同特点是都是屏幕上的图像,所以我们可以把小鸟和水管看作为同一个类,而针对图像我们可以简单的提取出两个简单的要素:
{
1). 图像的中心坐标
2). 图像的边界
}
我们把小鸟和水管都视为简单的矩形,于是我们定义一下一个结构体类型:
typedef struct{
uinsigned char px;//position
uinsigned char py;
uinsigned char ox;//offset
uinsigned char oy;
}OBJ_t;
其中px和py表示矩形的中心点坐标,ox和oy表示矩形的边界距中心点的偏移量
因为水管是成对出现的,我们不妨把上下两个水管视为一体,用ox和oy表示水管中间的空隙。
因为一个屏幕中最多只会同时存在一只小鸟和两只(两对)水管,
所以我们定义以下三个变量:
OBJ_t Bird, Pipe_New, Pipe_Old;
由于水管是一直向左移动,当旧的水管移动到屏幕的左边缘时,便会消失,同时屏幕的右边缘又会生成一个新的水管。小鸟是上下移动,按下按键时小鸟上升一定格数,否则小鸟会下降一定的格数。
分析完这些,我们开始正式讲解程序
首先我们需要底层来提供OLED的接口函数:
1.OLED清屏函数,
2.OLED画框函数,
3.OLED缓存刷新函数
这里要说一下缓存刷新函数,我们一般操作OLED都是屏幕上哪些地方要改动就立刻通过总线向OLED发送数据
这样确实很方便,但是当我们写一个游戏是,变的地方太多了,如果我们该一点写一点改一点,操作起来很麻烦,而且我们不知道同一时刻OLED的屏幕上的数据,怎么去判断小鸟是否和水管相撞呢。
所以我们就在内存里分配了一些空间用来放OLED的屏幕数据(就是显存),当While(1)的循环每执行一遍,就一次性把显存里的数据发送到OLED,或者我们打开一个定时器,每隔一段时间刷新一次缓存。
void FlappyBird(void)
{
OLED_Clear();//清屏
BirdCreate();//创建一个小鸟
PipeCreate();//创建一个水管
while(1)
{
if(小鸟死亡)
{
break;
}
else
{
if(旧的水管没有到达屏幕边界)
{
//移动旧水管
if(屏幕中有两个水管)
{
//移动新水管
}
if(旧水管到了屏幕中央)
{
//用于统计水管数量的变量加一
//创建一个新的水管
}
}
else
{
//消除旧水管
}
KeyScanHandle();//扫描按键
if(没有按键按下)
{
if(RiseCnt == 0)//如果小鸟上升的计数值为零
{
BirdDown();//小鸟下降
}
else//否则小鸟上升,同时上升的计数值加一
{
RiseCnt--;
BirdRise();
}
}
else if(有按键按下)
{
BirdRise();//小鸟立刻上升
RiseCnt = 10;//上升的计数值为10
}
Delay_ms(15);//延时一段时间按,用来调节游戏速度
}
}
OLED_Clear();
}
大致思路就是这样,这里附上整个工程(FlappyBird()只是这个工程里的一小部分),代码写的比较仓促,结构上会有一些不同,仅供参考。
http://download.csdn.net/detail/chenqt123/9886370
相关文章推荐
- 构建一个J2ME游戏:从GameCanvas类开始
- Android学习笔记(9)-开始做一个数独游戏[上]
- Android学习笔记(11)-开始做一个数独游戏[下]
- 分享一个帮助你快速构建HTML5游戏的javascript类库 - CreateJS
- 使用Box2d和cocos2d-x从头开始制作一个弹弓类游戏系列教材的第二部分
- (2)开始构建:一个基本的应用--ZF2官方教程译文
- 从头开始构建一个HTML电子邮件模板
- 从头开始构建一个web即时通讯系统 - 基础 - web即时通讯系统的四种实现
- 分享一个帮助你快速构建HTML5游戏的javascript类库 - CreateJS
- 报数游戏 有n个孩子站成一圈,从第一个孩子开始顺时针方向报数,报到3的人出列,下一个人继续从1报数, 直到最后剩下一个孩子为止。问剩下第几个孩子。
- Android学习笔记(12)-开始做一个数独游戏[补充]
- Android学习笔记(11)-开始做一个数独游戏[下]
- Android学习笔记(10)-开始做一个数独游戏[中]
- 从头开始构建一个嵌入式 Linux 发行版
- LGame(Android及J2SE游戏引擎)入门示例——如何构建一个游戏
- Android学习笔记(10)-开始做一个数独游戏[中]
- Android学习笔记(9)-开始做一个数独游戏[上]
- Silverlight C# 游戏开发:Flyer07做一个有开始的游戏
- 从头开始构建一个嵌入式 Linux 发行版
- flash socket 从头开始构建一个web即时通讯系统 - 客户端