上接半年前写的一篇关于用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);//下落的速度控制的延时
}
}
}
用户161601 2010-3-23 11:20
用户248234 2010-3-22 16:11