五月天青色头像情侣网名,国产亚洲av片在线观看18女人,黑人巨茎大战俄罗斯美女,扒下她的小内裤打屁股

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

(轉(zhuǎn))C++小游戲:坦克大戰(zhàn)-無敵AI自殘版(上半部分)

2022-11-04 18:39 作者:玄冥_丶  | 我要投稿


#include <stdio.h>


#include <windows.h>


#include <time.h>?


? ? ? ? ? ? ? ? ? ? ? ? ? ?//里規(guī)格:長39*2=78 (真坐標(biāo))(假坐標(biāo)寬為39)? 高39


? ? ? ? ? ? ? ? ? ? ? ? ? ?//外規(guī)格:長41*2=82 (真坐標(biāo))(假坐標(biāo)寬為41)? 高41


#define UP? ? 1


#define DOWN? 2


#define LEFT? 3


#define RIGHT 4


#define MAX_LEVEL 8


#define BULLET_NUM 20


#define MAX_LIFE 4


//程序中未寫入函數(shù)參數(shù)表中且未說明的變量只有map二維數(shù)組,level_info數(shù)組和level? ?


?


/*


? ? ? 此程序中涉及的x,y類的坐標(biāo)值,分為以下兩種:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?


? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??


假坐標(biāo):這里的坐標(biāo)指的是以一個■長度為單位的坐標(biāo),而不是真正的coord坐標(biāo) (用于map數(shù)組的坐標(biāo))? ? ? ? ? ? ? ? ? ? ? ? ? ? ?


? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??


真坐標(biāo):頭文件自帶的坐標(biāo)結(jié)構(gòu)coord中的坐標(biāo)(也可以說是控制臺里的真正坐標(biāo)值)? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?


? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??


? 區(qū)別:縱坐標(biāo)y兩值一致,假橫坐標(biāo)x值與真正coord橫坐標(biāo)(真坐標(biāo))關(guān)系是 x * 2 = coord 橫坐標(biāo)? ??


? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??


? ? ? ? ? coord橫坐標(biāo)既指GoTo函數(shù)中的x參數(shù),因?yàn)楸境绦蛴螒蚪缑嬉砸粋€■長度為基本單位,? ? ? ? ? ? ? ? ? ??


? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??


? ? ? ? ? 可以說涉及的coord橫坐標(biāo)全是偶數(shù)。既假坐標(biāo)要變真坐標(biāo)(變真坐標(biāo)才能發(fā)揮真正作用),橫坐標(biāo)須乘以2? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??




? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?


*/


typedef struct? ? ? ? ? ? ?//這里的出現(xiàn)次序指的是一個AI_tank變量中的次序,游戲共有四個AI_tank變量


{? ? ? ? ? ? ? ? ? ? ? ? ? //∵設(shè)定每個AI_tank每種特殊坦克只出現(xiàn)一次 ∴fast_tank & firm_tank 最多出現(xiàn)次數(shù)不超過1


? ? int fast_tank_order;? ?//fast_tank出現(xiàn)的次序(在第fast_tank_order次復(fù)活出現(xiàn),從第0次開始),且每個AI_tank只出現(xiàn)一次


? ? int firm_tank_order;? ?//firm_tank出現(xiàn)的次序,同上


} LevInfo;? ? ? ? ? ? ? ? ?//關(guān)卡信息(準(zhǔn)確說是該關(guān)出現(xiàn)的坦克信息)


LevInfo level_info [MAX_LEVEL] = {{-1,-1},{3,-1},{-1,3},{2,3},{2,3},{2,3},{2,3},{2,3}};? ?//初始化,-1代表沒有該類型坦克


?


?


typedef struct? ? ? //子彈結(jié)構(gòu)體


{


? ? int x,y;? ? ? ? //子彈坐標(biāo),假坐標(biāo)


? ? int direction;? //子彈方向變量


? ? bool exist;? ? ?//子彈存在與否的變量,1為存在,0不存在


? ? bool initial;? ?//子彈是否處于建立初狀態(tài)的值,1為處于建立初狀態(tài),0為處于非建立初狀態(tài)


? ? bool my;? ? ? ? //區(qū)分AI子彈與玩家子彈的標(biāo)記,0為AI子彈,1為玩家(我的)子彈


} Bullet;


Bullet bullet [BULLET_NUM];? //考慮到地圖上不太可能同時存在20顆子彈,所以數(shù)組元素設(shè)置20個


?


?


typedef struct? ? ? //坦克結(jié)構(gòu)體


{


? ? int x,y;? ? ? ? //坦克中心坐標(biāo)


? ? int direction;? //坦克方向


? ? int color;? ? ? //顏色參方向數(shù),1到6分別代表不同顏色,具體在PrintTank函數(shù)定義有說明


? ? int model;? ? ? //坦克圖案模型,值為1,2,3,分別代表不同的坦克圖案,0為我的坦克圖案,AI不能使用


? ? int stop;? ? ? ?//只能是AI坦克使用的參數(shù),非0代表坦克停止走動,0為可以走動


? ? int revive;? ? ?//坦克復(fù)活次數(shù)


? ? int num;? ? ? ? //AI坦克編號(固定值,為常量,初始化函數(shù)中定下)0~3


? ? int CD=0;? ? ? ? ?//發(fā)射子彈冷卻計(jì)時


? ? bool my;? ? ? ? //是否敵方坦克參數(shù),我的坦克此參數(shù)為1,為常量


? ? bool alive;? ? ?//存活為1,不存活為0


}? Tank;


Tank AI_tank[4] , my_tank;? //my_tank為我的坦克,Ai_tank 代表AI坦克


?


//∵所有的函數(shù)都有可能對全局變量map進(jìn)行讀寫(改變),


//∴函數(shù)中不另說明是否會對全局變量map讀寫


//基本操作與游戲輔助函數(shù)


void GoToxy(int x,int y);? ? //光標(biāo)移動


void HideCursor();? ? ? ? ? ?//隱藏光標(biāo)


void keyboard ();? ? ? ? ? ? //接受鍵盤輸入


void Initialize();? ? ? ? ? ?//初始化(含有對多個數(shù)據(jù)的讀寫)


void Stop();? ? ? ? ? ? ? ? ?//暫停


void Getmap();? ? ? ? ? ? ? ?//地圖數(shù)據(jù)存放與獲取


void Frame ();? ? ? ? ? ? ? ?//打印游戲主體框架


void PrintMap();? ? ? ? ? ? ?//打印地圖(地圖既地圖障礙物)(含對level的讀取)


void SideScreen ();? ? ? ? ? //副屏幕打印


void GameCheak();? ? ? ? ? ? //檢測游戲輸贏


void GameOver( bool home );? //游戲結(jié)束


void ClearMainScreen();? ? ? //主屏幕清屏函數(shù)∵system("cls")后打印框架有一定幾率造成框架上移一行的錯誤∴單獨(dú)編寫清屏函數(shù)


void ColorChoose(int color); //顏色選擇函數(shù)


void NextLevel();? ? ? ? ? ? //下一關(guān)(含有對level全局變量的讀寫)


?


//子彈部分


void BuildAIBullet(Tank *tank);? ? ? ? ? ? ? ? //AI坦克發(fā)射子彈(含有對my_tank的讀取,只讀取了my_tank坐標(biāo))


void BuildBullet? (Tank tank);? ? ? ? ? ? ? ? ?//子彈發(fā)射(建立)(人機(jī)共用)(含全局變量bullet的修改)我的坦克發(fā)射子彈直接調(diào)用該函數(shù),AI通過AIshoot間接調(diào)用


void BulletFly? ? (Bullet bullet[BULLET_NUM]); //子彈移動和打擊(人機(jī)共用),


