久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

立即注冊 登錄
返回首頁

uid:111475的個人空間

日志

俄羅斯方塊

已有 1111 次閱讀2016-3-31 02:15 | 俄羅斯方塊

/************************************************************************************
*  標(biāo)題: *******************俄羅斯方塊游戲*******************************************
*            連接方法:無需跳線。需要插上,12864(控制器st7920)液晶屏。                                 *                                                                                                                            
*                                                                                                                                                                   *
*                 1.進(jìn)階,游戲程序,感興趣的朋友可以看看代碼,自己理解。                     *     
*             2.游戲,按鍵功能說明; 1 號鍵盤(設(shè)置)        :暫停/開始                                          *
*                                                                2 號鍵盤(確認(rèn))         :翻轉(zhuǎn)                                                        *
*                                             3 號鍵盤(時間-)        :左移                                                        *                                                 
*                                                        4 號鍵盤(時間-)        :右移                                                        *
*                                                                                                                                                              *
*               第二功能鍵 ;當(dāng) 1 號鍵盤(設(shè)置)        :暫停/開始   按下后            *
*                                                    3,4號鍵是設(shè)置游戲難度的。                                               *
*                                                                                                                   *
*                                                                                                                                                                    *
*       Easy board 出品                                                                          *
                                                                                                                                                                                                                                                                                                                          *
*************************************************************************************/
//12864并行接口參考程序,控制器st7920  
#include "reg52.h"
#include "Lcd12864.h"
#include "Key.h"
#include "boardinit.h"

#define uchar unsigned char
#define uint unsigned int

static unsigned long Seed = 1;
#define A 48271L
#define M 2147483647L
#define Q (M / A)
#define R (M % A)
/************************************
偽隨機(jī)數(shù)發(fā)生器
*************************************/
double Random(void)
{
        long TmpSeed;
        TmpSeed=A*(Seed%Q)-R*(Seed/Q);
        if(TmpSeed>=0)
                Seed=TmpSeed;
        else
                Seed=TmpSeed+M;
        return (double)Seed/M;
}

/**************************************
為偽隨機(jī)數(shù)發(fā)生器播種
***************************************/
void InitRandom(unsigned long InitVal)
{
        Seed=InitVal;
}

//延時子程序
void Delay(unsigned int t)
{  
        unsigned int i,j;
        for(i=0;i<t;i++)
                for(j=0;j<10;j++);   
}

#define LGOU 0
#define RGOU 1
#define RZ        2
#define LZ        3
#define T        4
#define GUN 5
#define BOX 6
unsigned int idata num[19+2]={
0xfff,//第1行,最下面
0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,
0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,//第2行到第20行共19行
0xfff//第21行,最上面

};//定義共21行,其中num[0]為下墻壁行,num[20]為上墻壁行,每行12格,最左一格為左墻壁列,最右一格為右墻壁列
unsigned char code Block[28][2]={
/*
*   口     口口口   口口
*   口     口         口      口
*   口口              口  口口口      
*/
{0x88,0xc0},{0xe8,0x00},{0x62,0x20},{0x02,0xe0},
/*
*   口        口口 口口口
*   口 口     口       口
* 口口 口口口 口   
*/
{0x22,0x60},{0x08,0xe0},{0xc8,0x80},{0xe2,0x00},  
/*
*   口
*   口口         口口
*     口       口口
*/
{0x8c,0x40},{0x6c,0x00},{0x8c,0x40},{0x6c,0x00},
/*
*   口        口口
* 口口          口口
* 口
*/
{0x4c,0x80},{0xc6,0x00},{0x4c,0x80},{0xc6,0x00},  
/*
*          口                口
*   口     口口   口口口   口口
* 口口口   口       口       口
*/
{0x04,0xe0},{0x8c,0x80},{0xe4,0x00},{0x26,0x20},
/*口
* 口
* 口       口口口口
* 口
*/
{0x44,0x44},{0x0f,0x00},{0x44,0x44},{0x0f,0x00},  
/*
* 口口
* 口口
*/  
{0x06,0x60},{0x06,0x60},{0x06,0x60},{0x06,0x60}
};

#define PASSSCORE 20
struct Jimu
{
        unsigned int dat;
        char x;
        unsigned char y;
        unsigned char type;
        unsigned char change;
}Sign[3];//積木結(jié)構(gòu)體

unsigned char SysFlag=0;
#define NEWSIGNFLAG 0
#define DEADFLAG 1
#define PAUSEFLAG 2

unsigned char Score=0;
unsigned char Level=1;
unsigned char DelayCnt=5;
unsigned char KeyBuffer=0;
#define RESEVER 1
#define CHANGE 2
#define DOWN 3
#define LEFT 4
#define RIGHT 5
#define PAUSE 6

