可以用 Proteus仿真的KeilC俄罗斯方块程序.docx
《可以用 Proteus仿真的KeilC俄罗斯方块程序.docx》由会员分享,可在线阅读,更多相关《可以用 Proteus仿真的KeilC俄罗斯方块程序.docx(15页珍藏版)》请在冰豆网上搜索。
![可以用 Proteus仿真的KeilC俄罗斯方块程序.docx](https://file1.bdocx.com/fileroot1/2023-2/5/2e3c5872-27de-4525-893b-02350c3a33c4/2e3c5872-27de-4525-893b-02350c3a33c41.gif)
可以用Proteus仿真的KeilC俄罗斯方块程序
可以用Proteus仿真的KeilC俄罗斯方块程序
时间:
2006-12-29 来源:
作者:
徐文军 点击:
1792 字体大小:
【大中小】
//--------------------------------------------------------------------------//
// 源程序大公开 //
// (c)Copyright2001-2005xuwenjun //
// AllRightsReserved //
// V1.00 //
//--------------------------------------------------------------------------//
//标 题:
俄罗斯方块程序 ?
//
//文件名:
xwj_fk.c //
//版 本:
V1.00 //
//修改人:
徐文军 E-mail:
xuwenjun@ //
//日 期:
05-05-13 //
//描 述:
俄罗斯方块程序 ?
//
//声 明:
//
// 以下代码仅免费提供给学习用途,但引用或修改后必须在文件中声明出处.//
// 如用于商业用途请与作者联系. E-mail:
xuwenjun@ //
// 有问题请mailtoxuwenjun@ 欢迎与我交流!
//
//--------------------------------------------------------------------------//
//老版本:
无 老版本文件名:
//
//创建人:
徐文军 E-mail:
xuwenjun@ //
//日 期:
05-05-13 //
//描 述:
//
// 1、功能完整,直接使用 //
// 2、模块独立性强,移植方便,外部仅init和move函数,修改显示和输入即可//
// 3、对减少内存占用、尽量减少屏幕操作进行适当优化 //
// 4、新方块生成高度随机,绝对无规律 //
// 5、仿真环境为Keil7.5+Proteus6.5,可以联机也可脱机运行 //
// codeSIZE = 1845 ---- //
// constANTSIZE = 326 ---- //
// dataSIZE = 16 19 //
// idataSIZE = 50 ---- //
// bitSIZE = 1 1 //
//--------------------------------------------------------------------------//
#include
#include"xwj_lcd16.h" //字符液晶控制函数声明 //
#include"xwj_lcd6963.h" //T6963C公用函数
#include"xwj_hlkey.h" //P1口行列式键盘//
#include"xwj_serial.h" //串口函数集
#include"change.h" //数制转换
#include"xwj_fk.h" //俄罗斯方块程序
#defineulong unsignedlong
#defineuint unsignedint
#defineuchar unsignedchar
externvoiddelay(unsignedintx);
//----------------俄罗斯方块内部函数----------------------------------------//
voidfk_dot(ucharx,uchary); //显示1个方块点
voidfk_cldot(ucharx,uchary); //清除1个方块点
voidfk_show(void); //显示分数
voidfk_reffk(void); //刷新方块
voidfk_refnew(void); //刷新预览方块
voidfk_refline(yy); //刷新1行背景
bitfk_chk(void); //冲突检查
voidfk_new(void); //产生新方块
voidfk_add(void); //方块合并
/*
//-----------------俄罗斯方块公用函数--------------------------------------//
voidfk_init(void); //方块初始化
voidfk_move(unsignedcharmode); //移动方块
*/
//-------------------------------------------------------------------------//
#defineFULLMAP 0x0fff /*掩码*/
#defineLINEGUAN 20 /*20行过一关*/
#defineNEWX 15 /*预览方块X位置*/
#defineNEWY 12 /*预览方块Y位置*/
#defineLINEMAX 21 /*屏幕最高21行*/
uintidatafk_map[LINEMAX+4]; //背景映象
ucharfk_x,fk_y,fk_r; //方块左右、高度、方向
ucharfk_type; //方块形状
ucharfk_oldx,fk_oldy,fk_oldr; //方块上次左右、高度、方向
ucharfk_newtype,fk_newr; //新方块形状、方向
uintscore; //总分
uintline; //总行数
ucharspeed; //速度
ucharmoven; //速度相关计数器
ucharautomapn; //随机方块的行数
bitfk_run; //俄罗斯方坑蜗吩诵?
ucharcodefk_mod[][4][4]={ //方块模型号,4个方向,4行
0,0,7,2,0,1,3,1,0,0,2,7,0,2,3,2, //_|_
0,0,6,3,0,1,3,2,0,0,6,3,0,1,3,2, //_|~
0,0,3,6,0,2,3,1,0,0,3,6,0,2,3,1, //~|_
0,0,7,4,0,3,1,1,0,0,1,7,0,2,2,3, //|__
0,0,7,1,0,1,1,3,0,0,4,7,0,3,2,2, //__|
0,0,0,15,1,1,1,1,0,0,0,15,1,1,1,1, //____
0,0,3,3,0,0,3,3,0,0,3,3,0,0,3,3, //田字
};
ucharcodestrmap[4][9]={
"不错!
","真棒!
","好极啦!
","太棒了!
",
};
//--------------------------------------------------------------------------//
voidfk_dot(ucharx,uchary) //显示1个方块点
{
printat(x*3+1,241-(y-4)*12,"■");
}
//--------------------------------------------------------------------------//
voidfk_cldot(ucharx,uchary) //清除1个方块点
{
// printat(x*3+1,241-(y-4)*12,"□");
printat(x*3+1,241-(y-4)*12,"┘");
}
//--------------------------------------------------------------------------//
voidfk_show(void) //显示分数
{
printat(50,12,chnint(score,1));
printat(60,12,"00");
printat(40,12,"得分:
");
printat(54,36,chnint(line,1));
printat(40,36,"行数:
");
printat(54,60,chnchar(speed,1));
printat(40,60,"速度:
");
printat(54,84,chnchar(automapn,1));
printat(40,84,"关数:
");
}
//--------------------------------------------------------------------------//
voidfk_reffk(void) //刷新方块
{
uchari,j;
uchartemp;
//----------------------------------------------//清除原来的方块
for(i=0;i<4;i++)
{
temp=(fk_mod[fk_type][fk_oldr][i]);
for(j=fk_oldx;j {
if(temp&0x01)
{
fk_cldot(j,fk_oldy+i);
}
temp>>=1;
}
}
//----------------------------------------------//显示新的方块
for(i=0;i<4;i++)
{
temp=(fk_mod[fk_type][fk_r][i]);
for(j=fk_x;j {
if(temp&0x01)
{
fk_dot(j,fk_y+i);
}
temp>>=1;
}
}
fk_oldx=fk_x;fk_oldy=fk_y;fk_oldr=fk_r; //保存新方块位置
}
//--------------------------------------------------------------------------//
voidfk_refnew(void) //刷新预览方块
{
uchari,j;
uchartemp;
//----------------------------------------------//预览方块
for(i=0;i<4;i++)
{
temp=(fk_mod[fk_newtype][fk_newr][i]);
for(j=NEWX;j {
if(temp&0x01)
{
fk_dot(j,NEWY+i);
}
else
{
fk_cldot(j,NEWY+i);
}
temp>>=1;
}
}
}
//--------------------------------------------------------------------------//
voidfk_refline(yy) //刷新1行背景
{
uchari;
uinttemp;
if(yy>=4)
{
temp=fk_map[yy];
for(i=0;i<12;i++)
{
if((temp&0x01)!
=0)
fk_dot(i,yy);
else
fk_cldot(i,yy);
temp>>=1;
}
}
}
//--------------------------------------------------------------------------//
bitfk_chk(void) //冲突检查
{
uchari;
bitneq=0;
for(i=0;i<4;i++)
{
if((((fk_mod[fk_type][fk_r][i])<=(((fk_mod[fk_type][fk_r][i])< neq=1;
}
return(neq);
}
//--------------------------------------------------------------------------//
voidfk_new(void) //产生新方块
{
srand(rand()+fk_x+fk_y+fk_r);
fk_oldx=fk_x=5;
fk_oldy=fk_y=LINEMAX;
fk_type=fk_newtype;
fk_oldr=fk_newr;
fk_newtype=rand()%7;
fk_newr=rand()%4;
fk_refnew(); //刷新预览方块
if(fk_run)
fk_reffk(); //刷新显示
}
//--------------------------------------------------------------------------//
voidfk_add(void) //方块合并
{
uchari,j;
ucharfull=0x00;
ucharfulltemp;
ucharfullline=0x00;
for(i=0;i<4;i++) //方块合并
{
fk_map[fk_y+i]|=(fk_mod[fk_type][fk_r][i])< full<<=1;
if((fk_y+i>=4)&&(fk_map[fk_y+i]==0xffff)) //满行
{
full|=0x01;
}
}
if(full!
=0) //有满行
{
for(j=0;j<3;j++) //消行闪烁3次
{
delay(300);
fulltemp=full;
for(i=0;i<4;i++) //4行
{
if((fulltemp&0x08)!
=0)
{
fk_map[fk_y+i]^=FULLMAP;
}
fk_refline(fk_y+i);
fulltemp<<=1;
}
}
fulltemp=full;
for(i=fk_y;i {
if((i=fk_map[i]))
{
fk_map[i-fullline]=fk_map[i];
fk_refline(i-fullline);
}
if((i>=LINEMAX+4)&&(fk_map[i-fullline]!
=~FULLMAP))
{
fk_map[i-fullline]=~FULLMAP; //背景映象
fk_refline(i-fullline);
}
if((fulltemp&0x08)!
=0)
{
fullline++;
}
fulltemp<<=1;
}
if(((line+fullline)/LINEGUAN)!
=(line/LINEGUAN))//每20行速度+1
speed++;
line+=fullline; //更新分数、行数
score+=(1< printat(46,180,strmap[fullline-1]); //夸奖
fk_show(); //显示分数
fk_new(); //产生新方块
}
else
{
if(fk_y>LINEMAX-10) //在最高位置碰撞且不能消行则游戏结束
printat(46,180,"加油啊!
"); //加油啊
if(fk_y>LINEMAX-6) //在最高位置碰撞且不能消行则游戏结束
printat(46,180,"糟糕了!
"); //糟糕了
if(fk_y==LINEMAX) //在最高位置碰撞且不能消行则游戏结束
fk_run=0; //方块初始化
else
fk_new(); //产生新方块
}
}
//--------------------------------------------------------------------------//
voidfk_init(void) //方块初始化
{
uchari;
fk_run=0;
moven=0;
Lcd6963Cls();
Lcd6963Rec(0,0,152,255);
Lcd6963ChHz(0); //切换到16X16点阵
printat(2,16,"欢迎光临文君阁");
printat(2,48,"请按键选择:
");
printat(2,80,"-----------------");
printat(2,96,"7左旋8右旋9右旋");
printat(2,112,"4左移5右旋6右移");
printat(2,128,"4速度5开始6关数");
printat(2,144,"1左移2下移3右移");
printat(2,160,"-----------------");
Lcd6963ChHz
(1); //切换到12X12点阵
printat(46,180,"欢迎使用");
fk_show(); //显示分数
while(~fk_run)
{
fk_move(); //等待设置速度关数开始
delay(10);
}
for(i=0;i<4;i++)
{
fk_map[i]=0xffff; //背景映象
} delay(3000);
for(i=4;i {
if(i<(automapn+4))
fk_map[i]=rand()-1|~FULLMAP;//背景映象
else
fk_map[i]=~FULLMAP; //背景映象
fk_refline(i); //刷新1行背景
}
fk_show(); //显示分数
// fk_new(); //产生新方块
}
//--------------------------------------------------------------------------//
voidfk_move(void) //移动方块
{
unsignedchartemp;
if(KeyTest()) //检查有无按键
{
putinbuf(KeyGetcode()); //按键码输入接收缓冲区
}