#include<AT89X52.h> unsigned char position1=1;//position一共有3種狀態,0代表最邊上,1代表初始位置,2代表最前的位置 unsigned char position2=1;//position一共有3種狀態,0代表最邊上,1代表初始位置,2代表最前的位置 unsigned char fist1=0;//1沒有出拳 unsigned char fist2=0;//2沒有出拳 unsigned char leg1=0;//1沒有出腳 unsigned char leg2=0;//2沒有出腳 unsigned char count_back1=0; unsigned char count_back2=0; unsigned char count_forth1=0; unsigned char count_forth2=0; unsigned char time0_count=0; unsigned char time1_count=0; unsigned char blood1=7; unsigned char blood2=7; unsigned char buff1[16]={0x00,0x18,0x24,0x24,0x18,0x18,0x7E,0x66,//右邊小人的初始形態 0x66,0x24,0x3C,0x24,0x24,0x24,0x24,0x00}; unsigned char buff2[16]={0x00,0x18,0x24,0x24,0x18,0x18,0x7E,0x66,//右邊小人的初始形態 0x66,0x24,0x3C,0x24,0x24,0x24,0x24,0x00}; //定義兩名選手的操作鍵 //選手1 #define S11 P1_0//向前 #define S12 P1_1//后退 #define S13 P1_2//出拳 #define S14 P1_3//出腿 //選手2 #define S21 P1_4//向前 #define S22 P1_5//向后 #define S23 P1_6//出出 #define S24 P1_7//腿拳 //兩個選手的led點陣行掃描使能端 #define A_1 P0_0 #define B_1 P0_1 #define C_1 P0_2 #define D_1 P0_3 //兩個選手的2個595使能端 #define SCLK P2_0 #define SI P2_1 #define RCLK P2_2 //當按下S1時 開始游戲,游戲結束時顯示哪方獲勝,然后按下S2鍵后重新開始新一輪游戲 #define S1 P2_6 #define S2 P2_7 //第一個人的74HC154區域行選 #define NUMLED1OPEN(); {D_1=0;C_1=0;B_1=0;A_1=0;}; #define NUMLED2OPEN(); {D_1=0;C_1=0;B_1=0;A_1=1;}; #define NUMLED3OPEN(); {D_1=0;C_1=0;B_1=1;A_1=0;}; #define NUMLED4OPEN(); {D_1=0;C_1=0;B_1=1;A_1=1;}; #define NUMLED5OPEN(); {D_1=0;C_1=1;B_1=0;A_1=0;}; #define NUMLED6OPEN(); {D_1=0;C_1=1;B_1=0;A_1=1;}; #define NUMLED7OPEN(); {D_1=0;C_1=1;B_1=1;A_1=0;}; #define NUMLED8OPEN(); {D_1=0;C_1=1;B_1=1;A_1=1;}; #define NUMLED9OPEN(); {D_1=1;C_1=0;B_1=0;A_1=0;}; #define NUMLED10OPEN(); {D_1=1;C_1=0;B_1=0;A_1=1;}; #define NUMLED11OPEN(); {D_1=1;C_1=0;B_1=1;A_1=0;}; #define NUMLED12OPEN(); {D_1=1;C_1=0;B_1=1;A_1=1;}; #define NUMLED13OPEN(); {D_1=1;C_1=1;B_1=0;A_1=0;}; #define NUMLED14OPEN(); {D_1=1;C_1=1;B_1=0;A_1=1;}; #define NUMLED15OPEN(); {D_1=1;C_1=1;B_1=1;A_1=0;}; #define NUMLED16OPEN(); {D_1=1;C_1=1;B_1=1;A_1=1;}; //0是第一個選手的索引表的開始 80是第二個選手開始在表中的位置 #define START1 0 #define START2 80 #define INIT 16//第一個選手從的初始狀態在中間 為16 #define JUMP_UP_AND_BACK1 48//向后跳起的緩沖動作的位置 #define JUMP_UP_AND_BACK2 64//向后跳起的緩沖動作的位置 #define BACK 0//在最邊后面的狀態的位置 #define FORTH 32//在最前面的狀態的位置 #define GO 0//游戲的開始畫面 然后按S1開始游戲 //#define KO 32 #define P1_WIN 64//顯示P1勝利在索引表中的位置 #define P2_WIN 96//顯示P2勝利在索引表中的位置 //圖像表 //人物的各種形態和位置 unsigned char code role_action[]= { 0x00,0x0C,0x12,0x12,0x0C,0x0C,0x3F,0x33,//左邊小人后退一步的狀態0 0x33,0x12,0x1E,0x12,0x12,0x12,0x12,0x00, 0x00,0x18,0x24,0x24,0x18,0x18,0x7E,0x66,//左邊小人的初始形態16 0x66,0x24,0x3C,0x24,0x24,0x24,0x24,0x00, 0x00,0x30,0x48,0x48,0x30,0x30,0xFC,0xCC,//左邊小人前進一步的狀態32 0xCC,0x48,0x78,0x48,0x48,0x48,0x48,0x00, 0x18,0x24,0x24,0x18,0x18,0x66,0x66,0x65,//左邊小人向右后方向跳起的動作1 48 0x24,0x3C,0x24,0x12,0x12,0x12,0x00,0x00, 0x0C,0x12,0x12,0x0C,0x0C,0x33,0x33,0x53,//左邊小人向右后方向跳起的動作2 64 0x12,0x1E,0x12,0x24,0x24,0x24,0x00,0x00, 0x00,0x30,0x48,0x48,0x30,0x30,0xCC,0xCC,//右邊小人后退一步的動作80 0xCC,0x48,0x78,0x48,0x48,0x48,0x48,0x00, 0x00,0x18,0x24,0x24,0x18,0x18,0x7E,0x66,//左邊小人的初始形態96 0x66,0x24,0x3C,0x24,0x24,0x24,0x24,0x00, 0x00,0x0C,0x12,0x12,0x0C,0x0C,0x33,0x33,//右邊小人前進一步的狀態112 0x33,0x12,0x1E,0x12,0x12,0x12,0x12,0x00, 0x18,0x24,0x24,0x18,0x18,0x66,0x66,0xA6,//右邊小人向左后方向跳起的動作1 128 0x24,0x3C,0x24,0x48,0x48,0x48,0x00,0x00, 0x30,0x48,0x48,0x30,0x30,0xCC,0xCC,0xCA,//右邊小人向左后方向跳起的動作2 144 0x48,0x78,0x48,0x24,0x24,0x24,0x00,0x00 }; //開機畫面和結束時顯示哪方勝利的索引表 unsigned char code welecome_and_end[]= { 0x00,0x00,0x00,0x04,0xF9,0xF4,0xF9,0xF4,0x00,0x04,0xF9,0xF4,0xF9,0xF4,0x00,0x00, 0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//GO!!! 0 0x00,0x00,0x22,0x38,0x24,0x44,0x28,0x44,0x30,0x44,0x28,0x44,0x24,0x44,0x22,0x44, 0x22,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x92,0x49,0x45,0x14,0x28,0xA2,0x92,0x49,//KO 32 0x00,0x00,0x00,0x00,0x00,0x00,0x25,0x12,0x51,0x13,0x55,0x12,0x55,0x52,0x54,0xA7, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//P1 WIN 64 0x00,0x00,0x00,0x00,0x00,0x00,0x4A,0x24,0xA2,0x2A,0xAA,0x24,0xAA,0xA2,0xA9,0x4E, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00//P2 WIN 96 }; void delayu(unsigned int time);//延時函數 延時0.1ms void delay(unsigned int time);//延時函數 延時1ms void NUMLEDOPEN(int i);//74HC154進行行選擇,第i行 void dat_in(unsigned char dat);//將8為數據從597傳送過去 void display_one_page();//先加載各方“血”的狀態,并顯示一張圖片,顯示人的狀態和血的狀態 void display_scene(int scene);//顯示開機畫面和勝負畫面的函數 void change_buffer_to1(int position);//修改1的圖像狀態緩沖 從人物索引表的第position個8位數個開始顯示 void change_buffer_to2(int position);//修改2的圖像狀態緩沖 從人物索引表的第position個8位數個開始顯示 void action_back1();//第1個人向后一步 并將position減1 直到它不能后退 void action_back2();//第2個人向后一步 并將position減1 直到它不能后退 void action_forth1();//第1個人向前一步 并將position加1 直到它不能后退 void action_forth2();//第2個人向前一步 并將position加1 直到它不能后退 void fist_change_buff1();//由于1出拳對畫面的改動 要調用change_buff1_to_bit(int pos)和change_buff1_to_bit_low(int pos)函數 void leg_change_buff1();//由于1出腿對畫面的改動 要調用change_buff1_to_bit(int pos)和change_buff1_to_bit_low(int pos)函數 void fist_change_buff2();//由于2出拳對畫面的改動 要調用change_buff1_to_bit(int pos)和change_buff1_to_bit_low(int pos)函數 void leg_change_buff2();//由于2出腿對畫面的改動 要調用change_buff1_to_bit(int pos)和change_buff1_to_bit_low(int pos)函數 void change_buff1_to_bit(int pos); //將特定某一位置一 void change_buff2_to_bit(int pos);//將特定某一位置一 void change_buff1_to_bit_low(int pos);//將特定某一位置0 void change_buff2_to_bit_low(int pos);//將特定某一位置0 void action_fist1();//第1個人出拳 并處理減血情況 void action_fist2();//第2個人出拳 并處理減血情況 void action_leg1();//第1個人出腿 并處理減血情況 void action_leg2();//第2個人出腿 并處理減血情況 void scan_key(); //這個是函數的主體部分 分別掃描并處理向后退 向前走 出拳 出腿的動作 當出拳和出腿的時候 開啟定時器 //這300ms內記錄是否有對方出拳出腿的動作 并按照先掃描向后退 后掃描向前進的順序 掃描一遍 并處理 如果沒有這兩個動作 直接返回調用出拳 //否則處理后再出拳 出腳的道理一致 void init_interrupt();//中斷位的設置 //開啟定兩個時器中斷 16位模式 void shed_blood1(); //記錄流血的數字 void shed_blood2(); void main() { int i; while(1) { if(S1==0) { delay(1); if(S1==0) { for(i=0;i<blood1;i++) { change_buff1_to_bit(120+i); } for(i=0;i<blood2;i++) { change_buff2_to_bit(120+i); } init_interrupt(); scan_key(); } while(S2) { if(blood1==0) display_scene(P2_WIN); else display_scene(P1_WIN); } blood1=7; blood2=7; if(S2==0) { delay(1); while(S2) { if(blood1==0) display_scene(P2_WIN); else display_scene(P1_WIN); } } } else { while(S1) { display_scene(GO); } } } } void delayu(unsigned int time)//延時函數 延時0.1ms { unsigned int i,j; for(i=0;i<time;i++) for(j=0;j<100;j++);//1000次空操作的時間約為1ms } void delay(unsigned int time)//延時函數 延時1ms { unsigned int i,j; for(i=0;i<time;i++) for(j=0;j<1000;j++);//1000次空操作的時間約為1ms } void dat_in(unsigned char dat) { unsigned char i; for(i=0;i<8;i++) { SCLK=0; if((dat&0X80)!=0)SI=1; else SI=0; dat<<=1; SCLK=1; } //RCLK=0; //dat_out //RCLK=1; } void NUMLEDOPEN(int i)//74HC154進行行選擇,顯示第一個人的led區 { if(i==0) {NUMLED1OPEN();return;} if(i==1) {NUMLED2OPEN();return;} if(i==2) {NUMLED3OPEN();return;} if(i==3) {NUMLED4OPEN();return;} if(i==4) {NUMLED5OPEN();return;} if(i==5) {NUMLED6OPEN();return;} if(i==6) {NUMLED7OPEN();return;} if(i==7) {NUMLED8OPEN();return;} if(i==8) {NUMLED9OPEN();return;} if(i==9) {NUMLED10OPEN();return;} if(i==10) {NUMLED11OPEN();return;} if(i==11) {NUMLED12OPEN();return;} if(i==12) {NUMLED13OPEN();return;} if(i==13) {NUMLED14OPEN();return;} if(i==14) {NUMLED15OPEN();return;} if(i==15) {NUMLED16OPEN();return;} } void display_one_page()//顯示第i個人的一幀圖像 { int i; for(i=0;i<blood1;i++) { change_buff1_to_bit(120+i); } for(i=0;i<blood2;i++) { change_buff2_to_bit(120+i); } //NUMLEDOPEN1(1); for(i=0;i<16;i++) { dat_in(0x00); dat_in(0x00); NUMLEDOPEN(i); dat_in(buff2[i]); dat_in(buff1[i]); RCLK=0; //dat_out RCLK=1; delayu(1); } } void display_scene(int scene)//第1個人整體動畫的顯示函數 { int i; for(i=0;i<16;i++) { NUMLEDOPEN(i); dat_in(welecome_and_end[scene+i*2]); dat_in(welecome_and_end[scene+i*2+1]); RCLK=0; //dat_out RCLK=1; delayu(1); } } void change_buffer_to1(int position)//修改1的圖像狀態緩沖 { int i; for(i=0;i<16;i++) buff1[i]=role_action[position+i]; } void change_buffer_to2(int position)//修改2的圖像狀態緩沖 { int i; for(i=0;i<16;i++) buff2[i]=role_action[position+i]; } void action_back1()//第1個人向后一步 { int i; if(position1>0) { if(position1==2) { i=15; change_buffer_to1(START1+JUMP_UP_AND_BACK2); while(i--) display_one_page(); i=5; change_buffer_to1(START1+INIT); while(i--) display_one_page(); } else if(position1==1) { i=15; change_buffer_to1(START1+JUMP_UP_AND_BACK2); while(i--) display_one_page(); i=5; change_buffer_to1(START1+BACK); while(i--) display_one_page(); } position1--; } } void action_back2()//第2個人向后一步 { //先顯示向后跳起的動作 再顯示后退的狀態 int i; if(position2>0) { if(position2==2) { i=15; change_buffer_to2(START1+JUMP_UP_AND_BACK1); while(i--) display_one_page(); i=5; change_buffer_to2(START2+INIT); while(i--) display_one_page(); } else if(position2==1) { i=15; change_buffer_to2(START2+JUMP_UP_AND_BACK2); while(i--) display_one_page(); i=5; change_buffer_to2(START2+BACK); while(i--) display_one_page(); } position2--; } } void action_forth1()//第1個人向前一步 { int i; if(position1<2) { if(position1==1) { i=10; change_buffer_to1(START1+FORTH); while(i--) display_one_page(); } else if(position1==0) { i=10; change_buffer_to1(START1+INIT); while(i--) display_one_page(); } position1++; } } void action_forth2()//第2個人向前一步 { //直接顯示向前一步的狀態 int i; if(position2<2) { if(position2==1) { i=10; change_buffer_to2(START2+FORTH); while(i--) display_one_page(); } else if(position2==0) { i=10; change_buffer_to2(START1+INIT); while(i--) display_one_page(); } position2++; } } void change_buff1_to_bit(int pos) { int p1=pos/8; int p2=pos%8; unsigned char flag=0x01; flag=flag<<p2; buff1[p1]=buff1[p1]|flag; } void change_buff2_to_bit(int pos) { int p1=pos/8; int p2=pos%8; unsigned char flag=0x01; flag=flag<<p2; buff2[p1]=buff2[p1]|flag; } void change_buff1_to_bit_low(int pos) { int p1=pos/8; int p2=pos%8; unsigned char flag=0x01; flag=flag<<p2; flag=~flag; buff1[p1]=buff1[p1]&flag; } void change_buff2_to_bit_low(int pos) { int p1=pos/8; int p2=pos%8; unsigned char flag=0x01; flag=flag<<p2; flag=~flag; buff2[p1]=buff2[p1]&flag; } void fist_change_buff1()//由于1出拳對畫面的改動 { if(position1==0) { change_buff1_to_bit(54); change_buff1_to_bit(55); change_buff1_to_bit_low(61); change_buff1_to_bit_low(69); } else if(position1==1) { change_buff1_to_bit(55); change_buff2_to_bit(48); change_buff1_to_bit_low(62); change_buff1_to_bit_low(70); } else if(position1==2) { change_buff2_to_bit(48); change_buff2_to_bit(49); change_buff1_to_bit_low(63); change_buff1_to_bit_low(71); } } /* 這四個函數僅改變顯示緩沖的值 void fist_change_buff1();//由于1出拳對畫面的改動 void leg_change_buff1();//由于1出腿對畫面的改動 void fist_change_buff2();//由于2出拳對畫面的改動 void leg_change_buff2();//由于2出腿對畫面的改動 */ void leg_change_buff1()//由于1出腿對畫面的改動 { if(position1==0) { change_buff1_to_bit(85); change_buff1_to_bit(86); change_buff1_to_bit(87); change_buff2_to_bit(80); change_buff1_to_bit_low(92); change_buff1_to_bit_low(100); change_buff1_to_bit_low(108); change_buff1_to_bit_low(116); } else if(position1==1) { change_buff1_to_bit(86); change_buff1_to_bit(87); change_buff2_to_bit(80); change_buff2_to_bit(81); change_buff1_to_bit_low(93); change_buff1_to_bit_low(101); change_buff1_to_bit_low(109); change_buff1_to_bit_low(117); } else if(position1==2) { change_buff1_to_bit(87); change_buff2_to_bit(80); change_buff2_to_bit(81); change_buff2_to_bit(82); change_buff1_to_bit_low(94); change_buff1_to_bit_low(102); change_buff1_to_bit_low(110); change_buff1_to_bit_low(118); } } void fist_change_buff2()//由于2出拳對畫面的改動 { if(position2==0) { change_buff2_to_bit(48); change_buff2_to_bit(49); change_buff2_to_bit_low(58); change_buff2_to_bit_low(66); } else if(position2==1) { change_buff2_to_bit(48); change_buff1_to_bit(55); change_buff2_to_bit_low(57); change_buff2_to_bit_low(65); } else if(position2==2) { change_buff1_to_bit(54); change_buff1_to_bit(55); change_buff2_to_bit_low(56); change_buff2_to_bit_low(64); } } void leg_change_buff2()//由于2出腿對畫面的改動 { if(position2==0) { change_buff2_to_bit(80); change_buff2_to_bit(81); change_buff2_to_bit(82); change_buff1_to_bit(87); change_buff2_to_bit_low(91); change_buff2_to_bit_low(99); change_buff2_to_bit_low(107); change_buff2_to_bit_low(115); } else if(position2==1) { change_buff2_to_bit(80); change_buff2_to_bit(81); change_buff1_to_bit(86); change_buff1_to_bit(87); change_buff2_to_bit_low(90); change_buff2_to_bit_low(98); change_buff2_to_bit_low(106); change_buff2_to_bit_low(114); } else if(position2==2) { change_buff2_to_bit(80); change_buff1_to_bit(85); change_buff1_to_bit(86); change_buff1_to_bit(87); change_buff2_to_bit_low(89); change_buff2_to_bit_low(97); change_buff2_to_bit_low(105); change_buff2_to_bit_low(113); } } void action_fist1()//第1個人出拳 { int i; i=5; fist_change_buff1(); shed_blood2(); while(i--) { display_one_page(); } i=5; change_buffer_to1(position1*16); change_buffer_to2(position2*16); } void action_fist2()//第2個人出拳 { int i; i=10; fist_change_buff2(); shed_blood1(); while(i--) { display_one_page(); } change_buffer_to1(position1*16); change_buffer_to2(position2*16); } void action_leg1()//第1個人出腿 { int i; i=10; leg_change_buff1(); shed_blood2(); while(i--) { //display_one_page1(); display_one_page(); } change_buffer_to1(position1*16); change_buffer_to2(position2*16); } void action_leg2()//第2個人出腿 { int i; i=10; leg_change_buff2(); shed_blood1(); while(i--) { display_one_page(); } change_buffer_to1(position1*16); change_buffer_to2(position2*16); } void init_interrupt()//中斷位的設置 { TMOD=0x11;//定時器T0 T1工作在1模式 16位方式下 TH0=63536/256;//2ms一次定時器中斷 TL0=63536%256; TH1=63536/256;//2ms一次定時器中斷 TL1=63536%256; EA=1;//開總中斷 ET0=1;//開定時計數器T0 ET1=1;//開定時計數器T1 } void scan_key() { while(1) { if(blood1==0||blood2==0) break; while(S11&&S12&&S13&&S14&&S21&&S22&&S23&&S24) display_one_page(); while(S11||S12||S13||S14||S21||S22||S23||S24) { delay(1); if(S11&&S12&&S13&&S14&&S21&&S22&&S23&&S24) display_one_page(); else break; } if(S12==0) { delay(1); if(S12==0)//1向后的動作 { action_back1(); } } if(S22==0) { delay(1); if(S22==0)//2向后的動作 { action_back2(); } } else if(S11==0) { delay(1); if(S11==0)//1向前的動作 { action_forth1(); } } else if(S21==0) { delay(1); if(S21==0)//2向前的動作 { action_forth2(); } } else if(S13==0) { delay(1); if(S13==0) { TR0=1; while(TR0==1) { display_one_page(); if(S22==0) { delay(1); if(S22==0) { count_back2=1; } } else if(S21==0) { delay(1); if(S21==0) { count_forth2=1; } } } action_fist1(); } } else if(S23==0) { delay(1); if(S23==0) { TR1=1; while(TR1==1) { display_one_page(); if(S12==0) { delay(1); if(S12==0) { count_back1=1; } } else if(S11==0) { delay(1); if(S11==0) { count_forth1=1; } } } action_fist2(); } } else if(S13==0) { delay(1); if(S13==0) { TR0=1; while(TR0==1) { display_one_page(); if(S22==0) { delay(1); if(S22==0) { count_back2=1; } } else if(S21==0) { delay(1); if(S21==0) { count_forth2=1; } } } action_fist1(); } } else if(S23==0) { delay(1); if(S23==0) { TR1=1; while(TR1==1) { display_one_page(); if(S12==0) { delay(1); if(S12==0) { count_back1=1; } } else if(S11==0) { delay(1); if(S11==0) { count_forth1=1; } } } action_fist2(); } } else if(S14==0) { delay(1); if(S14==0) { TR0=1; while(TR0==1) { display_one_page(); if(S22==0) { delay(1); if(S22==0) { count_back2=1; } } else if(S21==0) { delay(1); if(S21==0) { count_forth2=1; } } } action_leg1(); } } else if(S24==0) { delay(1); if(S24==0) { TR1=1; while(TR1==1) { display_one_page(); if(S12==0) { delay(1); if(S12==0) { count_back1=1; } } else if(S11==0) { delay(1); if(S11==0) { count_forth1=1; } } } action_leg2(); } } } } void shed_blood1() { if(position2==1) { if(position1==2) { if(blood1>0) blood1--; } } else if(position2==2) { if(position1>0) { if(blood1>0) blood1--; } } } void shed_blood2() { if(position1==1) { if(position2==2) { if(blood2>0) blood2--; } } else if(position1==2) { if(position2>0) { if(blood2>0) blood2--; } } } void handle1() interrupt 1 { EA=0; TH0=63536/256;//2ms一次定時器中斷 TL0=63536%256; time0_count++; if(time0_count==200) { time0_count=0; TR0=0; if(count_back2==1) { count_back2=0; action_back2(); } else if(count_forth2==1) { count_forth2=0; action_forth2(); } } EA=1; } void handle2() interrupt 3 { EA=0; TH1=63536/256;//2ms一次定時器中斷 TL1=63536%256; time1_count++; if(time1_count==200) { time1_count=0; TR1=0; if(count_back1==1) { count_back1=0; action_back1(); } else if(count_forth1==1) { count_forth1=0; action_forth1(); } } EA=1; }