/*********************************
初始化MPU
**********************************/
void InitCpu(void)
{
        TMOD=0x0;
        TH0=0;
        TL0=0;
        TR0=1;
        ET0=1;
        EA=1;
}

/*****************************
定時中斷服務(wù)子程序
******************************/
void Timer0Int(void) interrupt 1
{
        switch(OSReadKey())
        {
                case 9:
                                KeyBuffer=PAUSE;
                                break;
                case 13:
                                KeyBuffer=CHANGE;
                                break;
                case 17:
                                KeyBuffer=DOWN;
                                break;
                case 21:
                                KeyBuffer=RIGHT;
                                break;
                   case 25:
                                KeyBuffer=LEFT;
                                break;
                default:
                                break;
        }
}

/******************************
畫墻壁,初始化界面
*******************************/
void DrawBoard(void)
{
        unsigned char n;
        for(n=0;n<12;n++)
        {
                Lcd_Rectangle(3*n,0,3*n+2,2,1);
                Lcd_Rectangle(3*n,60,3*n+2,62,1);
        }
        for(n=0;n<20;n++)
        {
                Lcd_Rectangle(0,3*n,2,3*n+2,1);
                Lcd_Rectangle(33,3*n,35,3*n+2,1);               
        }
        Lcd_WriteStr(4,0,"Easy出品");
        Lcd_WriteStr(3,2,"Score:");
        Lcd_WriteStr(3,3,"Level:");
}

/***********************************
游戲結(jié)束處理
************************************/
void GameOver(void)
{
        if((SysFlag&(1<<DEADFLAG))!=0)
                Lcd_WriteStr(3,1,"You Fail");
        else
                Lcd_WriteStr(3,1,"You Pass");
}

unsigned int code MaskTab[16]={
0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080,
0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000
};

/**********************************
根據(jù)積木圖標(biāo)左下坐標(biāo)X,Y來畫出積木圖標(biāo)
***********************************/
void DrawSign(struct Jimu Temp,unsigned char DrawMode)
{
        unsigned char m,n;
        for(m=0;m<4;m++)
                for(n=0;n<4;n++)
                {
                        if((Temp.dat&MaskTab[4*m+n])!=0)
                                Lcd_Rectangle(Temp.x+n*3,Temp.y-2-3*m,Temp.x+n*3+2,Temp.y-3*m,DrawMode);
                }
}

/********************************
將積木圖標(biāo)值融入num數(shù)據(jù)中
也即把積木圖標(biāo)固定,無法再下降
*********************************/
FixSign(void)
{
        unsigned char m,n;
        for(m=0;m<4;m++)//行循環(huán)
                for(n=0;n<4;n++)//列循環(huán)
                {
                        if((Sign[0].dat&MaskTab[4*m+n])!=0)
                        {
                                num[20-(Sign[0].y-2)/3+m]|=MaskTab[11-Sign[0].x/3-n];
                        }
                }
}

/********************************
判斷積木圖標(biāo)中方塊是否與障礙方塊重合
*********************************/

unsigned char CheckIf(void)
{
        unsigned char m,n;
        for(m=0;m<4;m++)//行循環(huán)
                for(n=0;n<4;n++)//列循環(huán)
                {
                        if((Sign[1].dat&MaskTab[4*m+n])!=0)
                        {
                                if((num[20-(Sign[1].y-2)/3+m]&MaskTab[11-Sign[1].x/3-n])!=0)
                                        return 0;
                        }
                }
        return 1;
}

/********************************
判斷積木圖標(biāo)是否可以繼續(xù)下降一格
********************************/
unsigned char CheckIfDown(void)
{
        Sign[1]=Sign[0];//
        Sign[1].y+=3;//假設(shè)下降一格       
        return CheckIf();
       
}

/********************************
判斷積木圖標(biāo)是否可以向左移動
*********************************/
unsigned char CheckIfLeft(void)
{
        Sign[1]=Sign[0];
        Sign[1].x-=3;       
        return CheckIf();
}

/********************************
判斷積木圖標(biāo)是否可以向右移動
*********************************/
unsigned char CheckIfRight(void)
{
        Sign[1]=Sign[0];
        Sign[1].x+=3;       
        return CheckIf();
}

/********************************
判斷是否可以旋轉(zhuǎn)
*********************************/
unsigned char CheckIfRoll(void)
{
        unsigned char i;
        unsigned int Temp;
        Sign[1]=Sign[0];
        if(++Sign[1].change>3)
                Sign[1].change=0;
           i=Sign[1].type*4+Sign[1].change;
        Temp=(unsigned int)Block[0]<<8;
        Temp=Temp|Block[1];
        Sign[1].dat=Temp;
       
        return CheckIf();
}

