OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 12587|回复: 37

Tetris,移植俄罗斯方块之不定期更新篇

[复制链接]

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
发表于 2016-1-10 13:50:36 | 显示全部楼层 |阅读模式
本帖最后由 龙之谷 于 2016-1-10 13:52 编辑
一直对小游戏(贪吃蛇、俄罗斯方块等)的程序编写有着莫名的好奇与敬佩,现在手头上有硬件开发板,论坛上有坛友无私分享,自己也就找时间来学着移植玩玩。
本帖是在坛友移植好的工程基础上进行一些或调整或补充,工程来源会在第一次引用楼层贴出链接与对应楼主。
更新时间不定、更新内容不定,但若更新结束会有专门楼层提示。
Start game.....

俄罗斯方块百度链接:俄罗斯方块链接


以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

6

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2016-5-1
在线时间
5 小时
发表于 2016-5-13 23:41:13 | 显示全部楼层
回复 支持 1 反对 0

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
 楼主| 发表于 2016-1-10 14:09:04 | 显示全部楼层
硬件:STM32F4探索者开发板(2.8寸TFTLCD)
说明:在子木阿伦移植到F4开发板工程基础上略微调整工程框架并修复两个小bug
         ①定时计数器参数配置调整;
         ②修复一次按键两次触发操作的情况。


STM32F4--Tetris V2.0.rar

1.15 MB, 下载次数: 1977

以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复 支持 1 反对 0

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2016-1-19 22:38:38 | 显示全部楼层
不错,cool
回复 支持 1 反对 0

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
 楼主| 发表于 2016-1-10 14:01:39 | 显示全部楼层
以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复 支持 反对

使用道具 举报

39

主题

598

帖子

0

精华

高级会员

Rank: 4

积分
875
金钱
875
注册时间
2013-12-18
在线时间
41 小时
发表于 2016-1-10 16:31:24 | 显示全部楼层
真棒啊
回复 支持 反对

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
 楼主| 发表于 2016-1-10 17:14:25 | 显示全部楼层

只是帖子的搬运工
以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2016-1-10 23:14:14 | 显示全部楼层
楼主又要搞好东东了?
回复 支持 反对

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
 楼主| 发表于 2016-1-10 23:32:51 | 显示全部楼层
正点原子 发表于 2016-1-10 23:14
楼主又要搞好东东了?

嘿嘿,瞎玩玩
以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复 支持 反对

使用道具 举报

15

主题

786

帖子

5

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3223
金钱
3223
注册时间
2015-7-26
在线时间
811 小时
发表于 2016-1-11 08:58:57 | 显示全部楼层
又有新玩意了,顶!
我的博客:http://blog.csdn.net/itdo_just
回复 支持 反对

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
 楼主| 发表于 2016-1-11 11:39:00 | 显示全部楼层
229382777@qq.co 发表于 2016-1-11 08:58
又有新玩意了,顶!

玩起来
以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复 支持 反对

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
 楼主| 发表于 2016-1-11 19:43:42 | 显示全部楼层
更新:2016年01月11日 19:49:03

内容:1.可配置多种操作方式(仅测试红外、按键通过)
         2.微调程序框架



STM32F4--Tetris V3.1.rar

1.35 MB, 下载次数: 1789

以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复 支持 反对

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
 楼主| 发表于 2016-1-11 20:19:07 | 显示全部楼层
更新:2016年01月11日

内容:Tetris移植打包,共包含5个文件
         Tetris.h:头文件
         Tetris.c:游戏实现基础函数
         Port_Tetris.h:移植接口头文件
         Port_Tetris.c:移植接口函数
         readme.txt:简单移植指南
         

TETRIS移植包.rar

6.33 KB, 阅读权限: 20, 下载次数: 64

以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复 支持 反对

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
 楼主| 发表于 2016-1-16 22:14:44 | 显示全部楼层
本帖最后由 龙之谷 于 2016-1-16 22:22 编辑

Tetris实现过程