void BulletHit? ? (Bullet* bullet);? ? ? ? ? ? //子彈碰撞(人機(jī)共用)(含Tank全局變量的修改),只通過BulletFly調(diào)用,子彈間的碰撞不在本函數(shù),子彈間碰撞已在BulletShoot中檢測并處理


void PrintBullet? (int x,int y,int T);? ? ? ? ?//打印子彈(人機(jī)共用)


void ClearBullet? (int x,int y,int T);? ? ? ? ?//清除子彈(人機(jī)共用)


int? BulletCheak? (int x,int y);? ? ? ? ? ? ? ?//判斷子彈前方情況(人機(jī)共用)


?


//坦克部分


void BuildAITank (int* position, Tank* AI_tank); //建立AI坦克


void BuildMyTank (Tank* my_tank);? ? ? ? ? ? ? ? //建立我的坦克


void MoveAITank? (Tank* AI_tank);? ? ? ? ? ? ? ? //AI坦克移動


void MoveMyTank? (int turn);? ? ? ? ? ? ? ? ? ? ?//我的坦克移動,只通過keyboard函數(shù)調(diào)用,既鍵盤控制


void ClearTank? ?(int x,int y);? ? ? ? ? ? ? ? ? //清除坦克(人機(jī)共用)


void PrintTank? ?(Tank tank);? ? ? ? ? ? ? ? ? ? //打印坦克(人機(jī)共用)


bool TankCheak? ?(Tank tank,int direction);? ? ? //檢測坦克dirtection方向的障礙物,返值1阻礙,0 暢通


int? AIPositionCheak (int position);? ? ? ? ? ?//檢測AI坦克建立位置是否有障礙物AIPositionCheak


?


//DWORD WINAPI InputX(LPVOID lpParameter); //聲明線程函數(shù),用于檢查X鍵輸入并設(shè)置X鍵的輸入冷卻時間


?


?


//注意map數(shù)組應(yīng)是縱坐標(biāo)在前,橫坐標(biāo)在后,既map[y][x],(∵數(shù)組行長度在前,列長度在后)


//map里的值: 個位數(shù)的值為地圖方塊部分,百位數(shù)的值為坦克,子彈在map上沒有值(子彈僅僅是一個假坐標(biāo))


//map里的值: 0為可通過陸地,1為紅磚,2黃磚,5為水,100~103為敵方坦克,200為我的坦克,


?


//全局變量


int map[41][41];? //地圖二維數(shù)組


int key_x;? ? ? ? // X鍵是否被“讀入”的變量,也是子彈是否可以發(fā)射的變,


int bul_num;? ? ? //子彈編號


int position;? ? ?//位置計(jì)數(shù),對應(yīng)AI坦克生成位置,-1為左位置,0為中間,1為右,2為我的坦克位置


int speed=7;? ? ? //游戲速度,調(diào)整用


int level=1;? ? ? //游戲關(guān)卡數(shù)


int score=0;? ? ? //游戲分?jǐn)?shù)


int remain_enemy; //剩余敵人(未出現(xiàn)的敵人)


?


char* tank_figure[4][3][4]=


{


? {


? ? {"◢┃◣", "◢━◣", "◢┳◣", "◢┳◣"},


? ? {"┣●┫", "┣●┫", "━●┃", "┃●━"},


? ? {"◥━◤", "◥┃◤", "◥┻◤", "◥┻◤"}


? },?


? {


? ? {"┏┃┓", "┏┳┓", "┏┳┓", "┏┳┓"},


? ? {"┣●|",? "┣●|",? "━●┫", "┣●━"},


? ? {"┗┻┛", "┗┃┛", "┗┻┛", "┗┻┛"}


? },?


? {


? ? {"┏┃┓", "◢━◣", "┏┳◣", "◢┳┓"},


? ? {"┣●┫", "┣●┫", "━●┃", "┃●━"},


? ? {"◥━◤", "┗┃┛", "┗┻◤", "◥┻┛"}


? },


? {


? ? {"╔┃╗", "╔╦╗", "╔╦╗", "╔╦╗"},


? ? {"╠█╣", "╠█╣", "━█╣", "╠█━"},


? ? {"╚╩╝", "╚┃╝", "╚╩╝", "╚╩╝"}


? }


};


?


?


?


int main ()? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//主函數(shù)


{


? ? int i;


? ? unsigned int interval[12]={1,1,1,1,1,1,1,1,1,1,1,1} ;? //間隔計(jì)數(shù)器數(shù)組,用于控制速度


? ? srand(time(NULL)); //設(shè)置隨機(jī)數(shù)種子(若不設(shè)置種子而調(diào)用rand會使每次運(yùn)行的隨機(jī)數(shù)序列一致)隨機(jī)數(shù)序列指:如首次調(diào)用rand得到1,第二次得2,第三次3,則此次隨機(jī)數(shù)序列為1,2,3


? ? HideCursor();? ? ? ? ? ? ? ? ? ? ? ? ?//隱藏光標(biāo)


? ? system("mode con cols=112 lines=42"); //控制窗口大小


? ? Frame ();? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//打印游戲主體框架


? ? Initialize();? ? ? ? ? ? ? ? ? ? ? ? ?//初始化,全局變量level初值便是1?


//? ? HANDLE h1 , h2 ;? ? ? ? ? ? ? ? ? ? ? //定義句柄變量


? ? for(;;)


? ? {


? ? ? ? if(interval[0]++%speed==0)? ? ? ? //速度調(diào)整用,假設(shè)interval[0]為a, 語句意為 a % 2==0,a=a+1;?


? ? ? ? {


? ? ? ? ? ? GameCheak();? ? ? ? ? ? ? ? ? //游戲勝負(fù)檢測


? ? ? ? ? ? BulletFly ( bullet );


? ? ? ? ? ? for(i=0 ; i<=3 ; i++)? ? ? ? ?//AI坦克移動循環(huán)


? ? ? ? ? ? {


? ? ? ? ? ? ? ? if(AI_tank[i].model==2 && interval[i+1]++%2==0) //四個坦克中的快速坦克單獨(dú)使用計(jì)數(shù)器1,2,3,4


? ? ? ? ? ? ? ? ? ? MoveAITank( & AI_tank[i]);


? ? ? ? ? ? ? ? if(AI_tank[i].model!=2 && interval[i+5]++%3==0) //四個坦克中的慢速坦克單獨(dú)使用計(jì)數(shù)器5,6,7,8


? ? ? ? ? ? ? ? ? ? MoveAITank( & AI_tank[i]);


? ? ? ? ? ? }


? ? ? ? ? ? for(i=0;i<=3;i++)? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//建立AI坦克部分


? ? ? ? ? ? ? ? ? ? ?if(AI_tank[i].alive==0 && AI_tank[i].revive<4 && interval[9]++%90==0)? //一個敵方坦克每局只有4條命


? ? ? ? ? ? ? ? {? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//如果坦克不存活。計(jì)時,每次建立有間隔? 1750 ms


? ? ? ? ? ? ? ? ? ? ? BuildAITank( &position, & AI_tank[i] );? ? ?//建立AI坦克(復(fù)活)


? ? ? ? ? ? ? ? ? ? ? break;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //每次循環(huán)只建立一個坦克


? ? ? ? ? ? ? ? ? }


? ? ? ? ? ? for(i=0;i<=3;i++)


? ? ? ? ? ? ? ? if(AI_tank[i].alive)


? ? ? ? ? ? ? ? ? ? BuildAIBullet(&AI_tank[i]);? ? ? ? ? ? ? ? ?//AIshoot自帶int自增計(jì)數(shù)CD,不使用main中的CD interval


? ? ? ? ? ? if(my_tank.alive && interval[10]++%2==0 )


? ? ? ? ? ? ? ? ?keyboard ();


? ? ? ? ? ? if(my_tank.alive==0 && interval[11]++%30==0 && my_tank.revive < MAX_LIFE)


? ? ? ? ? ? ? ? ?BuildMyTank( &my_tank );


? ? ? ? }


? ? ? ? Sleep(5);


? ? }


? ? return 0;


}


