|
MSP430單片機游戲程序,俄羅斯方塊,采用TI公司官方MSP430F5529開發板.TI公司的官方開發板,原理圖網上都有,TI官網也有下的
0.png (861.66 KB, 下載次數: 124)
下載附件
2017-3-13 02:15 上傳
0.png (418.57 KB, 下載次數: 135)
下載附件
2017-3-13 02:15 上傳
源碼:
- /*基于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=1;
- 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<MapHigh+1;i++)
- {
- Dogs102x6_pixelDraw(0, i, ON);
- Dogs102x6_pixelDraw(MapWide+1, i, ON);
- }
- for(i=0;i<MapWide+2;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<MapHigh;i++)
- {
- for(j=0;j<MapWide;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<MAXHANG;hang++)
- {
- if(cubeMap[hang]!=0) //跳過某行全為零的地方
- for(lie=0;lie<MAXLIE;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;
- }
- }
復制代碼
0.png (68.06 KB, 下載次數: 126)
下載附件
2017-3-13 02:16 上傳
全部源碼打包下載:
俄羅斯方塊游戲.rar
(75.65 KB, 下載次數: 86)
2017-3-13 02:19 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|
|