C51单片机12864液晶带按键制作俄罗斯方块C源码_第1页
C51单片机12864液晶带按键制作俄罗斯方块C源码_第2页
C51单片机12864液晶带按键制作俄罗斯方块C源码_第3页
C51单片机12864液晶带按键制作俄罗斯方块C源码_第4页
C51单片机12864液晶带按键制作俄罗斯方块C源码_第5页
已阅读5页,还剩12页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

**********去*说明*今*****赤**********************

此程序包含一•个俄罗斯方块.c文件和i个12864.1]文件

********************俄罗]所方块c文彳卜**茨*******************也***

#include"reg5i.h"

#include"I2864.h"

#dcfincucharunsignedchar

#defineuintunsignedint

staticunsignedlongSeed=1;

#defineA48271L

#defineM2147483647L

#dcfincQ(M/A)

#defineR(M%A)

sbitKl=P3A4;

sbitK2=P3A5;

sbitK3=P3A6;

sbitK4=P3A7;

unsignedintidatanum[19+2]={

Oxfff,第1行,最下而

0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,

0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801”第2行到第20行共19行

Oxfff〃第21行,最上而

};〃定义共21行,其中num⑼为下墙壁行,num[20]为上墙壁行,每行12格,最左一格为左墙

壁列,最右一格为右墙壁列

unsignedcharcodeBlock[28][2]={

/*

*口口口口口口

*口口口口

*口口口口口口

*/

{0x88,0xc0},{0xe8,0x(X)M0x62,0x20},{0x02,0xe0},

/*

*口口口口口口

*口口口口

*口口口口口口

*/

{0x22,0x60},{0x08,0xe0},{Oxc8,Ox8O},{0xe2,0x00},

/*

*口

*口口口口

*口口口

*/

{0x8c.0x40}.{0x6c.0x(X)},{0x8c,0x40},{0x6c,0x00},

*uuu

*口口口口

*n

*/

{0x4c.0x80}.{0xc6.0x00}.{0x4c.0x80}.{0xc6,0x00},

/*

*口U

*口口口口口口口口

*口口口口口口

*/

{0x04.OxcO).{Ox8c.Ox8O}.{0xc4.0x00}.{0x26,0x20},

/*口

*口

*口口口口口

*口

*/

{0x44.0x44},{OxOf,OxOO}.{0x44.0x44}.{OxOf.OxOO},

/*

*口口

*口口

*/

{0x06,0x60},{0x06,0x60},{0x06,0x60},{0x06,0x60}

);

#definePASSSCORE20

structJimu

(

unsignedintdat;

charx;

unsignedchary;

unsignedchartype;

unsignedcharchange;

}Sign[3]W积木结构体

unsignedcharSysFlag=O;

#defineNEWSIGNFLAG0

#defineDEADFLAGI

#dcfincPAUSEFLAG2

unsignedcharScore=0;

unsignedcharLcvel=1;

unsignedcharDelayCnt=5;

/*********************************************************/

#defineN25

/******京********************东********

伪随机数发生器

***********************去*************/

doubleRandom(void)

{

longTmpSeed;

TmpSeed=A*(Seed%Q)-R,:(Seed/Q);

if(TnipSecd>=0)

Seed=TmpSeed;

else

Sccd=TmpSccd+M;

retum(double)Seed/M;

/******京*****赤*******在*****今在****京*****

为伪随机数发生器播种

***************************************/

voidInitRandom(unsignedlongInitVai)

Sccd=Ini(Val:

〃延时子程序

voidDelay(unsignedintt)

unsignedinti.j;

for(i=0;i<t;i++)

for(j=0;j<IO;j++);

I

/*********************************

初始化MPU

**********************************/

voidInitCpu(void)

(

TMOD=OxO;

TH0=0;

TL0=0;

TRO=1:

ETO=1;

EXI=1;

EA=1;

TCON|=0x04;

unsignedintcodeMaskTab[16]=(

Ox(XX)l,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080,

0x0100.0x0200.0x0400.0x0800.0x1000.0x2000.0x4000.0x8000

);

/**********************************

根据积木图标左下坐标X.Y米画出积木图标

***木******水*******云***水木***********/

voidDrawSign(structJimuTcmp.unsigncdcharDrawModc)

unsignedcharm,n;

for(m=0:m<4;m++)

for(n=0;n<4;n++)

if((Tcmp.dat&MaskTab[4*m+n])!=0)

Lcd_Rectangle(Temp.x4-n*3,Temp.y-2-3*m,Temp.x+n*34-2,Temp.y-3*ni,DrawMode);

}

/********************************

将积木图标值融入num数据中

也即把积木图标固定,无法再下降

*********************************/

FixSign(void)

unsignedcharm.n;

for(m=0;m<4;m++)〃行循环

for(n=0;n<4:n++)〃列循环

if((Sign[0].dat&MaskTab[4*m+n])!=0)

num[2O-(Sign[O].y-2)/3+m]|=MaskTab[11-Sign[0].x/3-n];

)

/********************************

判断积木图标中方块是否与障碍方块重合

***赤才************米*****赤*********/

unsignedcharChecklf(void)

unsignedcharm,n;

for(m=0;m<4;m++)〃行循环

for(n=0;n<4;n++)〃列循环

if((Sign[1].dat&MaskTab[4*m+n])!=0)

if((num[20-(Signll].y-2)/3+m]&MaskTab[l1-S:gn[l].x/3-n])!=0)