?


?


///這里的多線程暫時不用? ? ? ? ? ? ? ? ? ?//x鍵用于子彈發(fā)射,x鍵的冷卻時間不能和上下左右一同設(shè)置,那樣就太快了


DWORD WINAPI InputX(LPVOID lpParameter)? ? //如果不用多線程運(yùn)行,那么在x鍵冷卻時間內(nèi)程序會因Sleep將會掛起,暫停運(yùn)行


{? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //因?yàn)橹挥幸粋€變量改變,而且變量改變先后順序是顯而易見的,所以不必設(shè)置緩沖區(qū)


? ? for(;;)? ? ? ? ? ? ? ? ? ? ? ? ? ? ??


? ? {? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??


? ? ? ? if(GetAsyncKeyState( 88 )& 0x8000) //88為x鍵鍵值,當(dāng)摁下x并且x鍵處于可輸入狀態(tài)


? ? ? ? {


? ? ? ? ? ? key_x=1;? ? ? ? ? ? ? ? ? ? ? ?// X鍵是否允許被“讀入”的變量,也是子彈是否可以發(fā)射的變量


? ? ? ? ? ??

? ? ? ? }


? ? ? ??


? ? }


? ? return 0;


}


?


?


void keyboard ()


{? ? ? ? ? ? ? ?// kbhit()? ?getch()? 用法可用但是不好用? ? ? ? ? ??




? ? int count=0;


? ? if (GetAsyncKeyState(VK_UP)& 0x8000)??


? ? ? ? MoveMyTank( UP );


? ? else if (GetAsyncKeyState(VK_DOWN)& 0x8000)??


? ? ? ? MoveMyTank( DOWN );


? ? else if (GetAsyncKeyState(VK_LEFT)& 0x8000)


? ? ? ? MoveMyTank( LEFT );


? ? else if (GetAsyncKeyState(VK_RIGHT)& 0x8000)??


? ? ? ? MoveMyTank( RIGHT );


? ? else if (GetAsyncKeyState( 0x1B )& 0x8000)? // Esc鍵


? ? ? ? exit(0);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //退出程序函數(shù)


? ? else if (GetAsyncKeyState( 0x20 )& 0x8000)? //空格


? ? ? ? Stop();


? ? else if (count++%7==0)? ? ? ? ? ? //這里添加計(jì)數(shù)器是為了防止按鍵粘連不能達(dá)到微調(diào)效果


? ? {


? ? ? ? if (speed>1 && GetAsyncKeyState( 0x6B )& 0x8000)? ?// +鍵


? ? ? ? {


? ? ? ? ? ? speed--;


? ? ? ? ? ? GoToxy(102,11);? ? ? ? ? ?//在副屏幕打印出當(dāng)前速度


? ? ? ? ? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_BLUE|FOREGROUND_RED);


? ? ? ? ? ? printf("%d ",21-speed);? ?//副屏幕顯示的速度為1~10


? ? ? ? }


? ? ? ? else if (speed<20 && GetAsyncKeyState( 0x6D )& 0x8000)? // - 鍵


? ? ? ? {


? ? ? ? ? ? speed++;


? ? ? ? ? ? GoToxy(102,11);? ? ? ? ? ?//在副屏幕打印出當(dāng)前速度


? ? ? ? ? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_BLUE|FOREGROUND_RED);


? ? ? ? ? ? printf("%d ",21-speed);? ?//副屏幕顯示的速度為1~10


? ? ? ? }


? ? }


? ? if(my_tank.CD==7)


? ? {


? ? ? ? if(GetAsyncKeyState( 88 )& 0x8000)


? ? ? ? {


? ? ? ? ? ? BuildBullet(my_tank);


? ? ? ? ? ? my_tank.CD=0;


? ? ? ? }


? ? }


? ? else


? ? ? ? my_tank.CD++;


}


?


?


?


void BuildAIBullet(Tank *tank)? ?//AI子彈發(fā)射(建立)含有對my_tank的讀取


{


? ? if(tank->CD==15)


? ? {


? ? ? ? if(!(rand()%11))? ? ?//冷卻結(jié)束后在隨后的每個游戲周期中有10分之一的可能發(fā)射子彈


? ? ? ? {


? ? ? ? ? ?BuildBullet(*tank);


? ? ? ? ? ? tank->CD=0;


? ? ? ? }


? ? }


? ? else


? ? ? ? tank->CD++;


? ? if(tank->CD >= 14)? ? ? ?//AI強(qiáng)化部分,在冷卻到達(dá)一定范圍即可使用


? ? {


? ? ? ? if(tank->y==38 )? ? ?//如果坦克在底部(這個最優(yōu)先)


? ? ? ? {


? ? ? ? ? ? if(tank->x < 20) //在老家左邊


? ? ? ? ? ? {


? ? ? ? ? ? ? ? if(tank->direction==LEFT)? //坦克方向朝左


? ? ? ? ? ? ? ? {


? ? ? ? ? ? ? ? ? ? BuildBullet(*tank);? ? ?//發(fā)射子彈


? ? ? ? ? ? ? ? ? ? tank->CD=0;


? ? ? ? ? ? ? ? }


? ? ? ? ? ? }


? ? ? ? ? ? else? ? ? ? ? ? ?//在老家右邊


? ? ? ? ? ? ? ? if(tank->direction==RIGHT)? ?//坦克方向朝右


? ? ? ? ? ? ? ? {


? ? ? ? ? ? ? ? ? ? BuildBullet(*tank);? ? ?//發(fā)射子彈


? ? ? ? ? ? ? ? ? ? tank->CD=0;


? ? ? ? ? ? ? ? }


? ? ? ? }


? ? ? ? else if(tank->x==my_tank.x+1 || tank->x==my_tank.x || tank->x==my_tank.x-1)? //AI坦克在縱向上"炮口"對準(zhǔn)我的坦克


? ? ? ? {


? ? ? ? ? ? if(tank->direction==DOWN && my_tank.y > tank->y || tank->direction==UP && my_tank.y < tank->y)


? ? ? ? ? ? {? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//若是AI朝下并且我的坦克在AI坦克下方(數(shù)值大的在下面)或者AI朝上我的坦克在AI上方


? ? ? ? ? ? ? ? int big=my_tank.y , smal=tank->y , i;?


? ? ? ? ? ? ? ? if(my_tank.y < tank->y)


? ? ? ? ? ? ? ? {


? ? ? ? ? ? ? ? ? ? big=tank->y;


? ? ? ? ? ? ? ? ? ? smal=my_tank.y;


? ? ? ? ? ? ? ? }


? ? ? ? ? ? ? ? for(i=smal+2;i<=big-2;i++)? //判斷AI炮口的直線上兩坦克間有無障礙


? ? ? ? ? ? ? ? ? ? if(map[i][tank->x]!=0 || map[i][tank->x]!=5)? ? ? //若有障礙


? ? ? ? ? ? ? ? ? ? ? ? break;


? ? ? ? ? ? ? ? if(i==big-1)? ? ? ? ? ? ? ? //若i走到big-1說明無障礙


? ? ? ? ? ? ? ? {


? ? ? ? ? ? ? ? ? ?BuildBullet(*tank);? ? ?//則發(fā)射子彈


? ? ? ? ? ? ? ? ? ? tank->CD=0;


? ? ? ? ? ? ? ? }


? ? ? ? ? ? }


? ? ? ? }


? ? ? ? else if(tank->y==my_tank.y+1 || tank->y==my_tank.y || tank->y==my_tank.y-1) //AI坦克在橫向上"炮口"對準(zhǔn)我的坦克


? ? ? ? {


? ? ? ? ? ? if(tank->direction==RIGHT && my_tank.x > tank->x || tank->direction==LEFT && my_tank.x < tank->x)


? ? ? ? ? ? {? ? ? ? ? ? ? ? ? //若是AI朝右并且我的坦克在AI坦克右方(數(shù)值大的在下面)或者AI朝左我的坦克在AI左方


? ? ? ? ? ? ? ? int big=my_tank.y , smal=tank->y , i;


? ? ? ? ? ? ? ? if(my_tank.x < tank->x)


? ? ? ? ? ? ? ? {


? ? ? ? ? ? ? ? ? ? big=tank->x;


? ? ? ? ? ? ? ? ? ? smal=my_tank.x;


? ? ? ? ? ? ? ? }


? ? ? ? ? ? ? ? for(i=smal+2;i<=big-2;i++)? //判斷AI炮口的直線上兩坦克間有無障礙


? ? ? ? ? ? ? ? ? ? if(map[tank->y][i]!=0 || map[tank->y][i]!=5)? ? ? //若有障礙


? ? ? ? ? ? ? ? ? ? ? ? break;


? ? ? ? ? ? ? ? if(i==big-1)? ?//若i走到big-1說明無障礙


? ? ? ? ? ? ? ? {


? ? ? ? ? ? ? ? ? ? BuildBullet(*tank);? ? ?//則發(fā)射子彈


? ? ? ? ? ? ? ? ? ? tank->CD=0;


? ? ? ? ? ? ? ? }


? ? ? ? ? ? }


? ? ? ? }


? ? }


}