/********************************
尋找滿格的行并做消除處理
最多尋找4個滿行并做消除
*********************************/
void DelFull(void)
{
        unsigned char m,n;
        unsigned char Temp;
        unsigned char Flag=0;
        Temp=(Sign[0].y-2)/3;
        if(Temp>=20)//防止越過了下邊界
                Temp=1;
        else
                Temp=20-Temp;
        for(n=Temp+3;n>=Temp;n--)//積木圖標(biāo)的最頂行開始尋找滿行比較有利于運(yùn)算
        {
                if(num[n]==0xfff)
                {
                        Flag=1;
                        for(m=n+1;m<=19;m++)
                        {
                                num[m-1]=num[m];
                        }
                        num[m]=0x801;
                        Score++;//每找到一個滿行,則分?jǐn)?shù)加1
                }
        }
        if(Flag)//為加速而設(shè)置并判斷的標(biāo)志,有已固定的積木有滿格消行變化則重畫積木界面
        {
                for(m=Temp;m<=19;m++)//為加速,不必要重第一行重畫起,只需要從積木圖標(biāo)最下行開始往上的重畫
                        for(n=1;n<=10;n++)
                        {
                                if((num[m]&MaskTab[n])==0)
                                {       
                                        if(Lcd_ReadPixel(30-(n-1)*3,57-(m-1)*3)!=0)//為加速而做的讀象素操作
                                        {
                                                Lcd_Rectangle(30-(n-1)*3,57-(m-1)*3,30-(n-1)*3+2,57-(m-1)*3+2,0);
                                        }
                                }
                                   else
                                {
                                        if(Lcd_ReadPixel(30-(n-1)*3,57-(m-1)*3)==0)//為加速而做的讀象素操作
                                        {
                                                Lcd_Rectangle(30-(n-1)*3,57-(m-1)*3,30-(n-1)*3+2,57-(m-1)*3+2,1);
                                        }
                                }
                        }
        }
}


/*******************************
隨機(jī)產(chǎn)生一個積木圖標(biāo)放到預(yù)產(chǎn)生區(qū)域并顯示出來
********************************/
void CreatSign(void)
{
        unsigned char n;
        unsigned int Temp;

        DrawSign(Sign[2],0);//先清除

        n=Random()*28;
        Temp=(unsigned int)Block[n][0]<<8;
        Temp=Temp|Block[n][1];
        Sign[2].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);//后畫出
}

void PrintScore(void)
{
        unsigned char Str[3];
        Str[0]=(Score/10)|0x30;
        Str[1]=(Score%10)|0x30;
        Str[2]=0;
        Lcd_WriteStr(6,2,Str);
}

void PrintLevel(void)
{
        unsigned char Str[3];
        Str[0]=(Level/10)|0x30;
        Str[1]=(Level%10)|0x30;
        Str[2]=0;
        Lcd_WriteStr(6,3,Str);
}