如图,俄罗斯方块界面简单分为两个区域:I区游戏区;Ⅱ区界面区。
QQ图片20160116202208.jpg
例程俄罗斯方块的实现大致分为三个阶段:
其一,II区界面区及图形实现;
其二,I区游戏区操作实现(主要部分);
其三,游戏持续运行实现。


以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复 支持 反对

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
 楼主| 发表于 2016-1-16 22:57:39 | 显示全部楼层
其一,II区界面区及图形实现

一、变量部分
①.h文件
#define SHAPE_COLOR 0x0000        //图形颜色->黑色
#define BOXS_COLOR        0xFFFF        //底板颜色->白色
#define WILL_COLOR        0x7D7C        //边界颜色->浅蓝色
#define TEXT_COLOR        0x0000        //字体颜色->黑色

#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:方块颜色*/
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:颜色值******************/
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:颜色值*********************/
/*消除图形时应将相应方块的标志位清零*/
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:字体颜色****/
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]
实现主要界面,打下游戏基础。
以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复 支持 反对

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
 楼主| 发表于 2016-1-17 13:46:57 | 显示全部楼层
其二,I区游戏区操作实现(主要部分)


主要由七个函数实现:
[mw_shl_code=c,true]void Create_Shape(void);
u8 Judge(u16 sx,u16 sy,u8 n,u8 mode);
void MoveLeft(void);
void MoveRight(void);
void DownFast(void);
void DownFree(void);
void Transform(void);[/mw_shl_code]

1.[mw_shl_code=c,true]/*创建新图形函数*/
void Create_Shape(void)
{
        u8 a,b;
        u16 temp;
        u8 i;
        NewShape.CurNum=NewShape.NextNum;     //获取新图形
        NewShape.x=60;
        NewShape.y=30;
        if(BoxSR[4]&0x03C0)ResetGame();     //如果第五行0000001111000000其中四位有一位被占用,则判游戏结束,重新开始
        else        LCD_DrawShape(NewShape.x,NewShape.y,NewShape.CurNum,SHAPE_COLOR);     //游戏区域显示新图形
        temp=Tetris[NewShape.NextNum];     //消除右侧4*4方格中原图形
        for(i=0;i<16;i++)
        {
                a=i/4;
                b=i%4;
                if(temp&0x8000)
                {
                        LCD_DrawBlock(180+b*BPIXEL,50+a*BPIXEL,WILL_COLOR);
                }
                temp<<=1;
        }
        NewShape.NextNum=rand()%19;
        temp=Tetris[NewShape.NextNum];
        for(i=0;i<16;i++)     //右侧最新随机图形
        {
                a=i/4;
                b=i%4;
                if(temp&0x8000)
                {
                        LCD_DrawBlock(180+b*BPIXEL,50+a*BPIXEL,SHAPE_COLOR);
                }
                temp<<=1;
        }
}[/mw_shl_code]该函数在当前图形不能继续下落操作时被调用,主要实现两个功能:①检查判断游戏是否不能继续,如满足游戏结束条件,重新开始游戏;②如还能继续运行,游戏区域绘制右侧4*4方格中当前图形继续运行,而4*4方格中消除当前图形并随机绘制新图形显示出来作为下一图形提示。

