基于Gamebuino设计的算盘小游戏
2.1硬件搭建
2.2软件设计
材料准备
搭建步骤
2.2.1实现功能
2.2.2功能设计
1.1技术背景
1.2实验意义
目录
一、引言
二、实验内容
三、实验结果和分析
四、试验改进
五、实验总结
目录
一、引言
1.1技术背景
Gamebuino 让玩家可以在一个小巧的设备上玩他们喜欢的像素化游戏,并学习编程来制作自己的游戏。Gamebuino 可以装在口袋里,里面有很多免费的独家游戏,电池可以持续使用一整天。一个可选的micro SD卡可以容纳更多的游戏,玩家可以在几秒钟内切换游戏。你可以在这个平台上DIY自己的项目。
1.2实验意义
通过参考手册、实例游戏代码的分析,到搭建自己的游戏机创新一个小游戏。在实验过程中锻炼了我们的自学能力和学行合一的实验精神。
二、实验内容
2.1硬件搭建
材料准备
单片机:ATmega328P,ArduinoUNO
显示屏:Nokia5110液晶屏,84*48
SD卡:2G存储容量一下
按键:7个
面包板:2个,8.5cm*5.5cm
杜邦线若干
USBtinyISP下载线一根
SD卡模块 CH376S
只准备了实现最基础功能的元器件,其他元器件可以参见官方说明Hardware.
搭建步骤
将下载好的gamebuino_boot文件复制到C:\arduino\hardware\arduino\avr\bootloaders目录下
BootLoader烧写:在正常运行的情况下,通过USB虚拟COM端口对Gamebuino进行编程,选择设备为“Arduino UNO”。但是,如果希望使用外部硬件程序(例如,另一个Arduino)来编写它或上传引导加载程序,那么必须在Arduino包中编辑board .txt文件(C:\arduino\hardware\arduino\boards.txt)在后面加上。
gamebuino.name=Gamebuino gamebuino.upload.protocol=arduino gamebuino.upload.maximum_size=30592gamebuino.upload.speed=115200gamebuino.bootloader.low_fuses=0xffgamebuino.bootloader.high_fuses=0xdagamebuino.bootloader.extended_fuses=0x05gamebuino.bootloader.path=gamebuino_boot gamebuino.bootloader.file=gamebuino_boot.hex gamebuino.bootloader.unlock_bits=0x3Fgamebuino.bootloader.lock_bits=0x0Fgamebuino.build.mcu=atmega328p gamebuino.build.f_cpu=16000000Lgamebuino.build.core=arduino gamebuino.build.variant=standard
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
USBTinyISP插口插入板子上ICSP
打开ardunio IDE ,工具->开发板->GameBuino,工具->编译器->USBtinyISP,烧入引导程序
当时不知道为什么报错,但是最后还是运行成功了,至今不明白什么意思。
按照官方原理图慢慢连线
最后把官网下载的小游戏导入SD卡,硬件部分就算成功了
2.2软件设计
2.2.1实现功能
尽管你掌握了算盘的原理打算盘就会是一件很简单的事,但是现在很多人都不会打算盘。这个小游戏实现的功能即玩家输入数字,可以自动在屏幕上模拟出该数字在算盘上应该如何表示。
2.2.2功能设计
(1)整体屏幕
左边部分是算盘界面,用drawmap()函数实现,右边部分是ResetDisplay()函数实现的数字显示界面。(2)drawmap()函数由gb.display.drawFastVLine和gb.display.drawFastHLine画出的框架和drawmap()函数画出的算珠组成。前两个函数都是库中自带的画直线功能在此不再赘述。因为屏幕大小原因,所以算盘只设置了个十百千万五位数。算盘是一个43*43的正方形,由5条垂直直线和一条水平分割线组成(刨除了周围的四边),垂直线的x坐标起始为5步长为10这样一个设置,每一个算珠的大小是5*4,上下两个相邻算珠的y坐标差值是6(因为一列总共6颗珠子再加上2个空位即有8位,48/8=6)。所以可以算出珠子的(x,y)坐标表达式。
void Drawbead(){ //画算珠 //ResetDisplay(); for(int x=0;x<40;x++){if(gameState.boardabacus[x]==1){ //值有效时才画珠gb.display.drawBitmap(((x)%5)*10+3,ceil((x+1)/5.0)*6-5,zhuzi); //(x,y,图形) } }}1234567812345678
(3)ResetDisplay()函数参见上一篇Gamebuino小游戏2048代码loop部分分析博客。
(4)对用户输入的数字进行接收和拆解。Gamebuino中有gb.keyboard()函数可以让用户输入数字,但是它返回的值是一个char类型的数组。用atoi函数将输入数据转换成一个int型的变量,再写一个 split()函数将整形变量按个十百千万位拆分入数组。这里要补充说明一下,之前建立了一个gamestate的结构体有三个比较重要的元素。
extern const int SIZE=40;typedef struct Gamestate{ int boardabacus[SIZE]; //储存算盘上40个位置的状态,值为1表示这里有算珠,0则表示空 char text[4]; //gb.keyboard()后得到的char数组 int split[5]; //拆分成个十百千万存入该数组}GameState;
1
2
3
4
5
6
1
2
3
4
5
6
(5)对数据进行更新和新排布,输入的新数值要先转换为 boardabacus[]数组数值的更新,再重新drawmap()实现画面更新。数据的更新用到了 arrange()和below()两个函数,分别对算盘分割线上下进行排序。
void arrange(){ //重新排序算盘矩阵 for(int i=0;i<5;i++){if(gameState.split[i]>=5){ //分别读取个十百千万位数字与5比大小 gameState.boardabacus[14-i]=1; //算盘的第三行对应列的珠子值为1 gameState.boardabacus[9-i]=0; //算盘的第二行对应列的珠子值为0 below(gameState.split[i],i); //算盘分割线下的珠子的排序}else{ below(gameState.split[i],i);} }}void below(int x,int line){ //下部分算盘的排序,x是该位数数值,line是第几列 int cup; int k=1; cup=x%5; //计算分割线下方有几颗珠子需要移动 for(int j=0;j<cup;j++){k=19+j*5; //跳转到对应行gameState.boardabacus[k-line]=1; //上面一行对应列值为1gameState.boardabacus[k+5-line]=0; //原来所在的那一行的对应列值为0 }}1234567891011121314151617181920212212345678910111213141516171819202122
三、实验结果和分析
在官方的学习网站里找到一个网页版的模拟器,在里面运行.hex和在实物上运行效果一致。
四、试验改进
作为一款小游戏它实在没有可玩性,汇报完后根据老师的指导建议决定加上延时效果,这样显示就是每拨动一颗算珠一个效果,演示性更强。(后续改动再更新)
五、实验总结
这次实验从硬件开始,去慢慢了解每个模块的驱动和各个功能,再到将它们组合到一起并录入游戏进行测试。从分析2048小游戏的代码,到逐行构建自己的小游戏都是一个摸石头过河的状态,期间历尽无数失败,细化问题到每一个点再去检测错误,都是对自我能力的新考验和锻炼。也培养了自己动手的热情,结合理论的实操能力的提升。