[導(dǎo)讀]本系列博文內(nèi)容鏈接如下:
【C++】做一個飛機(jī)空戰(zhàn)小游戲(一)——使用getch()函數(shù)獲得鍵盤碼值
【C++】做一個飛機(jī)空戰(zhàn)小游戲(二)——利用getch()函數(shù)實(shí)現(xiàn)鍵盤控制單個字符移動
【C++】做一個飛機(jī)空戰(zhàn)小游戲(三)——getch()函數(shù)控制任意造型飛機(jī)圖標(biāo)移動【C++】做一個飛機(jī)空戰(zhàn)小游戲(四)——給游戲添加背景音樂(多線程技巧應(yīng)用)
【C++】做一個飛機(jī)空戰(zhàn)小游戲(五)——getch()控制兩個飛機(jī)圖標(biāo)移動(控制光標(biāo)位置)
【C++】做一個飛機(jī)空戰(zhàn)小游戲(六)——給兩架飛機(jī)設(shè)置不同顏色(cout輸出彩色字符、結(jié)構(gòu)體使用技巧)
【C++】做一個飛機(jī)空戰(zhàn)小游戲(七)——兩組按鍵同時檢測平滑移動(GetAsyncKeyState()函數(shù)應(yīng)用)
【C++】做一個飛機(jī)空戰(zhàn)小游戲(八)——生成敵方炮彈(rand()函數(shù)應(yīng)用)
【C++】做一個飛機(jī)空戰(zhàn)小游戲(九)——發(fā)射子彈的編程技巧
【C++】做一個飛機(jī)空戰(zhàn)小游戲(十)——子彈擊落炮彈、炮彈與飛機(jī)相撞
今天這節(jié)介紹實(shí)現(xiàn)子彈擊落炮彈、炮彈與飛機(jī)相撞的效果,增加了飛機(jī)的血量屬性,炮彈撞擊一次掉血三分之一,三次撞擊則飛機(jī)被炮彈擊落。還增加了飛機(jī)命數(shù)屬性,飛機(jī)設(shè)置了3條命,飛機(jī)命數(shù)大于0的時候可以按復(fù)活鍵進(jìn)行復(fù)活,如果命為0時,飛機(jī)不可復(fù)活。還增加了游戲暫停功能,按空格鍵游戲暫停,再按一次即可恢復(fù)游戲。
目錄
一、炮彈與子彈或飛機(jī)相撞
(一)子彈擊落炮彈
1、子彈、炮彈初始血量和傷害值
2、子彈與炮彈相撞后血量
3、擊落函數(shù)
4、擊落后血量變化代碼
(二)炮彈與飛機(jī)相撞
1、飛機(jī)結(jié)構(gòu)體
2、飛機(jī)初始化函數(shù)
(1)單個飛機(jī)初始化
(2)所有飛機(jī)初始化
3、飛機(jī)初始血量
4、飛機(jī)與炮彈相撞后血量
(1)炮彈血量
(2)飛機(jī)血量
5、飛機(jī)命數(shù)
6、相撞函數(shù)
7、相撞后血量命數(shù)變化代碼
8、飛機(jī)復(fù)活
二、游戲暫停功能
(一)game中增加pause屬性
(二)游戲暫停按鍵
(三)游戲暫停代碼
三、完整代碼
(一)主函數(shù)
(二)頭文件control_plane.h
(三)庫函數(shù)control_plane.cpp
四、運(yùn)行效果
(一)子彈與炮彈相撞
(二)炮彈與飛機(jī)相撞、飛機(jī)復(fù)活
一、炮彈與子彈或飛機(jī)相撞
(一)子彈擊落炮彈
1、子彈、炮彈初始血量和傷害值
子彈炮彈相撞前:
子彈、炮彈血量hp=1;
子彈、炮彈傷害值dam=1;
2、子彈與炮彈相撞后血量
子彈炮彈相撞后:
相撞后子彈血量=相撞前子彈血量-炮彈傷害值;
相撞后炮彈血量=相撞前炮彈血量-子彈傷害值;
因此,子彈炮彈相撞后,兩者血量都為0,alive值都為false,會同歸于盡,炮彈被擊落。
3、擊落函數(shù)
bool shoot(Bullet bullet,Bomb bomb)
{
bool sbb,sx0,sx1,sy0,sy1;
sx0=(bomb.location.x>=bullet.location.x-1);
sx1=(bomb.location.x<=bullet.location.x+1);
sy0=(bomb.location.y>=bullet.location.y);
sy1=(bomb.location.y<=bullet.location.y+1);
sbb=sx0 &&sx1&&sy0&&sy1;
return sbb;
}
4、擊落后血量變化代碼
這部分代碼在子彈位置更新線程中,具體如下:
for(int k=0;k<game.bombs_round;k++)//判斷子彈是否擊中炮彈
{
if(shoot(bullet[i][j],bomb[k]))
{
bomb[k].hp-=bullet[i][j].dam;
bullet[i][j].hp-=bomb[k].dam;
}
}
(二)炮彈與飛機(jī)相撞
1、飛機(jī)結(jié)構(gòu)體
//定義飛機(jī)結(jié)構(gòu)體
typedef struct{
Location location; //飛機(jī)坐標(biāo)
int color; //飛機(jī)顏色
int icon; //飛機(jī)圖標(biāo)編號
direction_cmd keycmd; //飛機(jī)移動方向命令
bool fire; //飛機(jī)是否開火
int cnt_bullets; //按一次開火鍵加1,然后初始化bullet[cnt_bullets],子彈死亡一個減1
int hp; //飛機(jī)血量
bool alive; //飛機(jī)存活標(biāo)志
int No; //飛機(jī)序號
int life; //飛機(jī)命數(shù)
}Plane;
2、飛機(jī)初始化函數(shù)
(1)單個飛機(jī)初始化
//單個飛機(jī)初始化函數(shù)
Plane init_plane(Plane plane)
{
plane.alive=true;
plane.hp=3;
plane.keycmd=none_cmd;
plane.location=plocation[plane.No];
plane.color=plane.No+1;
plane.icon=plane.No+1;
return plane;
}
初始化函數(shù)用在游戲開始和飛機(jī)復(fù)活時,函數(shù)中沒有設(shè)置No和life兩項,因?yàn)镹o值不同,而life值每次死亡時減1,復(fù)活后不能再恢復(fù)為原值。
(2)所有飛機(jī)初始化
//所有飛機(jī)初始化函數(shù)
void init_planes(void)
{
for(int i=0;i<game.num_plane;i++)//刷新飛機(jī)圖標(biāo)
{
plane[i]=init_plane(plane[i]);
}
}
3、飛機(jī)初始血量
飛機(jī)初始血量hp=3,飛機(jī)沒有設(shè)置傷害值,默認(rèn)其傷害值為無窮大。
4、飛機(jī)與炮彈相撞后血量
(1)炮彈血量
炮彈與飛機(jī)相撞后,炮彈血量直接降為0,alive值為false。
(2)飛機(jī)血量
飛機(jī)與炮彈相撞后,相撞后飛機(jī)血量值=相撞前血量值-炮彈傷害值。飛機(jī)血量值小于等于0時,飛機(jī)死亡,alive值為false。
5、飛機(jī)命數(shù)
飛機(jī)命數(shù)life初始值為3。如果飛機(jī)死亡,其命數(shù)life值減1。
6、相撞函數(shù)
bool collide(Plane plane,Bomb bomb)
{
bool cpb,cx0,cx1,cy0,cy1;
cx0=bomb.location.x>=plane.location.x-1;
cx1=bomb.location.x<=plane.location.x+plane_width;
cy0=bomb.location.y>=plane.location.y;
cy1=bomb.location.y<=plane.location.y+plane_height;
cpb=cx0 && cx1 && cy0 && cy1;
return cpb;
}
7、相撞后血量命數(shù)變化代碼
飛機(jī)血量、命數(shù)的變化代碼放置在炮彈位置更新線程中,具體內(nèi)容如下:
for(int j=0;j<game.num_plane;j++)
{
if(plane[j].alive)
{
if(collide(plane[j],bomb[i]))
{
bomb[i].hp=0;
plane[j].hp-=bomb[i].dam;
}
if(plane[j].hp<=0)
{
plane[j].alive=false;
plane[j].life=plane[j].life-1;
plane[j].keycmd=none_cmd;
plane[j].location.x=0;
plane[j].location.y=b_b+8;
}
}
}
8、飛機(jī)復(fù)活
按復(fù)活鍵可復(fù)活,當(dāng)命數(shù)小于1時,不能再復(fù)活,永久死亡。plane[0]的復(fù)活代碼如下:
if(plane[0].life>0)
{
if (GetAsyncKeyState('O') & 0x8000) //飛機(jī)復(fù)活指令
{
plane[0]=init_plane(plane[0]);
show_plane(plane[0]);
}
}
二、游戲暫停功能
(一)game中增加pause屬性
//定義游戲結(jié)構(gòu)體
typedef struct{
int stage; //游戲當(dāng)前關(guān)
int bombs_round; //敵方每輪發(fā)射炮彈數(shù)量
int bombs_stage; //每關(guān)總計出現(xiàn)炮彈數(shù)量
bool clear; //游戲過關(guān)
bool complete; //游戲通關(guān)
bool gameover; //游戲結(jié)束
int num_plane; //飛機(jī)數(shù)量
int cur_num_bomb; //當(dāng)前已發(fā)射炮彈數(shù)量
int bomb_interval; //位置更新間隔
bool bomb_move; //炮彈是否移動
bool bullet_move; //子彈是否移動
bool pause; //游戲是否暫停
}Game;
(二)游戲暫停按鍵
游戲暫停鍵為空格鍵,游戲進(jìn)行時,按下空格鍵game.pause=true,游戲暫停,再按一次game.pause=false,游戲恢復(fù),代碼在key()函數(shù)中,內(nèi)容如下:
if (GetAsyncKeyState(VK_SPACE) & 0x8000)
{
Sleep(50);
game.pause=!game.pause;
}
代碼中Sleep(50)為按鍵去抖動作用,防止按了一次被識別為多次。
(三)游戲暫停代碼
游戲暫停時,主函數(shù)中除背景音樂之外所有的線程都暫停。在需要暫停的線程中加入如下代碼:
while(game.pause)
{
;
}
三、完整代碼
(一)主函數(shù)
#include "control_plane.h"
#include "quenue.h"
using namespace std;
Plane plane[eq_plane];
Game game;
Bomb bomb[eq_bombs_round];
Bullet bullet[eq_plane][eq_bullets_round];
Location plocation[]={{2*r_b/3,b_b},{r_b/3,b_b}};
int main(int argc, char** argv) {
init(); //初始化
bgmusic();//播放背景音樂
getkey();
bomb_location_update();
bullet_location_update();
while(1) //循環(huán)等待鍵盤指令
{
while(game.pause)
{
;
}
if(plane[0].keycmd!=none_cmd ||plane[1].keycmd!=none_cmd ||game.bomb_move ||game.bullet_move)
{
game.bomb_move=false;
game.bullet_move=false;
system("cls");
for(int i=0;i<game.num_plane;i++)
{
if(plane[i].alive)
{
show_plane(plane[i]);//刷新飛機(jī)圖標(biāo)
}
}
for(int i=0;i<game.bombs_round;i++)
{
if(bomb[i].alive)
{
show_bomb(bomb[i]);
}
}
for(int i=0;i<eq_plane;i++)
{
for(int j=0;j<eq_bullets_round;j++)
{
if(bullet[i][j].alive)
{
show_bullet(bullet[i][j]);
}
}
}
}
}
return 0;
}
(二)頭文件control_plane.h
#ifndef CONTROL_PLANE_H
#define CONTROL_PLANE
#include <iostream>
#include <ctime>
#include <string>
#include<stdlib.h>
#include<windows.h>
#include <pthread.h>//導(dǎo)入線程頭文件庫
#include <mmsystem.h> //導(dǎo)入聲音頭文件庫
#pragma comment(lib,"winmm.lib")//導(dǎo)入聲音的鏈接庫
#define _CRT_SECURE_NO_WARNINGS
using namespace std;
#define t_b 0 //圖形顯示區(qū)域上側(cè)邊界
#define l_b 0 //圖形顯示區(qū)域左側(cè)邊界
#define r_b 100 //圖形顯示區(qū)域右側(cè)邊界
#define b_b 20 //圖形顯示區(qū)域下側(cè)邊界
#define plane_width 9
#define plane_height 6
#define eq_plane 2 //飛機(jī)架數(shù)
#define eq_bombs_round 23 //eq=end quantity最終炮彈數(shù)量
#define eq_rt 10 //復(fù)活最大時間
#define eq_bullets_round 20 //eq=end quantity飛機(jī)一次發(fā)射最多子彈數(shù)量
//定義飛機(jī)造型
const string icon_plane1[]={" ■","■ ■ ■","■■■■■","■ ■ ■"," ■"," ■■■"};
const string icon_plane2[]={" ■","■ ■ ■","■■■■■"," ■"," ■■■","■■■■■"};
//定義炮彈造型
const string icon_bomb="■";
//定義子彈造型
const string icon_bullet="■";
//定義坐標(biāo)結(jié)構(gòu)體
typedef struct{
int x;
int y;
} Location;
//定義移動方向命令枚舉類型
typedef enum {none_cmd,up_cmd,down_cmd,left_cmd,right_cmd} direction_cmd;
//定義游戲結(jié)構(gòu)體
typedef struct{
int stage; //游戲當(dāng)前關(guān)
int bombs_round; //敵方每輪發(fā)射炮彈數(shù)量
int bombs_stage; //每關(guān)總計出現(xiàn)炮彈數(shù)量
bool clear; //游戲過關(guān)
bool complete; //游戲通關(guān)
bool gameover; //游戲結(jié)束
int num_plane; //飛機(jī)數(shù)量
int cur_num_bomb; //當(dāng)前已發(fā)射炮彈數(shù)量
int bomb_interval; //位置更新間隔
bool bomb_move; //炮彈是否移動
bool bullet_move; //子彈是否移動
bool pause; //游戲是否暫停
}Game;
//定義飛機(jī)結(jié)構(gòu)體
typedef struct{
Location location; //飛機(jī)坐標(biāo)
int color; //飛機(jī)顏色
int icon; //飛機(jī)圖標(biāo)編號
direction_cmd keycmd; //飛機(jī)移動方向命令
bool fire; //飛機(jī)是否開火
int cnt_bullets; //按一次開火鍵加1,然后初始化bullet[cnt_bullets],子彈死亡一個減1
int hp; //飛機(jī)血量
bool alive; //飛機(jī)存活標(biāo)志
int No; //飛機(jī)序號
int life; //飛機(jī)命數(shù)
}Plane;
//定義敵方炮彈結(jié)構(gòu)體
typedef struct{
Location location; //炮彈位置
bool alive; //炮彈是否存活
int color; //炮彈顏色
string icon; //炮彈圖標(biāo)
int rt; //rt=respawn time復(fù)活時間
int hp; //hp=hit point 生命值,此值<=0時,敵方炮彈死亡,敵方炮彈被飛機(jī)子彈擊中hp會減少,墜地或與飛機(jī)相撞hp直接降為0
int dam; //dam=damage 傷害值
int type; //炮彈類型
}Bomb;
//定義子彈結(jié)構(gòu)體
typedef struct{
Location location; //子彈位置
bool alive; //子彈是否存活
int color; //子彈顏色
string icon; //子彈圖標(biāo)
int hp; //hp=hit point 生命值,子彈擊中炮彈或沖出屏幕上方hp直接降為0,子彈死亡
int dam; //dam=damage 傷害值
int type; //子彈類型
}Bullet;
extern Plane plane[eq_plane];
extern Game game;
extern Bomb bomb[eq_bombs_round];
extern Bullet bullet[eq_plane][eq_bullets_round];
extern Location plocation[];
//extern Location plocation1={r_b/3,b_b};
//聲明刷新飛機(jī)位置函數(shù)
void show_plane(Plane plane);
//獲取鍵盤指令
void key(void);
//更新所有飛機(jī)坐標(biāo)
void plane_location_update(void);
//初始化函數(shù)
void init(void);
//播放背景音樂線程
void* thread_bgmusic(void* arg);
void play_bgmusic();
void bgmusic();
//獲取按鍵指令線程
void* thread_key(void* arg);
void getkey();
//輸出彩色字符函數(shù)
template<typename T> //T表示任何可以被cout輸出的類型
void ColorCout(T t, const int ForeColor = 7, const int BackColor = 0);
void init_bombs(void);
Bomb init_(Bomb bomb);
void* thread_bomb(void* arg);
void bomb_location_update();
void show_bomb(Bomb bomb);
void bullet_location_update(); //子彈位置更新
void* thread_bullet(void* arg); //子彈線程函數(shù)
Bullet init_bullet(Bullet bullet); //單個子彈初始化
void init_bullets(void); //所有子彈初始化
Bullet fire(Plane plane,Bullet bullet); //飛機(jī)開火函數(shù),確定子彈出現(xiàn)的起始位置
void show_bullet(Bullet bullet); //顯示子彈圖標(biāo)
bool collide(Plane plane,Bomb bomb);
bool shoot(Bullet bullet,Bomb bomb);
Plane init_plane(Plane plane);
void init_planes(void);
#endif
(三)庫函數(shù)control_plane.cpp
#include <iostream>
#include "conio.h"
#include <string>
#include "control_plane.h"
#include<windows.h>
using namespace std;
//彩色輸出函數(shù)
template<typename T> //T表示任何可以被cout輸出的類型
void ColorCout(T t, const int ForeColor = 7, const int BackColor = 0)
{
// 0 = 黑色 1 = 藍(lán)色 2 = 綠色 3 = 淺綠色 4 = 紅色 5 = 紫色 6 = 黃色 7 = 白色
// 8 = 灰色 9 = 淡藍(lán)色 10 = 淡綠色 11 = 淡淺綠色 12 = 淡紅色 13 = 淡紫色 14 = 淡黃色 15 = 亮白色
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), ForeColor + BackColor * 0x10);
cout << t;
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
}
//隱藏光標(biāo)函數(shù)
HANDLE han = GetStdHandle(-11);
void hide(){
CONSOLE_CURSOR_INFO cursor;
cursor.bVisible = 0;
cursor.dwSize = 1;
SetConsoleCursorInfo(han,&cursor);
}
//初始化函數(shù)
void init(void)
{
plane[0].No=0;
plane[1].No=1;
plane[0].life=3;
plane[1].life=3;
srand(time(NULL));
game.num_plane=2;
game.bombs_round=3;
game.bomb_move=false;
game.bullet_move=false;
game.bomb_interval=1000;
game.stage=1;
game.bombs_stage=100;
game.pause=false;
init_bombs();
init_bullets();
init_planes();
system("cls");
for(int i=0;i<game.num_plane;i++)//刷新飛機(jī)圖標(biāo)
{
show_plane(plane[i]);
}
game.bombs_round=3;
hide();//隱藏光標(biāo)
}
//********************************************************************************
//以下三個函數(shù)為獲得按鍵指令線程函數(shù)
//********************************************************************************
void* thread_key(void* arg)
{
while(1)
{
Sleep(60); //獲取指令延時一定時間,起濾波作用,延緩獲取指令的響應(yīng)速度
key(); //獲取按鍵指令
plane_location_update() ;//獲取完指令馬上更新飛機(jī)坐標(biāo)
}
}
void getkey()
{
pthread_t tid;
pthread_create(&tid, NULL, thread_key, NULL);
}
//獲取鍵盤指令函數(shù)
void key(void)
{
if (GetAsyncKeyState(VK_SPACE) & 0x8000)
{
Sleep(50);
game.pause=!game.pause;
}
if(!game.pause)
{
if(plane[0].alive)
{
direction_cmd c=none_cmd;
if (GetAsyncKeyState(VK_UP) & 0x8000) c = up_cmd;
if (GetAsyncKeyState(VK_DOWN) & 0x8000) c = down_cmd;
if (GetAsyncKeyState(VK_LEFT) & 0x8000) c = left_cmd;
if (GetAsyncKeyState(VK_RIGHT) & 0x8000) c = right_cmd;
plane[0].keycmd=c; //刷新飛機(jī)方向指令
if (GetAsyncKeyState('P') & 0x8000) plane[0].fire = true; //飛機(jī)開火指令
}
else
{
if(plane[0].life>0)
{
if (GetAsyncKeyState('O') & 0x8000) //飛機(jī)復(fù)活指令
{
plane[0]=init_plane(plane[0]);
show_plane(plane[0]);
}
}
}
if(plane[1].alive)
{
direction_cmd d=none_cmd;
if (GetAsyncKeyState('W') & 0x8000) d = up_cmd;
if (GetAsyncKeyState('S') & 0x8000) d = down_cmd;
if (GetAsyncKeyState('A') & 0x8000) d = left_cmd;
if (GetAsyncKeyState('D') & 0x8000) d = right_cmd;
plane[1].keycmd=d;//刷新飛機(jī)圖標(biāo)
if (GetAsyncKeyState('F') & 0x8000) plane[1].fire = true;
}
else
{
if(plane[1].life>0)
{
if (GetAsyncKeyState('Q') & 0x8000)
{
plane[1]=init_plane(plane[1]);
show_plane(plane[1]);
}
}
}
}
}
void gotoxy(int x, int y) {
COORD pos = { x,y };
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);//獲取標(biāo)準(zhǔn)輸出設(shè)備句柄
SetConsoleCursorPosition(hOut, pos);//兩個參數(shù)分別指定哪個窗口,具體位置
}
//飛機(jī)圖標(biāo)刷新函數(shù)
void show_plane(Plane plane) //預(yù)先定義字符定位顯示函數(shù),x是列坐標(biāo),y是行坐標(biāo),原點(diǎn)(x=0,y=0)位于屏幕左上角
{
int x,y;
int i,j;
int rows;
x=plane.location.x;
y=plane.location.y;
switch(plane.icon)
{
case 1://第一種造型
rows=sizeof(icon_plane1)/sizeof(icon_plane1[0]);
for(i=0;i<rows;i++)
{
gotoxy(x,y+i);
ColorCout(icon_plane1[i],plane.color);
}
break;
case 2://第二種造型
rows=sizeof(icon_plane2)/sizeof(icon_plane2[0]);
for(i=0;i<rows;i++)
{
gotoxy(x,y+i);
ColorCout(icon_plane2[i],plane.color);
}
break;
}
}
//更新兩個飛機(jī)的坐標(biāo)
void plane_location_update(void)
{
for(int i=0;i<2;i++)
{
if(plane[i].keycmd!=none_cmd)
{
int x,y;
x=plane[i].location.x;
y=plane[i].location.y;
switch(plane[i].keycmd)
{
case up_cmd:
y--; //字符上移一行,行值y減1
if(y<t_b) //限定y值最小值為0
{
y=t_b;
}
break;
case down_cmd:
y++; //字符下移一行,行值y加1
if(y>b_b) //限定y高度
{
y=b_b;
}
break;
case left_cmd:
x--; //字符左移一列,列值x減1
if(x<l_b)
{
x=l_b; //限定x最小值為0;
}
break;
case right_cmd:
x++; //字符右移一列,列值x加1
if(x>r_b)
{
x=r_b; //限定x寬度
}
break;
}
plane[i].location.x=x;
plane[i].location.y=y;
plane[i].keycmd=none_cmd;
}
}
}
//單個炮彈初始化函數(shù)
Bomb init_bomb(Bomb bomb)
{
bomb.location.x=rand()%r_b;
bomb.location.y=b_b+6;
bomb.icon=icon_bomb;
bomb.color=6;
bomb.dam=1;
bomb.hp=1;
bomb.alive=false;
bomb.rt=rand()%(eq_rt+1)+1;
return bomb;
}
//所有炮彈初始化函數(shù)
void init_bombs(void)
{
game.bomb_move=false;
for(int i=0;i<game.bombs_round;i++)
{
bomb[i]=init_bomb(bomb[i]);
}
}
//炮彈位置更新 線程
void* thread_bomb(void* arg)
{
while(1)
{
while(game.pause)
{
;
}
Sleep(game.bomb_interval);
game.bomb_move=true;
for(int i=0;i<game.bombs_round;i++)
{
if(bomb[i].alive)
{
bomb[i].location.y++;
if(bomb[i].location.y>b_b+5)
{
bomb[i].hp=0;
}
for(int j=0;j<game.num_plane;j++)
{
if(plane[j].alive)
{
if(collide(plane[j],bomb[i]))
{
bomb[i].hp=0;
plane[j].hp-=bomb[i].dam;
}
if(plane[j].hp<=0)
{
plane[j].alive=false;
plane[j].life=plane[j].life-1;
plane[j].keycmd=none_cmd;
plane[j].location.x=0;
plane[j].location.y=b_b+8;
}
}
}
if(bomb[i].hp<=0)
{
bomb[i]=init_bomb(bomb[i]);
}
}
else
{
bomb[i].rt--;
if(bomb[i].rt<=0)
{
bomb[i].alive=true;
bomb[i].location.y=0;
}
}
}
}
}
//炮彈位置更新
void bomb_location_update()
{
pthread_t tid;
pthread_create(&tid, NULL, thread_bomb, NULL);
}
炮彈圖標(biāo)刷新函數(shù)
void show_bomb(Bomb bomb) //預(yù)先定義字符定位顯示函數(shù),x是列坐標(biāo),y是行坐標(biāo),原點(diǎn)(x=0,y=0)位于屏幕左上角
{
int x,y;
x=bomb.location.x;
y=bomb.location.y;
hide();//隱藏光標(biāo)
gotoxy(x,y);
ColorCout(bomb.icon,bomb.color);
}
//發(fā)射子彈
Bullet fire(Plane plane,Bullet bullet)
{
game.bullet_move=true;
bullet.location.x=plane.location.x+plane_width/2;
bullet.location.y=plane.location.y-1;
bullet.alive=true;
return bullet;
}
//單個子彈初始化函數(shù)
Bullet init_bullet(Bullet bullet)
{
bullet.icon=icon_bullet;
bullet.location.x=0;
bullet.location.y=b_b+7;
bullet.alive=false;
bullet.color=4;
bullet.dam=1;
bullet.hp=1;
return bullet;
}
//所有子彈初始化函數(shù)
void init_bullets(void)
{
game.bullet_move=false;
for(int i=0;i<eq_plane;i++)
{
for(int j=0;j<eq_bullets_round;j++)
{
bullet[i][j]=init_bullet(bullet[i][j]);
}
}
}
//單個飛機(jī)初始化函數(shù)
Plane init_plane(Plane plane)
{
plane.alive=true;
plane.hp=3;
plane.keycmd=none_cmd;
plane.location=plocation[plane.No];
plane.color=plane.No+1;
plane.icon=plane.No+1;
return plane;
}
//所有飛機(jī)初始化函數(shù)
void init_planes(void)
{
for(int i=0;i<game.num_plane;i++)//刷新飛機(jī)圖標(biāo)
{
plane[i]=init_plane(plane[i]);
}
}
//子彈位置更新 線程
void* thread_bullet(void* arg)
{
while(1)
{
while(game.pause)
{
;
}
Sleep(game.bomb_interval);
for(int i=0;i<eq_plane;i++)
{
if(plane[i].fire) //如果飛機(jī)開火,要搜尋一個子彈處于死亡狀態(tài)的位置激活子彈
{
game.bullet_move=true;
for(int j=0;j<eq_bullets_round;j++)
{
if(!bullet[i][j].alive)
{
bullet[i][j]=fire(plane[i],bullet[i][j]);
break;
}
}
}
plane[i].fire=false;
}
for(int i=0;i<eq_plane;i++)
{
for(int j=0;j<eq_bullets_round;j++)
{
if(bullet[i][j].alive)
{
bullet[i][j].location.y--;
if(bullet[i][j].location.y<0)
{
bullet[i][j].hp=0;
}
for(int k=0;k<game.bombs_round;k++)//判斷子彈是否擊中炮彈
{
if(shoot(bullet[i][j],bomb[k]))
{
bomb[k].hp-=bullet[i][j].dam;
bullet[i][j].hp-=bomb[k].dam;
}
}
if(bullet[i][j].hp<=0)
{
//bullet[i][j].alive=false;
bullet[i][j]=init_bullet(bullet[i][j]);
}
}
}
}
}
}
//子彈位置更新
void bullet_location_update()
{
pthread_t tid;
pthread_create(&tid, NULL, thread_bullet, NULL);
}
子彈圖標(biāo)刷新函數(shù)
void show_bullet(Bullet bullet) //預(yù)先定義字符定位顯示函數(shù),x是列坐標(biāo),y是行坐標(biāo),原點(diǎn)(x=0,y=0)位于屏幕左上角
{
int x,y;
x=bullet.location.x;
y=bullet.location.y;
hide();//隱藏光標(biāo)
gotoxy(x,y);
ColorCout(bullet.icon,bullet.color);
}
//********************************************************************************
//以下函數(shù)為子彈被擊落或撞落功能
//********************************************************************************
bool collide(Plane plane,Bomb bomb)
{
bool cpb,cx0,cx1,cy0,cy1;
cx0=bomb.location.x>=plane.location.x-1;
cx1=bomb.location.x<=plane.location.x+plane_width;
cy0=bomb.location.y>=plane.location.y;
cy1=bomb.location.y<=plane.location.y+plane_height;
cpb=cx0 && cx1 && cy0 && cy1;
return cpb;
}
bool shoot(Bullet bullet,Bomb bomb)
{
bool sbb,sx0,sx1,sy0,sy1;
sx0=(bomb.location.x>=bullet.location.x-1);
sx1=(bomb.location.x<=bullet.location.x+1);
sy0=(bomb.location.y>=bullet.location.y);
sy1=(bomb.location.y<=bullet.location.y+1);
sbb=sx0 &&sx1&&sy0&&sy1;
return sbb;
}
//********************************************************************************
//以下三個函數(shù)為播放背景音樂功能
//********************************************************************************
//播放一遍背景音樂
void play_bgmusic() {
mciSendString(TEXT("open hero.mp3 alias s1"),NULL,0,NULL);
mciSendString(TEXT("play s1"),NULL,0,NULL);
Sleep(153*1000);//153*1000意思是153秒,是整首音樂的時長
mciSendString(TEXT("close S1"),NULL,0,NULL);
}
//循環(huán)播放音樂線程函數(shù)
void* thread_bgmusic(void* arg) //
{
while(1)
{
play_bgmusic();
}
}
//創(chuàng)建音樂播放線程,開始循環(huán)播放音樂
void bgmusic()
{
pthread_t tid;
pthread_create(&tid, NULL, thread_bgmusic, NULL);
}
四、運(yùn)行效果
(一)子彈與炮彈相撞
(二)炮彈與飛機(jī)相撞、飛機(jī)復(fù)活
文章來源:http://www.zghlxwxcb.cn/news/detail-660779.html
?(未完待續(xù))文章來源地址http://www.zghlxwxcb.cn/news/detail-660779.html
到了這里,關(guān)于【C++】做一個飛機(jī)空戰(zhàn)小游戲(十)——子彈擊落炮彈、炮彈與飛機(jī)相撞的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!