文章目錄
- 1.前言
- 2.效果展示
- 3.圖片素材的準備
- 4.需要構建的函式
- 5.變數的定義
- 6.資料的初始化
- 7.畫面的呈現
- 8.飛機移動的實作
- 9.子彈的構建和移動
- 9.1子彈的構建
- 9.2子彈的移動
- 10.敵機的創建和移動
- 11.敵機消滅函式
- 12.結束語
- 13.完整代碼
1.前言
本次需要用到easyx圖形庫,關于easyx的安裝和一些基本函式,我在另外一篇推箱子小游戲中也有介紹,需要了解的小伙伴也可以點擊進去看一看,下面會附上鏈接;
在寫程式程序中需要的圖片,可以去百度找,也可以自己制作,有想要了解如何制作的小伙伴也可以點擊我下面的博客鏈接;
圖片素材如何制作鏈接
easyx介紹鏈接
2.效果展示

3.圖片素材的準備
如下圖所示,我將我用到的圖片的背景圖和原碼圖都放在了源檔案的檔案夾,這樣訪問的時候直接填寫圖片檔案名即可;
有個小建議,圖片名字別亂取,因為找起來特別麻煩,啊哈哈;

4.需要構建的函式
下圖中,展示了我們需要構建的函式以及定義的結構體,下面我將會解釋各個函式的實作

5.變數的定義
我們使用變數時需要定義,我們的圖片在使用之前也需要定義和加載,如下圖所示:

6.資料的初始化
由上面可知我們定義了飛機結構體變數,變數中的的x,y即代表了飛機的坐標,我們的飛機在出生時,應該在界面的最低的中央處,子彈和敵機的初始化一目了然這里就不再贅述了;
下圖展現了視窗的坐標,和飛機的起始坐標取值:

7.畫面的呈現
通過判斷我方飛機,子彈,敵機的結構體中的bool值來確定是否列印圖案;
我們的子彈和敵機的設定為陣列,通過陣列元素形成的時間差,來營造連綿不斷的動態效果;

8.飛機移動的實作

9.子彈的構建和移動
9.1子彈的構建

9.2子彈的移動

10.敵機的創建和移動
敵機的創建和移動就是子彈的復制版本,兩者邏輯是一樣的

11.敵機消滅函式