2.[mw_shl_code=c,true]/***********************判断函数***********************/
/*****************判断移动图形的可行性*****************/
/*mode:1->左移;2->右移;3->旋转;4->加速下落;5->自由下落*/
u8 Judge(u16 sx,u16 sy,u8 n,u8 mode)
{
        int cx,cy,temp1=Tetris[n],temp2=Tetris[n];
        u8 a,b,i,Flag=0;
        switch(mode)
        {
                case 1:        cx=sx-BPIXEL;cy=sy;break;
                case 2:        cx=sx+BPIXEL;cy=sy;break;
                case 3:        cx=sx;
                                cy=sy;
                                switch(NewShape.CurNum)
                                {
                                        case 0:temp2=1;break;
                                        case 1:temp2=0;break;
                                        case 2:temp2=2;break;
                                        case 3:temp2=4;break;
                                        case 4:temp2=5;break;
                                        case 5:temp2=6;break;
                                        case 6:temp2=3;break;
                                        case 7:temp2=8;break;
                                        case 8:temp2=9;break;
                                        case 9:temp2=10;break;
                                        case 10:temp2=7;break;
                                        case 11:temp2=12;break;
                                        case 12:temp2=11;break;
                                        case 13:temp2=14;break;
                                        case 14:temp2=13;break;
                                        case 15:temp2=16;break;
                                        case 16:temp2=17;break;
                                        case 17:temp2=18;break;
                                        case 18:temp2=15;break;
                                }
                                NewShape.TurnNum=temp2;
                                temp2=Tetris[temp2];
                                break;
                case 5:        cx=sx;cy=sy+BPIXEL;break;
                default:cx=sx;cy=sy;break;                                       
        }
        for(i=0;i<16;i++)     //先消除原图形占用标记,如果可以移动,则直接继续进行,否则判断后重新画原图形
        {
                a=i/4;       
                b=i%4;
                if(temp1&0x8000)BoxSR[sy/BPIXEL+a]&=~(1<<((sx/BPIXEL)+b));
                temp1<<=1;
        }
       
        for(i=0;i<16;i++)     //判断将要移动区域是否已经被占用,如果占用则不可移动
        {
                a=i/4;
                b=i%4;
                if(temp2&0x8000)
                {
                        if(BoxSR[cy/BPIXEL+a]&(1<<((cx/BPIXEL)+b)))Flag=1;
                }
                temp2<<=1;                       
        }       
        if(Flag==0)return 1;
        else return 0;
}[/mw_shl_code]
判断图形是否可左、右、翻转、自由下操作,基本过程是:先根据操作获取对应位移-----消除原图形占用区域标记-----判断图形新位置是否已经被占用,如果被占用则不能移动,返回0,如果能够继续移动则返回1。其中,翻转操作是查Teris【】表,因为原图形和对应翻转图形都在表中所以翻转后只要在表中找到对应图形即可。

3.[mw_shl_code=c,true]/*图形左移函数*/
void MoveLeft(void)
{
        u8 Draw_Ready;
        if(NewShape.Move==0)
        {
                NewShape.Move=1;
                Draw_Ready=Judge(NewShape.x,NewShape.y,NewShape.CurNum,1);
                if(Draw_Ready==1)
                {
                        LCD_ClearShape(NewShape.x,NewShape.y,NewShape.CurNum,BOXS_COLOR);
                        NewShape.x-=BPIXEL;
                        LCD_DrawShape(NewShape.x,NewShape.y,NewShape.CurNum,SHAPE_COLOR);
                }
                else LCD_DrawShape(NewShape.x,NewShape.y,NewShape.CurNum,SHAPE_COLOR);
                NewShape.Move=0;
        }
}[/mw_shl_code]
图形左移函数,先判断是否可以左移,如可以左移则清除原图形坐标左移后重新绘图,如不能重新绘制原图形。

4.[mw_shl_code=c,true]/*图形右移函数*/
void MoveRight(void)
{
        u8 Draw_Ready;
        if(NewShape.Move==0)
        {
                NewShape.Move=1;
                Draw_Ready=Judge(NewShape.x,NewShape.y,NewShape.CurNum,2);
                if(Draw_Ready==1)
                {
                        LCD_ClearShape(NewShape.x,NewShape.y,NewShape.CurNum,BOXS_COLOR);
                        NewShape.x+=BPIXEL;
                        LCD_DrawShape(NewShape.x,NewShape.y,NewShape.CurNum,SHAPE_COLOR);
                }
                else LCD_DrawShape(NewShape.x,NewShape.y,NewShape.CurNum,SHAPE_COLOR);
                NewShape.Move=0;
        }
}[/mw_shl_code]
同3.

