原创 俄罗斯方块的原理以及arm实现

2008-12-6 15:29 8140 7 11 分类: MCU/ 嵌入式

俄罗斯方块的arm实现<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />



   测试知道朋友那块320*240的彩屏液晶是好的以后,想做点什么来玩下。于是用该液晶写了个标准的俄罗斯方块游戏,用arm7(s3c44B0)做的控制。下面做个详细的总结,加深理解,其次有兴趣的同仁可以试着用单片机做做,比较有趣!


先说原理:(原理是在网上查阅先人的资料后,得以总结的,感谢那些把资料发布于互联网的前辈,为我们提供了一个学习的平台)。首先要完成的就是建模工作。


建立模型:本人认为游戏编程中建模是十分重要的,语言的表达以及描述是基本功问题了。标准的俄罗斯方块游戏有一下几种图形:


c280c668-ed36-496a-95ed-3fcc8da4478b.jpg


显然我们可以用一个5*5的数组将其分别表示:可以这样理解在上图中每个图形都是5*5的大小,在黑点处将其在数组中的对应值赋1即可,其余为0。如第一个图“横条子”可以用 


            a[5][5]={ 0,0,0,0,0
                        0,0,0,0,0
                        1,1,1,1,0
                        0,0,0,0,0
                        0,0,0,0,0}


表示。其余的类推即可。对于这写图形的变换操作,只需写一个函数void rotateBox(int box1[5][5], int box2[5][5]) 对其进行矩阵的倒转即可。


void rotateBox(int box1[5][5], int box2[5][5]) 


{


                                /*旋转box1输出到box2*/


    int x, y;


    for(x = 0; x < 5; x++)      /*这个函数可以须要实际*/


        for(y = 4; y >= 0; y--)  /*编写一下才能印像深刻*/


            box2[y][x] = box1[x][4 - y];


}


我们可以用一个3维数组将7中基本方块全部表示出来:(当然这里MAX_C=7)


int box[MAX_C][5][5] = {     /*MAX_C(7)种预定义的盒子*/
            {
                {0,0,0,0,0},
                {0,0,0,0,0},
                {1,1,1,1,0},
                {0,0,0,0,0},
                {0,0,0,0,0}
            },
            
            {
                {0,0,0,0,0},
                {0,0,1,0,0},
                {0,1,1,1,0},
                {0,0,0,0,0},
                {0,0,0,0,0}
            },
            
            {
                {0,0,0,0,0},
                {0,1,1,0,0},
                {0,0,1,1,0},
                {0,0,0,0,0},
                {0,0,0,0,0}
            },
            
            {
                {0,0,0,0,0},
                {0,0,1,1,0},
                {0,1,1,0,0},
                {0,0,0,0,0},
                {0,0,0,0,0}
            },
            
            {
                {0,0,0,0,0},
                {0,1,1,0,0},
                {0,0,1,0,0},
                {0,0,1,0,0},
                {0,0,0,0,0}
            },
            
            {
                {0,0,0,0,0},
                {0,0,1,1,0},
                {0,0,1,0,0},
                {0,0,1,0,0},
                {0,0,0,0,0}
            },
            
            {
                {0,0,0,0,0},
                {0,0,1,1,0},
                {0,0,1,1,0},
                {0,0,0,0,0},
                {0,0,0,0,0}
            }
    };


接着要建立的模型就是背景了。我们这里设置的俄罗斯方块游戏的游戏显示区有12行20列。根据前面的思想我们也可以将其抽象为一个12*20的数组,但为了后面判断碰撞方便,我们把其抽象为16*22的数组 int map[MAX_Y][MAX_X]。0,1,14,15列全初始为1,最下面俩行即20,21俩行全初始为1;示意图如下:


6f6c4549-0af1-45f3-9d26-f67da8bd6176.jpg