12.結束語
非常感謝大家的訪問,期待你們的指導,
這次只實作了飛機大戰基本的功能,后面會繼續更新其它有趣的內容;
13.完整代碼
#ifndef _PLANE_H_
#define _PLANE_H_
#include <stdio.h>
#include <graphics.h>
#include <time.h>
#define SIZE 600 //背景大小
#define PSIZE 80 //飛機大小
#define BSIZE 40 //子彈大小
#define MAX 10//子彈數目
#define FMAX 10//敵機數目
typedef struct Member
{
double x;
double y;
bool lable;
}mem;
void Game();
void Load();//圖片加載
void DataInit();//資料初始化
void PlaneCtr();//通過輸入上下左右來改變飛機的坐標
void Show();//畫面呈現
void BullterCre();//按了空格,呼叫函式,創建子彈
void BullterMove();//子彈移動
void FplaneCre();//敵機創建
void FplaneMove();//敵機移動
void Hit();//消滅敵機
#endif
#include"plane.h"
//定義圖片變數
IMAGE background;//背景圖
IMAGE plane_back;//飛機背景圖
IMAGE plane_mask;//飛機掩碼圖
IMAGE fplane_back;//敵機背景圖
IMAGE fplane_mask;//敵機掩碼圖
IMAGE bullte_back;//子彈背景圖
IMAGE bullte_mask;//子彈掩碼圖
//定義全域變數
mem plane;//飛機結構體
mem bullte[MAX];//子彈結構體陣列
mem fplane[FMAX];//敵機結構體
DWORD time_start, time_last; //時間變化量
void Load()//圖片加載
{
loadimage(&background, "background.jpg", SIZE, SIZE);
loadimage(&plane_back, "plane_back.jpg", PSIZE, PSIZE);
loadimage(&plane_mask, "plane_mask.jpg", PSIZE, PSIZE);
loadimage(&fplane_back, "fplane_back.jpg", PSIZE, PSIZE);
loadimage(&fplane_mask, "fplane_mask.jpg", PSIZE, PSIZE);
loadimage(&bullte_back, "bullte_back.jpg", BSIZE, BSIZE);
loadimage(&bullte_mask, "bullte_mask.jpg", BSIZE, BSIZE);
}
void DataInit()//資料初始化
{
//飛機的資料初始化
plane.x = SIZE / 2 - PSIZE / 2; //飛機起始位置在背景圖的中央
plane.y = SIZE - PSIZE;
plane.lable = true; //飛機出生是存活的
//子彈初始化
for (int i = 0; i < MAX; i++)
{
bullte[i].lable = false;//子彈沒按空間前是不存在的
}
time_start = time_last = GetTickCount();//開機到現在的毫秒數
//敵機初始化
for (int i = 0; i>FMAX; i++)
{
fplane[i].lable = false;
}
}
void PlaneCtr()//通過輸入上下左右來改變飛機的坐標
{
if (GetAsyncKeyState(VK_UP))//向上移動
{
if (plane.y>0)//不能越界
plane.y-=0.8;
}
if (GetAsyncKeyState(VK_DOWN))//向下移動
{
if (plane.y<SIZE-PSIZE)//y最大值600,飛機圖片大小為80
plane.y+=0.8;
}
if (GetAsyncKeyState(VK_LEFT))//向左移動
{
if (plane.x>-PSIZE/2)//可以縮入墻壁一半機體
plane.x-=0.8;
}
if (GetAsyncKeyState(VK_RIGHT))//向右移動
{
if (plane.x<SIZE-PSIZE/2)
plane.x+=0.8;
}
if (GetAsyncKeyState(VK_SPACE) &&time_last - time_start>80)//發射子彈,每顆子彈間接為80毫秒
{
BullterCre();//空格發射子彈
time_start = time_last;
}
time_last = GetTickCount();
}
void Show()//畫面呈現
{
BeginBatchDraw();//雙緩沖繪圖,防閃爍
putimage(0, 0, &background);
if (plane.lable)//飛機存活就列印飛機
{
putimage((int)plane.x, (int)plane.y, &plane_mask, SRCAND);
putimage((int)plane.x, (int)plane.y, &plane_back, SRCPAINT);
}
for (int i = 0; i < MAX; i++)//回圈判斷子彈
{
if (bullte[i].lable)//子彈存在就列印子彈
{
putimage((int)bullte[i].x, (int)bullte[i].y, &bullte_mask, SRCAND);
putimage((int)bullte[i].x, (int)bullte[i].y, &bullte_back, SRCPAINT);
}
}
for (int i = 0; i < FMAX; i++)
{
if (fplane[i].lable)//列印敵機
{
putimage((int)fplane[i].x, (int)fplane[i].y, &fplane_mask, SRCAND);
putimage((int)fplane[i].x, (int)fplane[i].y, &fplane_back, SRCPAINT);
}
}
EndBatchDraw();
}
void BullterCre()//按了空格,呼叫函式,創建子彈
{
for (int i = 0; i < MAX; i++)
{
if (!bullte[i].lable)//子彈不存在就創建子彈
{
//從飛機的正前方發出去
bullte[i].x = plane.x + PSIZE / 2 - BSIZE / 2;
bullte[i].y = plane.y - BSIZE;
bullte[i].lable = true;
break;//一次空格產生一顆子彈
}
}
}
void BullterMove()//子彈移動
{
for (int i = 0; i < MAX; i++)
{
if (bullte[i].lable)//子彈存在,它的y坐標就減少
{
bullte[i].y--;//坐標減,產生移動
if (bullte[i].y < 0)//子彈回收,否則下次全是發射出去的子彈
{
bullte[i].lable = false;
}
}
}
}
void FplaneCre()//敵機創建
{
for (int i = 0; i < FMAX; i++)
{
if (!fplane[i].lable&&time_last-time_start>100)//沒有敵機就進行構建,用時間函式控制產生速度
{
fplane[i].lable = true;
fplane[i].x = rand() % SIZE - PSIZE;//不讓敵出現在視窗外
fplane[i].y = 0;
time_start = time_last;
break;//每次一個
}
time_last = GetTickCount();//獲取新的時間
}
}
void FplaneMove()//敵機移動
{
for (int i = 0; i < FMAX; i++)
{
if (fplane[i].lable)
{
fplane[i].y+=0.3;//敵機往下走
if (fplane[i].y>SIZE)//敵機回收
fplane[i].lable = false;
}
}
}
void Hit()//消滅敵機
{
for (int i = 0; i < FMAX; i++)
{
if (!fplane[i].lable)//不存在則換下一個判斷
continue;
for (int j = 0; j < MAX; j++)
{
if (!bullte[j].lable)
continue;//子彈不存在也換下一個判斷
if (bullte[j].x>fplane[i].x&& //子彈和敵機有交集則都消失
bullte[j].x<fplane[i].x + PSIZE
&&bullte[j].y>fplane[i].y&&
bullte[j].y <fplane[i].y + PSIZE)
{
bullte[j].lable = false;
fplane[i].lable = false;
}
}
}
}
void Game()
{
//加載圖片數和初始化資料
Load();
DataInit();
srand((unsigned)time(NULL));//種下亂數種子
while (1)
{
Show();//影像顯示
PlaneCtr();//操控
BullterMove();//子彈移動
FplaneCre();//敵機創建
Hit();//判斷是否打中敵機
FplaneMove();//敵機往下走
}
}
#include"plane.h"
int main()
{
initgraph(600, 600);
Game();
getchar();
return 0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/244331.html
標籤:其他