return0;

return1;

)

/*************也******************

判断积木图标是否可以继续下降一格

***********************木*******京/

unsignedcharChcckltDown(void)

Sign[IJ=Sign[Ol;//

Sign[1].y+=3;〃假设下降一格

retumChecklf();

/********************************

判断积木图标是否可以向左移动

*********************************/

unsignedcharChecklfLeft(void)

SignflJ=Sign[OJ;

Sign[l].x-=3;

returnChecklf();

/********************************

判断枳木图标是否可以向右移动

*********************************/

unsignedcharChecklfRight(void)

Sign[l]=Sign[O];

Sign[ll.x+=3;

returnChecklf();

判断是否可以旋转

unsignedcharCheckIfRol1(void)

unsignedchari;

unsignedintTemp;

Sign[l]=Sign[O];

if(++Sign[1].change>3)

Sign!I|.change=0;

i=Sign[1].type*4+Sign[1].change;

Temp=(unsignedint)Blockil(01«8;

Temp=Temp|Block[i][1];

Sign[l].dat=Tcnip;

returnChecklf();

)

寻找满格的行并做消除处理

最多寻找4个满行并做消除

******************量**************/

voidDelFull(void)

(

unsignedcharm,n;

unsignedcharTemp;

unsignedcharFlag=0;

Temp=(Sign|0|.y-2)/3;

if(Tcmp>=20)〃防止越过了下边界

Temp=l;

else

Tcmp=20-Tcinp;

for(n=Temp+3;n>=Temp;n--)〃枳木图标的最顶行开始寻找演行比较有利于运算

(

if(nujn[n]==Oxfff)

(

Flag=l;

for(m=n+l:m<=19:m++)

|

num[m-l]=num[m];

}

num[in]=0x801;

Score++;〃每找到一个满行,则分数加I

}

)

if(Flag)〃为加速而设置并判断的标志,有已固定的积木有满格消行变化则重画积木界面

foi(ni=Temp;m<=19;m++)〃为加速,不必要重第一行重画起,只需要从积木图标最

下行开始往上的重画

for(n=1;n<=10;n++)

(

if((num[m]&MaskTab[n])==O)

(

if(Lcd_ReadPixel(30-(n-l)*3,57・(m“)*3)!=0)〃为加速而做的读象素操

I

Lcd_Rectangle(30-(n-1)*3,57-(m-1)*3,30-(n-1)*3+2,57-(m-1)»3+2,0);

)

1

else

(

if(Lcd-ReadPixel(30-(n-l)*3,57-(m-l)*3)==0)〃为加速而做的读象素操

(

Lcd_Rectangle(30-(n-1)*3,57-(m-1)*3,30-(n-1)*3+2,57-(m-1)*3+2,1);

)

}

/*******************************

随机产生一个积木图标放到预产生.区域并显示出来

**左木木****本木************今布***:!:*木木/

voidCreatSign(void)

unsignedcharn;

unsignedintTemp:

DrawSign(Sign⑵,0);//先清除

n=Random()*28:

Temp=(unsignedint)Blockn][0]«8;

Temp=Temp|Block[n][I];

Sign[21.dat=Temp;

Sign[2].x=45;

Sign[2].y=4*3+2;

Sign[2].type=n/4;

Sign[2].change=n%4;

DrawSign(Sign[2],1)W后画出

voidPrintScorc(void)

(

unsignedcharStr[3];

Str[0]=(Score/10)|0x30;

Str|1l=(Score%10)|0x30;

Str[2]=0;

Lcd_Wri(cStr(6.2.Str);

voidPrintLevcl(void)

(

unsignedcharStr[3];

Str[O]=(Lcvcl/10)10x30;

Str[l]=(Level%10)|0x30;

Str⑵=0;

Lcd_WritcStr(6.3,Str);

游戏的具体过程,也是俄罗斯方块算法的关键部分

************************》******玄*/

voidGamcPlay(void)

(

unsignedcharm,n;

unsignedin(Temp;

S*Flag|=lvvNEWSIGNFLAG;〃刚开始初始化为需要产生新的枳木图标

InitRandom(TLO);

Lcd_Wri(cStr(3J;'Playing");

PrintScore();

PrintLeveK);

CreatSign();

while(l)

{

if((SysFlag&(1«NEWSIGNFLAG))==1)〃判是否需要产生新的积木图标

(

SysFlag&=-(I«NEWSIGNFLAG);

Sign[0]=Sign[21;

CreatSign();

Sign[0].x=l2;

Sign[0].y=14;

for(ni=0:m<4:n】++)〃行循环

(

for(n=0:n<4;n++)〃列循环

(

if((Sign[O].dat&MaskTab[15-m*4-n])=0)

break;

1

if(n==4)

Sign[0].y-=3;

}〃将积木图标出现置顶

for(m=0;m〈4;m++)〃行循环

for(n=0;n<4:n++)/例循环

(

if((Sign[0].dat&MaskTab[4*m+n])!=0)

(

if((num[20-(Sign[0].y-2)/3+m]&MaskTab[11-Sign[0].x/3-n])!=0)

Sysriag|=1«DEADPLAG;

)

)

if((SysFlag&(I«DEADFLAG))!=O)

break;〃如果产生新的积木图标中的方块与己固定好的方块重合,则死亡。

游戏结束

DrawSign(Sign[(.i|,l);

}

if((CheckIfLeft())&&(K3==0))〃左

(

DrawSign(Sign[O],O);

Sign[0].x-=3;

DrawSign(Sign[O]J);

)

if((CheckIfRight())&&(K4==0))〃右

{

DrawSign(Sign[O],O);

Sign[0].x+=3;

DrawSign(Sign[O],1);

)

if<(CheckIfDown())&&(K2==0))〃下

(

DrawSign(Sign[O].O);

Sign[0].y+=3;

DrawSign(Sign[O],1);

if((Check【fRoll())&&(Kl==()))〃翻转

(

DrawSign(Sign[O],O);

if(++Sign[0J.change>3)

Sign[O].changc=O;

m=Sign[0].lype*4+Sign[0].change;

Temp=(unsignedint)Block|m][0]«8;

Temp=Tcmp|Block[m][1];

Sign[O].dat=Temp;

DrawSign(Sign[O],l);

)

if((SysFlag&(1«PAUSEFLAG))!=O)

continue;

Dclay(500);

if(++DelayCnt>=2*(11-Level))

(

DelayCnt=O;

iRChecklfDown())〃判断是否能继续下降一格

(

DrawSign(Sign[O],O);

Sign[0].y+=3;

DrawSign(Sign[O],l);

)

else

{

FixSign();

DelFuli();

PrintScoreO;

if(Scorc>=PASSSCORE)

(

SysFlag&=-(I«DEADFLAG);

break;/:跳出玩游戏过程

)

SysFlag|=l«NEWSIGNFLAG;〃新的积木图榇产生标志置I

voidMain()

IniiCpu();〃初始化CPU

Lcd_Reset();〃初始化LCD屏

Lcd_Clear(O);〃清屏

Lcd_Rcset();〃初始化LCD屏

Lcd_Clear(O);〃清屏

DrawBoard();〃画界面

GamcPlayO;〃玩游戏

GameOverO;〃游戏结束

Lcd_Reset();〃初始化LCD屏

Lcd_Qcar(O);〃清屏

********************12864h文件***********************x***

******************************************************

#include<intrins.h>

sbitRS=P2AO:〃并行的指令/数据选择信号,H数据,L命令

"sbi'tRW^A;:力洋与震誉捻孤莓’节基,;筝

sbitE=P2A2;〃并行使能端,H有效,L无效

sbitPSB=P2人3;〃并/串接口选择,H并,L串

sbitRET=P2A4;〃复位,L有效

tfdetineLedDataPO

unsignedcharLcd_CheckBusy(void)

(

unsignedcharBusy;

LcdData=OxtT;

RS=O;

RW=1;

E=l;

_nop_();

Busy=LcdDala&Ox8O:

E=0;

returnBusy;

/***************************

向LCD写入字节数据

voidLcd_WritcData(unsigncdcharData)

(

while(Lcd_CheckBusy());

RS=1;

RW=0;

E=0;

_nop_();

_nop_();

LedDala=Data;

E=l;

_nop_();

_nop_();

E=0;

/******京********************东*******

从LCD中读出数据

***本木******奈***********京车***********/

unsignedcharLcd_ReadData(void)

unsignedcharTemp;

while(Lcd_CheckBusy());

LcdData=Oxff;

RS=1;

RW=1;

E=l;

_nop_();

Tcmp=LxdData;

E=0;

retumTemp;

/****米木京车****本木****木木****:!:*京木**木**本***

想LCD中写入指令代码

**************************************/

voidLcd_WriteCmd(unsignedcharCmdCode)

(

whilc(Lcd_CheckBusy());

RS=O;

RW=0;

E=0;

_nop_();

-nop_();

LcdData=CmdCode;

_nop_();

_nop_();

E=l;

_nop_();

_nop_();

E=0;

/******今*****赤************************

向LCD指定起始位置写入一个字符串

*************************************/

voidLcd_WriteStr(unsignedcharx.unsignedchary,unsignedchar*Str)

(

if((y>3)||(x>7))

relurn,如果指定位置不在显示区域内,则不做任何写入直接返回

EA=0;

switch(y)

(

case0:

Lcd_WritcCmd(0x80+x);

break;

case1:

Lcd_Wri(cCmd(0x90+x);

break;

case2:

Lcd_WriteCmd(0x88+x);

break;

case3:

Lcd_WriteCmd(0x98+x);

break;

I

while(*Str>0)

(

Ixd_WriteData(*Str);

Str++;

)

EA=1;

I

/**************************************

为加速逻辑运和而设置的掩码表,这是以牺牲空间而换取时间的办法

***************************************/

codeunsignedint

LcdMaskTabf]={0x00()1.0x0()02.0x0004.0x0008.0x0010.0x0020.0x0040.0x0080.

0x01(X),0x02(X),0x()4(X),0x08(X).0x1000,0x2000,0x4000,0x8000}:

/*************也*******************也*****

向LCD指定坐标写入一个象素,象素颜色有两种,0代表白(无显示),1代表黑(有显示)

****************************************/

voidLxd_Pu(Pixel(unsignedcharx.unsignedchary,unsignedcharColor)

unsignedcharz.w;

unsignedintTemp;

if(x>=128||y>=64)

return;

Color=Color%2;

w=15-x%l6;〃确定对这个字的第多少位进行操作

x=x/16;〃确定为一行上的第几字

if(y<32)〃如果为上页

z=0x80;

else〃否则如果为下页

7=0x88;

y=y%32;

EA=0;

Lcd_Wri(cCmd(0x36);

Lcd_WriteCmd(y+0x80);〃行地址

Lcd_WriteCmd(x+z);〃列地址

Tcmp=Lcd_RcadDaia();//先空读一次

Temp=(unsignedinl)Lcd_ReadData()<<8;〃再读出高8位

Tcmp|=(unsigncdint)Lcd_RcadDala0”再读出低8位

EA=1;

if(Color==l)〃如果写入颜色为1

Ten】p|=LcdMaskTab[w];〃在此处查表实现加速

else〃如果写入颜色为0

Temp&=~LcdMaskTab|w];〃在此处查表实现加速

EA=0;

Lcd_WritcCmd(y+0x80);〃行地址

Lcd_WriteCmd(x+z);〃列地址

Lcd_WriteData(Temp»8):〃先写入高8位,再写入低8位

Lcd_WritcData(Tcmp&OxOOff);

Lcd_WriteCmd(0x30);

EA=1;

/******************************************

从LCD指定坐标读取象索颜色值

*******************************************/

unsignedcharLcd_ReadPixel(unsignedcharx,unsignedchary)

unsignedcharz.w;

unsignedintTemp:

if(x>=128||y>=64)

return0;

w=15-x%l6;〃确定对这个字的第多少位进行操作

x=x/16;〃确定为一行上的第几字

if(y<32)〃如果为上页

z=0x80;

else〃否则如果为下页

z=0x88;

y=y%32;

EAR;

Lcd_WnteCmd(0x36);

Lcd_WriteCmd(y+0x80);〃行地址

Lcd_Wri(cCmd(x+z);〃列地址

Temp=Lcd_ReadDala();〃先空读一次

Temp=(unsignedinl)Lcd_ReadDala()«8;〃再读出高8位

Tcmp|=(unsigncdinl)Lcd_RcadDaia(),再读出低8位

EA=1;

if((Temp&&LcdMaskTab[w])==O)

return0;

else

returnI;

/***************************************

向LCD指定位置画一条长度为Length的指定颜色的水平线

*本木***小*左****木木木****木木****:1:*左木**木木本:$:**/

voidLxd_HoriLine(unsignedcharx,unsignedchary,unsignedcharLength,unsignedcharColor)

unsignedchari;

if(Length==O)

return;

for(i=O;i<Length;i++)

Lcd_Pu(Pixcl(x+i,y.Color);

)

/*******************木*****:*******木******

向LCD指定位置画条长度为Length的指定颜色的垂直线

****************************************/

voidLcd_VertLine(unsignedcharx,unsignedchary,unsignedcharLength,unsignedcharColor)

unsignedchari;

if(Length==O)

return;

for(i=0;i<Length;i++)

Lcd_PutPixel(x,y+i,CDlor);

)

/*******************************************

向LCD指定左上角坐标和右下角坐标画一个指定颜色的矩形

***木******水*******云***水木********************/

voidLcd_Rcctanglc(unsigncd

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论