仿真在Proteus8.3運行正常,8.9不行
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei.gif (273.3 KB, 下載次數: 25)
下載附件
2023-6-20 00:05 上傳
1686905057198.jpg (67.93 KB, 下載次數: 26)
下載附件
2023-6-16 16:45 上傳
部分代碼
- #include <REG52.H>
- #include"pic.c"
- #include <intrins.h>
- #define LCD_DATA P2
- #define button_delay 150 //按鍵延時
- #define button_acceleration 65 //按鍵加速度閾值
- #define GAME_LOCATION 30
- sbit change = P3^4;
- sbit OK = P3^5;
- sbit up = P3^2;
- sbit down = P3^0;
- sbit left = P3^1;
- sbit right = P3^3;
- sbit speaker=P3^6;
- sbit LCD_RS=P1^0;
- sbit LCD_RW=P1^1;
- sbit LCD_E=P1^2;
- sbit LCD_CS2=P1^4; //右屏選擇(左右屏有時候相反)
- sbit LCD_CS1=P1^3; //左屏選擇
- sbit LCD_RST=P3^7;
- unsigned int up_reg=button_delay; //按鍵up累加器
- unsigned int down_reg=button_delay; //按鍵down累加器
- unsigned int left_reg=button_delay; //按鍵left累加器
- unsigned int right_reg=button_delay; //按鍵right累加器
- unsigned int button_a_reg=button_delay; //按鍵button_a累加器
- unsigned int button_b_reg=button_delay; //按鍵button_b累加器
- unsigned int right_acceleration=0; //按鍵right加速度寄存器
- unsigned int left_acceleration=0; //按鍵left加速度寄存器
- unsigned int idata Box_Ram[19];//定義游戲點陣緩存10*16
- unsigned char box_down_reg;//定義方塊下落累加寄存器
- unsigned char time0_reg;//定義定時器0累加寄存器
- unsigned char next_mode;//定義下一個方塊的類型
- unsigned char next_shape;//定義下一個方塊的形狀
- unsigned int destroy_row_num=0;//定義所消的行數
- unsigned char speed_num=0;//定義游戲速度等級
- unsigned char level_num;//定義游戲難度等級
- bit game_over_flag;//游戲結束標志位置0表示游戲未結束
- bit pause_game_flag;//游戲暫停標志位置0表示游戲未暫停
- struct
- {
- unsigned char mode;//類型
- unsigned char shape;//形狀
- unsigned char x;//x坐標
- unsigned char y;//y坐標
- unsigned int box;//定義方塊緩存
- }s_box; //定義方塊結構體
- //LCD檢測忙狀態函數
- void LCD_check_busy()
- {
- unsigned char temp;
- LCD_RS=0;
- LCD_RW=1;
- do
- {
- LCD_DATA=0xff;
- LCD_E=1;
- temp=LCD_DATA;
- LCD_E=0;
- }while((temp&0x80)==0x80);
- }
- //寫指令代碼(cs為0選左屏,cs為1選右屏)
- void LCD_W_code(unsigned char tpcode,bit cs)
- {
- LCD_RS=0;
- LCD_RW=0;
- LCD_CS2=~cs;
- LCD_CS1=cs;
- LCD_DATA=tpcode;
- LCD_E=1;
- _nop_();
- LCD_E=0;
- }
- //寫顯示數據(cs為0選左屏,cs為1選右屏)
- void LCD_W_data(unsigned char tpdata,bit cs)
- {
- LCD_check_busy();
- LCD_RS=1;
- LCD_RW=0;
- LCD_CS2=~cs;
- LCD_CS1=cs;
- LCD_DATA=tpdata;
- LCD_E=1;
- _nop_();
- LCD_E=0;
- }
- //LCD初始化函數
- void LCD_initialize()
- {
- LCD_RST=0;
- _nop_();
- _nop_();
- LCD_RST=1;
- LCD_W_code(0x3f,0); //開顯示設置
- LCD_W_code(0xc0,0); //設置顯示起始行為第一行
- LCD_W_code(0xb8,0); //頁面地址設置
- LCD_W_code(0x40,0); //列地址設為0
- LCD_W_code(0x3f,1);
- LCD_W_code(0xc0,1);
- LCD_W_code(0xb8,1);
- LCD_W_code(0x40,1);
- }
- //LCD清屏函數
- void LCD_clear()
- {
- unsigned char i,j;
- for(j=0;j<8;j++)
- {
- LCD_W_code(0xb8+j,0);
- LCD_W_code(0x40,0);
- LCD_W_code(0xb8+j,1);
- LCD_W_code(0x40,1);
- for(i=0;i<64;i++)
- {
- LCD_W_data(0x00,0);
- LCD_W_data(0x00,1);
- }
- }
- }
- //LCD顯示字符串函數(word表示要顯示的字符串,
- //length表示要顯示的字符串寬度,
- //x表示首字符所在行數,
- //y表示首字符所在列數)
- void LCD_display_word(unsigned char word[],
- unsigned int length,
- unsigned char x,
- unsigned char y)
- {
- unsigned char i;
- for(i=0;i<length;i++)
- {
-
- LCD_W_code(0xb8+x,0);
- LCD_W_code(0xb8+x,1);
- if(y+i<64)
- {
- LCD_W_code(0x40+y+i,0);
- LCD_W_data(word[i],0);
- }
- else
- {
- LCD_W_code(y+i,1);
- LCD_W_data(word[i],1);
- }
- }
- }
- //LCD畫全屏函數
- void LCD_full_draw(unsigned char word[])
- {
- unsigned char i,j;
- for(i=0;i<8;i++)
- {
- LCD_W_code(0xb8+i,0);
- LCD_W_code(0x40,0);
- for(j=0;j<64;j++)
- {
- LCD_W_data(word[i*128+j],0);
- }
- LCD_W_code(0xb8+i,1);
- LCD_W_code(0x40,1);
- for(j=0;j<64;j++)
- {
- LCD_W_data(word[i*128+64+j],1);
- }
- }
- }
- //LCD顯示一個字節函數(
- //x表示x坐標,
- //y表示y坐標,
- //tpdata表示要顯示的數據)
- void LCD_display_byte(unsigned char x,
- unsigned char y,
- unsigned char tpdata)
- {
- if(x<64)
- {
- LCD_W_code(0xb8+y,0);
- LCD_W_code(0x40+x,0);
- LCD_W_data(tpdata,0);
- }
- else
- {
- LCD_W_code(0xb8+y,1);
- LCD_W_code(x,1);
- LCD_W_data(tpdata,1);
- }
- }
- void LCD_draw(unsigned char word[])
- {
- unsigned char i,j;
- for(i=0;i<8;i++)
- {
- LCD_W_code(0xb8+i,1);
- LCD_W_code(0x40+20,1);
- for(j=0;j<44;j++)
- {
- LCD_W_data(word[i*44+j],1);
- }
- }
- }
- //基本界面顯示函數
- void display_basic()
- {
- unsigned char i;
- for(i=0;i<8;i++)
- {
- LCD_display_byte(GAME_LOCATION,i,0xff);
- LCD_display_byte(GAME_LOCATION+41,i,0xff);
- }
- }
- //刷新游戲區域函數
- void refurbish_display()
- {
- unsigned char i,j,tpdata;
- for(i=0;i<8;i++)
- {
- for(j=0;j<10;j++)
- {
- tpdata=0x00;
- if( (Box_Ram[2*i]>>(12-j))&0x0001==1 )
- {
- tpdata=0x0f;
- }
- if( (Box_Ram[2*i+1]>>(12-j))&0x0001==1 )
- {
- tpdata|=0xf0;
- }
- LCD_display_byte(GAME_LOCATION+1+j*4,i,tpdata);
- LCD_display_byte(GAME_LOCATION+2+j*4,i,0xbb&tpdata);
- LCD_display_byte(GAME_LOCATION+3+j*4,i,0xdd&tpdata);
- LCD_display_byte(GAME_LOCATION+4+j*4,i,tpdata);
- }
- }
- }
- //基本按鍵程序(返回0表示沒按鍵被按下,返回1表示down被按下,返回2表示up被按下,返回3表示button_a被按下,返回4表示left被按下,返回5表示right被按下)
- //游戲中按鍵識別程序(有優先級,從高到低依次是button_a_reg>down>left>right>up)
- unsigned char basic_button()
- {
- unsigned char tpflag=0;
- if(OK==0)
- {
- if(button_b_reg<button_delay*8)
- {
- button_b_reg++;
- }
- else
- {
- button_b_reg=0;
- tpflag=6;
- }
- }
- else
- {
- button_b_reg=button_delay*8;
- }
- if(down==0)
- {
- if(down_reg<button_delay)//按鍵一直被按下時設置時間間隔觸發
- {
- down_reg++;
- }
- else
- {
- down_reg=0;
- tpflag=1;//返回1表示down被按下
- }
- }
- else
- {
- down_reg=button_delay;//釋放按鍵時置按鍵緩存為button_delay,以便在下次按鍵時及時響應
- }
- if(up==0)
- {
- if(up_reg<button_delay)//按鍵一直被按下時設置時間間隔觸發
- {
- up_reg++;
- }
- else
- {
- up_reg=0;
- tpflag=2;//返回2表示up被按下
- }
- }
- else
- {
- up_reg=button_delay;//釋放按鍵時置按鍵緩存為button_delay,以便在下次按鍵時及時響應
- }
- if(change==0)
- {
- if(button_a_reg<button_delay*8)//按鍵一直被按下時設置時間間隔觸發
- {
- button_a_reg++;
- }
- else
- {
- button_a_reg=0;
- tpflag=3;//返回3表示button_a被按下
- }
- }
- else
- {
- button_a_reg=button_delay*8;//釋放按鍵時置按鍵緩存為button_delay,以便在下次按鍵時及時響應
- }
- if(left==0)
- {
- if(left_reg<(button_delay))//按鍵一直被按下時設置時間間隔觸發
- {
- left_reg++;
- }
- else
- {
- left_reg=left_acceleration*button_acceleration;
- if(left_acceleration<2)left_acceleration++;
- tpflag=4;//返回4表示left被按下
- }
- }
- else
- {
- left_acceleration=0;
- left_reg=button_delay;//釋放按鍵時置按鍵緩存為button_delay,以便在下次按鍵時及時響應
- }
- if(right==0)
- {
- if(right_reg<(button_delay))//按鍵一直被按下時設置時間間隔觸發
- {
- right_reg++;
- }
- else
- {
- right_reg=right_acceleration*button_acceleration;
- if(right_acceleration<2)right_acceleration++;
- tpflag=5;//返回5表示right被按下
- }
- }
- else
- {
- right_acceleration=0;
- right_reg=button_delay;//釋放按鍵時置按鍵緩存為button_delay,以便在下次按鍵時及時響應
- }
- return(tpflag);
- }
- //檢查覆蓋函數(檢查此時帶入的參數所確定的方塊是否會覆蓋原有圖形,不會覆蓋返回1,覆蓋返回0)
- bit check_cover(unsigned char tpx,unsigned char tpy,unsigned int tpbox)
- {
- unsigned char i;
- bit tpflag=1;
- unsigned int temp;
- temp=s_box.box;
- for(i=0;i<4;i++)
- {
- Box_Ram[3-i+s_box.y]&=(~((temp&0x000f)<<(9-s_box.x)));
- temp=temp>>4;
- }//先將現有的方塊從游戲點陣緩存中刪除
- temp=tpbox;
- for(i=0;i<4;i++)
- {
- if((((temp&0x000f)<<(9-tpx))&Box_Ram[3-i+tpy])!=0x0000)
- {
- tpflag=0;
- }
- temp=temp>>4;
- }//檢查方塊是否和原有圖形重疊,重疊置標志位tpflag為0,不重疊不置標志位,即tpflag為1
- temp=s_box.box;
- for(i=0;i<4;i++)
- {
- Box_Ram[3-i+s_box.y]|=((temp&0x000f)<<(9-s_box.x));
- temp=temp>>4;
- }//在游戲點陣緩存中恢復原有方塊
- return(tpflag);
- }
- //方塊緩存數據函數(輸入方塊類型和形狀即可獲得方塊緩存數據)
- unsigned int box_read_data(unsigned char tpmode,unsigned char tpshape)
- {
- unsigned int tpbox;
- switch(tpmode)
- {
- case 0: switch(tpshape)
- {
- case 0: tpbox=0xf000;break;
- case 1: tpbox=0x4444;break;
- case 2: tpbox=0xf000;break;
- case 3: tpbox=0x4444;break;
- default:;
- }break;
- case 1: switch(tpshape)
- {
- case 0: tpbox=0xe800;break;
- case 1: tpbox=0xc440;break;
- case 2: tpbox=0x2e00;break;
- case 3: tpbox=0x88c0;break;
- default:;
- }break;
- case 2: switch(tpshape)
- {
- case 0: tpbox=0xe200;break;
- case 1: tpbox=0x44c0;break;
- case 2: tpbox=0x8e00;break;
- case 3: tpbox=0xc880;break;
- default:;
- }break;
- case 3: switch(tpshape)
- {
- case 0: tpbox=0xcc00;break;
- case 1: tpbox=0xcc00;break;
- case 2: tpbox=0xcc00;break;
- case 3: tpbox=0xcc00;break;
- default:;
- }break;
- case 4: switch(tpshape)
- {
- case 0: tpbox=0xc600;break;
- case 1: tpbox=0x4c80;break;
- case 2: tpbox=0xc600;break;
- case 3: tpbox=0x4c80;break;
- default:;
- }break;
- case 5: switch(tpshape)
- {
- case 0: tpbox=0x6c00;break;
- case 1: tpbox=0x8c40;break;
- case 2: tpbox=0x6c00;break;
- case 3: tpbox=0x8c40;break;
- default:;
- }break;
- case 6: switch(tpshape)
- {
- case 0: tpbox=0x4e00;break;
- case 1: tpbox=0x8c80;break;
- case 2: tpbox=0xe400;break;
- case 3: tpbox=0x4c40;break;
- default:;
- }break;
- default:;
- }
- return(tpbox);
- }
- //方塊載入函數
- void box_load()
- {
- s_box.box=box_read_data(s_box.mode,s_box.shape);
- }
- //方塊映射游戲點陣緩存函數(參數是原來方塊的位置、緩存,先消去原有位置的方塊)
- void box_to_Box_Ram(unsigned char tpx,unsigned char tpy,unsigned int tpbox)
- {
- unsigned char i;
- unsigned int temp;
- temp=tpbox;
- for(i=0;i<4;i++)
- {
- Box_Ram[3-i+tpy]=Box_Ram[3-i+tpy]&(~((temp&0x000f)<<(9-tpx)));
- temp=temp>>4;
- }//從游戲點陣緩存中刪除以前的方塊
- temp=s_box.box;
- for(i=0;i<4;i++)
- {
- Box_Ram[3-i+s_box.y]=((temp&0x000f)<<(9-s_box.x))|Box_Ram[3-i+s_box.y];
- temp=temp>>4;
- }//在游戲點陣緩存中加入新的方塊
- }
- //顯示數字函數(
- //x表示x坐標,
- //y表示y坐標,
- //tpdata表示要顯示的數字)
- //顯示速度函數
- void show_num(unsigned char x,
- unsigned char y,
- unsigned char tpdata)
- {
- unsigned char i;
- for(i=0;i<4;i++)
- {
- LCD_display_byte(x+i,y,num_data[tpdata*4+i]);
- }
- }
- void show_speed_num(unsigned char x,unsigned char y)
- {
- show_num(x,y,speed_num);
- }
- //顯示得分函數
- void show_score_num(unsigned char x,unsigned char y)
- {
- show_num(x,y,destroy_row_num/10000);
- show_num(x+=5,y,(destroy_row_num%10000)/1000);
- show_num(x+=5,y,(destroy_row_num%1000)/100);
- show_num(x+=5,y,(destroy_row_num%100)/10);
- show_num(x+=5,y,destroy_row_num%10);
- }
- //消行函數
- void destroy_row()
- {
- unsigned char i,j=0;
- unsigned char tpflag[4]={0,0,0,0};//最多一次只能消四行,所以設置四個標志位即可,初值為0
- for(i=0;i<16;i++)
- {
- if((Box_Ram[i]&0x3ffc)==0x3ffc)
- {
- tpflag[j]=i+1;//tpflag為0表示不標志,1表示第0行緩存為0xffff,n表示第n+1行緩存為0xffff
- destroy_row_num++;//消除的行數加一
- /*如不把Box_Ram[19]定義成idata類型的話加入這段代碼顯示數據區就溢出了*/
- if(destroy_row_num%30==0&&speed_num!=9)
- {
- speed_num++;//消夠三十行游戲速度加一
- show_speed_num(13,4);//調用顯示游戲速度函數
- }
- /*如不把Box_Ram[19]定義成idata類型的話加入這段代碼顯示數據區就溢出了*/
- j++;
- if(j==4)
- {
- break;
- }//檢查完有四行要消除則退出檢查循環
- }
- }//依次檢測是否有行緩存為0xffff,如果是則標志tpflag為此行的行號
- for(j=0;j<4;j++)
- {
- if(tpflag[j]!=0)
- {
- for(i=tpflag[j]-1;i>0;i--)
- {
- Box_Ram[i]=Box_Ram[i-1];
- Box_Ram[0]=0x2004;
- }
- }
- }//被標志的行依次被上一行所取代,即被消去
- show_score_num(3,1);
- }
- //顯示下一個方塊函數
- void show_next_box()
- {
- unsigned char i,tpdata;
- unsigned int temp;
- temp=box_read_data(next_mode,next_shape);
- for(i=0;i<4;i++)
- {
- tpdata=0x00;
- if( ((temp>>(15-i))&0x0001)==1 )
- {
- tpdata=0x0f;
- }
- if( ((temp>>(11-i))&0x0001)==1 )
- {
- tpdata|=0xf0;
- }
- LCD_display_byte(7+i*4,6,tpdata);
- LCD_display_byte(8+i*4,6,0xbb&tpdata);
- LCD_display_byte(9+i*4,6,0xdd&tpdata);
- LCD_display_byte(10+i*4,6,tpdata);
- tpdata=0x00;
- if( ((temp>>(7-i))&0x0001)==1 )
- {
- tpdata=0x0f;
- }
- if( ((temp>>(3-i))&0x0001)==1 )
- {
- tpdata|=0xf0;
- }
- LCD_display_byte(7+i*4,7,tpdata);
- LCD_display_byte(8+i*4,7,0xbb&tpdata);
- LCD_display_byte(9+i*4,7,0xdd&tpdata);
- LCD_display_byte(10+i*4,7,tpdata);
- }
- }
- //方塊生成函數
- void box_build()
- {
- s_box.mode=next_mode;
- s_box.shape=next_shape;
- s_box.x=3;
- s_box.y=0;
- next_mode=TL0%7;//產生隨機數,但是是偽隨機的
- next_shape=TL0%4;//產生隨機數,但是是偽隨機的
- show_next_box();//放到game_execute()函數中不知道為什么就是不正常顯示(2015注釋:程序可能重入了)
- }
- void game_button()
- {
-
- switch(basic_button())
- {
- case 3: if(s_box.y!=0)//3表示button_a被按下
- {
- EA=0;//關中斷,如果不關的話可能引起游戲顯示混亂
- speaker=0;
- if(s_box.shape==3&&check_cover(s_box.x,s_box.y,box_read_data(s_box.mode,0)))
- {
-
- s_box.shape=0;
- box_load();
- box_to_Box_Ram(s_box.x,s_box.y,box_read_data(s_box.mode,3));
- }
- else if(check_cover(s_box.x,s_box.y,box_read_data(s_box.mode,0)))
- { if(check_cover(s_box.x,s_box.y,box_read_data(s_box.mode,s_box.shape+1)))
- {
- s_box.shape++;
- box_load();
- box_to_Box_Ram(s_box.x,s_box.y,box_read_data(s_box.mode,s_box.shape-1));
- }
- }
- EA=1;//開中斷
- speaker=1;
- }break;
- case 1: if(s_box.y!=0)//1表示down被按下
- {
- EA=0;//關中斷,如果不關的話可能引起游戲顯示混亂
- speaker=0;
- while(check_cover(s_box.x,s_box.y+1,s_box.box))//檢測是否能下降,指導不能再下降為止
- {
- s_box.y++;
- box_to_Box_Ram(s_box.x,s_box.y-1,s_box.box);
- }
- destroy_row();
- box_build();
- box_load();
- // game_over_flag=check_game_over();//游戲結束標志位置1表示游戲結束
- // next_box();
- box_to_Box_Ram(s_box.x,s_box.y,s_box.box);
- EA=1;//開中斷
- speaker=1;
- }break;
- case 4: if(s_box.y!=0)//4表示left被按下
- {
- EA=0;//關中斷,如果不關的話可能引起游戲顯示混亂
- speaker=0;
- if(check_cover(s_box.x-1,s_box.y,s_box.box))
- {
- s_box.x--;
- box_to_Box_Ram(s_box.x+1,s_box.y,s_box.box);
- }
- EA=1;//開中斷
- speaker=1;
- }break;
- case 5: if(s_box.y!=0)//5表示right被按下
- {
- EA=0;//關中斷,如果不關的話可能引起游戲顯示混亂
- speaker=0;
- if(check_cover(s_box.x+1,s_box.y,s_box.box))
- {
- s_box.x++;
- box_to_Box_Ram(s_box.x-1,s_box.y,s_box.box);
- }
- EA=1;//開中斷
- speaker=1;
- }break;
- case 2: //2表示up被按下
- speaker=0;
- pause_game_flag=~pause_game_flag;//游戲暫停標志取反
- while(up==0);
- speaker=1;
- break;
- default:;
- }
- }
- //檢查游戲結束函數(游戲結束返回1,游戲沒有結束返回0)
- bit check_game_over()
- {
- unsigned char i;
- bit tpflag=0;
- unsigned int temp;
- temp=s_box.box;
- for(i=0;i<4;i++)
- {
- if((((temp&0x000f)<<(9-s_box.x))&Box_Ram[3-i+s_box.y])!=0x0000)
- {
- tpflag=1;
- }
- temp=temp>>4;
- }//檢查新建方塊是否和原有圖形重疊,重疊置標志位tpflag為1,不重疊不置標志位,即tpflag為0
- return(tpflag);
- }
- //游戲執行函數(控制方塊下落,檢測是否到底,如果到底調用消行函數)
- void game_execute()
- {
- if(box_down_reg<20-(speed_num<<1))
- {
- box_down_reg++;
- }
- else
- {
- box_down_reg=0;
- if(check_cover(s_box.x,s_box.y+1,s_box.box))
- {
- s_box.y++;
- box_to_Box_Ram(s_box.x,s_box.y-1,s_box.box);
- }//檢測是否還可以下降,如果還能下降則繼續下降
- else
- {
- destroy_row();
- box_build();
- box_load();
- game_over_flag=check_game_over();//游戲結束標志位置1表示游戲結束
- box_to_Box_Ram(s_box.x,s_box.y,s_box.box);
- box_down_reg=(20-(speed_num<<1)-1);//為了使方塊一出現就能變換形狀,所以需要盡快使得方塊下降一行,不知道為什么最高行不能變換形狀
- }//如果不能下降則調用消行函數檢查是否可以消行,之后重新建立方塊
- }
- }
- //選擇游戲速度函數
- void select_speed()
- {
- unsigned char i;
- bit tpflag=1;//置循環標志位為1
- LCD_clear();
- for(i=0;i<128;i++)
- {
- LCD_display_byte(i,0,0xff);
- LCD_display_byte(i,7,0xff);
- }
- LCD_display_byte(60,4,0x7f);
- LCD_display_byte(59,4,0x3e);
- LCD_display_byte(58,4,0x1c);
- LCD_display_byte(57,4,0x08);
- LCD_display_byte(67,4,0x7f);
- LCD_display_byte(68,4,0x3e);
- LCD_display_byte(69,4,0x1c);
- LCD_display_byte(70,4,0x08);
- LCD_display_word(speed_data,24,3,52);
- show_speed_num(62,4);
- while(tpflag)
- {
- switch(basic_button())
- {
- case 4: if(speed_num!=0)
- {
- speaker=0;
- speed_num--;
- show_speed_num(62,4);
- speaker=1;
- }
- while(left==0);
- break;
- case 5: if(speed_num!=9)
- {
- speaker=0;
- speed_num++;
- show_speed_num(62,4);
- speaker=1;
- }
- while(right==0);
- break;
- case 6: tpflag=0;
- speaker=0;
- while(OK==0);
- speaker=1;
- break;
- default:;
- }
- }//選擇游戲速度循環
- }
- //游戲開始顯示畫面
- void game_start_show()
- {
- bit tpflag=1;//置循環標志位為1
- LCD_full_draw(start_pic);
- while(tpflag)
- {
- switch(basic_button())
- {
- case 6: tpflag=0;
- speaker=0;
- while(OK==0);
- speaker=1;
- break;
- default:;
- }
- }//game_start_show循環
- }
- //游戲初始化函數
- void game_initialize()
- {
- box_down_reg=0;
- next_mode=6;
- next_shape=2;
- destroy_row_num=0;
- game_over_flag=0;
- pause_game_flag=0;
- LCD_clear();
- time0_reg=0;
- display_basic();
- LCD_display_word(score_data,24,0,3);
- LCD_display_word(speed_data,24,3,3);
- show_score_num(3,1);
- show_speed_num(13,4);
- }
- //定時器0初始化函數
- void time0_initialize()
- {
- TMOD=0x03;//定時器0,16位工作方式
- TR0=1; //啟動定時器
- ET0=1; //打開定時器0中斷
- //默認中斷優先級為低
- EA=1; //打開總中斷
- }
- //俄羅斯方塊游戲主函數
- void Tetris_main()
- {
- unsigned char i;
- for(i=0;i<19;i++)
- {
- Box_Ram[i]=Box_Ram_data[i];
- };//載入游戲初始顯示畫面
- LCD_draw(mpic);
- game_over_flag=0;//游戲結束標志位置0表示游戲未結束
- box_build();
- box_load();
- // next_box();
- box_to_Box_Ram(s_box.x,s_box.y,s_box.box);
- box_down_reg=(20-(speed_num<<1)-1);//為了使方塊一出現就能變換形狀,所以需要盡快使得方塊下降一行,不知道為什么最高行不能變換形狀
- time0_initialize();
- while(!game_over_flag)//如果游戲結束標志位置1,表示游戲結束,打破循環,調用游戲結束畫面顯示函數
- {
- game_button();
- }
- EA=0;//游戲結束后關中斷
- }
- //游戲結束畫面顯示函數
- void game_over_show()
- {
- unsigned char i;
- bit tpflag=1;//置循環標志位為1
- LCD_full_draw(over_pic);
- while(change==0);
- while(tpflag)
- {
- switch(basic_button())
- {
- case 6: tpflag=0;
- speaker=0;
- while(OK==0);
- speaker=1;
- break;
- default:;
- }
- }//game over畫面循環
- LCD_clear();
- for(i=0;i<128;i++)
- {
- LCD_display_byte(i,0,0xff);
- LCD_display_byte(i,7,0xff);
- }
- LCD_display_word(score_data,24,3,52);
- show_score_num(52,4);
- tpflag=1;
- while(tpflag)
- {
- switch(basic_button())
- {
- case 6: tpflag=0;
- speaker=0;
- while(OK==0);
- speaker=1;
- break;
- default:;
- }
- }//游戲得分顯示循環
- }
- void main()
- {
- LCD_initialize();
- LCD_clear();
- while(1)
- {
- game_start_show();
- select_speed();
- game_initialize();//調用游戲初始化函數,初始化游戲所有變量以及在液晶屏上顯示基本的信息
- Tetris_main();
- game_over_show();
- }
- }
- //定時器0中斷服務
- void timer0() interrupt 1
- {
- TH0=0x00;
- TL0=0x00;
- if(time0_reg<10)
- {
- time0_reg++;
- }
- else
- {
- time0_reg=0;
- if(pause_game_flag==0)
- {
- game_execute();
- refurbish_display();
- }
- }
- }
復制代碼
仿真在Proteus8.13 8.3運行正常,8.9不行
Keil代碼與Proteus仿真下載:
Proteus8.13仿真程序.7z
(80.34 KB, 下載次數: 29)
2023-6-20 00:06 上傳
點擊文件名下載附件
俄羅斯方塊 下載積分: 黑幣 -5
|