一年前做的小玩意了,硬件丟失了,程序還在,以前都是寫在一個文件內,翻出來分成幾個文件,程序注釋寫的很詳細,希望對初入單片機的師兄有所幫助
單片機源程序如下:
- //=================================================================================================================================================================
- //軟件功能:貪吃蛇
- //硬件描述:最小系統+4x(8x8點陣)+ (1x(HC154)+3x(74HC14D)) + 1x(HC595)
- //程序描述:74595.c中有串進并出程序
- // delay.c中有延遲函數
- // dispaly.c中有點陣顯示函數
- // anjian.c中有按鍵函數
- // related.c中有初始化參數函數、游戲結束圖案函數、點陣顯示清除函數、糖果隨機函數、蛇顯示變化函數
- //功能概括描述:16x16點陣用于顯示、5個按鍵有旋轉按鍵、上、下、左、右按鍵
- // 上、下、左、右按鍵用于控制蛇上下左右移動
- // 有轉折點判斷(理論上蛇可以打15折)、蛇碰壁判斷、蛇速度改變判斷
- //=================================================================================================================================================================
- #include "reg52.h" //51頭文件
- #include "intrins.h" //部分運算符所需頭文件
- #include "74595.h" //74595程序
- #include "delay.h"
- #include "display.h"
- #include "anjian.h"
- #include "related.h"
- #define uchar unsigned char
- #define uint unsigned int
- //=================================================================================================================================================================
- //sbit Beep=P2^7; //蜂鳴器
- uint HUANCUN[16],STX,SWX,GCUNY; //緩存顯示數組,蛇頭橫坐標,蛇尾橫坐標,轉折點存儲數組,果子位置存儲
- uchar SSS,t,STY,SWY,GUO,CBN,GCUNX,Q,cus; //蛇方向變量,定時器計時變量,蛇頭縱坐標,蛇尾縱坐標,轉折點反向存儲數組,糖果,計時變量,隨機數,蛇方向前一個狀態變量
- uchar idata ZZS[16];
- uint idata ZZD[16];
- //=================================================================================================================================================================
- void Init() //初始化
- {
- TMOD=0x01; //工作方式1
- EA=1; //CPU中斷開啟
- ET0=1; //定時器T0中斷開啟
- TH0=(65536-5000)/256; //定時5ms
- TL0=(65536-5000)%256;
- TR0=0; //定時器關閉狀態
- KS=1; //開始鍵置高電平
- // Beep=0;
- }
- //=================================================================================================================================================================
- void main()
- {
- Init();
- while(1)
- {
- Q=rand()%256; //隨機代碼放在while(1)函數中不停運轉
- if(TR0==0){ //如果定時器在關閉狀態
- J_S(); //清除緩存
- K_S(); //各種數據初始化
- }else{
- if(GUO!=1){ //如果沒有糖果
- SUI_JI(); //調用隨機子程序
- t--; //蛇的速度加快
- CBN=t; //CBN用于保存改變后的t
- }
- }
- XIANSI(); //循環顯示函數
- }
- }
- //=================================================================================================================================================================
- void time0() interrupt 1
- {
- TH0=(65536-5000)/256;
- TL0=(65536-5000)%256;
- AN_J(); //調用按鍵子程序
- if((--CBN==0)||(cus!=SSS)){
- CBN=t; //CBN隨t的變化而變化
- SE_BH(); //調用蛇變子程序
- }
- }
- //=================================================================================================================================================================
復制代碼- #include "related.h"
- //=================================================================================================================================================================
- extern uchar SSS,t,STY,SWY,GUO,GCUNX,Q;
- extern uint HUANCUN[16],STX,SWX,GCUNY;
- extern uchar idata ZZS[16];
- extern uint idata ZZD[16];
- //=================================================================================================================================================================
- //功能描述:開始鍵按下后,初始化各種參數
- //=================================================================================================================================================================
- void K_S()
- {
- uchar i;
- if(KS==0){ //如果開始鍵按下
- QC_HC();
- SSS=2; //蛇方向向右
- t=50; //蛇初始速度
- SWY=7; //蛇尾初始縱坐標
- STY=7; //蛇頭初始縱坐標
- STX=0x0040; //蛇頭初始橫坐標
- SWX=0x0100; //蛇尾初始橫坐標
- HUANCUN[7]=0x01c0; //初始化蛇全身
- ZZS[0]=SSS; //存儲蛇的方向
- for(i=0;i<16;i++){
- ZZD[i]=0xffff;
- }
- GUO=0; //無糖果
- TR0=1; //定時器開啟
- }
- }
- //=================================================================================================================================================================
- //功能描述:游戲結束后顯示預設圖案
- //=================================================================================================================================================================
- void J_S() //結束子程序
- {
- QC_HC();
- HUANCUN[2]=0x0ff0; //顯示笑臉
- HUANCUN[3]=0x1008;
- HUANCUN[4]=0x2424;
- HUANCUN[5]=0x2a54;
- HUANCUN[6]=0x2004;
- HUANCUN[7]=0x2004;
- HUANCUN[8]=0x2004;
- HUANCUN[9]=0x2004;
- HUANCUN[10]=0x2244;
- HUANCUN[11]=0x2184;
- HUANCUN[12]=0x1008;
- HUANCUN[13]=0x0ff0;
- }
- //=================================================================================================================================================================
- //功能描述:16x16點陣顯示清除
- //=================================================================================================================================================================
- void QC_HC() //清除緩存子程序
- {
- uchar i;
- for(i=0;i<16;i++){ //緩存清零
- HUANCUN[i]=0;
- }
- }
- //=================================================================================================================================================================
- //功能說明:”糖果“隨機函數
- //程序說明:Q取0~255之間的數,對應16x16點陣上的256個點
- // Q/16取16x16點陣的哪一行,0x0001<<(Q%16)取16x16點陣的哪一列
- // Q隨機出一個數后,有可能點陣上的點是亮著的,要重新隨機,直到隨機到沒亮著的點
- // 然后改變對應緩存顯示數組HUANCUN[]里的數據
- // 16x16點陣是以左上角為原點的一個坐標(不過y軸不是負的),記錄下對應點的橫坐標和縱坐標
- // 改變“糖果”的狀態變量GUO=1,就是說當前有“糖果”在
- //=================================================================================================================================================================
- void SUI_JI()
- {
- while(HUANCUN[Q/16]&(0x0001<<(Q%16))) //判斷隨機數對應的點陣上的點是否是滅的狀態
- {
- Q=rand()%256; //如果是亮的,那么再隨機一次,直到隨機到滅的點
- }
- HUANCUN[Q/16]|=(0x0001<<(Q%16)); //讓這個點亮起來
- GCUNX=Q/16; //記錄該點的橫坐標和縱坐標
- GCUNY=(0x0001<<(Q%16));
- GUO=1; //記錄糖果狀態
- }
- //=================================================================================================================================================================
- //功能說明:當蛇尾處在轉折點處時,這個轉折點數據沒用了,判斷蛇還有沒有轉折點,如果有,覆蓋掉這個轉折點
- // 根據改變后的轉折點,確定蛇尾的坐標
- //=================================================================================================================================================================
- void ZZ_X()
- {
- uchar i;
- if(ZZS[1]!=0){ //如果有第二個轉折點
- for(i=0;i<15;i++){ //把第一個轉折點覆蓋
- ZZD[i]=ZZD[i+1];
- ZZS[i]=ZZS[i+1];
- }
- }
- switch(ZZS[0]) //判斷改變后蛇的方向,而后改變蛇尾坐標
- {
- case 1:
- SWY--;
- break;
- case 2:
- SWX>>=1;
- break;
- case 3:
- SWY++;
- break;
- case 4:
- SWX<<=1;
- break;
- }
- }
- //=================================================================================================================================================================
- //思維說明:蛇移動是不是要判斷前面有沒有障礙物?這個障礙物有可能是蛇的身體,也有可能是糖果。還有,蛇會不會碰壁呢?
- //程序說明:根據蛇的方向(SSS)來分成4種情況,
- // 蛇頭就是一個點,這個點被記錄下橫(STY)和縱坐標(STX),再加上記錄下的方向(SSS),可以確定蛇頭的下一個位置
- // 當SSS=1時,蛇向上移動,把蛇頭橫坐標(STX)和緩存顯示數組HUANCUN[STY-1]相與,確定該位置是否被點亮,為什么是STY-1呢?點陣第一行對應HUANCUN[0]
- // 當該位置沒被點亮時,表示蛇可以移動上去了,把蛇頭的坐標改變
- // 否則,把該位置的坐標和糖果的坐標比較,如果是糖果位置,蛇頭一樣可變。其他情況游戲結束,關定時器TR0
- // 其他3種情況分析同上
- // 蛇尾也不能忘了,一條蛇只標蛇頭可不行
- // 如果蛇吃了糖果,那么蛇頭長了一點,蛇尾不用變,蛇頭坐標變后跳出函數就行了
- // 否則,就要讓蛇尾滅掉HUANCUN[SWY]&=(~SWX);
- // 再則,一條蛇可會轉彎的哦,那么必須要有轉折點,不止一個,要判斷,如果需要的話,要做改變
- //=================================================================================================================================================================
- void SE_BH() //蛇變子程序
- {
- switch(SSS)
- {
- case 1:
- if(STY>0){ //大于0是要判斷的,因為下面HUANCUN[STY-1]
- if((HUANCUN[STY-1]&STX)==0) //判斷下一個蛇坐標是否是滅的
- STY--; //蛇頭坐標改變
- else{
- if(((STY-1)==GCUNX)&&(STX==GCUNY)){ //否則,判斷該點是否是糖果點
- STY--; //蛇頭坐標改變
- GUO=0; //糖果變量清零
- }else
- TR0=0; //定時器關閉
- return; //跳出
- }
- }else{
- TR0=0;
- return;
- }
- break;
- case 2:
- if((HUANCUN[STY]&(STX>>1))==0)
- STX>>=1;
- else{
- if((STY==GCUNX)&&((STX>>1)==GCUNY)){
- STX>>=1; //蛇頭橫坐標右移一位
- GUO=0;
- }else
- TR0=0;
- return;
- }
- break;
- case 3:
- if((HUANCUN[STY+1]&STX)==0)
- STY++; //蛇頭縱坐標減一位
- else{
- if(((STY+1)==GCUNX)&&(STX==GCUNY)){
- STY++;
- GUO=0;
- }else
- TR0=0;
- return;
- }
- break;
- case 4:
- if((HUANCUN[STY]&(STX<<1))==0)
- STX<<=1;
- else{
- if((STY==GCUNX)&&((STX<<1)==GCUNY)){
- STX<<=1;
- GUO=0;
- }else
- TR0=0;
- return;
- }
- break;
- }
- if((STX!=0)&&(STY>=0)&&(STY<16)){ //如果蛇頭沒超出邊界
- HUANCUN[STY]|=STX; //讓蛇頭亮起
- HUANCUN[SWY]&=(~SWX); //讓蛇尾滅掉
- switch(ZZS[0])
- {
- case 1:
- if(SWY!=ZZD[0])
- SWY--;
- else ZZ_X();
- break;
- case 2:
- if(SWX!=ZZD[0])
- SWX>>=1;
- else ZZ_X();
- break;
- case 3:
- if(SWY!=ZZD[0])
- SWY++;
- else ZZ_X();
- break;
- case 4:
- if(SWX!=ZZD[0])
- SWX<<=1;
- else ZZ_X();
- break;
- }
- }else{
- TR0=0;
- // return;
- }
- }
- //=================================================================================================================================================================
復制代碼
- #include "anjian.h"
- extern uchar cus,STY,SSS;
- extern uint STX;
- extern uchar idata ZZS[16];
- extern uint idata ZZD[16];
- //=================================================================================================================================================================
- //思維說明:4個按鍵控制蛇的方向,當蛇往一個方向移動的時候,控制蛇在這一線上的移動方向的兩個按鍵會失效,只有兩個鍵有用
- //程序說明:SSS表示蛇方向的一個變量,有4個方向,取值范圍是1~4
- // 當蛇的方向改變是,存儲轉折點的橫或縱坐標放在數組ZZD[],存儲轉折點的方向存在ZZS[]
- // 蛇尾是跟著存儲起來的轉折點轉向的,一個點的坐標用橫坐標和縱坐標兩個坐標表示的,這里為了節省存儲空間,
- // 當蛇在橫向上移動的時候,可以只存橫坐標,為什么存橫坐標?因為這個時候縱坐標不變
- // 當蛇在縱向上移動的時候,可以只存縱坐標
- //=================================================================================================================================================================
- void AN_J() //按鍵子程序
- {
- static uchar a=1,b=1,c=1,d=1; //定義4個方向鍵的狀態變量
- uchar i;
- cus=SSS; //保存蛇的方向
- if(SHANG!=a){ //比較按鍵當前狀態和前一個狀態是否一致
- if(a==1){ //前一個狀態是否是高電平
- if((SSS!=1)&&(SSS!=3)){ //蛇的狀態是左右的時候,才生效
- SSS=1;
- }
- }
- a=SHANG; //鎖住,直到下一次按鍵按下才會再進來
- }
- if(YOU!=b){
- if(b==1){
- if((SSS!=2)&&(SSS!=4)){
- SSS=2;
- }
- }
- b=YOU;
- }
- if(XIA!=c){
- if(c==1){
- if((SSS!=1)&&(SSS!=3)){
- SSS=3;
- }
- }
- c=XIA;
- }
- if(ZUO!=d){
- if(d==1){
- if((SSS!=2)&&(SSS!=4)){
- SSS=4;
- }
- }
- d=ZUO;
- }
- if(cus!=SSS){ //如果蛇的方向改變了
- for(i=0;i<16;i++){ //從第一個轉折點開始判斷
- if(ZZD[i]==0xffff){ //如果轉折點是0xffff,說明后面沒有轉折點了
- ZZS[i+1]=SSS; //把當前蛇的方向存儲起來
- if((cus==1)||(cus==3)){ //如果蛇前一個方向是上下
- ZZD[i]=STY; //把轉折點的縱坐標存儲起來
- }else ZZD[i]=STX; //否則,存橫坐標
- break; //跳出
- }
- }
- }
- }
- //=================================================================================================================================================================
復制代碼
原理圖: 無
仿真: 無
代碼:
貪吃蛇.rar
(58.42 KB, 下載次數: 101)
2020-1-21 23:21 上傳
點擊文件名下載附件
|