修導師的8051微處理器課程的期末專題~

基本上是以8051微控制器為基礎製作的簡易RPG遊戲......範例

 

雖然當初在製作的時候很想轟轟烈烈的寫很多事件,不過殘酷的現實告訴我們光是寫了開頭劇情檔案就超過了2K......

所以事件幾乎沒有寫到囉.......(聳肩)

因為寫者我們很而且機台還回去了(不還助教會殺來跟我們拼命阿.....)

所以沒有圖片也沒有影片~

當初只是選這個專題作好玩的,提供程式碼給有興趣的人作參考~

但是出問題或是程式碼有問題請千萬不要來找我.......

 

另外就是因為當初程式超過2K的關係,所以程式碼裡面有些寫法和一般的通用寫法不太一樣,

那是因為我們必須在程式碼做到2K內,但是這個是加過註解的版本,

所以一些刪掉的LED函式和蜂鳴器函式都有補回去,所以檔案是超過2K的,

如果是使用試用版的人~可以把那些多餘的函式刪掉就可以了~

 

 


 

[專案描述]

1.以8051作為基礎的簡易式的RPG小遊戲。

2.經由玩家選擇行徑路線,選擇不同的路線會遇上不同事件和選項,且依照事件判定增減玩家生命值。

3.遇上事件時會閃起LED燈號。

4.行徑到結局判定遊戲成功,當生命值為零則為遊戲失敗。

 

[專案規格]

 

  1 × 8051 微控制器

  1 × 9X2中文LCD

  1 × LED

  1 × 七段顯示器

  1 × 四鍵按鈕開關

 

 

>>9X2中文LCD用來顯示系統說明、對話和選項,讓使用者明瞭遊戲的行進。

>>四鍵按鈕開關作為對話的進行鍵,和使用者遭遇選項時的選擇鍵。

>>七段顯示器用來顯示使用者當前的生命值。

>>LED用來顯示使用者目前遭遇的狀況,當使用者遭遇事件時閃爍。

 

[接線方式]

 

9X2中文LCD

J12 (D0~D7) J72 (P20-P27)

J13 (ER/WRS) J74 (P35-P37)

 

四鍵按鈕開關

J90 (PB1-PB4) J75 (P30-P33)

 

七段顯示器

a ~ dp J70 (P10-P17)

DSP1 J60 短路

 

LED

J7 J67 (P00-P07)

 

 


[C程式碼]

 

#include<at89x51.h>
 
#define RS P3_7
#define RW P3_6
#define EN P3_5
#define DATA_BUS P2

unsigned char KeyStatus;//按鈕狀態
unsigned char key=0;
unsigned char hp=2;
unsigned char i=0;
unsigned char j=0;
unsigned char k=0;