?


?


?


void BuildBullet(Tank tank)? //子彈發(fā)射(建立),傳入結(jié)構(gòu)體Tank,這里包含改變了全局變量結(jié)構(gòu)體bullet


{? ? ? ? ? ? ? ? ? ? ? ? ? ? //∵實(shí)現(xiàn)方式為順序循環(huán)建立子彈,每次調(diào)用改變的bullet數(shù)組元素都不同


? ? switch(tank.direction)? ?//∴為了方便,不將bullet放入?yún)?shù),bullet作為全局變量使用


? ? {


? ? ? ? case UP? ? :


? ? ? ? ? ? ? ? bullet [bul_num].x = tank.x;


? ? ? ? ? ? ? ? bullet [bul_num].y = tank.y-2;


? ? ? ? ? ? ? ? bullet [bul_num].direction=1;


? ? ? ? ? ? ? ? break;


? ? ? ? case DOWN? :


? ? ? ? ? ? ? ? bullet [bul_num].x = tank.x;


? ? ? ? ? ? ? ? bullet [bul_num].y = tank.y+2;


? ? ? ? ? ? ? ? bullet [bul_num].direction=2;


? ? ? ? ? ? ? ? break;


? ? ? ? case LEFT? :


? ? ? ? ? ? ? ? bullet [bul_num].x = tank.x-2;


? ? ? ? ? ? ? ? bullet [bul_num].y = tank.y;


? ? ? ? ? ? ? ? bullet [bul_num].direction=3;


? ? ? ? ? ? ? ? break;


? ? ? ? case RIGHT :


? ? ? ? ? ? ? ? bullet [bul_num].x = tank.x+2;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?


? ? ? ? ? ? ? ? bullet [bul_num].y = tank.y;?


? ? ? ? ? ? ? ? bullet [bul_num].direction=4;


? ? ? ? ? ? ? ? break;?


? ? }? ? ?


? ? bullet [bul_num].exist = 1;? ? //子彈被建立,此值為1則此子彈存在


? ? bullet [bul_num].initial = 1;? //子彈處于初建立狀態(tài)


? ? bullet [bul_num].my=1;? ?//如果是我的坦克發(fā)射的子彈bullet.my=1,否則為0


? ? bul_num++;


? ? if(bul_num==BULLET_NUM)? ? ? ? //如果子彈編號增長到20號,那么重頭開始編號


? ? ? ? bul_num=0;? ? ? ? ? ? ? ? ?//考慮到地圖上不可能同時存在20顆子彈,所以數(shù)組元素設(shè)置20個


}


?


?


void BulletFly(Bullet bullet[BULLET_NUM]) //子彈移動和打擊


{? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//含有全局變量Bullet的改變


? ? for(int i =0; i<BULLET_NUM;i++)


? ? {


? ? ? ? if(bullet [i].exist)? ? ? ? ? ? ? //如果子彈存在


? ? ? ? {? ?


? ? ? ? ? ? if(bullet [i].initial==0)? ? ?//如果子彈不是初建立的


? ? ? ? ? ? {? ? ? ? ? ? ? ? ? ? ? ? ? ?


? ? ? ? ? ? ? ? if(map[bullet[i].y] [bullet[i].x]==0 || map[bullet[i].y] [bullet[i].x]==5)? ?//如果子彈坐標(biāo)當(dāng)前位置無障礙


? ? ? ? ? ? ? ? ? ? ClearBullet( bullet[i].x , bullet[i].y , BulletCheak(bullet[i].x , bullet[i].y ));? ? ?//抹除子彈圖形


? ? ? ? ? ? ? ? switch(bullet [i].direction)? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //然后子彈坐標(biāo)變化(子彈變到下一個坐標(biāo))


? ? ? ? ? ? ? ? {


? ? ? ? ? ? ? ? ? ? case UP? ? :(bullet [i].y)--;break;


? ? ? ? ? ? ? ? ? ? case DOWN? :(bullet [i].y)++;break;


? ? ? ? ? ? ? ? ? ? case LEFT? :(bullet [i].x)--;break;


? ? ? ? ? ? ? ? ? ? case RIGHT :(bullet [i].x)++;break;


? ? ? ? ? ? ? ? }


? ? ? ? ? ? }


? ? ? ? ? ? int collide = BulletCheak ( bullet [i].x , bullet [i].y );? ?//判斷子彈當(dāng)前位置情況,判斷子彈是否碰撞,是否位于水面上。


? ? ? ? ? ? if( collide )? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //如果檢測到當(dāng)前子彈坐標(biāo)無障礙(無碰撞)(包括在地面上與在水面上)


? ? ? ? ? ? ? ? PrintBullet( bullet[i].x , bullet[i].y , collide);? ? ? ?//則打印子彈,若有碰撞則不打印


? ? ? ? ? ? else


? ? ? ? ? ? ? ? BulletHit( & bullet [i] );? ? ?//若有碰撞則執(zhí)行子彈碰撞函數(shù)? ? ? ? ? ? ? ? ??


? ? ? ? ? ? if(bullet [i].initial)? ? ? ? ? ? ?//若子彈初建立,則把初建立標(biāo)記去除


? ? ? ? ? ? ? ? bullet [i].initial = 0;


? ? ? ? ? ? for(int j=0; j< BULLET_NUM ; j++)? //子彈間的碰撞判斷,若是我方子彈和敵方子彈碰撞則都刪除,若為兩敵方子彈則無視


? ? ? ? ? ? ? ? if(bullet [j].exist && j!=i && (bullet[i].my || bullet[j].my) && bullet[i].x==bullet[j].x && bullet[i].y==bullet[j].y)


? ? ? ? ? ? ? ? {? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //同樣的兩顆我方子彈不可能產(chǎn)生碰撞


? ? ? ? ? ? ? ? ? ? bullet [j].exist=0;


? ? ? ? ? ? ? ? ? ? bullet [i].exist=0;


? ? ? ? ? ? ? ? ? ? ClearBullet( bullet[j].x , bullet[j].y , BulletCheak(bullet[j].x , bullet[j].y ));? //抹除j子彈圖形,子彈i圖形已被抹除


? ? ? ? ? ? ? ? ? ? break;


? ? ? ? ? ? ? ? }


? ? ? ? }


? ? }


}


