专家
公告
财富商城
电子网
旗下网站
首页
问题库
专栏
标签库
话题
专家
NEW
门户
发布
提问题
发文章
STM32
Tetris,移植俄罗斯方块之不定期更新篇
2019-07-20 03:55
发布
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
站内问答
/
STM32/STM8
10714
37
1762
本帖最后由 龙之谷 于 2016-1-10 13:52 编辑
一直对小游戏(贪吃蛇、俄罗斯方块等)的程序编写有着莫名的好奇与敬佩,现在手头上有硬件开发板,论坛上有坛友无私分享,自己也就找时间来学着移植玩玩。
本帖是在坛友移植好的工程基础上进行一些或调整或补充,工程来源会在第一次引用楼层贴出链接与对应楼主。
更新时间不定、更新内容不定,但若更新结束会有专门楼层提示。
Start game.....
俄罗斯方块百度链接:
俄罗斯方块链接
友情提示:
此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
37条回答
龙之谷
2019-07-21 06:39
其一,II区界面区及图形实现
一、变量部分
①.h文件
#define SHAPE_COLOR 0x0000 //图形颜 {MOD}->黑 {MOD}
#define BOXS_COLOR 0xFFFF //底板颜 {MOD}->白 {MOD}
#define WILL_COLOR 0x7D7C //边界颜 {MOD}->浅蓝 {MOD}
#define TEXT_COLOR 0x0000 //字体颜 {MOD}->黑 {MOD}
#define BPIXEL 10 //一个小方块边长的像素值
#define X_BOXS 14 //游戏底板X轴小方块个数
#define Y_BOXS 25 //游戏底板Y轴小方块个数
#define LEFT 34
#define RIGHT 194
#define DOWN 168
#define TURN 98
#define RESET 162
extern u16 BoxSR[Y_BOXS+4]; //游戏区域标志位
typedef struct
{
u16 x;
u16 y;
u16 color;
u8 CurNum; //当前图形编号
u8 NextNum;//下一个图形编号
u8 TurnNum;//翻转图形编号
u8 Move; //标志位,实现互斥
}_Shape;
extern _Shape NewShape;
typedef struct //游戏速度、级别、得分
{
u16 speed;
u8 level;
u32 score;
}_Game;
②.c文件
u16 Tetris[19]={0x0F00,0x4444,0x0660,0x4460,0x02E0,0x6220,0x0740,0x2260,0x0E20,0x6440,0x0470,0x0C60,0x2640,0x0360,0x4620,0x04E0,0x2620,0x0E40,0x4640}; //19种图形,其中有同一图形的翻转形式,每四位控制1列
u16 BoxSR[Y_BOXS+4]={0x0000,0x0000,0x0000,0x8001,0x8001,0x8001,0x8001,0x8001,0x8001,0x8001,
0x8001,0x8001,0x8001,0x8001,0x8001,0x8001,0x8001,0x8001,0x8001,0x8001,
0x8001,0x8001,0x8001,0x8001,0x8001,0x8001,0x8001,0x8001,0xFFFF}; //顶部三层空+25层操作区域+地基
_Shape NewShape={60,30,SHAPE_COLOR,1,1,1,0};
_Game Game={10000,1,0};
//界面字库
const u8 tfont16[][16];
二、函数部分
主要5个函数,如下
void LCD_DrawBlock(u16 sx,u16 sy,u16 color);
void LCD_DrawShape(u16 sx,u16 sy,u8 n,u16 color);
void LCD_ClearShape(u16 sx,u16 sy,u8 n,u16 color);
void LCD_Show_CH_Font16(u16 sx,u16 sy,u8 n,u16 color);
void Show_TetrisFace(void);
①[mw_shl_code=c,true]
/*LCD画小方块函数**/
/*(sx,xy):起始坐标*/
/***color:方块颜 {MOD}*/
void LCD_DrawBlock(u16 sx,u16 sy,u16 color) //矩形+实体黑芯
{
LCD_DrawRectangle(sx,sy,sx+BPIXEL-1,sy+BPIXEL-1);
LCD_Fill(sx+2,sy+2,sx+BPIXEL-3,sy+BPIXEL-3,color);
}[/mw_shl_code]俄罗斯方块中每块拼图的基础单位是10*10的方格组成,实现时,先画一个10*10的方格,然后在此方格中填充8*8的实心以便突出。
②[mw_shl_code=c,true]/*********绘制图形函数************/
/*(sx,sy):基点,在4*4区域的左上角*/
/*******n:基本图形编号************/
/***color:颜 {MOD}值******************/
void LCD_DrawShape(u16 sx,u16 sy,u8 n,u16 color) //绘制基本操作图形(19种)
{
u8 a,b;
u16 temp=Tetris[n];
u8 i;
for(i=0;i<16;i++)
{
a=i/4; //列
b=i%4; //行
if(temp&0x8000)
{
LCD_DrawRectangle(sx+b*BPIXEL,sy+a*BPIXEL,sx+(b+1)*BPIXEL-1,sy+(a+1)*BPIXEL-1);
LCD_Fill(sx+b*BPIXEL+2,sy+a*BPIXEL+2,sx+(b+1)*BPIXEL-3,sy+(a+1)*BPIXEL-3,color);
BoxSR[sy/BPIXEL+a]|=1<<((sx/BPIXEL)+b); //标记该方块已被图形占用 列中 当前行是否被占用
}
temp<<=1;
}
}[/mw_shl_code]
绘制游戏过程中游戏区域出现的图块,每个图块在4*4个小方块区域中通过扫描Tetris【x】实现,通过对Terit【x】列扫描,为1则响应位置绘制小方块,为0则不必处理,扫描过程中对绘制小方块区域进行标记,标志其被占用。
③[mw_shl_code=c,true]/*********消除图形函数***************/
/*(sx,sy):基点,在4*4区域的左上角****/
/*******n:基本图形编号***************/
/***color:颜 {MOD}值*********************/
/*消除图形时应将相应方块的标志位清零*/
void LCD_ClearShape(u16 sx,u16 sy,u8 n,u16 color)
{
u8 a,b;
u16 temp=Tetris[n];
u8 i;
for(i=0;i<16;i++)
{
a=i/4;
b=i%4;
if(temp&0x8000)
{
LCD_Fill(sx+b*BPIXEL,sy+a*BPIXEL,sx+(b+1)*BPIXEL-1,sy+(a+1)*BPIXEL-1,color);
BoxSR[sy/BPIXEL+a]&=~(1<<((sx/BPIXEL)+b)); //标记该方块未被图形占用
}
temp<<=1;
}
}[/mw_shl_code]在移动等操作时,需将移动前状态进行清除,本函数即实现此功能。
④[mw_shl_code=c,true]/*LCD显示16*16点阵汉字*/
/**(sx,sy):起始坐标****/
/********n:汉字编号****/
/****color:字体颜 {MOD}****/
void LCD_Show_CH_Font16(u16 sx,u16 sy,u8 n,u16 color)
{
u8 temp,i,j;
u16 curx=sx,cury=sy; //起点坐标
for(i=0;i<32;i++)
{
if(i<16)temp=tfont16[n*2]
;
else temp=tfont16[n*2+1][i-16];
for(j=0;j<8;j++)
{
if(temp&0x80)LCD_DrawPoint(curx,cury);
temp<<=1;
cury++;
if((cury-sy)==16)
{
cury=sy;
curx++;
break;
}
}
}
}[/mw_shl_code]
II区界面区主要由16*16字体实现,故需实现字库显示函数。
⑤[mw_shl_code=c,true]//显示整体界面
void Show_TetrisFace(void)
{
u8 i,j;
u16 curpos=30;
LCD_Clear(BOXS_COLOR);
LCD_Show_CH_Font16(0,0,19,TEXT_COLOR); //俄
LCD_Show_CH_Font16(16,0,20,TEXT_COLOR); //罗
LCD_Show_CH_Font16(32,0,21,TEXT_COLOR); //斯
LCD_Show_CH_Font16(48,0,22,TEXT_COLOR); //方
LCD_Show_CH_Font16(64,0,23,TEXT_COLOR); //块
LCD_Show_CH_Font16(160,30,11,TEXT_COLOR); //下
LCD_Show_CH_Font16(176,30,12,TEXT_COLOR); //一
LCD_Show_CH_Font16(192,30,13,TEXT_COLOR); //个
LCD_Show_CH_Font16(160,100,7,TEXT_COLOR); //分
LCD_Show_CH_Font16(176,100,8,TEXT_COLOR); //数
LCD_Show_CH_Font16(160,140,9,TEXT_COLOR); //等
LCD_Show_CH_Font16(176,140,10,TEXT_COLOR); //级
LCD_Show_CH_Font16(170,210,24,TEXT_COLOR);//按
LCD_Show_CH_Font16(210,210,25,TEXT_COLOR);//键
LCD_Show_CH_Font16(190,190,26,TEXT_COLOR);//信
LCD_Show_CH_Font16(190,230,27,TEXT_COLOR);//息
LCD_ShowNum(170,120,Game.score,6,16);
LCD_ShowNum(170,160,Game.level,3,16);
for(i=0;i<4;i++) //右侧4*4方格
{
for(j=0;j<4;j++)
{
LCD_DrawBlock(180+i*BPIXEL,50+j*BPIXEL,WILL_COLOR);
}
}
for(i=0;i<25;i++) //左边界
{
LCD_DrawBlock(0,curpos,WILL_COLOR);
curpos+=BPIXEL;
}
curpos=30;
for(i=0;i<25;i++) //右边界
{
LCD_DrawBlock(150,curpos,WILL_COLOR);
curpos+=BPIXEL;
}
curpos=0;
for(i=0;i<16;i++) //下边界
{
LCD_DrawBlock(curpos,280,WILL_COLOR);
curpos+=BPIXEL;
}
}[/mw_shl_code]
实现主要界面,打下游戏基础。
加载中...
查看其它37个回答
一周热门
更多
>
相关问题
STM32F4上I2C(在PROTEUS中模拟)调试不通的问题
6 个回答
芯片供应紧张,准备换个MCU,MM32L系列替换STM32L系列的怎么样?
7 个回答
STM32同时使用两个串口进行数据收发时数据丢包的问题
5 个回答
STM32F103串口通信死机问题
4 个回答
STM32WLE5CC连接SX1268在LoRa模式下能与 SX1278互通吗?
2 个回答
相关文章
ST公司第一款无线低功耗单片机模块有效提高物联网设计生产效率
0个评论
如何实现对单片机寄存器的访问
0个评论
通过USB用STM32片内自带Bootloader下载程序及注意事项
0个评论
欲练此功必先自宫之STM32汇编启动,放慢是为了更好的前行
0个评论
×
关闭
采纳回答
向帮助了您的知道网友说句感谢的话吧!
非常感谢!
确 认
×
关闭
编辑标签
最多设置5个标签!
STM32
保存
关闭
×
关闭
举报内容
检举类型
检举内容
检举用户
检举原因
广告推广
恶意灌水
回答内容与提问无关
抄袭答案
其他
检举说明(必填)
提交
关闭
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
×
付费偷看金额在0.1-10元之间
确定
×
关闭
您已邀请
0
人回答
查看邀请
擅长该话题的人
回答过该话题的人
我关注的人
一、变量部分
①.h文件
#define SHAPE_COLOR 0x0000 //图形颜 {MOD}->黑 {MOD}
#define BOXS_COLOR 0xFFFF //底板颜 {MOD}->白 {MOD}
#define WILL_COLOR 0x7D7C //边界颜 {MOD}->浅蓝 {MOD}
#define TEXT_COLOR 0x0000 //字体颜 {MOD}->黑 {MOD}
#define BPIXEL 10 //一个小方块边长的像素值
#define X_BOXS 14 //游戏底板X轴小方块个数
#define Y_BOXS 25 //游戏底板Y轴小方块个数
#define LEFT 34
#define RIGHT 194
#define DOWN 168
#define TURN 98
#define RESET 162
extern u16 BoxSR[Y_BOXS+4]; //游戏区域标志位
typedef struct
{
u16 x;
u16 y;
u16 color;
u8 CurNum; //当前图形编号
u8 NextNum;//下一个图形编号
u8 TurnNum;//翻转图形编号
u8 Move; //标志位,实现互斥
}_Shape;
extern _Shape NewShape;
typedef struct //游戏速度、级别、得分
{
u16 speed;
u8 level;
u32 score;
}_Game;
②.c文件
u16 Tetris[19]={0x0F00,0x4444,0x0660,0x4460,0x02E0,0x6220,0x0740,0x2260,0x0E20,0x6440,0x0470,0x0C60,0x2640,0x0360,0x4620,0x04E0,0x2620,0x0E40,0x4640}; //19种图形,其中有同一图形的翻转形式,每四位控制1列
u16 BoxSR[Y_BOXS+4]={0x0000,0x0000,0x0000,0x8001,0x8001,0x8001,0x8001,0x8001,0x8001,0x8001,
0x8001,0x8001,0x8001,0x8001,0x8001,0x8001,0x8001,0x8001,0x8001,0x8001,
0x8001,0x8001,0x8001,0x8001,0x8001,0x8001,0x8001,0x8001,0xFFFF}; //顶部三层空+25层操作区域+地基
_Shape NewShape={60,30,SHAPE_COLOR,1,1,1,0};
_Game Game={10000,1,0};
//界面字库
const u8 tfont16[][16];
二、函数部分
主要5个函数,如下
void LCD_DrawBlock(u16 sx,u16 sy,u16 color);
void LCD_DrawShape(u16 sx,u16 sy,u8 n,u16 color);
void LCD_ClearShape(u16 sx,u16 sy,u8 n,u16 color);
void LCD_Show_CH_Font16(u16 sx,u16 sy,u8 n,u16 color);
void Show_TetrisFace(void);
①[mw_shl_code=c,true]
/*LCD画小方块函数**/
/*(sx,xy):起始坐标*/
/***color:方块颜 {MOD}*/
void LCD_DrawBlock(u16 sx,u16 sy,u16 color) //矩形+实体黑芯
{
LCD_DrawRectangle(sx,sy,sx+BPIXEL-1,sy+BPIXEL-1);
LCD_Fill(sx+2,sy+2,sx+BPIXEL-3,sy+BPIXEL-3,color);
}[/mw_shl_code]俄罗斯方块中每块拼图的基础单位是10*10的方格组成,实现时,先画一个10*10的方格,然后在此方格中填充8*8的实心以便突出。
②[mw_shl_code=c,true]/*********绘制图形函数************/
/*(sx,sy):基点,在4*4区域的左上角*/
/*******n:基本图形编号************/
/***color:颜 {MOD}值******************/
void LCD_DrawShape(u16 sx,u16 sy,u8 n,u16 color) //绘制基本操作图形(19种)
{
u8 a,b;
u16 temp=Tetris[n];
u8 i;
for(i=0;i<16;i++)
{
a=i/4; //列
b=i%4; //行
if(temp&0x8000)
{
LCD_DrawRectangle(sx+b*BPIXEL,sy+a*BPIXEL,sx+(b+1)*BPIXEL-1,sy+(a+1)*BPIXEL-1);
LCD_Fill(sx+b*BPIXEL+2,sy+a*BPIXEL+2,sx+(b+1)*BPIXEL-3,sy+(a+1)*BPIXEL-3,color);
BoxSR[sy/BPIXEL+a]|=1<<((sx/BPIXEL)+b); //标记该方块已被图形占用 列中 当前行是否被占用
}
temp<<=1;
}
}[/mw_shl_code]
绘制游戏过程中游戏区域出现的图块,每个图块在4*4个小方块区域中通过扫描Tetris【x】实现,通过对Terit【x】列扫描,为1则响应位置绘制小方块,为0则不必处理,扫描过程中对绘制小方块区域进行标记,标志其被占用。
③[mw_shl_code=c,true]/*********消除图形函数***************/
/*(sx,sy):基点,在4*4区域的左上角****/
/*******n:基本图形编号***************/
/***color:颜 {MOD}值*********************/
/*消除图形时应将相应方块的标志位清零*/
void LCD_ClearShape(u16 sx,u16 sy,u8 n,u16 color)
{
u8 a,b;
u16 temp=Tetris[n];
u8 i;
for(i=0;i<16;i++)
{
a=i/4;
b=i%4;
if(temp&0x8000)
{
LCD_Fill(sx+b*BPIXEL,sy+a*BPIXEL,sx+(b+1)*BPIXEL-1,sy+(a+1)*BPIXEL-1,color);
BoxSR[sy/BPIXEL+a]&=~(1<<((sx/BPIXEL)+b)); //标记该方块未被图形占用
}
temp<<=1;
}
}[/mw_shl_code]在移动等操作时,需将移动前状态进行清除,本函数即实现此功能。
④[mw_shl_code=c,true]/*LCD显示16*16点阵汉字*/
/**(sx,sy):起始坐标****/
/********n:汉字编号****/
/****color:字体颜 {MOD}****/
void LCD_Show_CH_Font16(u16 sx,u16 sy,u8 n,u16 color)
{
u8 temp,i,j;
u16 curx=sx,cury=sy; //起点坐标
for(i=0;i<32;i++)
{
if(i<16)temp=tfont16[n*2];
else temp=tfont16[n*2+1][i-16];
for(j=0;j<8;j++)
{
if(temp&0x80)LCD_DrawPoint(curx,cury);
temp<<=1;
cury++;
if((cury-sy)==16)
{
cury=sy;
curx++;
break;
}
}
}
}[/mw_shl_code]
II区界面区主要由16*16字体实现,故需实现字库显示函数。
⑤[mw_shl_code=c,true]//显示整体界面
void Show_TetrisFace(void)
{
u8 i,j;
u16 curpos=30;
LCD_Clear(BOXS_COLOR);
LCD_Show_CH_Font16(0,0,19,TEXT_COLOR); //俄
LCD_Show_CH_Font16(16,0,20,TEXT_COLOR); //罗
LCD_Show_CH_Font16(32,0,21,TEXT_COLOR); //斯
LCD_Show_CH_Font16(48,0,22,TEXT_COLOR); //方
LCD_Show_CH_Font16(64,0,23,TEXT_COLOR); //块
LCD_Show_CH_Font16(160,30,11,TEXT_COLOR); //下
LCD_Show_CH_Font16(176,30,12,TEXT_COLOR); //一
LCD_Show_CH_Font16(192,30,13,TEXT_COLOR); //个
LCD_Show_CH_Font16(160,100,7,TEXT_COLOR); //分
LCD_Show_CH_Font16(176,100,8,TEXT_COLOR); //数
LCD_Show_CH_Font16(160,140,9,TEXT_COLOR); //等
LCD_Show_CH_Font16(176,140,10,TEXT_COLOR); //级
LCD_Show_CH_Font16(170,210,24,TEXT_COLOR);//按
LCD_Show_CH_Font16(210,210,25,TEXT_COLOR);//键
LCD_Show_CH_Font16(190,190,26,TEXT_COLOR);//信
LCD_Show_CH_Font16(190,230,27,TEXT_COLOR);//息
LCD_ShowNum(170,120,Game.score,6,16);
LCD_ShowNum(170,160,Game.level,3,16);
for(i=0;i<4;i++) //右侧4*4方格
{
for(j=0;j<4;j++)
{
LCD_DrawBlock(180+i*BPIXEL,50+j*BPIXEL,WILL_COLOR);
}
}
for(i=0;i<25;i++) //左边界
{
LCD_DrawBlock(0,curpos,WILL_COLOR);
curpos+=BPIXEL;
}
curpos=30;
for(i=0;i<25;i++) //右边界
{
LCD_DrawBlock(150,curpos,WILL_COLOR);
curpos+=BPIXEL;
}
curpos=0;
for(i=0;i<16;i++) //下边界
{
LCD_DrawBlock(curpos,280,WILL_COLOR);
curpos+=BPIXEL;
}
}[/mw_shl_code]
实现主要界面,打下游戏基础。
一周热门 更多>