5.[mw_shl_code=c,true]/*快速下落函数*/
void DownFast(void)
{
        u8 Draw_Ready;
        if(NewShape.Move==0)
        {
                NewShape.Move=1;
                Draw_Ready=Judge(NewShape.x,NewShape.y,NewShape.CurNum,5);
                if(Draw_Ready==1)
                {
                        LCD_ClearShape(NewShape.x,NewShape.y,NewShape.CurNum,BOXS_COLOR);
                        NewShape.y+=BPIXEL;
                        LCD_DrawShape(NewShape.x,NewShape.y,NewShape.CurNum,SHAPE_COLOR);
                }
                else
                {
                        LCD_DrawShape(NewShape.x,NewShape.y,NewShape.CurNum,SHAPE_COLOR);
                }
                NewShape.Move=0;
        }
}[/mw_shl_code]
快速下落是在游戏进行过程中,定时自由落下的间隙加一次下落,体现出来的效果就是游戏速度加快。

6.[mw_shl_code=c,true]/*自由下落函数*/
void DownFree(void)
{
        u8 Draw_Ready;
        u8 i,j,Clear_Flag;
        u16 temp;
        if(NewShape.Move==0)
        {
                NewShape.Move=1;
                Draw_Ready=Judge(NewShape.x,NewShape.y,NewShape.CurNum,5);
                if(Draw_Ready==1)     //图形可以继续下落
                {
                        LCD_ClearShape(NewShape.x,NewShape.y,NewShape.CurNum,BOXS_COLOR);
                        NewShape.y+=BPIXEL;
                        LCD_DrawShape(NewShape.x,NewShape.y,NewShape.CurNum,SHAPE_COLOR);
                }
                else     //当前图形不能继续下落
                {
                        LCD_DrawShape(NewShape.x,NewShape.y,NewShape.CurNum,SHAPE_COLOR);
                        for(i=4;i<Y_BOXS+4-1;i++)     //检查当前有效行是否有占满情况
                        {
                                if(BoxSR==0xFFFF)     //有,消去行,增加积分
                                {
                                        Game.score++;
                                        Game.level=1+Game.score/100;
                                        LCD_ShowNum(170,120,Game.score,6,16);
                                        LCD_ShowNum(170,160,Game.level,3,16);//void LCD_ShowNum(u16 x,u16 y,u32 num,u8 len,u8 size)
                                        Clear_Flag=1;
                                        for(j=i;j>3;j--)BoxSR[j]=BoxSR[j-1];
                                }               
                        }
                        if(Clear_Flag)LCD_Fill(10,30,149,279,BOXS_COLOR);     //清除当前所有图形区域
                        for(i=3;i<Y_BOXS+4-1;i++)     //刷新显示消除后的每一行
                        {
                                temp=BoxSR;
                                temp>>=1;
                                for(j=1;j<15;j++)
                                {
                                        if(temp&0x0001)LCD_DrawBlock(j*BPIXEL,i*BPIXEL,SHAPE_COLOR);
                                        temp>>=1;
                                }
                        }
                        Create_Shape();     //消去后开始新图形
                }
                NewShape.Move=0;
        }
}[/mw_shl_code]
自由下落比较重要。
先判断是否能够继续下落
     如果能则继续进行;
     如果不能则遍历判断是否有可消去行
          如果有可消去行,更新标志位、得分等;
          更新游戏区;
          生成新图形

7.[mw_shl_code=c,true]//变换方向
void Transform(void)
{
        u8 Draw_Ready=0;
        if(NewShape.Move==0)
        {
                NewShape.Move=1;
                Draw_Ready=Judge(NewShape.x,NewShape.y,NewShape.CurNum,3);
                if(Draw_Ready==1)
                {
                        LCD_ClearShape(NewShape.x,NewShape.y,NewShape.CurNum,BOXS_COLOR);
                        NewShape.CurNum=NewShape.TurnNum;
                        LCD_DrawShape(NewShape.x,NewShape.y,NewShape.CurNum,SHAPE_COLOR);
                }
                else LCD_DrawShape(NewShape.x,NewShape.y,NewShape.CurNum,SHAPE_COLOR);
                NewShape.Move=0;
        }
}[/mw_shl_code]同3.