?


?


void BulletHit(Bullet* bullet)? //含有Tank全局變量的修改,子彈間的碰撞不在本函數(shù),子彈間碰撞已在BulletShoot中檢測并處理


{? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//∵每次打中的坦克都不一樣,不可能把所有坦克放在參數(shù)表中


? ? int x=bullet->x;? ? ? ? ? ? //∴這里的Tank使用全局變量


? ? int y=bullet->y;? ? ? ? ? ? //這里傳入的值是子彈坐標(biāo),這兩個值不需要改變


? ? int i;


? ? if(map[y][x]==1 || map[y][x]==2)? //子彈碰到磚塊


? ? {


? ? ? ? if(bullet->direction==UP || bullet->direction==DOWN)? ?//如果子彈是縱向的


? ? ? ? ? ? for(i = -1 ; i<=1 ; i++)


? ? ? ? ? ? ? ? if(map[y][x+i]==1 || map[y][x+i]==2)? //如果子彈打中磚塊兩旁為磚塊,則刪除磚,若不是(一旁為坦克或其他地形)則忽略


? ? ? ? ? ? ? ? {


? ? ? ? ? ? ? ? ? ? map[y][x+i]=0;? ? //磚塊碎


? ? ? ? ? ? ? ? ? ? ?GoToxy(2*x+2*i,y);


? ? ? ? ? ? ? ? ? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED); //背景黑色


? ? ? ? ? ? ? ? ? ? ?printf("? ");


? ? ? ? ? ? ? ? }


? ? ? ? if(bullet->direction==LEFT || bullet->direction==RIGHT)? ? ?//若子彈是橫向的? (與子彈縱向?qū)崿F(xiàn)同理)


? ? ? ? ? ? for(i = -1 ; i<=1 ; i++)


? ? ? ? ? ? ? ? if(map[y+i][x]==1 || map[y+i][x]==2)


? ? ? ? ? ? ? ? {


? ? ? ? ? ? ? ? ? ? map[y+i][x]=0;


? ? ? ? ? ? ? ? ? ? ?GoToxy(2*x,y+i);


? ? ? ? ? ? ? ? ? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED); //背景黑色


? ? ? ? ? ? ? ? ? ? ?printf("? ");?


? ? ? ? ? ? ? ? }


? ? ? ? bullet->exist=0;? ? ? ? ? ?//這顆子彈已經(jīng)不存在了


? ? }


? ? else if(map[y][x]==4 || map[y][x]==6 )? //子彈碰到邊框或者不可摧毀方塊


? ? ? ? bullet->exist=0;


? ? else if(bullet->my && map[y][x]>=100 && map[y][x]<104 )? //若我的子彈碰到了敵方坦克


? ? {


? ? ? ? int num = map[y][x]%100;? ?//map[y][x]%100 等同于 tank.num ,可通過map值讀取該坦克信息


? ? ? ? if(AI_tank[num].model==3 && AI_tank[num].color==2)? ?//若為firm tank,且color==2。該坦克為綠色,表明沒有受到傷害


? ? ? ? ? ? ? ? AI_tank[num].color=3;? ? ? ? ? ? ? ? ? ? ? ? //則變成黃色,color=3為黃色


? ? ? ? else if (AI_tank[num].model==3 && AI_tank[num].color==3)


? ? ? ? ? ? ? ? AI_tank[num].color=4;? ? ? ? ? ? ? ? ? ? ? ? //4為紅色


? ? ? ? else? ? ? ? ? ? ? ? ? ? ? ?//其他類型的坦克或者firm tank為紅色的情況


? ? ? ? {


? ? ? ? ? ? AI_tank[num].alive=0;


? ? ? ? ? ? ClearTank(AI_tank[num].x , AI_tank[num].y);? ? ? //清除該坦克


? ? ? ? }


? ? ? ? bullet->exist=0;


? ? ? ? score+=100;


? ? ? ? GoToxy(102,5);? ? ? ? ? ? ?//在副屏幕上打印出分?jǐn)?shù)


? ? ? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);


? ? ? ? printf("%d ",score);


? ? }


? ? /*else if(map[y][x]==200 && bullet->my==0 )? ?//若敵方子彈擊中我的坦克


? ? {


? ? ? ? my_tank.alive=0;


? ? ? ? ClearTank(my_tank.x , my_tank.y);


? ? ? ? bullet->exist=0;


? ? ? ? my_tank.revive++;? ? ? //我的坦克復(fù)活次數(shù)+1(∵我的坦克復(fù)活次數(shù)與生命值有關(guān)∴放在這里自減)


? ? ? ? score-=100;? ? ? ? ? ? //分?jǐn)?shù)減少


? ? ? ? GoToxy(102,5);? ? ? ? ?//在副屏幕上打印出分?jǐn)?shù)


? ? ? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);


? ? ? ? printf("%d? ?",score);


? ? ? ? GoToxy(102,7);? ? ? ? ?//在副屏幕打印出我的剩余生命值


? ? ? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN);


? ? ? ? printf("%d? ?", MAX_LIFE-my_tank.revive);


? ? }*/


//? ? else if(bullet->my==0 && map[y][x]>=100 && map[y][x]<104) //敵方子彈擊中敵方坦克,可以設(shè)置兩種子彈運(yùn)行方式,這種暫時不用


//? ? ? ? bullet->exist=0;


? ? else if(map[y][x]==9)? ? ? //子彈碰到家(無論是誰的子彈)


? ? {


? ? ? ? bullet->exist=0;


? ? ? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_BLUE|FOREGROUND_RED|FOREGROUND_GREEN);


? ? ? ? GoToxy(38,37);? ? ?printf("軍事基地");


? ? ? ? GoToxy(38,38);? ? ?printf("◢◣? ");


? ? ? ? GoToxy(38,39);? ? ?printf("███");


? ? ? ? //GameOver(1);? ? ? ? ? ?//游戲結(jié)束,傳入1代表老家被毀


? ? }


}


?


?


int BulletCheak (int x,int y)? //判斷子彈當(dāng)前位置情況,判斷子彈是否碰撞,是否位于水面上。


{? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //有障礙返回0,無障礙且子彈在地面返回1,子彈在水面上返回2


? ? if(map[y][x]==0)


? ? ? ? return 1;


? ? else if(map[y][x]==5)


? ? ? ? return 2;


? ? else


? ? ? ? return 0;


}


?


?


void PrintBullet (int x,int y,int T)? ?//當(dāng)前坐標(biāo)BulletCheak 的值做參量 T


{


? ? if(T==1)? ? ? ? ? //? T==1 表示子彈當(dāng)前坐標(biāo)在陸地上


? ? ? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY);


? ? else if(T==2)? ? ?//? T==2 表示子彈當(dāng)前坐標(biāo)在水面上


? ? ? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY|BACKGROUND_BLUE);


? ? GoToxy(2*x,y);


? ? printf(".");


}


?


?


void ClearBullet(int x,int y,int T)? ?//當(dāng)前坐標(biāo)BulletCheak 的值做參量 T


{


? ? GoToxy(2*x,y);


? ? if(T==2)? ? ? ? //? T==2 表示子彈當(dāng)前坐標(biāo)在水面上


? ? {


? ? ? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|BACKGROUND_BLUE|FOREGROUND_BLUE|FOREGROUND_GREEN);


? ? ? ? printf("~");


? ? }


? ? else if(T==1)? ?//? T==1 表示子彈當(dāng)前坐標(biāo)在陸地上


? ? {


? ? ? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_BLUE);


? ? ? ? printf("? ");


? ? }


}


?


?


//position為坦克生成位置,-1為左位置,0為中間,1為右,2為我的坦克位置


void BuildAITank(int* position, Tank* AI_tank)? ?//執(zhí)行一次該函數(shù)只建立一個坦克


{? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//rand函數(shù)公式:0<=rand()%(a+1)<=a? 0+m<=rand()%(n-m+1)+m<=n??


? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //rand函數(shù)實(shí)現(xiàn)1到n:1<=rand()%(n)+1<=n


? ? ? ?if(AIPositionCheak(*position))? ? ? ? //若此位置無障礙,可生成。position參數(shù)詳見AIPositionCheak函數(shù)定義


? ? {


? ? ? ? AI_tank->x= 20 + 18*(*position);? //20 + 18 * position 對應(yīng)三個生成位置的x假坐標(biāo)


? ? ? ? AI_tank->y=2;


? ? ? ? if(AI_tank->revive==level_info[level-1].firm_tank_order)? //坦克出現(xiàn)(復(fù)活)次序==關(guān)卡信息(level_info)中firm tank的出現(xiàn)次序


? ? ? ? {


? ? ? ? ? ? AI_tank->model = 3;? ? ? ? ? ?//3為firm tank的模型(外觀)


? ? ? ? ? ? AI_tank->color = 2;? ? ? ? ? ?//顏色參數(shù)2為綠色,具體詳見函數(shù)ColorChoose


? ? ? ? }


? ? ? ? else if(AI_tank->revive==level_info[level-1].fast_tank_order)? //同上if,這里是fast_tank的


? ? ? ? {


? ? ? ? ? ? AI_tank->model = 2;


? ? ? ? ? ? AI_tank->color = rand()%6+1;? //若不是firm tank則隨機(jī)顏色,顏色參數(shù)為1~6,分別代表不同顏色,詳見函數(shù)ColorChoose


? ? ? ? }


? ? ? ? else? ? ? //普通坦克


? ? ? ? {


? ? ? ? ? ? AI_tank->model = 1;


? ? ? ? ? ? ? ?AI_tank->color = rand()%6+1;? //若不是firm tank則隨機(jī)顏色


? ? ? ? }


? ? ? ? AI_tank->alive = 1;? ? ? ?//坦克變?yōu)榇嬖?/p>


? ? ? ? AI_tank->direction = 2 ;? //方向朝下


? ? ? ? AI_tank->revive++;? ? ? ? //復(fù)活次數(shù)+1


? ? ? ? PrintTank(*AI_tank);


? ? ? ? (*position)++;?


? ? ? ? remain_enemy--;


? ? ? ? GoToxy(102,9);? ? ? ? ? ? //在副屏幕上打印剩余坦克數(shù)


? ? ? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED);


? ? ? ? printf("%d ",remain_enemy);


? ? ? ? if(*position==2)? ? ? ? ? //position只能為0,1,-1,這里position循環(huán)重置


? ? ? ? ? ? *position = -1;


? ? ? ? ? ? ?return ;? ? ? ? ? ? ? ? ? //若生成了一輛坦克,則結(jié)束該函數(shù)


? ? }


}


?


?


int AIPositionCheak( int position )? ? //position為坦克生成位置2為我的坦克位置,其余為AI位,-1為左位,0為中間位置,1為右位


{


? ? int? ? x,y;


? ? if(position==2)? ? ? ? ? ? ? ? ? ? //2為我的坦克位置,現(xiàn)在暫時用不到


? ? ? ? x=15,y=38;


? ? else


? ? ? ? y=2 , x= 20 + 18 * position ;? //20 + 18 * position 對應(yīng)三個生成位置的x假坐標(biāo)


? ? for(int i=0;i<3;i++)


? ? ? ? for(int j=0;j<3;j++)


? ? ? ? ? ? if( map[y+j-1][x+i-1]!=0)? //如果遍歷的九宮格里有障礙物


? ? ? ? ? ? ? ? return 0;? ? ? ? ? ? ? //則返回0,表示此生成位置有阻礙


? ? return 1;? ? ? ? ? ? ? ? ? ? ? ? ? //否則生成1,表示此生成位置無阻礙


}


?


?


void MoveAITank(Tank* AI_tank) //AI專用函數(shù),該函數(shù)主要為AI加強(qiáng)


{


? ? ? ?if(AI_tank->alive)? ? ? ? ?//如果坦克活著


? ? {


? ? ? ? if(AI_tank->stop!=0)? ?//坦克是否停止運(yùn)動的判斷,若stop參數(shù)不為0


? ? ? ? {


? ? ? ? ? ? AI_tank->stop--;? ?//則此坦克本回合停止運(yùn)動


? ? ? ? ? ? return;


? ? ? ? }


? ? ? ? if( !(rand()%23) )? ? ?//22分之1的概率執(zhí)行方向重置


? ? ? ? {


? ? ? ? ? ? AI_tank->direction = rand()%4+1;


? ? ? ? ? ? if( rand()%3 )? ? ?//在方向重置后有2分之1的概率停止走動3步的時間


? ? ? ? ? ? {


? ? ? ? ? ? ? ? AI_tank->stop=2;


? ? ? ? ? ? ? ? return;


? ? ? ? ? ? }


? ? ? ? }


? ? ? ? ClearTank (AI_tank->x , AI_tank->y);


? ? ? ? if(TankCheak ( *AI_tank , AI_tank->direction))? ?//如果前方無障礙


? ? ? ? ? ? switch ( AI_tank->direction )


? ? ? ? ? ? {


? ? ? ? ? ? ? ? ? ?case UP? ?: AI_tank->y--; break;? //上前進(jìn)一格


? ? ? ? ? ? ? ? case DOWN : AI_tank->y++; break;? //下前進(jìn)一格


? ? ? ? ? ? ? ? ?case LEFT : AI_tank->x--; break;? //左前進(jìn)一格


? ? ? ? ? ? ? ? case RIGHT: AI_tank->x++; break;? //右前進(jìn)一格


? ? ? ? ? ? }


? ? ? ? else? ? ? ? ? ? ? ? ? ? ?//前方有障礙


? ? ? ? {


? ? ? ? ? ? if(!(rand()%4))? ? ? //3分之1的概率亂轉(zhuǎn)


? ? ? ? ? ? {


? ? ? ? ? ? ? ? AI_tank->direction=rand()%4+1;


? ? ? ? ? ? ? ? AI_tank->stop=2; //亂轉(zhuǎn)之后停止走動3步的時間


? ? ? ? ? ? ? ? PrintTank(*AI_tank);


? ? ? ? ? ? ? ? return;? ? ? ? ? //∵continue會跳過下面的打印函數(shù),∴這里先打印


? ? ? ? ? ? }


? ? ? ? ? ? else? ? ? ? ? ? ? ? ?//另外3分之2的幾率選擇正確的方向


? ? ? ? ? ? {


? ? ? ? ? ? ? ? int j;


? ? ? ? ? ? ? ? for(j=1;j<=4;j++)


? ? ? ? ? ? ? ? ? ? if(TankCheak ( *AI_tank , j ))? //循環(huán)判斷坦克四周有無障礙,此函數(shù)返值1為可通過


? ? ? ? ? ? ? ? ? ? ? ? break;


? ? ? ? ? ? ? ? if(j==5)? ? ? ? ?//j==5說明此坦克四周都有障礙物,無法通行


? ? ? ? ? ? ? ? {


? ? ? ? ? ? ? ? ? ? PrintTank(*AI_tank);


? ? ? ? ? ? ? ? ? ? return;? ? ? //則跳過下面的while循環(huán)以防程序卡死


? ? ? ? ? ? ? ? }


? ? ? ? ? ? ? ? while(TankCheak ( *AI_tank , AI_tank->direction) == 0)? //如果前方仍有障礙


? ? ? ? ? ? ? ? ? ? AI_tank->direction=(rand()%4+1);? ? ? ? ? ? ? ? ? ? //則換個隨機(jī)方向檢測


? ? ? ? ? ? }


? ? ? ? }


? ? ? ? PrintTank(*AI_tank);? ? ?//打印AI坦克


? ? }


}


