原创 俄罗斯方块(arm7 44b0 )源码

2010-1-24 11:59 3119 8 10 分类: MCU/ 嵌入式

上接半年前写的一篇关于用arm7实现的俄罗斯方块游戏


几个主要的程序在这里:仅供参考


#include <stdio.h>
//#include <time.h>
#include "eluosi.h"
//#include "glib.h"
#include <stdlib.h>
void base_box( int x, int y,int flag);
//#define MAX_SX      12   /*可见最大X*/
//#define MAX_SY      20
#define MAX_X       16   /*可见最大X*/
#define MAX_Y      22   /*可见最大Y*/
                       /*我们定义了最大的可见X和Y,那么即还有不
                         可见的部分,事实上地图(大盒子)里的左右
                         两侧和底部各两行都被1填充,这样大大简化
                         出界的判断,事实上,在本例中没有这样的
                         代码,因为旁边有一圈1阻止小盒子越出大
                         盒子的按制范围
                        */
#define MAX_C       7    /*最大种类,这个无须解释*/
 int map[MAX_Y][MAX_X]={0}; /*地图\大盒子...MAX_X,Y是可见面积*/
                           /*我已说过需要在外面布两圈"卫兵"*/
 int curbox[5][5];          /*当前下落的盒子*/
 int curx, cury;            /*保存着当前活动盒子在地图上的位置*/
 int nextbox[5][5];         /*保存着下一个形状的盒子*/
//int Max_scro=123;
int  scro="0";
int level="0";
 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}
            }
    };
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];
}


int newfall(void) {            /*创建下落元素失败返回0*/
    int x, y;
    cury = 5;  /*重新指定小盒位置*/
    curx = 0;
    for(y = 0; y < 5; y++)
        for(x = 0; x < 5; x++)
            curbox[y][x] = nextbox[y][x];/*将nextBox复制过来*/
    rebuidNext();          /*重建nextBox*/
    return test(curx, cury, curbox);
}
   
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;
        }
    }
   
 //   map[19][2]=1;
  //  map[18][10]=1;
                               /*这里初始化出这个形状*/
}                               /*当然是无盖的...*/
void rebuidNext(void)
{    /*新建下一个形状并放到nextbox中*/
    int i, x, y;
   // time_t t;
  //  srand((unsigned) time(&t));
     srand(rand()+MAX_C);
    i = rand()%(MAX_C);          /*从几种方块里面选一种*/
    for(y = 0; y < 5; y++)      /*并复制过来*/
        for(x = 0; x < 5; x++)
            nextbox[y][x] = box[y][x];   /*复制*/
}
void dis_box(int x,int y,int c_box[5][5])//y=0->(ture y="-32")don't display
{
 int i,j;
 
for(i=4;i>=0;i--)
  for(j=0;j<5;j++)
   {
    if(c_box[j])
    
     base_box((20-x)*16-(4-i)*16,y*16+j*16-32,1);
   // else
       // base_box(x-i*16,y+j*16,0);
   } 
}
void dis_next_box(void)
{
 int i, j;
 for(i=4;i>=0;i--)
    for(j=0;j<5;j++)
     {
     if(nextbox[j])
     base_box_8X8(320-(4-i)*8,192+j*8,1);
     else
   base_box_8X8(320-(4-i)*8,192+j*8,0);
   }
   } 


void dis_map(void)
{
 int i,j;
 for(i=0;i<MAX_Y;i++)
  for(j=0;j<MAX_X-2;j++)
   {
   if(map[j])
  //if(map[i+2][j])
    
      base_box(320-i*16,j*16-32,1);
     else
          base_box(320-i*16,j*16-32,0);
        }
 }


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];
}
   
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;
}


int drop(void) {                    /*下落,返回成功与否*/
    int newx;                   /*盒子要下落的新位置*/
    newx = curx +1;            /*为当前Y位置+1*/
    if(test(newx,cury,  curbox)) {
        curx = newx;            /*测试下落盒在这个位置*/
        return 1;               /*上是否有冲突,没有的话*/
    }                           /*直接设置cury*/
    return 0;
}



int move(int dir) {            /*返回成功与否*/
    int newy;
    if(dir) newy = cury + 1;
                      /*与drop一样,准备移动后的坐标*/
    else newy = cury - 1;
    if(test(curx, newy, curbox)) { /*测试是否冲突*/
        cury = newy;           /*可以的话切换curx*/
        return 1;
    }
    return 0;
}


int rotate(void) {
    int x, y;
    int newbox[5][5];    /*我们必须将当前盒子转动到新的盒子*/
                         /*再对这个新的盒子的冲突作测试*/
    rotateBox(curbox, newbox);    /*转动到新的盒子*/
    if(test(curx, cury, newbox)) {
                         /*并且新的盒子能放到地图上而不冲突*/
        for(y = 0; y < 5; y++)
            for(x = 0; x < 5; x++)
                curbox[y][x] = newbox[y][x];     /*复制进来*/
        return 1;
    }
    else return 0;
}
void Get_scroce(void)
{
 char scroce[5];
 char lev[2];
    sprintf(scroce,"%d",scro);
     sprintf(lev,"%d",level);
    TGlib_disp_ascii16x8(320-64-4,192,lev,8);//
    TGlib_disp_ascii16x8(320-88-20,192,scroce,8);
   
}