以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复 支持 反对

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
 楼主| 发表于 2016-1-17 17:10:21 | 显示全部楼层
其三,游戏持续运行实现


运行需要三个条件协同工作:
1.无操作时的自由下落,定时器实现
[mw_shl_code=c,true]/*TIM3定时器初始化*/
void TIM3_Int_Init(u16 arr,u16 psc)
{
        RCC->APB1ENR|=1<<1;
        TIM3->ARR=arr;
        TIM3->SC=psc;
        TIM3->DIER|=1<<0;
        TIM3->CR1|=0x01;
        MY_NVIC_Init(1,3,TIM3_IRQn,2);
}

/*TIM3中断函数*/
void TIM3_IRQHandler(void)
{
        if(TIM3->SR&0x0001)
        {
                if(NewShape.Move==0)DownFree();     //保证游戏运行
        }
        TIM3->SR&=~(1<<0);
}


TIM3_Int_Init(4999,16799);[/mw_shl_code]


2.有操作,操作方式实现:红外或按键或游戏手柄等。


3.对操作方式的响应,循环检测实现
[mw_shl_code=c,true]//游戏中...
void Play_Game(void)
{       
        u8 KeyVal = 0;
       
        KeyVal=Control_Scan();

        switch(KeyVal)
        {
                case LEFT:MoveLeft();LED1=~LED1;break;
                case RIGHT:MoveRight();LED1=~LED1;break;
                case DOWNownFast();LED1=~LED1;break;
                case TURN:Transform();LED1=~LED1;break;
                case RESET:ResetGame();LED1=~LED1;break;       
                default :        break;
        }
       
        if((KeyVal != DOWN) && (KeyVal != 0))
        {
                RmtSta=0;             //源程序小bug修复,避免非加速下落模式一次按键多次触发操作       
        }

}[/mw_shl_code]
以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复 支持 反对

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
 楼主| 发表于 2016-1-18 16:58:52 | 显示全部楼层
以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复 支持 反对

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
 楼主| 发表于 2016-1-18 17:04:05 | 显示全部楼层
本帖最后由 龙之谷 于 2016-1-19 08:39 编辑

硬件:STM32F1 V3战舰开发板(2.8寸TFTLCD)
说明:只是对原基于V2版本俄罗斯方块移植到V3版本


(STM32F1 V3.0)TETRISV2.0.zip

5.93 MB, 下载次数: 807

以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复 支持 反对

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
 楼主| 发表于 2016-1-19 09:06:01 | 显示全部楼层
Ed4DZ43bUD.png
1.移植了坛友两个俄罗斯方块的代码,刚开始的热情劲驱动着对第一个进行了较多的学习。
2.基本了解了俄罗斯方块游戏的流程,有一些收获。
3.趁着刚移植完第二个俄罗斯方块代码,不拖泥带水了,速度结贴,省得成了烂尾帖-----想结贴有遗憾,不结贴没动力。
4.Thank you.
以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复 支持 反对

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
 楼主| 发表于 2016-1-19 22:57:22 | 显示全部楼层

谢原子老大鼓励
以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2016-1-19 23:19:56 | 显示全部楼层

应该的,呵呵,好帖子啊
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

1

主题

40

帖子

0

精华

初级会员

Rank: 2

积分
77
金钱
77
注册时间
2016-1-18
在线时间
7 小时
发表于 2016-1-24 20:53:36 | 显示全部楼层
上程序嘛
回复 支持 反对

使用道具 举报

29

主题

91

帖子

1

精华

中级会员

Rank: 3Rank: 3

积分
360
金钱
360
注册时间
2015-4-24
在线时间
37 小时
发表于 2016-4-26 21:48:56 | 显示全部楼层
楼主,最近也想做这样一个程序练手,但是我在每个方框移动判断是否能够移动,这个问题卡壳了,想不到一个比较好的解决办法,能提供下你的思路吗/
一起学,一起进步,未来总有你我的一片天空……
回复 支持 反对