?


?


void BuildMyTank (Tank* my_tank) //建立我的坦克


{


? ? my_tank->x=15;


? ? ? ?my_tank->y=38;


? ? ? ?my_tank->stop=NULL;


? ? ? ?my_tank->direction=1;


? ? my_tank->model=0;


? ? my_tank->color=1;


? ? my_tank->alive=1;


? ? my_tank->my=1;


? ? my_tank->CD=7;


? ? PrintTank (*my_tank) ;? ?//打印我的坦克


}


?


?


void MoveMyTank(int turn )? ?//玩家專用函數(shù),turn為keyboard函數(shù)里因輸入不同方向鍵而傳入的不同的值


{


? ? ClearTank(my_tank.x , my_tank.y);? ? ? ? //map 數(shù)組中“我的坦克”參數(shù)清除工作已在此函數(shù)中完成


? ? my_tank.direction=turn;? ? ? ? ? ? ? ? ? //將鍵盤輸入的方向值傳入我的坦克方向值


? ? if(TankCheak ( my_tank , my_tank.direction ))? //若此時我的坦克當(dāng)前方向上無障礙


? ? ? ? switch (turn)


? ? ? ? {


? ? ? ? ? ? case UP? ?: my_tank.y--; break;? //上前進(jìn)一格


? ? ? ? ? ? case DOWN : my_tank.y++; break;? //下前進(jìn)一格


? ? ? ? ? ? case LEFT : my_tank.x--; break;? //左前進(jìn)一格


? ? ? ? ? ? case RIGHT: my_tank.x++; break;? //右前進(jìn)一格


? ? }? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //若坦克當(dāng)前方向上有障礙則跳過坐標(biāo)變化直接打印該轉(zhuǎn)向的坦克


? ? PrintTank (my_tank);


}


?


?


bool TankCheak(Tank tank,int direction)? //檢測坦克前方障礙函數(shù),參量為假坐標(biāo)。返值1為可通過,返值0為阻擋(人機(jī)共用)


{


? ? switch(direction)? ? ? ? ? ? ? ? ? ? //direction變量? ?1上,2下,3左,4右


? ? {


? ? ? ? case UP:


? ? ? ? ? ? if (map[tank.y-2][tank.x]==0 && map[tank.y-2][tank.x-1]==0 && map[tank.y-2][tank.x+1]==0)


? ? ? ? ? ? ? ? return 1;


? ? ? ? ? ? else


? ? ? ? ? ? ? ? return 0;


? ? ? ? case DOWN:


? ? ? ? ? ? if (map[tank.y+2][tank.x]==0 && map[tank.y+2][tank.x-1]==0 && map[tank.y+2][tank.x+1]==0)


? ? ? ? ? ? ? ? return 1;


? ? ? ? ? ? else


? ? ? ? ? ? ? ? return 0;


? ? ? ? case LEFT:


? ? ? ? ? ? if (map[tank.y][tank.x-2]==0 && map[tank.y-1][tank.x-2]==0 && map[tank.y+1][tank.x-2]==0)


? ? ? ? ? ? ? ? return 1;


? ? ? ? ? ? else


? ? ? ? ? ? ? ? return 0;


? ? ? ? case RIGHT:


? ? ? ? ? ? if (map[tank.y][tank.x+2]==0 && map[tank.y-1][tank.x+2]==0 && map[tank.y+1][tank.x+2]==0)


? ? ? ? ? ? ? ? return 1;


? ? ? ? ? ? else


? ? ? ? ? ? ? ? return 0;


? ? ? ? default:


? ? ? ? ? ? printf("錯誤!!");


? ? ? ? ? ? Sleep(5000);


? ? ? ? ? ? return 0;


? ? }


}


?


?


void ClearTank(int x,int y)? ?//清除坦克函數(shù)(人機(jī)共用)


{


? ? for(int i=0;i<3;i++)


? ? ? ? for(int j=0;j<3;j++)


? ? ? ? {? ? ? ? ? ? ? ? ? ? ?//將坦克占用的地圖上的九格去掉


? ? ? ? ? ? ?map[y+j-1][x+i-1]=0;


? ? ? ? ? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN);


? ? ? ? ? ? GoToxy(2*x+2*j-2,y+i-1);


? ? ? ? ? ? printf("? ");


? ? ? ? }


}


?


?


void PrintTank(Tank tank)? ? ?//打印坦克(人機(jī)共用) 由于讀取的Tank參數(shù)較多,故就不將參數(shù)一一傳入了


{? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// tank.color參數(shù)對應(yīng)不同的顏色,范圍 1 ~ 6


? ? ColorChoose(tank.color);? //顏色選擇函數(shù)? ?定義一個數(shù)組里裝著字符指針(既裝字符串)的數(shù)組指針(指向一維數(shù)組首地址的指針)


? ? char *(*tankF)[4] = tank_figure[tank.model];? //將二維數(shù)組首址賦初值給數(shù)組指針 model==0為我的坦克,4為電腦1坦克,8為電腦2,類推


? ? for(int i = 0; i < 3; i++)? ?


? ? {


? ? ? ? GoToxy((tank.x-1)*2 , tank.y-1+i);? ? ? ? //在坦克中心坐標(biāo)的左邊,上中下三行打印


? ? ? ? printf("%s", tankF[i][tank.direction-1]); //打印的是地址,地址既字符串


? ? ? ? ?for(int j=0;j<3;j++)


? ? ? ? ? ? if(tank.my)? ? ? ?//若為我的坦克


? ? ? ? ? ? ? ? map[tank.y+j-1][tank.x+i-1]=200;? //在map上把"坦克"九格填滿代表敵我坦克的參數(shù)。敵方此值為100~103,我方為200


? ? ? ? ? ? else


? ? ? ? ? ? ? ? map[tank.y+j-1][tank.x+i-1]=100+tank.num;? //這樣可以通過map值讀取坦克編號,讀取操作在BulletHit 函數(shù)


? ? }


}


?


?


void HideCursor()? //隱藏光標(biāo)


{? ? ? ? ? ? ? ? ? //CONSOLE_CURSOR_INFO結(jié)構(gòu)體包含控制臺光標(biāo)的信息,DWORD dwSize光標(biāo)百分比厚度(1~100)和BOOL bVisible光標(biāo)是否可見


? ? CONSOLE_CURSOR_INFO cursor_info={1,0};


? ? SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info); //SetConsoleCursorInfo用來設(shè)置指定的控制臺光標(biāo)的大小和可見性。


}


?


?


void GoToxy(int x,int y)? //光標(biāo)移動函數(shù),X表示橫坐標(biāo),Y表示縱坐標(biāo)。


{


? ? COORD? coord;? ? ? ? ?//使用頭文件自帶的坐標(biāo)結(jié)構(gòu)


? ? coord.X=x;? ? ? ? ? ? //這里將int類型值傳給short,不過程序中涉及的坐標(biāo)值均不會超過short范圍


? ? coord.Y=y;


? ? HANDLE a=GetStdHandle(STD_OUTPUT_HANDLE);? //獲得標(biāo)準(zhǔn)輸出句柄


? ? SetConsoleCursorPosition(a,coord);? ? ? ? ?//以標(biāo)準(zhǔn)輸出的句柄為參數(shù)設(shè)置控制臺光標(biāo)坐標(biāo)


}


?


?


void ColorChoose(int color)? ?//顏色選擇函數(shù)


{


? ? switch(color)


? ? {


? ? ? ? ? ?case 1:? ? ? ? ? ? ? ?//天藍(lán)色(我的坦克顏色)


? ? ? ? ? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE);


? ? ? ? ? ? break;


? ? ? ? case 2:? ? ? ? ? ? ? ?//綠色


? ? ? ? ? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN);? ??


