一:前期准备
用到的硬件材料Arduino Mega2560 + LCD4884 Joystick Shiled
屏幕分辨率为48*84
软件平台 Arduino IDE, 需要用到的库 U8glib +MsTime2
二:设计思路
1:游戏整体界面
标准的俄罗斯方块为行宽为10,列高为20,结合屏幕大小每个最小单位点设为2*2像素,共计七种方块,19种形状,使用[10][20]的二维数组存放方块位置信息,需要显示则将相应位置的数组值改为1,空白则为0。并在左侧显示下一个方块形状,右侧显示当前分数和等级
游戏界面如图所示
2:方块的产生、变换和移动
我没有采用使用整体存放方块图形信息的方法,因为不知道怎么使用U8glib库旋转单个图形,采用的是一种比较笨的方法。
每一种方块选取一个中心点,围绕这个中心点来绘制方块,移动的时候也是直接移动中心点然后重新在中心点绘制方块,总共有16种方块图形这里选取其中一种来做例子说明
(1) 方块的产生
例如Z形方块
选取B为中心点,只需要获取B的坐标信息,设为(x,y)那么其他几个方块的坐标也能相应求出来,然后将二维数组中的这几个对应值设为1,循环绘制的时候就能显示出方块图形了
(2)方块的变换和移动
我们想要控制方块旋转的时候就需要重新获取方块生成的方式
在方块移动和变换的时候在这之前都需要先在二维数组中清空原有的方块信息,然后重新按照新的生成方式写入数组里面
(3):方块检测
每一次在移动和和变换的过程中还需要判断是否能够移动和变换,需要检测方块周围是否有足够的空间
检测方法如下
由于方块无法向上移动,所以上部不需要判断,我们只知道B的坐标,1-7号坐标可以根据B的坐标推断出来
当我们需要右移动的时候就需要判断 2、4、6号位置是否已有方块阻挡或者到达边界,同理下移则需判断5、7号位置
三:详细设计
1:按键检测
LCD4884 Joystick Shiled带有一个摇杆按键,并且和A0脚连接,所以读取A0引脚值即可。
void Control()
{
switchVoltage = analogRead(0);
if ( switchVoltage > 600 && switchVoltage < 800 ) //上
dir = 1 ;
else if ( switchVoltage > 180 && switchVoltage < 400 ) //下
dir = 3;
else if ( switchVoltage == 0 ) //左
dir = 4;
else if ( switchVoltage > 400 && switchVoltage < 600 ) //右
dir = 2;
else if ( switchVoltage > 0 && switchVoltage < 180 ) //确认
dir = 5;
}
为了防止按键粘连,使用了MsTime2库定时扫描
MsTimer2::set(100, Control); /*定时器中断按键的扫描*/
MsTimer2::start();
2:初始化
在游戏运行之前,初始化屏幕亮度、游戏等级、随机数种子(防止每一次方块出现次数都相同、清空数组值以及方块中心点位置,
randomSeed(analogRead(1)); /*随机产生随机数序列以免方块的顺序为固定的*/
block_num = random(1, 20); /*生成第一个方块信息
block_num_next = random(1, 20) ; /*生成第二个方块
x = 5 , y = 2;
block_state_right = 0 ;
block_state_left = 0;
block_state_down = 0;
level_now = 300;
light_value = 50; /*设置背光亮度*/
pinMode(LCD_BACKLIGHT_PIN , OUTPUT);
analogWrite(LCD_BACKLIGHT_PIN, light_value);
3:绘制游戏界面背景
显示当前等级和分数,以及下一个方块形状,游戏的等级设置的是每次自动向下移动时延时的毫秒数,move_speed越小等级越高,方块向下移动也越来越快
void interface()
{
u8g.setFont(u8g_font_timR08);
u8g.drawStr(57, 10, "Score");
u8g.drawStr(57, 30, "Grade");
u8g.drawStr(0, 10, "Next");
u8g.setPrintPos(70, 20);
/*显示分数*/
u8g.print(score);
/*显示等级*/
if ( move_speed = 3; m--)
for ( n = 0; n < 10; n++)
block[n][m] = block[n][m - 1];
}
四:结语
这个游戏是在一年前完成的,到今天很多细节忘得差不多了,只能凭借印象来大致的说明一下主要的流程和思路,代码中有很大一部分重用导致看起来很臃肿现在也懒得改了,有想折腾的可以尝试完善完善,另外其他的屏幕也是能适用的,只需要更改按键控制那个函数和u8glib那个头文件即可,但是分辨率就没办法了
源码连接,喜欢的还请赏个Star
https://github.com/FanMLei/Arduino_Games
试玩视频
http://v.youku.com/v_show/id_XMzM5NjA0NjY2OA==.html?spm=a2h3j.8428770.3416059.1
|