危機處理-16X16宮格糞GAME






一開始的想法是先寫一個 draw_block函式,
只需要輸入畫布陣列圖像陣列X,Y座標即可印出整個16X16宮格。
p.s.請記得置於副函式歐同學

//繪圖函式16X16像素   //畫布陣列,主角陣列X座標,Y座標 
void draw_block(unsigned char *buffer, unsigned char *pic_buffer,  unsigned char *pic_buffer2, int x, int y ){ 
  //清空九宮格大小的方塊
  clr_part_pannal(buffer, 0, 60, 0, 7);
  //畫16x16格線
  LineBresenham(buffer, 0, 0, 60, 0, 1);
  LineBresenham(buffer, 0, 0, 0, 60, 1);
  LineBresenham(buffer, 60, 60, 0, 60, 1);
  LineBresenham(buffer, 60, 60, 60, 0, 1);
  LineBresenham(buffer, 0, 15, 60, 15, 1);
  LineBresenham(buffer, 0, 30, 60, 30, 1);
  LineBresenham(buffer, 0, 45, 60, 45, 1);
  LineBresenham(buffer, 15, 0, 15, 60, 1);
  LineBresenham(buffer, 30, 0, 30, 60, 1);
  LineBresenham(buffer, 45, 0, 45, 60, 1);
  //將主角輸入至畫布上
  create_picture(buffer, 15*x, 15*y, pic_buffer, 16, 16);
  //將地雷輸入至畫布上
  create_picture(buffer, 15,  15, pic_buffer2, 16, 16);
  create_picture(buffer, 30,  45, pic_buffer2, 16, 16);
  //將畫布輸出
  draw_part_LCD(buffer, 0, 60, 0, 7); 
}

然後開始著手主程式6
ScanKey函式原本的程式並沒有,記得要宣告

#include <stdio.h>
#include "NUC1xx.h"
#include "Driver\DrvSYS.h"
#include "Driver\DrvGPIO.h"
#include "Driver\DrvSPI.h"
#include "LCD_Driver.h"
#include "LCD_Driver_Extend.h"
#include "ScanKey.h"//記得宣告
void Init_GPIO(void);
extern unsigned char Ascii[];
extern unsigned char man[16][16];
extern unsigned char dick[16][16];
extern unsigned char dick2[16][16];
const unsigned char me[8*128];
unsigned char DisplayBuf [8*128];
unsigned char num[16];
const unsigned char zero [8*128];
const unsigned char one[8*128];
const unsigned char two[8*128];
const unsigned char three[8*128];
const unsigned char four[8*128];
const unsigned char five[8*128];
const unsigned char six[8*128];
const unsigned char seven[8*128];
const unsigned char eight[8*128];
const unsigned char nine[8*128];
const unsigned char one2[8*128];  
const unsigned char two2[8*128];
const unsigned char three2[8*128];
      int main(void)
{
  int i, j, x, key, a=0, b=0, cnt=0, n, m;
  //系統初始化
  UNLOCKREG();
  DrvSYS_SetOscCtrl(E_SYS_XTL12M, 1);
  SysTimerDelay(5000);
  /* HCLK clock source. 0: external 12MHz; 4:internal 22MHz RC oscillator */
  DrvSYS_SelectHCLKSource(0);  
  LOCKREG();    
  //螢幕初始化
  Initial_pannel();  //call initial pannel function
  clr_all_pannal();   
  DrvGPIO_Open(E_GPD, 14, E_IO_OUTPUT);
  DrvGPIO_ClrBit(E_GPD,14);
  //鍵盤初始化
  OpenKeyPad(); 
  DrvGPIO_Open(E_GPD, 14, E_IO_OUTPUT);
  DrvGPIO_ClrBit(E_GPD,14);

  //顯示自我畫面並閃三次
  for(int c=0; c<3; c++){
    draw_LCD(me);
    DrvSYS_Delay(235000);
    DrvSYS_Delay(335000);
    clr_all_pannal();
    DrvSYS_Delay(235000);
    DrvSYS_Delay(235000);
  }
  
  //遊戲畫面初始  //炸彈0.5秒後消失
  draw_LCD(zero);
  draw_block(DisplayBuf, man,  dick, a, b);
  DrvSYS_Delay(200000);
  DrvSYS_Delay(200000);
  DrvSYS_Delay(100000);
  draw_block(DisplayBuf, man,  dick2, a, b);
  //計步器初始顯示
  print_lcd_right(3,"count:0");
  
  
  //遊戲主程式
  while(1) {
    //鍵盤掃描
    key=Scankey();    
   
    //主角移動
    if(key==2&&b>0&&n==0){
      b--; n=1;
      draw_block(DisplayBuf, man, dick2, a, b);
    }
    else if(key==8&&b<3&&n==0){
      b++; n=1;
     draw_block(DisplayBuf, man, dick2, a, b);
    } 
    else if(key==4&&a>0&&n==0){
      a--; n=1;
      draw_block(DisplayBuf, man, dick2, a, b);
    } 
    else if(key==6&&a<3&&n==0){
      a++; n=1;
      draw_block(DisplayBuf, man, dick2, a, b);
    }
    else if(key==7&&a>0&&b<3&&n==0){
      a--; b++; n=1;
      draw_block(DisplayBuf, man, dick2, a, b);
    }
    else if(key==9&&a<3&&b<3&&n==0){
      a++; b++; n=1;
      draw_block(DisplayBuf, man, dick2, a, b);
    }
    else if(key==1&&a>0&&b>0&&n==0){
      a--; b--; n=1;
      draw_block(DisplayBuf, man, dick2, a, b);
    }
    else if(key==3&&a<3&&b>0&&n==0){
      a++; b--; n=1;
      draw_block(DisplayBuf, man, dick2, a, b);
    }
    if(key==0){
      draw_block(DisplayBuf, man, dick2, a, b);
      n=0;
    }
    //圖片計數顯示器
    if(key!=0&&key!=5&&m==0&&n!=0){
      m=1;
      cnt++;
      if(cnt%10==1)draw_part_LCD(one, 62, 127, 0, 7);
      if(cnt%10==2)draw_part_LCD(two, 62, 127, 0, 7);
      if(cnt%10==3)draw_part_LCD(three, 62, 127, 0, 7);
      if(cnt%10==4)draw_part_LCD(four, 62, 127, 0, 7);
      if(cnt%10==5)draw_part_LCD(five, 62, 127, 0, 7);
      if(cnt%10==6)draw_part_LCD(six, 62, 127, 0, 7);
      if(cnt%10==7)draw_part_LCD(seven, 62, 127, 0, 7);
      if(cnt%10==8)draw_part_LCD(eight, 62, 127, 0, 7);
      if(cnt%10==9)draw_part_LCD(nine, 62, 127, 0, 7);
      if(cnt%10==0)draw_part_LCD(zero, 62, 127, 0, 7);
      if(cnt/10==1)draw_part_LCD(one2, 62, 100, 0, 7);
      if(cnt/10==2)draw_part_LCD(two2, 62, 100, 0, 7);
      if(cnt/10==3)draw_part_LCD(three2, 62, 100, 0, 7);
      //文字計數器
      sprintf(num,"count:%d", cnt);
      print_lcd_right(3, num);
     }
    else if(key==0){
      m=0;
    }
   
    //輸贏判斷(win)
    if(a==3&&b==3){
      clr_part_pannal(DisplayBuf, 0, 127, 0, 7);
      draw_part_LCD(DisplayBuf, 0, 60, 0, 7);  
      clr_all_pannal();
      print_lcd(1,"    YOU WIN!!");
      sprintf(num,"    %dSTEPS~~", cnt);
      print_lcd(2,num);
      break;
    }
    //輸贏判斷(lose)
    if((a==1&&b==1)||(a==2&&b==3)){
      clr_part_pannal(DisplayBuf, 0, 127, 0, 7);
      draw_part_LCD(DisplayBuf, 0, 60, 0, 7);  
      clr_all_pannal();
      print_lcd(1,"     LOSE !!");
      break;
    }
  }
}