? ? ? ? ? ? break;


? ? ? ? case 3:? ? ? ? ? ? ? ?//黃色


? ? ? ? ? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_GREEN);


? ? ? ? ? ? break;


? ? ? ? case 4:? ? ? ? ? ? ? ?//紅色


? ? ? ? ? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED);


? ? ? ? ? ? break;


? ? ? ? case 5:? ? ? ? ? ? ? ?//紫色


? ? ? ? ? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_BLUE);


? ? ? ? ? ? break;


? ? ? ? case 6:? ? ? ? ? ? ? ?//白色


? ? ? ? ? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN);


? ? ? ? ? ? break;


? ? ? ? case 7:? ? ? ? ? ? ? ?//深藍(lán)色(∵顏色深難與黑色背景辨識度不高 ∴坦克顏色不選用此顏色),只用在字體顏色閃爍中


? ? ? ? ? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_BLUE);


? ? ? ? ? ? break;


? ? }


}


?


?


void Stop()? ? //暫停


{


? ? int color=1,timing=0;


? ? while(1)


? ? {


? ? ? ? if(timing++%30==0)


? ? ? ? {


? ? ? ? ? ? ColorChoose(color);? ?//顏色選擇


? ? ? ? ? ? GoToxy(100,13);? ? ? ?//副屏幕打印


? ? ? ? ? ? printf("游戲暫停");


? ? ? ? ? ? GoToxy(88,17);


? ? ? ? ? ? printf("按回車鍵回到游戲");


? ? ? ? ? ? GoToxy(88,18);


? ? ? ? ? ? printf("或按 Esc鍵退出游戲");


? ? ? ? ? ? if(++color==8)


? ? ? ? ? ? ? ? color=1;


? ? ? ? }


? ? ? ? if (GetAsyncKeyState( 0xD )& 0x8000)? ? ? //回車鍵


? ? ? ? {


? ? ? ? ? ? GoToxy(100,13);? ? ? ?//副屏幕打印


? ? ? ? ? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE);


? ? ? ? ? ? printf("正在進(jìn)行");? ?//覆蓋掉原來的提示


? ? ? ? ? ? GoToxy(88,17);


? ? ? ? ? ? printf("? ? ? ? ? ? ? ? ? ? ?");


? ? ? ? ? ? GoToxy(88,18);


? ? ? ? ? ? printf("? ? ? ? ? ? ? ? ? ? ?");


? ? ? ? ? ? break;


? ? ? ? }


? ? ? ? else if(GetAsyncKeyState( 0x1B )& 0x8000) //Esc鍵退出? ??


? ? ? ? ? ? exit(0);


? ? ? ? Sleep(20);


? ? }


}


?


?


void ClearMainScreen()? //主屏幕清屏函數(shù),因使用system("cls");再打印框架有一定幾率造成框架上移一行的錯誤,所以單獨(dú)編寫清屏函數(shù)


{


? ? for(int i=1;i<40;i++)


? ? {


? ? ? ? GoToxy(2,i);


? ? ? ? printf("? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ");


? ? }


}


?


?


void Frame ()? ? ?//打印游戲主體框架


{? ? ? ? ? ? ? ? ?//SetConsoleTextAttribute為設(shè)置文本顏色和文本背景顏色函數(shù)


? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_INTENSITY);


? ? printf("? ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁? ");


? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY|FOREGROUND_BLUE);?


? ? printf("? ▂▂▂▂▂▂▂▂▂▂▂▂▂ \n");


? ? for(int i=0;i<14;i++)


? ? {


? ? ? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN|FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_INTENSITY);


? ? ? ? printf("▕? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ▏");


? ? ? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY|FOREGROUND_BLUE);?


? ? ? ? printf(" |? ? ? ? ? ? ? ? ? ? ? ? ? |\n");


? ? }


? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN|FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_INTENSITY);


? ? printf("▕? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ▏");


? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY|FOREGROUND_BLUE);?


? ? printf(" |═════════════|\n");


? ? for(int i=0;i<24;i++)


? ? {


? ? ? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN|FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_INTENSITY);


? ? ? ? printf("▕? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ▏");


? ? ? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY|FOREGROUND_BLUE);?


? ? ? ? printf(" |? ? ? ? ? ? ? ? ? ? ? ? ? |\n");


? ? }


? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN|FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_INTENSITY);


? ? printf("? ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔? ");


? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY| FOREGROUND_BLUE);?


? ? printf(" ﹊﹊﹊﹊﹊﹊﹊﹊﹊﹊﹊﹊﹊﹊\n");


? ? SideScreen ();? //打印副屏幕


}


?


?


void PrintMap()? ? ?// 打印地圖(地圖既地圖障礙物)


{


? ? for(int j=0;j<41;j++)


? ? ? ? for(int i=0;i<41;i++)


? ? ? ? ? ? if(map[i][j]==6)


? ? ? ? ? ? {


? ? ? ? ? ? ? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN


? ? ? ? ? ? ? ? ? ? |FOREGROUND_RED|FOREGROUND_BLUE|BACKGROUND_GREEN|BACKGROUND_RED|BACKGROUND_BLUE);


? ? ? ? ? ? ? ? GoToxy(2*j,i);


? ? ? ? ? ? ? ? printf("■");


? ? ? ? ? ? }


? ? ? ? ? ? else if(map[i][j]==2)


? ? ? ? ? ? {


? ? ? ? ? ? ? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_RED|BACKGROUND_GREEN|BACKGROUND_RED);


? ? ? ? ? ? ? ? GoToxy(2*j,i);


? ? ? ? ? ? ? ? printf("▓");


? ? ? ? ? ? }


? ? ? ? ? ? else if(map[i][j]==1)


? ? ? ? ? ? {


? ? ? ? ? ? ? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|BACKGROUND_GREEN|BACKGROUND_RED);


? ? ? ? ? ? ? ? GoToxy(2*j,i);


? ? ? ? ? ? ? ? printf("▓");


? ? ? ? ? ? }


? ? ? ? ? ? else if(map[i][j]==5)


? ? ? ? ? ? {? ? ? ? ? ? ? ? ? ? ??


? ? ? ? ? ? ? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|BACKGROUND_BLUE|FOREGROUND_BLUE|FOREGROUND_GREEN);


? ? ? ? ? ? ? ? GoToxy(2*j,i);


? ? ? ? ? ? ? ? printf("~");


? ? ? ? ? ? }


? ? SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_BLUE|FOREGROUND_RED|FOREGROUND_GREEN);


? ? GoToxy(38,37);? ? ?printf("◣◢");


? ? GoToxy(38,38);? ? ?printf("███");? ? //∵無論地圖怎么變,家所在位置不變,且家的字符多種,不方便用上述方式打印


? ? GoToxy(38,39);? ? ?printf("◢█◣");? ? //∴直接打印(且家的map值與符號無關(guān))


}


?


?



覺得可以的給個贊吧

也是支持原作者

(轉(zhuǎn))C++小游戲:坦克大戰(zhàn)-無敵AI自殘版(上半部分)的評論 (共 條)

分享到微博請遵守國家法律
英超| 辉县市| 雷波县| 陇川县| 汕尾市| 平邑县| 苍山县| 台前县| 芜湖县| 垫江县| 资源县| 鄂托克旗| 贵定县| 东丰县| 翁牛特旗| 江津市| 若尔盖县| 新化县| 许昌县| 韶关市| 社旗县| 大邑县| 安义县| 建湖县| 孟连| 景洪市| 金塔县| 项城市| 呼玛县| 会同县| 新和县| 房产| 泾阳县| 马边| 常熟市| 天长市| 灵台县| 同心县| 内黄县| 修水县| 淄博市|