/********************************
游戲的具體過程,也是貪吃蛇算法的關(guān)鍵部分
*********************************/
void GamePlay(void)
{
       
        unsigned char m,n;
        unsigned int Temp;

        SysFlag|=1<<NEWSIGNFLAG;//剛開始初始化為需要產(chǎn)生新的積木圖標(biāo)
        InitRandom(TL0);
        Lcd_WriteStr(3,1,"Playing");
        PrintScore();
        PrintLevel();
        CreatSign();
        while(1)
        {       
                if((SysFlag&(1<<NEWSIGNFLAG))==1)//判是否需要產(chǎn)生新的積木圖標(biāo)
                {
                        SysFlag&=~(1<<NEWSIGNFLAG);
                        Sign[0]=Sign[2];
                        CreatSign();
                        Sign[0].x=12;
                        Sign[0].y=14;

                        for(m=0;m<4;m++)//行循環(huán)
                        {
                                for(n=0;n<4;n++)//列循環(huán)
                                {
                                        if((Sign[0].dat&MaskTab[15-m*4-n])==0)
                                                break;
                                }
                                if(n==4)
                                        Sign[0].y-=3;
                        }//將積木圖標(biāo)出現(xiàn)置頂
                       
                        for(m=0;m<4;m++)//行循環(huán)
                                for(n=0;n<4;n++)//列循環(huá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)
                                                        SysFlag|=1<<DEADFLAG;
                                        }
                                }
                        if((SysFlag&(1<<DEADFLAG))!=0)
                                break;//如果產(chǎn)生新的積木圖標(biāo)中的方塊與已固定好的方塊重合,則死亡。游戲結(jié)束
                        DrawSign(Sign[0],1);       
                }
                switch(KeyBuffer)
                {
                        case LEFT:
                                        KeyBuffer=0;
                                        if((SysFlag&(1<<PAUSEFLAG))==0)
                                        {
                                                if(CheckIfLeft())
                                                {
                                                        DrawSign(Sign[0],0);
                                                        Sign[0].x-=3;
                                                        DrawSign(Sign[0],1);
                                                }
                                        }
                                        else
                                        {
                                                if(++Level>=10)
                                                        Level=1;
                                                PrintLevel();
                                        }
                                        break;
                        case RIGHT:
                                        KeyBuffer=0;
                                        if((SysFlag&(1<<PAUSEFLAG))==0)
                                        {
                                                if(CheckIfRight())
                                                {
                                                        DrawSign(Sign[0],0);
                                                        Sign[0].x+=3;
                                                        DrawSign(Sign[0],1);       
                                                }
                                        }
                                        else
                                        {
                                                if(++Level>=10)
                                                        Level=1;
                                                PrintLevel();
                                        }
                                        break;
                        case DOWN:
                                        KeyBuffer=0;
                                        if((SysFlag&(1<<PAUSEFLAG))==0)
                                        {
                                                if(CheckIfDown())//判斷是否能繼續(xù)下降一格
                                                {
                                                        DrawSign(Sign[0],0);
                                                        Sign[0].y+=3;
                                                        DrawSign(Sign[0],1);       
                                                }
                                        }
                                        break;
                        case CHANGE:
                                        KeyBuffer=0;
                                        if((SysFlag&(1<<PAUSEFLAG))==0)
                                        {
                                                if(CheckIfRoll())
                                                {
                                                        DrawSign(Sign[0],0);
                                                        if(++Sign[0].change>3)
                                                                Sign[0].change=0;
                                                           m=Sign[0].type*4+Sign[0].change;
                                                        Temp=(unsigned int)Block[m][0]<<8;
                                                        Temp=Temp|Block[m][1];
                                                        Sign[0].dat=Temp;
                                                        DrawSign(Sign[0],1);
                                                }
                                        }
                                        break;
                           case PAUSE:
                                        KeyBuffer=0;
                                        SysFlag^=1<<PAUSEFLAG;
                                        if((SysFlag&(1<<PAUSEFLAG))==0)
                                        {
                                                Lcd_WriteStr(3,1,"          ");
                                                Lcd_WriteStr(3,1,"Playing");
                                        }
                                        else
                                        {
                                                Lcd_WriteStr(3,1,"          ");
                                                Lcd_WriteStr(3,1,"Pause");       
                                        }
                                        break;
                    default:
                                        break;
                }
                if((SysFlag&(1<<PAUSEFLAG))!=0)
                        continue;
                Delay(500);
                if(++DelayCnt>=2*(11-Level))
                {
                        DelayCnt=0;
                        if(CheckIfDown())//判斷是否能繼續(xù)下降一格
                        {
                                DrawSign(Sign[0],0);
                                Sign[0].y+=3;
                                DrawSign(Sign[0],1);
                        }
                        else
                        {
                                FixSign();
                                DelFull();
                                PrintScore();
                                if(Score>=PASSSCORE)
                                {
                                        SysFlag&=~(1<<DEADFLAG);
                                        break;//跳出玩游戲過程
                                }
                                SysFlag|=1<<NEWSIGNFLAG;//新的積木圖標(biāo)產(chǎn)生標(biāo)志置1
                        }
                }
        }
}

void Main()
{  
        InitCpu();//初始化CPU
        boardinit();       
        Lcd_Reset(); //初始化LCD屏
        Lcd_Clear(0);//清屏
        DrawBoard();//畫界面
        GamePlay();//玩游戲
        GameOver();//游戲結(jié)束
        while(1);//要想重玩,只能重啟,可繼續(xù)完善該游戲
}



路過

雞蛋

鮮花

握手

雷人

評論 (0 個評論)

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

返回頂部
主站蜘蛛池模板: 在线婷婷| 国产96色在线 | 精品在线一区二区三区 | 久久亚洲一区 | 免费a国产 | 亚洲最大av| 久久777 | 91在线一区 | av片免费 | 国产高清在线精品 | 97人人澡人人爽91综合色 | 精品一区国产 | 日韩一区二区三区视频 | 一区二区亚洲 | 午夜播放器在线观看 | 国产精品7777777 | 五月免费视频 | www.日日操 | av天天操 | 日韩中文字幕一区二区三区 | 日本一区二区电影 | 日韩精品一区二区三区视频播放 | 日韩国产欧美在线观看 | 怡红院怡春院一级毛片 | 免费一级片 | 男人天堂免费在线 | 一本一道久久a久久精品蜜桃 | 91精品国产综合久久香蕉麻豆 | 欧美一区二区三区在线免费观看 | 国产一区免费视频 | 中文区中文字幕免费看 | 国产精品毛片无码 | 在线超碰 | 亚洲精品一区国语对白 | 国产欧美一区二区三区另类精品 | 日屁视频 | 国产精品欧美日韩 | 91精品久久久久 | 免费黄色a视频 | 成人在线观看亚洲 | 精品亚洲永久免费精品 |