剩下的圖片陣列都在https://ppt.cc/fjMeWx 同學們ctrl+C起來阿!然後記得都要宣告!

最後講一下keybounce這東西
從學長得到的情報有這種好東西可以使按鍵
不用再使用令人鼻酸的Delay去解決按太久解果偵測到一堆東西的問題

while(1){
//設key=1為按下,key=0為放開
  if(key==1&&n==0){
    n=1;
    執行指令
  }
  else if(key==0){
    n==0;
  }
}
我們假設還沒按按鍵的時候(key=0) n的初始值不為0 
接著進入else if判式令n=0
這時我們按下了按鍵key=1且n=0 ===> 令n=1 並執行指令
(因為while(1)的無窮迴圈掃描速度很快所以這時我們的手在案按鍵的動作中~)
第二次迴圈的時候雖然key值還是1(手還在按著)但是由於n=1所以不執行
直到手放開之後(key=0)才會重置n值為0

備註:甘霖老師我debug到凌晨5點才睡馬的
備註2: print_lcd_right 函式 & Show_World_right

void Show_Word_right(unsigned char x, unsigned char y,unsigned char ascii_word)
{
int i=0,k=0;
 unsigned char temp;   
   k=(ascii_word-32)*16;   
   
   for(i=0;i<8;i++)
   {
   SetPACA((x*2),(129-(y*8)-i-65));
   temp=Ascii[k+i];  
      WriteData(temp);
   }

      for(i=0;i<8;i++)
   {
   SetPACA((x*2)+1,(129-(y*8)-i-65));  
      temp=Ascii[k+i+8];
   WriteData(temp);
   }
}




void print_lcd_right(unsigned char line, char *str)
{
int i=0; 
  do{   
    Show_Word_right(line,i,*str++); 
   i++;
   if(i>15)
   break;
    }
   while(*str!='\0');
}

留言

張貼留言

這個網誌中的熱門文章

PSPICE不正確使用手冊-方波

PSpice不正確使用手冊-下載篇

PSpice不正確使用手冊-畫畫&分析篇