完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
/*基于MSP430F5529俄罗斯方块游戏程序*/
//作者: 詹磊 //功能: 基于MSP430F5529俄罗斯方块游戏程序 //说明: 运行环境:ti官方MSP-EXP5529开发板(外接4个带上拉电阻独立按键) // 非原创,思路是从51单片机上移植过来的 // 底层液晶驱动是TI官方提供的LCD API // 游戏算法部分的底层程序多处已经修改,与原版会有较大的差别 //版本: 测试版 V1.0(基本能流畅运行,但需要进一步的美化和优化) #include "MSP430F5529.h" #include "LCD_102x64.h" #include "main.h" #include "Key.h" #define MAXHANG 20 //游戏显示行数 #define MAXLIE 16 //游戏显示列数 #define MapWide 48 //地图宽 #define MapHigh 60 //地图高 #define ON 0 #define OFF 1 #define BIT(n) (1<<(n)) volatile uint cubeMap[MAXHANG]; //地图显示存存 typedef struct{ uchar const * box; //方块图形字模数据指针 uchar cube : 4; //方块形态(占用4个位域) uchar state : 4; //方块状态(占用4个位域) char row; //方块所在行 char column; //方块所在列 } block; block this; uchar liang=11; uchar Speed=1,Score=0; uint timeA=0; uchar downflag=0; uchar randomNumber=0; const uchar cube[]= { /* ■ ■■■ */ 0,4,0xe,0, 0,2,6,2, 0,7,2,0, 4,6,4,0, /*■ ■■■ */ 0,8,0xe,0, 0,4,4,0xc, 0,0,0xe,2, 0,6,4,4, /*■■■ ■ */ 0,0xe,8,0, 0,4,4,6, 0,1,7,0, 6,2,2,0, /*■■ ■■ */ 0,0xc,6,0, 0,2,6,4, 0,6,3,0, 2,6,4,0, /* ■■ ■■ */ 0,6,0xc,0, 0,4,6,2, 0,3,6,0, 4,6,2,0, /*■■■■ */ 0,0xf,0,0, 4,4,4,4, 0,0,0xf,0, 2,2,2,2, /*■■ ■■ */ 0,6,6,0, 0,6,6,0, 0,6,6,0, 0,6,6,0 }; void delay_ms(uint z)//毫秒级延时函数 { uint i,m; for(i=z;i>0;i--) for(m=4500;m>0;m--) { _NOP(); } } //-------------------------------------------// //函数名:八位LED灯控制函数 //入口:Number:Number哪位为一则哪位LED点亮 //出口:Void //功能: //-------------------------------------------// void DigitalLedControl(uchar Number) { if(Number&BIT7) P1OUT|=BIT0; else P1OUT&=~BIT0; if(Number&BIT6) P8OUT|=BIT1; else P8OUT&=~BIT1; if(Number&BIT5) P8OUT|=BIT2; else P8OUT&=~BIT2; if(Number&BIT4) P1OUT|=BIT1; else P1OUT&=~BIT1; if(Number&BIT3) P1OUT|=BIT2; else P1OUT&=~BIT2; if(Number&BIT2) P1OUT|=BIT3; else P1OUT&=~BIT3; if(Number&BIT1) P1OUT|=BIT4; else P1OUT&=~BIT4; if(Number&BIT0) P1OUT|=BIT5; else P1OUT&=~BIT5; } //-------------------------------------------// //函数名:显存清空函数 //入口:Void //出口:Void //功能:清空显存 //-------------------------------------------// void DisplayRamClear() { uchar i; for(i=0;i<20;i++) { cubeMap[i]=0x0; } } //-------------------------------------------// //函数名:两位十进制数字显示函数 //入口: Row:显示的行数 // Column:显示的列数 // Number:需要显示的数字<100 && >=0 //出口:Void //功能: //-------------------------------------------// void Number2BitDisplay(uchar Row,uchar Column,uchar Number) { uchar tempShi,tempGe; tempShi=Number/10; tempGe=Number%10; Dogs102x6_charDraw(Row, Column,tempShi+'0',ON); Dogs102x6_charDraw(Row, Column+6,tempGe+'0',ON); } //-------------------------------------------// //函数名:游戏背景函数 //入口:Void //出口:Void //功能:绘制游戏背景地图 //-------------------------------------------// void GameBackground() { uchar i; for(i=0;i Dogs102x6_pixelDraw(0, i, ON); Dogs102x6_pixelDraw(MapWide+1, i, ON); } for(i=0;i Dogs102x6_pixelDraw(i, 0, ON); Dogs102x6_pixelDraw(i, MapHigh+1, ON); } DisplayRamClear(); Dogs102x6_stringDraw(3, 10, "START",ON); Dogs102x6_stringDraw(1, 51, "NEXT:",ON); Dogs102x6_stringDraw(3, 51, "SPEED:--",ON); Dogs102x6_stringDraw(5, 51, "SCORE:--",ON); Number2BitDisplay(3,87,Speed); Number2BitDisplay(5,87,Score); } //-------------------------------------------// //函数名:游戏Map清空 //入口:Void //出口:Void //功能:清空游戏背景地图(不清空显存) //-------------------------------------------// void GameMapClear() { uchar i,j; for(i=0;i for(j=0;j Dogs102x6_pixelDraw(j+1, i+1, OFF); } } } //-------------------------------------------// //函数名:系统初始化 //入口:Void //出口:Void //功能: //-------------------------------------------// void SystemInit() { WDTCTL = WDTPW + WDTHOLD; P8DIR|=BIT1+BIT2; P8OUT|=BIT1+BIT2; P1DIR|=BIT0+BIT1+BIT2+BIT3+BIT4+BIT5; P1OUT|=BIT0+BIT1+BIT2+BIT3+BIT4+BIT5; InitKey(); UCSCTL3 = SELREF_2; // Set DCO FLL reference = REFO UCSCTL4 |= SELA_2; // Set ACLK = REFO __bis_SR_register(SCG0); // Disable the FLL control loop UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx UCSCTL1 = DCORSEL_7; // Select DCO range 50MHz operation UCSCTL2 = FLLD_1 + 609; // Set DCO Multiplier for 25MHz(这里设置为20MHz适应液晶的SPI通信) // (N + 1) * FLLRef = Fdco // (762 + 1) * 32768 = 25MHz // Set FLL Div = fDCOCLK/2 __bic_SR_register(SCG0); // Enable the FLL control loop TA1CCTL0 = CCIE; // CCR0 interrupt enabled TA1CCR0 = 328-1; TA1CTL = TASSEL_1 + MC_1 + TACLR; // ACLK, upmode, clear TAR _BIS_SR(GIE); Dogs102x6_init(); Dogs102x6_clearScreen(); Dogs102x6_backlightInit(); Dogs102x6_setContrast(11); Dogs102x6_setBacklight(liang); } //-------------------------------------------// //函数名:3x3点显示函数 //入口: x:x轴坐标 // y:y轴坐标 // mode:ON 打点;OFF 消点 //出口:Void //功能: //-------------------------------------------// void Display3x3Pixels(uchar x,uchar y,uchar mode) { x=3*x+1; y=3*y+1; Dogs102x6_pixelDraw(x, y, mode); Dogs102x6_pixelDraw(x+1, y, mode); Dogs102x6_pixelDraw(x+2, y, mode); Dogs102x6_pixelDraw(x, y+1, mode); Dogs102x6_pixelDraw(x+1, y+1, mode); Dogs102x6_pixelDraw(x+2, y+1, mode); Dogs102x6_pixelDraw(x, y+2, mode); Dogs102x6_pixelDraw(x+1, y+2, mode); Dogs102x6_pixelDraw(x+2, y+2, mode); } //-------------------------------------------// //函数名:显示像素点更改函数 //入口: Row:行数 // Column:列数 // mode:ON 打点;OFF 消点 //出口:Void //功能: //-------------------------------------------// void ChangeRamBit(uchar Row,uchar Column,uchar mode) { uint tempData; tempData=(0x8000>>(Column%16)); if(mode==ON) cubeMap[Row]|=tempData; else cubeMap[Row]&=~tempData; } //-------------------------------------------// //函数名:读取某个显示像素点位值函数 //入口: Row:行数 // Column:列数 //出口:uchar 1:所选点位1,0:所选的点位0 //功能: //-------------------------------------------// uchar ReadDisplayRamBit(uchar Row,uchar Column) { uint tempData; tempData=(0x8000>>(Column%16)); if(cubeMap[Row]&tempData) return 1; else return 0; } //-------------------------------------------// //函数名:下一个方块显示函数 //入口: x:x轴坐标 // y:y轴坐标 // *p:图形字模数据指针 //出口:Void //功能: //-------------------------------------------// void showNextCube(uchar const * p,uchar x,uchar y) #define NexPoinX 27 //下一个图形显示的X坐标 #define NexPoinY 2 //下一个图形显示的Y坐标 { uchar i,j,temp; for(i=0;i<4;i++) { temp=0x08; for(j=0;j<4;j++) { if(p[i] & temp) Display3x3Pixels(x+j,y+i,ON); else Display3x3Pixels(x+j,y+i,OFF); temp>>=1; } } } //-------------------------------------------// //函数名:显示函数 //入口:Void //出口:Void //功能:将显存的内容写入显示器显示 //-------------------------------------------// void showCubeMap(void) { uchar hang,lie; for(hang=0;hang if(cubeMap[hang]!=0) //跳过某行全为零的地方 for(lie=0;lie if(cubeMap[hang]&(0x8000>>(lie%16))) Display3x3Pixels(lie,hang,ON); } } } //-------------------------------------------// //函数名:产生新方块函数 //入口:Void //出口:Void //功能: //-------------------------------------------// void createCube(void) { static uchar next=0; this.cube=next; next=randomNumber%7; //产生随机数 this.row=0; //初始行为0 this.column=6; //初始列为6 this.state=0; //初始状态为0 this.box=cube+16*this.cube; //设定方块指针起始地址 showNextCube(cube+16*next,NexPoinX,NexPoinY); //提示区显示下一个方块 timeA=0; downflag=0; } //-------------------------------------------// //函数名:写显存函数 //入口:mode:ON 打点;OFF 消点 //出口:Void //功能:将数据写入显存,同时写入显示器显示 //-------------------------------------------// void writeCubeToMap(uchar mode) { uchar tempData,tempRow,tempColumn,i,j,k=0; for(i=0;i<4;i++) { tempData=this.box[i]; if(tempData==0) continue; for(j=0;j<4;j++) { if(tempData&0x08) { tempRow=this.row+k; tempColumn=this.column+j; ChangeRamBit(tempRow,tempColumn,mode); Display3x3Pixels(tempColumn,tempRow,mode); } tempData<<=1; } k++; } } //-------------------------------------------// //函数名:方块边沿检测函数 //入口:Void //出口:uchar 0:可以继续移动 1:到底,停止移动 //功能: //-------------------------------------------// uchar checkClask(void) { uchar tempData,tempRow,tempColumn,i,j,k=0; for(i=0;i<4;i++) { tempData=this.box[i]; if(tempData==0) //跳过全为零的行 continue; for(j=0;j<4;j++) { if(tempData&0x08) { tempRow=this.row+k; tempColumn=this.column+j; if ( ReadDisplayRamBit(tempRow,tempColumn) //与边上的方块接触 ||(tempRow>=MAXHANG) //到了最底部 ||(tempColumn>=MAXLIE) //到了最右边 ||(tempColumn==255) //到了最左边 ) return 1; //返回1,停止移动 } tempData<<=1; } k++; } return 0; //返回0,可以继续移动 } //-------------------------------------------// //函数名:地图检测函数 //入口:Void //出口:Void //功能:检测地图中是否有满行,有的话就消行,加分,一定分后加速,同时刷一次屏 //-------------------------------------------// void CheckMap() { uchar fullFlag=0; static uchar tempScore=0,tempSpeed=0; char i,j; for(i=MAXHANG-1;i>0;i--) { if(cubeMap[i]==0xffff) { fullFlag++; for(j=i;j>0;j--) { if(j>0) cubeMap[j]=cubeMap[j-1]; else cubeMap[j]=0; } i++; } } tempScore=Score; tempSpeed=Speed; switch(fullFlag) { case 1:Score++;break; case 2:Score+=2;break; case 3:Score+=4;break; case 4:Score+=6;break; default:break; } if(Score>99) { Speed++; if(Speed>9) Speed=1; Score=0; } if(tempScore!=Score) Number2BitDisplay(5,87,Score); if(tempSpeed!=Speed) Number2BitDisplay(3,87,Speed); if(fullFlag) { GameMapClear(); showCubeMap(); } } //-------------------------------------------// //函数名:方块左移函数 //入口:Void //出口:Void //功能: //-------------------------------------------// void moveLeft(void) { writeCubeToMap(OFF); this.column--; if(checkClask()) this.column++; writeCubeToMap(ON); } //-------------------------------------------// //函数名:方块右移函数 //入口:Void //出口:Void //功能: //-------------------------------------------// void moveRigh(void) { writeCubeToMap(OFF); this.column++; if(checkClask()) this.column--; writeCubeToMap(ON); } //-------------------------------------------// //函数名:方块下移函数 //入口:Void //出口:uchar 到底返回1,否则返回0; //功能: //-------------------------------------------// uchar moveDown(void) { writeCubeToMap(OFF); this.row++; if(checkClask()) //到底 { this.row--; writeCubeToMap(ON); CheckMap(); //是否消行 return 1; } else { writeCubeToMap(ON); return 0; } } //-------------------------------------------// //函数名:方块翻转函数 //入口:Void //出口:Void //功能: //-------------------------------------------// void cubeRotation(void) { uchar temp; temp=this.state; writeCubeToMap(OFF); this.state=++this.state%4; this.box=cube+16*this.cube+4*this.state; if(checkClask()) { this.state=temp; this.box=cube+16*this.cube+4*this.state; } writeCubeToMap(ON); } //-------------------------------------------// //函数名:俄罗斯方块结束界面函数 //入口:Void //出口:Void //功能: //-------------------------------------------// void TetrisGameOver() { DisplayRamClear(); GameMapClear(); Score=0; Speed=1; Number2BitDisplay(5,87,Score); Number2BitDisplay(3,87,Speed); Dogs102x6_stringDraw(3, 13, "GAME",ON); Dogs102x6_stringDraw(4, 13, "OVER",ON); } //-------------------------------------------// //函数名:俄罗斯方块游戏运行函数 //入口:Void //出口:Void //功能:不阻塞CPU //-------------------------------------------// void TetrisGame() { uchar temp=0; static uchar Flag=0; if(Flag==0) { createCube(); if(checkClask()) { TetrisGameOver(); delay_ms(1000); GameMapClear(); } else writeCubeToMap(ON); Flag=1; } if(downflag&&Flag) { downflag=0; if(moveDown()) { Flag=0; } } temp=GetKey(); switch(temp) { case KeyUP:cubeRotation();DigitalLedControl(0); break; case KeyDOWN:while(moveDown()==0);Flag=0;DigitalLedControl(1); break; case KeyLEFT:moveLeft();DigitalLedControl(2); break; case KeyRIGHT:moveRigh();DigitalLedControl(3); break; case KeyBACK:DigitalLedControl(4);liang=--liang%12;Dogs102x6_setBacklight(liang); break; case KeyMEU:DigitalLedControl(5); break; case 0: break; default: break; } } void main(void) { SystemInit(); GameBackground(); DisplayRamClear(); GameMapClear(); showCubeMap(); while(1) { TetrisGame(); } } #pragma vector=TIMER1_A0_VECTOR __interrupt void TIMER1_A0_ISR(void) { randomNumber=++randomNumber%100; if(downflag==0) timeA++; if(timeA==(10-Speed)*10) { timeA=0; downflag=1; } } |
|
相关推荐
71 个讨论
|
|
只有小组成员才能发言,加入小组>>
3039个成员聚集在这个小组
加入小组2938 浏览 1 评论
MSP430FR5994 使用库函数 定时器触发AD问题请教
3615 浏览 2 评论
请问怎么把下面51单片机的代码改成msp430 g2 pocket的代码,还有改下时间变成30秒
2350 浏览 1 评论
4813 浏览 1 评论
2579 浏览 1 评论
1335浏览 3评论
MSP430FR5994 使用库函数 定时器触发AD问题请教
3616浏览 2评论
2938浏览 1评论
1524浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-4 07:53 , Processed in 1.510559 second(s), Total 64, Slave 57 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号