C語言實作坦克大戰~
新人投稿~
很快啊!大一上學期就過去了,
作為新時代的大學生,C語言大作業怎么能應付呢!!
所以,放棄高數放棄英語的我(咳,沒撿起來過)好不容易寫了一個自己的東西——坦克大戰😁
雖然還是有很多地方借鑒,比如隱藏游標函式啊,不閃瞎眼的函清屏數啊,
:_ :附良心課程鏈接:
鏈接: 做游戲,學編程(C語言).
但是!真真的用心寫了!
那個AI坦克我實在是沒啥想法,只能用概率讓他多向基地走走攻擊攻擊——來自郭老師😛的提議,大佬有想法的可以評論區告訴我,感激不盡!
對對對!還有一個沒實作(迫于時間緊迫🤐)坦克子彈不能連發,要是連發,,可能有點鬼畜😭,
廢話就真么多~
下面是代碼~(寫給自己看所以沒有很多注釋😶)
/**************************
作者:wckkkkk
時間:11.12
專案名稱:坦克大戰
**************************/
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <conio.h>
#include <time.h>
//系統引數
/** 畫布 */
int high;
int width;
/**操作*/
char op[8] ="wsadsdsd";
/**結束*/
int over = 0;
//不一樣的數字代表不一樣的墻
/** map */
int map[12][22] = //畫地圖
{
{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
{-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1},
{-1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,-1},
{-1,0,0,1,0,0,3,0,1,1,1,1,1,1,1,0,0,0,1,0,0,-1},
{-1,0,0,1,1,0,3,0,0,0,0,0,0,0,0,0,0,0,1,0,0,-1},
{-1,0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,0,0,0,3,0,-1},
{-1,0,0,-1,-1,-1,-1,0,1,0,1,0,1,0,1,0,3,0,3,-1,0,-1},
{-1,0,0,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,3,-1,-1,0,-1},
{-1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,3,-1,-1,0,0,-1},
{-1,0,1,1,1,1,0,0,0,1,1,2,1,1,0,3,-1,-1,0,1,0,-1},
{-1,0,0,0,0,1,0,0,0,1,2,2,2,1,0,0,0,0,0,0,0,-1},
{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}
};
/**over map*/
int overmap[4][12][22] =
{
{
//win
{-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1},
{-1,0,1,0,0,0,0,0,1,0,1,1,1,0,1,1,0,0,0,1,0,-1},
{-1,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,1,0,-1},
{-1,0,0,1,0,1,0,1,0,0,0,1,0,0,1,0,1,0,0,1,0,-1},
{-1,0,0,1,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0,1,0,-1},
{-1,0,0,1,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0,1,0,-1},
{-1,0,0,0,1,1,1,1,0,0,0,1,0,0,1,0,0,0,1,1,0,-1},
{-1,0,0,0,1,0,1,0,0,0,1,1,1,0,1,0,0,0,1,1,0,-1},
{-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1},
{-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1},
{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}
},
{
//lose
{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
{-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1},
{-1,0,1,0,0,0,0,1,1,1,0,0,0,1,1,0,0,1,1,1,1,-1},
{-1,0,1,0,0,0,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,-1},
{-1,0,1,0,0,0,1,0,0,0,1,0,1,0,0,0,0,1,0,0,0,-1},
{-1,0,1,0,0,0,1,0,0,0,1,0,1,1,0,0,0,1,1,1,0,-1},
{-1,0,1,0,0,0,1,0,0,0,1,0,0,0,1,1,0,1,0,0,0,-1},
{-1,0,1,0,0,0,1,0,0,0,1,0,0,0,0,1,0,1,0,0,0,-1},
{-1,0,1,0,0,0,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,-1},
{-1,0,1,1,1,0,0,1,1,1,0,0,0,1,1,0,0,1,1,1,1,-1},
{-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1},
{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}
},
{
//draw
{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
{-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1},
{-1,0,1,1,0,0,0,1,1,1,1,0,0,1,0,0,1,0,0,0,1,-1},
{-1,0,1,0,1,0,0,1,0,0,1,0,1,1,1,0,1,0,0,0,1,-1},
{-1,0,1,0,0,1,0,1,0,0,1,0,1,0,1,0,1,0,0,0,1,-1},
{-1,0,1,0,0,1,0,1,1,1,1,0,1,0,1,0,1,0,1,0,1,-1},
{-1,0,1,0,0,1,0,1,1,0,0,0,1,1,1,0,1,0,1,0,1,-1},
{-1,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,1,0,1,0,1,-1},
{-1,0,1,1,0,0,0,1,0,0,1,0,1,0,1,0,0,1,0,1,0,-1},
{-1,0,1,0,0,0,0,1,0,0,1,0,1,0,1,0,0,1,0,1,0,-1},
{-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1},
{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}
},
{
//game over
{-1,0,1,1,1,0,0,0,1,0,0,0,0,1,0,1,0,0,1,1,1,-1},
{-1,1,0,0,0,0,0,1,0,1,0,0,1,0,1,0,1,0,1,0,0,-1},
{-1,1,0,0,1,1,0,1,1,1,0,0,1,0,1,0,1,0,1,1,0,-1},
{-1,1,0,0,0,1,0,1,0,1,0,0,1,0,0,0,1,0,1,0,0,-1},
{-1,0,1,1,1,0,0,1,0,1,0,0,1,0,0,0,1,0,1,1,1,-1},
{-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1},
{-1,0,0,1,1,0,0,1,0,1,0,0,0,1,1,1,0,0,1,1,1,-1},
{-1,0,1,0,0,1,0,1,0,1,0,0,0,1,0,0,0,0,1,0,1,-1},
{-1,0,1,0,0,1,0,1,0,1,0,0,0,1,1,0,0,0,1,1,1,-1},
{-1,0,1,0,0,1,0,1,1,1,0,0,0,1,0,0,0,0,1,1,0,-1},
{-1,0,0,1,1,0,0,0,1,0,0,0,0,1,1,1,0,0,1,0,1,-1},
{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}
}
};
//物件們
/**子彈*/
typedef struct
{
//坐標
int x;
int y;
int velocity;//速度
int form;//方向
char kind;//形式
} BUL;
/** tank */
typedef struct
{
/** 坦克坐標 */
int x;
int y;
/** 坦克方向*/
int direction;//0 up ; 1 down;2 left;3 right
/**坦克形態*/
char form[5] ;
/**子彈*/
BUL bul;
/**敵坦克cd*/
long long CD;
} TANK;
TANK tank;
TANK emery;
//主體函式
void menu();//開始選單
void start();//初始化
void show();//顯示畫面
void print(int o,int h,int w);//列印地圖
void update_un();//與用戶輸入輸入無關的更新
void update_ne();//與用戶輸入有關的更新
void Overmenu(int result);//結束
void color(short x) ;//顏色
void gotoxy(int x,int y);//清屏函式
void HideCursor();//隱藏游標
/**坦克函式*/
void MoveTank(char input,TANK * tk);//坦克移動
void AIemery();//自動化敵坦克
/**子彈函式*/
//子彈發射
void bulfire(TANK *tk);
//子彈移動
void updatebul(TANK *tk);
//子彈打墻
void collition_bull_wall(TANK *tk);
//子彈打坦克
void collition_bull_TANK() ;
/***************************************************************************************
主函式
***************************************************************************************/
int main()
{
menu();
start();
while(!over)
{
update_ne();
update_un();
show();
}
system("cls");
Overmenu(over);//結束
return 0;
}
/***********************************************************************************
************************************************************************************/
void menu()//開始選單
{
printf("*********************************************\n");
color(13);
printf(" 歡迎來到坦克大戰 \n");
color(16);
printf("*********************************************\n");
color(4);
printf("幾點說明:\n");
printf(" 1.坦克形態為:A V < > ,代表四個方向,\n 由wasd控制,子彈按下空格發射,\n\n");
printf(" 2.我方坦克為紅色,敵方為黃色,\n\n");
printf(" 3.務必將輸入法改成英文!!!!!\n\n");
printf(" 4.子彈連發未實作>﹏<\n");
color(16);
printf("*********************************************\n");
printf("按任意鍵進入進入...");
getch();
system("cls");
}
void start()//初始化
{
high = 12;
width = 22;
tank.x = 10;
tank.y = 8;
tank.form[0] = 'A';
tank.form[1] = 'V';
tank.form[2] = '<';
tank.form[3] = '>';
tank.direction = 0;
tank.bul.kind = '*';
tank.bul.x = 0;
tank.bul.y = 0;
tank.bul.velocity = 0;
emery.x = 1;
emery.y = 1;
emery.form[0] = 'A';
emery.form[1] = 'V';
emery.form[2] = '<';
emery.form[3] = '>';
emery.direction = 1;
emery.bul.kind = '*';
emery.bul.x = 0;
emery.bul.y = 0;
emery.bul.velocity = 0;
emery.CD = 10;
HideCursor();//隱藏游標
srand((unsigned)time(NULL));//亂數
}
void show()//顯示畫面
{
gotoxy(0,0);//清屏
for(int i = 0; i < high; i++) /**顯示界面*/
{
for(int j = 0; j < width; j++)
{
if(map[i][j] == -1)
{
color(3);
printf("■");
color(16);
}
else if(map[i][j] == 1)
{
color(12);
printf("□");
color(16);
}
else if(map[i][j] == 2)
{
color(6);
printf("▲");
color(16);
}
else if(map[i][j] == 3)
{
color(2);
printf("■");
color(16);
}
else if(i == tank.x &&j == tank.y)
{
color(4);
printf("%c ",tank.form[tank.direction]);
color(16);
}
else if(i == emery.x &&j == emery.y)
{
color(6);
printf("%c ",emery.form[emery.direction]);
color(16);
}
else if(i == tank.bul.x && j == tank.bul.y)
{
color(4);
printf("%c ",tank.bul.kind);
color(16);
}
else if(i == emery.bul.x && j == emery.bul.y)
{
color(6);
printf("%c ",emery.bul.kind);
color(16);
}
else printf(" ");
}
printf("\n");
}
}
void update_un()//與用戶輸入輸入無關的更新
{
AIemery();
updatebul(&tank);
updatebul(&emery);
collition_bull_wall(&tank);
collition_bull_wall(&emery);
collition_bull_TANK();
}
void update_ne()//與用戶輸入有關的更新
{
char input;
if(kbhit())
{
input = getch();
if(input == ' ')
bulfire(&tank);
else
MoveTank(input,&tank);//坦克移動
}
}
void bulfire(TANK *tk)
{
//根據坦克方向定位子彈
switch(tk->direction)
{
case 0:
tk->bul.x =tk->x - 1;
tk->bul.y = tk->y;
break;
case 1:
tk->bul.x =tk->x + 1;
tk->bul.y = tk->y;
break;
case 2:
tk->bul.x =tk->x ;
tk->bul.y = tk->y - 1;
break;
case 3:
tk->bul.x =tk->x ;
tk->bul.y = tk->y + 1;
break;
}
tk->bul.form = tk->direction;
}
void updatebul(TANK *tk)
{
if(tk->bul.x > 0)
tk->bul.velocity++;
if(tk->bul.velocity == 20)
{
switch(tk->bul.form)
{
case 0:
tk->bul.x --;
break;
case 1:
tk->bul.x ++;
break;
case 2:
tk->bul.y--;
break;
case 3:
tk->bul.y++;
break;
}
tk->bul.velocity = 0;
}
}
void collition_bull_wall(TANK *tk)
{
if(map[tk->bul.x][tk->bul.y] == 1)
{
map[tk->bul.x][tk->bul.y] = 0;
tk->bul.x =0;
tk->bul.y = 0;
tk->bul.form = tk->direction;
}
if(map[tk->bul.x][tk->bul.y] == -1)
{
tk->bul.x =0;
tk->bul.y = 0;
tk->bul.form = tk->direction;
}
}
void collition_bull_TANK()
{
if(tank.bul.x == emery.x && tank.bul.y == emery.y)
{
emery.x = 0;
emery.y = 0;
over = 1;
}
if(emery.bul.x == tank.x && emery.bul.y == tank.y)
{
tank.x = 0;
tank.y = 0;
over = 2;
}
if(emery.x == tank.x&&emery.y == tank.y )
{
tank.x = 0;
tank.y = 0;
emery.x = 0;
emery.y = 0;
over = 3;
}
if(emery.bul.x == tank.bul.x && emery.bul.y == tank.bul.y)
{
tank.bul.x = 0;
tank.bul.y = 0;
emery.bul.x = 0;
emery.bul.y = 0;
}
if(map[emery.bul.x][emery.bul.y] == 2||map[tank.bul.x][tank.bul.y] == 2)
over = 2;
}
void AIemery()//自動化敵坦克
{
emery.CD ++;
if(emery.CD == 150)
{
int temp = rand()%4;
if(emery.x >= 9)//橫坐標等于基地
temp = 5;
else if(emery.y >=10 && emery.y <=12)//縱坐標=基地
temp = 6;
else if(emery.x == tank.x && map[tank.x][tank.y] != 3)//橫坐標=我方坦克
temp = 7;
else if(emery.y == tank.y&& map[tank.x][tank.y] != 3)//縱坐標=我方坦克
temp = 8;
switch(temp)
{
case 0://打子彈+坦克移動
temp = rand()%4;
bulfire(&emery) ;
MoveTank(op[temp+rand()%4],&emery);
break;
case 1://改方向+坦克移動
temp = rand() % 4;
emery.direction = temp;
MoveTank(op[temp+rand()%4],&emery);
break;
case 3://坦克移動+打子彈
temp = rand() % 4;
MoveTank(op[temp+rand()%4],&emery);
bulfire(&emery) ;
break;
case 4://坦克移動+打子彈
temp = rand() % 4;
MoveTank(op[temp+rand()%4],&emery);
bulfire(&emery) ;
break;
case 5://橫坐標=基地
if(emery.y > width/2)
{
MoveTank('a',&emery);
bulfire(&emery) ;
}
else
{
MoveTank('d',&emery);
bulfire(&emery) ;
}
break;
case 6://縱坐標=基地
MoveTank('s',&emery);
bulfire(&emery) ;
break;
case 7://橫坐標=我方
if(emery.y > tank.y)
{
MoveTank('a',&emery);
bulfire(&emery) ;
}
else
{
MoveTank('d',&emery);
bulfire(&emery) ;
}
break;
case 8://縱坐標=我方
if(emery.x >tank.x)
{
MoveTank('w',&emery);
bulfire(&emery) ;
}
else
{
MoveTank('s',&emery);
bulfire(&emery) ;
}
break;
}
emery.CD = 0;
}
}
void MoveTank(char input,TANK * tk)//坦克移動
{
switch(input)
{
/**控制坦克*/
case 'w'://方向一致且不撞地圖
if(tk->direction == 0 && map[tk->x-1] [tk->y]!= -1&& map[tk->x-1] [tk->y]!= 1&& map[tk->x-1] [tk->y]!= 2)
tk->x--;
else
tk->direction = 0;
break;
case 's':
if(tk->direction == 1 && map[tk->x+1] [tk->y] != -1&&map[tk->x+1] [tk->y] != 1&&map[tk->x+1] [tk->y] != 2)
tk->x++;
else
tk->direction = 1;
break;
case 'a':
if(tk->direction == 2 && map [tk->x][tk->y-1] != -1 && map [tk->x][tk->y-1] != 1 && map [tk->x][tk->y-1] != 2)
tk->y--;
else
tk->direction = 2;
break;
case 'd':
if(tk->direction == 3 && map[tk->x][tk->y+1] != -1&& map[tk->x][tk->y+1] != 1&& map[tk->x][tk->y+1] != 2)
tk->y++;
else
tk->direction = 3;
break;
}
}
void Overmenu(int result)//結束
{
print(result-1,high,width);
printf("*********************************************\n");
printf("按任意鍵進入退出...");
getch();
system("cls");
print(3,high,width);
Sleep(1000);
}
void print(int o,int h,int w)//列印地圖
{
for(int i = 0; i < h; i++)
{
for(int j = 0; j < w; j++)
{
switch(overmap[o][i][j])
{
case -1:
color(3);
printf("■");
color(16);
break;
case 0:
printf(" ");
break;
case 1:
color(12);
printf("□");
color(16);
break;
}
}
printf("\n");
}
}
void gotoxy(int x,int y)//清屏函式
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
COORD pos;
pos.X = x;
pos.Y = y;
SetConsoleCursorPosition(handle,pos);
}
void HideCursor()//隱藏游標
{
CONSOLE_CURSOR_INFO cursor_info = {1,0};
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);
}
void color(short x) //自定義函根據引數改變顏色
{
if(x>=0 && x<=15)//引數在0-15的范圍顏色
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), x); //只有一個引數,改變字體顏色
else//默認的顏色白色
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/239586.html
標籤:其他
上一篇:聊一聊我的二〇二〇