//數字顯示0-9
unsigned char segcode[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

//LED
unsigned char event[]={0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa};
unsigned char gameover[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
unsigned char end[]={0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff};


//=============================================================
// 中文LCD函式 
//=============================================================

//DELAY副程式
void lcddelay(unsigned int dly)
{
  while(dly)
    dly--;
}

//LCD bzcheck 副程式
void checkbz(void)
{
  RS=0;
  RW=1;
  EN=1;
  lcddelay(255);
  lcddelay(255);
  lcddelay(255);
  EN=0;
}

//P2 to LCD_DATA程式
void lcddata(unsigned char ins)
{
  DATA_BUS=ins; 
}

//lcd指令--write instructions副程式
void wins(unsigned char ins)
{
  RS=0;
  RW=0;
  EN=1;
  lcddata(ins);
  EN=0;
  checkbz();
  lcddelay(100);
}

//lcd gotoxy副程式
void gotoxy(unsigned char x,unsigned char y)
{
  if(y==0)
    lcddata(0x80+x);
  else if(y==1)
    lcddata(0x90+x);
  RS=0;
  RW=0;
  EN=1;
  EN=0;
  lcddelay(150);
}

//lcd輸出單字副程式
void wdat(unsigned char dat)
{
  RS=1;
  RW=0;
  EN=1;
  lcddata(dat);
  EN=0;
  lcddelay(50);
}

//lcd輸出字串副程式
void prst(unsigned char *dat,unsigned char strlong)
{
  unsigned char i;
  for(i=0;i<strlong;i++)
  {
    wdat(dat[i]);
  }
}

//初始lcd副程式
void initlcd(void)
{
  wins(0x30);
  wins(0x0c);
  wins(0x02);
  wins(0x06);
  wins(0x01);
  wins(0x14);
}

//清除LCD副程式
void cls(void)
{
  wins(0x01); 
}

//lcd在座標xy輸出字串副程式(會先清除原先字串)
void aa(unsigned char x,unsigned char y,unsigned char *dat,unsigned char strlong)
{
  cls();
  gotoxy(x,y);
  prst(dat,strlong);
}

//lcd在座標xy輸出字串副程式
void bb(unsigned char x,unsigned char y,unsigned char *dat,unsigned char strlong)
{
  gotoxy(x,y);
  prst(dat,strlong);
}


//=============================================================
// 確認按鈕狀態 
//=============================================================

//歸零
void KeyScan(void)
{
  P3_0=1;
  P3_1=1;
  P3_2=1;
  P3_3=1;
 
  KeyStatus=~P3;
  KeyStatus=KeyStatus << 4;
  KeyStatus=KeyStatus >> 4;
}

//按鈕流程
void Scan(void)   
{
  KeyScan();
  if(KeyStatus!=0)    //將按鈕狀態存入KEY
  key=KeyStatus;
}

//延遲
void del(unsigned int s)
{
      for(i=0;i<255;i++){
        for(j=0;j<s;j++)
            lcddelay(255);
    }
}


//=============================================================
// LED燈 
//=============================================================
void led_event(void)
{
    for(k=0;k<16;k++){
        P0=event[k];
        del(1);
    }
}

void led_over(void)
{
    for(k=0;k<8;k++){
        P0=gameover[k];
        del(3);
    }
}

void led_end(void)
{
    for(k=0;k<16;k++){
        P0=end[k];
        del(2);
    }
}

//=============================================================
// 遊戲函式 
//=============================================================
void over(void)
{
    aa(0,0,"鄭老師:",8);
    bb(0,1,"同學明年見......",16);
    led_over();

    while(1){}
}

//顯示現在分數
void seven(unsigned int num)
{
    P1=segcode[num];    //顯示現在的分數
    if(num==0)    //如果分數為0則呼叫over()
      over();
}




//=============================================================
//主程式
//=============================================================

main()
{
      initlcd();
ma:
    P1=segcode[0];
       aa(0,0,"簡易 RPG範例系統",16);
        bb(0,1,"按 PB1進行遊戲",10);
    del(5);

    while(1)
    {
        Scan();
        if(key==0x01)    如果按下PB1
        {
                 aa(0,0,"鄭老師:同學你這學",18);
                bb(0,1,"期很不認真喔!",14);
            del(4);
                 aa(0,0,"鄭老師:這樣下去,",18);
                bb(0,1,"這學期我只能給你..",18);
            del(4);
                 aa(0,0,"豬腳:多、多少?",16);
                bb(0,1," (._.?)",10);
            del(4);
                 aa(0,0,"鄭老師:....2分",16);
                bb(0,1,"┐ (─_─) ┌",14);
            del(4);

                 aa(0,0,"豬腳:什、什麼!!",16);
                bb(0,1," ̄□ ̄||",8);
            del(4);
                 aa(0,0,"豬腳:老、老師我會",18);
                bb(0,1,"好好努力的!!",14);
            del(4);
                 aa(0,0,"豬腳:請再給我一次",18);
                bb(0,1,"機會吧!!",10);
            del(4);

                 aa(0,0,"鄭老師:就給你一次",18);
                bb(0,1,"補救的機會吧!",14);
            del(4);

                 aa(0,0,"鄭老師:等下我會把",18);
                bb(0,1,"你的note還你",12);
            del(4);

                 aa(0,0,"鄭老師:你要在下次",18);
                bb(0,1,"來學校前",8);
            del(4);

                 aa(0,0,"鄭老師:把分數加到",18);
                bb(0,1,"及格,You can pass",18);
            del(4);

                 aa(0,0,"豬腳:老師你真是個",18);
                bb(0,1,"好人!!",6);
            del(4);

                 aa(0,0,"系統:你要參加補考",18);
                bb(0,1,"活動嗎?",8);
            del(4);

                 aa(0,0,"是>PB4",6);
                bb(0,1,"否>PB3",6);
            del(4);

            break ;
        }
    }

    key=0x00;    //歸零

        while(1)
        {
        Scan();
        if(key==0x08)    //如果按下PB4
        {
            seven(2);
                 aa(0,0,"鄭老師:同學加油喔",18);
            del(4);
            break ;
        }
        if(key==0x04)    //如果按下PB3
        {
                  over();    //進入OVER結局
            del(4);
            break ;
        }
        }

    key=0x00;    //歸零

    initlcd();
         aa(0,0,"系統:選項一按PB4 ",18);
        bb(0,1,",選項二按PB3 。",16);
    del(4);

         aa(0,0,"系統:前方有兩條路",18);
        bb(0,1,",你要選擇哪一條?",18);
    del(4);
    initlcd();
         aa(0,0,"1.左邊",6);
        bb(0,1,"2.右邊",6);
    del(4);

        while(1)
        {
        Scan();
        if(key==0x08)    //如果按下PB4
        {
                 aa(0,0,"系統:警告!因為程",18);
                bb(0,1,"式碼大小超過2K",14);
            del(3);
                 aa(0,0,"系統現在強制關閉,",18);
                bb(0,1,"同鞋請離開。",12);
            del(3);

                 aa(0,0,"豬腳:給我等一下!",18);
                bb(0,1,"我的分數啊啊啊!!",18);
            del(3);
            over();    //進入OVER結局
        }

        if(key==0x04)    //如果按下PB3
        {
                 aa(0,0,"系統:天空上掉下",16);
                bb(0,1,"一個牌子",8);
            del(3);
                 aa(0,0,"上面寫著..再來一次",18);
            del(3);           
            goto ma;    //重新開始,跳回開頭
        }

        }

  while(1){}

}

 

Posted by hango000 at 痞客邦 PIXNET Comments(0) Trackback(0) Hits(224)