void clear_line(void) {                 /*清除掉满行*/
                /*这个函数实际上效率也很低的,为了简便
                  它从头到尾作了测试*/
/*具体的算法为:
  从第0行开始到最后一行,测试地图点阵是否为满,如果是的话
  从当前行算起,之上的地图向下掉一行*/
    int x, y;
    int dx, dy;
    int fullflag;
    for(y = 2; y < MAX_Y - 2; y++) {  /*最后两行保留行*/
        fullflag = 1;                 /*假设为满*/
        for(x = 2; x < MAX_X - 2; x++) {    /*保留列~*/
            if(!map[y][x]) {
                fullflag = 0;
                break;
            }
        }
        if(fullflag) {               /*向下移动一行*/
            for(dy = y; dy > 0; dy--)
                for(dx = 2; dx < MAX_X - 2; dx++)
                    map[dy][dx] = map[dy - 1][dx];
            for(dx = 2; dx < MAX_X - 2; dx++)
                map[0][dx] = 0;
                          /*并清除掉第一行*/
            scro+=100;
            if(scro>=1000) level++;
            Get_scroce();
        }
    }
}
void Menu_eluosi(void)
{
  Glib_FilledRectangle(0,0,320,192,180);//1yelllow
 
 
        //Glib_Line(0,48,320,48,200);//
      Glib_FilledRectangle(0,192,320-40,240,120);//2 blue
       Glib_FilledRectangle(320-40,192,320,240,120);//3
       TGlib_disp_hzk16(320-48,192,"下一个",8);
      Glib_FilledRectangle(320-48-16,192,320-48-16-3,240,210);//line
   //    TGlib_disp_ascii16x8(320-64-4,192,Max_scroce,8);
      
        TGlib_disp_hzk16(320-64-8-16,192,"级别",8);
        Glib_FilledRectangle(320-88-16,192,320-88-16-4,240,210);//line
    //      TGlib_disp_ascii16x8(320-88-4,192,scroce,8);
       Get_scroce();
        
         TGlib_disp_hzk16(320-88-20-16,192,"得分",8);
           Glib_FilledRectangle(320-140,192,320-146,240,210);//line
         TGlib_disp_hzk16(320-140-16,192,"肖捷文",8);
         TGlib_disp_hzk16(320-140-18-16,192,"制作",8);
        Glib_FilledRectangle(146-16,192,146-16-4,240,210);//line
        TGlib_disp_hzk16(146-20,192,"献给",8);
          TGlib_disp_hzk16(146-20-20,192,"李莎",8);
             Glib_FilledRectangle(106-16,192,106-16-4,240,210);//line
         TGlib_disp_ascii16x8(106-20-4,192,"QQ:521",8);
          TGlib_disp_ascii16x8(106-20-20,192,"73509",8);
            Glib_FilledRectangle(16+4,192,16,240,210);//line


 


}


 



void Test_LcdColor(void)
{
    int i,j,k;
  
   // rPDATE="rPDATE"&~(1<<5)|(1<<5); //GPE5=H 
   // rPCONE="rPCONE"&~(3<<10)|(1<<10); //GPE5=output
    //rPCONC=rPCONC&~(0xff<<8)|(0xff<<8); //GPC[4:7] => VD[7:4]
   // rPCONC=(rPCONC&0xfffcffff)|0x1ff00;
   // rPCOND=(rPCOND&0x0)|0xaaaa;
   // rPDATC&=0xfeff;
   
    Uart_Printf("[(240x3)x320 COLOR ST1sss]\n");
 
    Uart_Printf("     R:0   ...    7 \n");
    Uart_Printf("G:0  B0:1 B0:1 B0:1 \n");
    Uart_Printf("G:.   2:3  2:3  2:3 \n");
    Uart_Printf("G:.  B0:1 B0:1 B0:1 \n");
    Uart_Printf("G:.   2:3  2:3  2:3 \n");
    Uart_Printf("G:.  B0:1 B0:1 B0:1 \n");
    Uart_Printf("G:7   2:3  2:3  2:3 \n");
    Lcd_DispON();
    Lcd_Init(MODE_COLOR);
   
    Glib_Init(MODE_COLOR);


    Glib_ClearScr(0);
   
   
   
    Uart_Printf("The screen is clear!\n");
     Kb_init();//键盘中断初始化
     Menu_eluosi();//显示界面
    while(1)//整个游戏大循环
    {
       Key_value=5;
     
     TGlib_disp_hzk16(200,32,"请按第一个键开始",8);
     Uart_Printf("按任意键开始1111!!!\n");
        while(Key_value!=0)
        Uart_Printf("按\n") ;   //等待开始
       Uart_Printf("按任意键开始1111!!!\n");
        Menu_eluosi();//显示界面 
        initMap();//初始化背景数组
        rebuidNext(); 
       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);//下落的速度控制的延时
   
    }
   }


}

文章评论2条评论)

登录后参与讨论

用户161601 2010-3-23 11:20

c呀

用户248234 2010-3-22 16:11

你这是用什么语言编的啊
相关推荐阅读
用户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...
我要评论
2
8
关闭 站长推荐上一条 /2 下一条