欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2593|回復: 0
打印 上一主題 下一主題
收起左側

基于單片機的俄羅斯方塊游戲課程設計

[復制鏈接]
跳轉到指定樓層
樓主
ID:243526 發表于 2017-10-27 20:38 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
  • /*基于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=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 & 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;
  •                 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;
  •                 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==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;
  •         }
  • }

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表