使用道具 举报

0

主题

32

帖子

0

精华

初级会员

Rank: 2

积分
171
金钱
171
注册时间
2016-3-16
在线时间
48 小时
发表于 2016-6-4 14:54:34 | 显示全部楼层
移植包有权限限制 下载不了
回复 支持 反对

使用道具 举报

0

主题

8

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1273
金钱
1273
注册时间
2013-8-31
在线时间
176 小时
发表于 2016-6-12 13:25:12 | 显示全部楼层
没权限,只好慢慢攒积分了
回复 支持 反对

使用道具 举报

8

主题

571

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2919
金钱
2919
注册时间
2016-5-13
在线时间
185 小时
发表于 2016-6-12 14:56:23 | 显示全部楼层
好东东啊。
虽然不明白你们在说什么,但感觉很厉害的样子。
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手上路

积分
41
金钱
41
注册时间
2016-8-30
在线时间
7 小时
发表于 2016-8-30 08:34:29 | 显示全部楼层
mark,学习中
回复 支持 反对

使用道具 举报

3

主题

36

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
379
金钱
379
注册时间
2014-7-4
在线时间
115 小时
发表于 2016-8-30 11:38:27 | 显示全部楼层
学习了
回复 支持 反对

使用道具 举报

1

主题

36

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
350
金钱
350
注册时间
2016-7-29
在线时间
71 小时
发表于 2016-9-30 09:59:11 | 显示全部楼层
精华,值得学习。
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
16
金钱
16
注册时间
2016-9-21
在线时间
1 小时
发表于 2016-9-30 18:55:48 | 显示全部楼层
先顶再看好习惯
回复 支持 反对

使用道具 举报

4

主题

93

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
262
金钱
262
注册时间
2016-10-27
在线时间
47 小时
发表于 2017-7-13 17:31:51 | 显示全部楼层
龙之谷 发表于 2016-1-18 17:04
硬件:STM32F1 V3战舰开发板(2.8寸TFTLCD)
说明:只是对原基于V2版本俄罗斯方块移植到V3版本

您好,楼主!战舰板子V3上面下载该程序,必须要使用SD卡吗,我现在没有插SD卡,一直是在黄颜色的游戏初始界面!
回复 支持 反对

使用道具 举报

2

主题

7

帖子

0

精华

新手上路

积分
23
金钱
23
注册时间
2018-4-1
在线时间
4 小时
发表于 2018-5-2 17:04:02 | 显示全部楼层
龙之谷 发表于 2016-1-10 14:09
硬件:STM32F4探索者开发板(2.8寸TFTLCD)
说明:在子木阿伦移植到F4开发板工程基础上略微调整工程框架并 ...

请问怎么修改屏幕尺寸啊
回复 支持 反对

使用道具 举报

2

主题

56

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1394
金钱
1394
注册时间
2014-12-31
在线时间
187 小时
发表于 2018-5-3 15:08:33 | 显示全部楼层
群主牛人,学习了
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
2
金钱
2
注册时间
2018-9-5
在线时间
0 小时
发表于 2018-9-5 21:01:20 | 显示全部楼层
大佬我是个新手,为什么我用探索者烧录你的程序后,无法控制游戏?
回复 支持 反对

使用道具 举报

2

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
71
金钱
71
注册时间
2018-9-2
在线时间
14 小时
发表于 2018-9-25 15:09:31 | 显示全部楼层
带走看看
回复 支持 反对

使用道具 举报

8

主题

155

帖子

0

精华

高级会员

Rank: 4

积分
750
金钱
750
注册时间
2011-11-12
在线时间
155 小时
发表于 2018-12-18 16:47:56 | 显示全部楼层
感谢分享,学习了
回复 支持 反对

使用道具 举报

19

主题

86

帖子

0

精华

高级会员

Rank: 4

积分
795
金钱
795
注册时间
2013-9-29
在线时间
179 小时
发表于 2019-1-5 09:38:28 | 显示全部楼层
牛人,学习了
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-9 19:20

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表