关注
HarmonyOS技术社区
,回复
【鸿蒙】
送
小米小爱音箱mini
(数量不多,先到先得)
,还可以
免费下载
鸿蒙
入门资料
!
👇
扫码
立刻关注
👇
专注开源技术,共建鸿蒙生态
俄罗斯方块相信大家都玩过,首先把场景分成可移动部分、和固定部分,如下图:
unsigned short data_blk[16]; //游戏固定部分
unsigned short data_act[4]; //游戏移动部分
unsigned char display_blk_data[53] = {0x40,0xff
,0x55}; //游戏场景部分用于显示
unsigned char display_nst_data[17] = {0x40}; //游戏显示将出场的下一个方块
unsigned char data_nst; //下一个方块的内容
unsigned int score = 0; //得分
unsigned int delay = 100000; //下降延时控制速度
char row_act = -1; //活动方块所在行数
hi_i2c_data display_blk; //用于显示
hi_i2c_data display_nst; //用于显示
固定场景部分大小为 16x12,用 16 个无符号 short(16 位)型表示,仅用到低 12 位。
可移动部分大小为 4x12,用 4 个无符号 short(16 位)型表示,仅用到低 12 位。
所有的方块(19 种)有预定义为 block[19][4],下一个预告用一个无符号 char 型(0-18)表示 19 个其中的一个。
通过 row_act(活动方块所在行数)控制活动方块向下移动。
void display(void)
{
//show the canvas
unsigned short temp;
for(unsigned char i=0;i<8;++i)
{
for(unsigned char j=0;j<12;++j)
{
for(unsigned char k=0;k<4;++k)
{
display_blk_data[3+j*4+k] = 0x00;
temp = i*2>=row_act && i*24 ? data_blk[i*2]|data_act[i*2-row_act] : data_blk[i*2];
display_blk_data[3+j*4+k] |= temp&1<0x00;
temp = i*2+1>=row_act && i*23 ? data_blk[i*2+1]|data_act[i*2+1-row_act] : data_blk[i*2+1];
display_blk_data[3+j*4+k] |= temp&1<4 : 0x00;
}
}
oled_write_data(0, i, &display_blk);
}
//show the nest block
for(unsigned
char i=0;i<2;++i)
{
for(unsigned char j=0;j<4;++j)
{
for(unsigned char k=0;k<4;++k)
{
display_nst_data[j*4+k+1] = 0;
display_nst_data[j*4+k+1] |= block[data_nst][i*2]&0x10<0x00;
display_nst_data[j*4+k+1] |= block[data_nst][i*2+1]&0x10<4 : 0x00;
}
}
oled_write_data(64, i+1, &display_nst);
}
//show the score
oled_write_num(64, 7, score, 0);
}
显示函数由三部分组成:
游戏场景、下一块预告、分数。
重点介绍一下游戏场景部分:
最外层 i 循环共 8 次,每次显示 16 行中的两行。
第二层 j 循环共 12 次,每次处理一行中的一个像素。
第三层 k 循环把第个游戏像素换算成用于显示的 4x4 个像素:
temp = i*2>=row_act && i*24 ? data_blk[i*2]|data_act[i*2-row_act] : data_blk[i*2];
temp = 行数遇到可移动部分?背景+前景:背景。
display_blk_data[3+j*4+k] |= temp&1<
用于显示的像素数据 |= 显性像素?img 中的一列:不显示。
下一块预告部分与上面类似,相信能举一反三的理解一下。
再简单介绍一下显示分数的部分“void oled_write_num(hi_u8 x,hi_u8 y,unsigned int n,hi_bool zero)"。
x y 是要显示的数值所在的坐标,n 是要显示的数值,zero 是否显示前面的 0:
void oled_write_num(hi_u8 x, hi_u8 y, unsigned int n, hi_bool zero)
{
unsigned int number = n;
unsigned char str_num[9];
for(unsigned char i=0;i<8;++i)
{
str_num[7-i] = num[number%10];
number /= 10;
}
str_num[8] = 0;
if(zero)
{
oled_write_string_57(x, y, (hi_u8 *)str_num);
}
else
{
hi_u8 *p = str_num;
for(;*p=='0';++p);
oled_write_string_57(x, y, p);
}
}
这部分比较简单相信大家都能理解,把 int 型按位转换成字符串显示,如果去除前面的 0 直接将字符串的起始地址向后移动,直到有非 0 数字。
如果想仔细研究显示原理请下载附件显示驱动芯片数据手册。
void block_left(void)
{
//限制移动代码
//move to right on screen left