我们用下面这个函数来实现上面的数组:


 void initMap(void) {            /*初始化地图*/


    int x, y;                   /*我们须要一圈卫兵...*/


    for(y = 0; y < MAX_Y; y++) {


        for(x = 0; x < MAX_X; x++) {


            if(x < 2 || x > MAX_X - 3 || y > MAX_Y - 3)


                map[y][x] = 1;


            else map[y][x] = 0;


        }


    }


好了有了前面这俩个模型的建立后面的就好理解了。我们可以认为背景就是如上的一个大盒子,而每个基本图形就是上面的小盒子。整个游戏简单来说就是小盒子在大盒子里面的移动(下落,左右移动)。而难点就是如何判断小盒子已经落到了大盒子的边界的问题。


判断碰撞:前面在给大盒子(背景)建模的时候,给大盒子的四周都围了2层1。


那我们可以这样来判断小盒子与大盒子的碰撞。小盒子的数组与其在大盒子数组中的对应位置的值相与。显然若果与后的值为1,证明大盒子与小盒子在此处的值都为1,及表明在此处发生了碰撞。而在最首先背景(大盒子)中都为0,只有边界处有2层1。这时只用来了判断小盒子是否出界。当小盒子降落到大盒子底部后,将小盒子的内容对应写入大盒子数组中,这样大盒子(背景)就得以更新。


int test(int mx, int my, int box[5][5])//测试大小盒子是否碰撞


 {


                /*测试box在map里mx,my位置上是否能着陆*/


                /*这个是最关键的一个函数,它判断是否产生非空冲突*/


               /*但算法还是很简单的*/


    int x, y;


    


     for(x = 4; x >=0; x--)


        for(y = 4; y >=0; y--)


            if(map[y +mx][x + my] && box[x][4-y])


                return 0;


    return 1;


}


void putBox(void)  //把碰撞后的小盒子融入到大盒子中,得到新的大盒子


 {                        /*将curbox填充到地图上*/


    int x, y;


    for(y = 0; y < 5; y++)     /*这个也简单,主要是要根*/


        for(x = 0; x < 5; x++) /*据curx,cury指出位置  */


            if(curbox[y][x])


                map[4-x + curx][y + cury] = curbox[y][x];


}


可以用下面俩副示意图来形象的表示一下:


e8793165-7a1a-418f-8777-ca6ba48a4186.jpg


06b13db7-9fa2-4b13-a067-c99fdf076843.jpg


整体流程:所以我们的主程序的流程可以这样表示:


 while(1)//一次游戏的循环


      {  


        if(!newfall())


         {


            Uart_Printf("game over!. Press any key!\n");


             TGlib_disp_hzk16(180,32,"游戏结束再接再厉",8);


             break;//如果不能再创建新的图形,则游戏结束


           }


         dis_next_box();//显示下一个


    while(1)//一个图形的降落循环


           {                    


          if(!drop())


          


           {       


                 putBox();//把图形加入到背景中       


                clear_line();  //如果有满行则销层,且更新分数和等级      


          break;//退出该图形的降落循环,迎接下一个


        }


        dis_map();//实时显示背景


  dis_box(curx,cury,curbox);//实时显示图形


  Delay_ms((6-level)*100);//下落的速度控制的延时


 


  }


 


}


这里只是为后面的具体实现打下了理论基础,下一编将来讲解具体的代码实现,每个函数的源代码都具体给出。希望观者给予支持。下面先看几张完成后的游戏图片:


296b41d5-49a1-44e9-9930-7435020745eb.jpg0e3dc1ed-2c0b-40e8-9911-5dfea4493edc.jpg


601cc32e-7b21-4221-979c-c86d35605a05.jpg545ad0cf-823e-4bcd-880d-277f3734a037.jpg


 


 

文章评论4条评论)

登录后参与讨论

用户1655369 2011-11-26 17:09

你怎么要用5*5的数组表示,为什么不用4*4的呢?

用户188194 2010-11-27 19:32

能不能把完整的程序发给我,我在做这个程序有些问题想不通,谢了! 我的邮箱: shao.hh@163.com

用户248234 2010-3-20 10:25

向你学习

用户1079511 2008-12-7 10:28

不错,我刚做了贪吃蛇的游戏,回头再试试俄罗斯方块!
相关推荐阅读
用户161601 2013-06-06 11:27
AT91LINUX编译试验 SAMA5DX cortex A5
atmel官方网站www.at91.com中对基于DTB的linux内核编译流程如下:   本文档为本人在ubuntu 10.04下实验流程,红色文字为本人添加的记录; by Jevon...
用户161601 2013-04-21 10:54
ubuntu10.04 vm6.5 hgfs 共享实现
以前用的VMWARE6.5+FC12安装好VM TOOL后 就可以在/mnt/hgfs 访问window中的共享文件夹了; 如今把FC12抛弃了,改装了ubuntu10.04但发现hgfs目录...
用户161601 2012-11-29 09:46
芯片制造工艺流程(转)
  芯片制造工艺流程   芯片制作完整过程包括 芯片设计、晶片制作、封装制作、成本测试等几个环节,其中晶片片制作过程尤为...
用户161601 2011-12-13 14:28
摄像头的组成以及红外摄像头
摄像头的工作原理大致为:景物通过镜头(LENS)生成的光学图像投射到图像传感器表面上,然后转为电信号,经过A/D(模数转换)转换后变为数字图像信号,再送到数字信号处理芯片(DSP)中加工处理,再通...
用户161601 2011-11-01 10:50
KEIL MDK生成 bin 文件 for nxp MCU
说明:本文的实践是基于lpc1343; 要想在keil中直接生成bin文件一般需要加用户命令调用fromelf工具: 如下图在Options for Target 中 加上编译后的命令; ...
用户161601 2011-10-09 11:52
基于新唐DMX512帧头的判断
DMX 512协议是Digital Multiplex的缩写,是灯光行业数字化设备的通用信号控制协议,同时也是是一种国际协议;由美国剧场技术协会(United State Institute for...
我要评论
4
7
关闭 站长推荐上一条 /2 下一条