1-2 飛機大戰游戲場景

前言:


根據前面的項目框架,搭建游戲的運行場景......


1.0 框架預覽


基于該框架首先實現游戲的運行場景


2.0 圖片文件


創建圖片文件,本次項目使用easyx作為圖形庫文件,在easyx中想要顯示圖片,需要有一張圖片和圖片的掩碼文件,創建image.h文件和image.cpp文件用于圖片設置,具體創建效果如下所示。創建的頭文件中做了函數的聲明,包含函數的x,y軸的坐標和圖片的地址,掩碼圖片的地址。


#ifndef __IMAGE_H_
#define __IMAGE_H_
#include <easyx.h>void put_trans_parent_image
(int x, int y, const IMAGE* mask, const IMAGE* img
);#endif


#define  _CRT_SECURE_NO_WARNINGS
#include "image.h"void put_trans_parent_image(int x, int y, const IMAGE *mask, const IMAGE *img)
{putimage(x, y, mask, SRCAND);putimage(x, y, img, SRCPAINT);
}

3.0 程序對象


注:對于這款飛機大戰游戲,對應的對象就是精靈,然后將將所有元素的共性抽象成一個對象進行方便后續的調用,具體程序如下所示。


這個精靈對象就是所有游戲中出現的對象的共同特性,我們只需要繼承精靈,就能在此基礎上,續寫其他的對象了。將上面的代碼寫入文件 sprite.h,并添加上頭文件守衛。

#ifndef __SPRITE_H_
#define __SPRITE_H_// 飛機的屬性和方法
typedef struct sprite
{void (*draw)(sprite*);void (*update)(sprite*);int x;int y;int width;int height;
}sprite_t;#endif

hero.h文件,繼承sprite對象的屬性和方法


#ifndef  __HERO_H_
#define  __HERO_H_#include "sprite.h"
#include <easyx.h>typedef enum heroStatus
{hero_normal0 = 0,			// 英雄處于正常的狀態hero_normal1 = 1,			// 英雄處于正常的狀態hero_down0   = 3,			// 英雄處于銷毀狀態1hero_down1   = 4,			// 英雄處于銷毀狀態2hero_down2   = 5,			// 英雄處于銷毀狀態3hero_down3   = 6,			// 英雄處于銷毀狀態4hero_destory			    // 英雄完全被銷毀
}heroStatus_e;typedef struct hero
{sprite_t super;IMAGE* imgArrHero[6];		// 對應6種不同狀態的圖片IMAGE* imgArrHeroMask[6];	// 對應6種不同狀態的掩碼heroStatus_e status;		// 英雄的狀態更換int life;					// 英雄的生命值int heroUpdateCnt;			// 計數值
}hero_t;void heroInit(hero_t* h);void heroDestory(hero_t* h);#endif

hero.cpp文件,對hero.h文件中的對象和參數進行處理


#define  _CRT_SECURE_NO_WARNINGS
#include "hero.h"
#include <stdio.h>
#include "image.h"#define HERO_IMAGE_STRUCT	6
#define IMAGE_PAST			50
#define MASK_IMAGE_PAST		50
#define IMAGE_TYPE_NORMAL	2
#define IMAGE_TYPE_DOWN		4enum heroStatus heroStatusSqauence[7] =
{hero_normal0,hero_normal1,hero_down0,hero_down1,hero_down2,hero_down3,hero_destory
};void heroDraw(hero_t* h)		// 繪制函數
{put_trans_parent_image(h->super.x,h->super.y,h->imgArrHero[h->status],h->imgArrHeroMask[h->status]);
};void heroUpdate(hero_t* h)						// 飛機狀態更新
{h->heroUpdateCnt++;if (h->heroUpdateCnt >= 15){h->heroUpdateCnt = 0;if (h->life != 0){if (h->status == hero_normal0){h->status = hero_normal1;}else if (h->status == hero_normal1){h->status = hero_normal0;}}else{// 狀態向后變化if (h->status < hero_destory){h->status = heroStatusSqauence[h->status + 1];}}}
}void heroInit(hero_t *h)
{h->super.draw = (void (*)(sprite_t*))heroDraw;h->super.update = (void (*)(sprite_t*))heroUpdate;h->heroUpdateCnt = 0;h->status = hero_normal0;h->life = 1;h->super.x = 178;h->super.y = 600;for (int i = 0; i < HERO_IMAGE_STRUCT; i++){h->imgArrHero[i] = new IMAGE;h->imgArrHeroMask[i] = new IMAGE;}char imgPath[IMAGE_PAST];char imgMaskPath[MASK_IMAGE_PAST];for (int i = 0; i < IMAGE_TYPE_NORMAL; i++)	// 飛機完整的2種狀態{sprintf(imgPath, "asset/img/hero/hero%d.png", i);sprintf(imgMaskPath, "asset/img/hero/hero%d_mask.png", i);loadimage(h->imgArrHero[i], imgPath);loadimage(h->imgArrHeroMask[i], imgMaskPath);}for (int i = 0; i < IMAGE_TYPE_DOWN; i++)  // 飛機銷毀的4種狀態{sprintf(imgPath, "asset/img/hero/hero_down%d.png", i);sprintf(imgMaskPath, "asset/img/hero/hero_down%d_mask.png", i);loadimage(h->imgArrHero[i + 2], imgPath);loadimage(h->imgArrHeroMask[i + 2], imgMaskPath);}
}// 銷毀飛機函數
void heroDestory(hero_t* h)
{for (int i = 0; i < HERO_IMAGE_STRUCT; i++){delete h->imgArrHero[i];delete h->imgArrHeroMask[i];}
}

4.0 游戲循環


gameLoop.h文件:現在,我們將這個循環封裝成一個函數,放置到源文件 gameloop.cpp 當中。函數的參數為 sprite 對象

指針與游戲幀率 fps 。為了保證 sprite 對象的 draw 方法與 update 方法,每一幀都被執行一次。可以在循環中,調用 sprite 的 draw 方法與 update 方法。


gameLoop.cpp文件

#define  _CRT_SECURE_NO_WARNINGS
#include <easyx.h>
#include "gameloop.h"
#include "sprite.h"void gameLoop(sprite_t* s, int fps)
{timeBeginPeriod(1);							// 設置系統計時器的分辨率到 1 毫秒,提高時間測量精度LARGE_INTEGER startCount, endCount, F;		// 聲明用于高精度計時的變量QueryPerformanceFrequency(&F);				// 獲取高性能計數器每秒的頻率(即每秒計數值),存儲在 F 中BeginBatchDraw();							// 開始批處理繪圖模式,減少不必要的屏幕刷新,優化繪圖效率while(1)									// 無限循環,保持游戲運行{QueryPerformanceCounter(&startCount);	// 獲取當前計數器值作為起始時間點cleardevice();							// 清除繪圖設備,準備新一幀的繪制s->draw(s);								// 繪制			s->update(s);							// 狀態更新		QueryPerformanceCounter(&endCount);		// 獲取當前計數器值作為結束時間點long long elapse =						// 算從幀開始到結束所經過的時間,單位是微秒(endCount.QuadPart - startCount.QuadPart) /F.QuadPart * 1000000;while (elapse < 1000000 / fps)			// 確保每一幀的時間間隔大致等于 1000000 / fps 微秒(即每秒幀數的倒數){Sleep(1);QueryPerformanceCounter(&endCount);elapse = (endCount.QuadPart - startCount.QuadPart)* 1000000 / F.QuadPart;}FlushBatchDraw();						// 將批處理中的繪圖操作立即提交并顯示在屏幕上}EndBatchDraw();								// 結束批處理繪圖模式timeEndPeriod(1);							// 恢復系統計時器的默認分辨率
}

5.0 游戲場景


background.h文件,背景文件中包含背景A和背景B,背景還繼承了精靈的屬性和方法,同時包含存儲背景圖片地址的參數。

#ifndef __BACKGROUND_H_
#define __BACKGROUND_H_
#include "sprite.h"
#include <easyx.h>typedef struct background
{sprite_t super;int yA;int yB;IMAGE* imgBackground;
}background_t;void backgroundInit(background_t *);void backgroundDestory(background_t *);#endif

background.cpp文件:

backgroundpraw 為分別繪制A、B兩幅背景的函數。兩幅背景圖片的左上角坐標分別為:(0, yA),(0,yB) 圖片為 imgBackground。

backgroundupdate 更新兩幅圖片的左上角坐標,每次移動1像素。若 yA 大于等于0,則將 yA 復位
為-750,yB 復位為0。

接著就是初始化函數,將 draw 和 update 兩個方法賦值為 backgroundpraw 和backgroundupdate? yA初始值設置為-750, y8 初始值設置為0。創建并載入圖片 img/bg·png。

最后是 backgroundDestroy 函數,銷毀初始化時創建的 IMAGE 對象即可。


把當前主函數中 hero 對象,改為 background 對象,可以看到游戲循環 gameloop ,正常渲染并更新了背景對象。


6.0 渲染更新



#define  _CRT_SECURE_NO_WARNINGS
#include "gameloop.h"
#include "hero.h"
#include "background.h"int main(void)
{initgraph(422, 750);		// 初始化畫布setbkcolor(WHITE);			// 設置畫布顏色cleardevice();				// 清除畫布hero_t h;heroInit(&h);gameLoop((sprite*)&h, 60);heroDestory(&h);background b;backgroundInit(&b);gameLoop((sprite_t*)&b, 60);backgroundDestory(&b);closegraph();return 0;
}

7.0 運行結果


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/67407.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/67407.shtml
英文地址,請注明出處:http://en.pswp.cn/web/67407.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

進程通訊——類型和發展

進程常用交互方法如上

JavaScript系列(49)--游戲引擎實現詳解

JavaScript游戲引擎實現詳解 &#x1f3ae; 今天&#xff0c;讓我們深入探討JavaScript的游戲引擎實現。游戲引擎是一個復雜的系統&#xff0c;它需要處理渲染、物理、音頻、輸入等多個方面&#xff0c;讓我們一步步實現一個基礎但功能完整的游戲引擎。 游戲引擎基礎概念 &am…

安裝zsh并美化

0 Zsh 是一種功能強大的 shell&#xff0c;通常用于替代默認的 Bash shell。它為命令行提供了更多的功能&#xff0c;例如自動補全、強大的模式匹配和主題支持等。 Oh My Zsh 是用于管理 Zsh 配置的框架。 powerlevel10k是樣式&#xff0c;通過p10k configure腳本可以調節自己…

GMSL 明星產品之 MAX96717

在上一篇文章中&#xff0c;我們詳細介紹了車載市場中爆火的 GMSL 到底是個啥 &#xff1a; 揭開 GMSL 的面紗&#xff1a;自動駕駛背后的隱藏技術。今天我們就來詳細了解下如今在攝像頭側超級火爆的加串器&#xff1a;MAX96717。 MAX96717 系列有三款產品&#xff1a; MAX967…

線段樹 算法

文章目錄 基礎知識適用場景小結 題目概述題目詳解300.最長遞增子序列2407.最長遞增子序列 II 基礎知識 線段樹和樹狀數組都只是一個工具來的&#xff0c;題目并不會一下子就告訴你這個題目用到線段樹和樹狀數組&#xff0c;這個取決于你想使用的數據結構以及所要優化的方向 線…

MATLAB提供的顏色映射表colormap——偽彩色

圖像處理領域的一個習慣&#xff1a;不是真實的顏色&#xff0c;一般用偽彩色。一是說明不是物體本身的顏色&#xff0c;二是彩色更容易分辨。 MATLAB陸續提供了16種顏色映射表colormap。 之前的都很丑&#xff0c;近5年新增的4種還可以。總的說來還是丑。 這是一種鳥的名字。…

20.Word:小謝-病毒知識的科普文章?【38】

目錄 題目? NO1.2.3文檔格式 NO4.5 NO6.7目錄/圖表目錄/書目 NO8.9.10 NO11索引 NO12.13.14 每一步操作完&#xff0c;確定之后記得保存最后所有操作完記得再次刪除空行 題目 NO1.2.3文檔格式 樣式的應用 選中應用段落段落→開始→選擇→→檢查→應用一個一個應用ctr…

【16屆藍橋杯寒假刷題營】第2期DAY4

【16屆藍橋杯寒假刷題營】第2期DAY4 - 藍橋云課 問題描述 幼兒園小班的浩楠同學有一個序列 a。 他想知道有多少個整數三元組 (i,j,k) 滿足 1≤i,j,k≤n 且 ai?aj?ak?。 輸入格式 共2行&#xff0c;第一行一個整數 n&#xff0c;表示序列的長度。 第二行 n 個整數&#x…

MySQL查詢優化(三):深度解讀 MySQL客戶端和服務端協議

如果需要從 MySQL 服務端獲得很高的性能&#xff0c;最佳的方式就是花時間研究 MySQL 優化和執行查詢的機制。一旦理解了這些&#xff0c;大部分的查詢優化是有據可循的&#xff0c;從而使得整個查詢優化的過程更有邏輯性。下圖展示了 MySQL 執行查詢的過程&#xff1a; 客戶端…

Van-Nav:新年,將自己學習的項目地址統一整理搭建自己的私人導航站,供自己后續查閱使用,做技術的同學應該都有一個自己網站的夢想

嗨&#xff0c;大家好&#xff0c;我是小華同學&#xff0c;關注我們獲得“最新、最全、最優質”開源項目和高效工作學習方法 Van-Nav是一個基于Vue.js開發的導航組件庫&#xff0c;它提供了多種預設的樣式和靈活的配置選項&#xff0c;使得開發者可以輕松地定制出符合項目需求…

VSCode+Continue實現AI輔助編程

Continue是一款功能強大的AI輔助編程插件&#xff0c;可連接多種大模型&#xff0c;支持代碼設計優化、錯誤修正、自動補全、注釋編寫等功能&#xff0c;助力開發人員提高工作效率與代碼質量。以下是其安裝和使用方法&#xff1a; 一、安裝VSCode 參見&#xff1a; vscode安…

【hot100】刷題記錄(6)-輪轉數組

題目描述&#xff1a; 給定一個整數數組 nums&#xff0c;將數組中的元素向右輪轉 k 個位置&#xff0c;其中 k 是非負數。 示例 1: 輸入: nums [1,2,3,4,5,6,7], k 3 輸出: [5,6,7,1,2,3,4] 解釋: 向右輪轉 1 步: [7,1,2,3,4,5,6] 向右輪轉 2 步: [6,7,1,2,3,4,5] 向右輪轉…

FPGA 使用 CLOCK_DEDICATED_ROUTE 約束

使用 CLOCK_DEDICATED_ROUTE 約束 CLOCK_DEDICATED_ROUTE 約束通常在從一個時鐘區域中的時鐘緩存驅動到另一個時鐘區域中的 MMCM 或 PLL 時使 用。默認情況下&#xff0c; CLOCK_DEDICATED_ROUTE 約束設置為 TRUE &#xff0c;并且緩存 /MMCM 或 PLL 對必須布局在相同…

阿里:基于路由和規劃的多agent系統

&#x1f4d6;標題&#xff1a;Talk to Right Specialists: Routing and Planning in Multi-agent System for Question Answering &#x1f310;來源&#xff1a;arXiv, 2501.07813 &#x1f31f;摘要 &#x1f538;利用大型語言模型&#xff08;LLM&#xff09;&#xff0c…

數論問題77一一3x+1問題

3X 1問題&#xff0c;也被稱為考拉茲猜想、角谷猜想等&#xff0c;是數學領域一個著名的未解決問題&#xff0c;以下是關于它的介紹&#xff1a; 問題表述 對于任意一個正整數X&#xff0c;如果X是奇數&#xff0c;則將其變為3X 1&#xff1b;如果X是偶數&#xff0c;則將其變…

【Unity3D】實現2D角色/怪物死亡消散粒子效果

核心&#xff1a;這是一個Unity粒子系統自帶的一種功能&#xff0c;可將粒子生成控制在一個Texture圖片網格范圍內&#xff0c;并且粒子顏色會自動采樣圖片的像素點顏色&#xff0c;之后則是粒子編輯出消散效果。 Particle System1物體&#xff08;爆發式隨機速度擴散10000個粒…

Synology 群輝NAS安裝(10)安裝confluence

Synology 群輝NAS安裝&#xff08;10&#xff09;安裝confluence 寫在前面本著一朝鮮吃遍天的原則&#xff0c;我又去了這個github的作者那里翻車的第一次嘗試手工創建數據庫制作一個新的docker-compose of confluence 不折騰但成功啟動的版本 寫在前面 在裝完jira之后&#x…

萬字長文總結前端開發知識---JavaScriptVue3Axios

JavaScript學習目錄 一、JavaScript1. 引入方式1.1 內部腳本 (Inline Script)1.2 外部腳本 (External Script) 2. 基礎語法2.1 聲明變量2.2 聲明常量2.3 輸出信息 3. 數據類型3.1 基本數據類型3.2 模板字符串 4. 函數4.1 具名函數 (Named Function)4.2 匿名函數 (Anonymous Fun…

DeepSeek R1有什么不同

每周跟蹤AI熱點新聞動向和震撼發展 想要探索生成式人工智能的前沿進展嗎&#xff1f;訂閱我們的簡報&#xff0c;深入解析最新的技術突破、實際應用案例和未來的趨勢。與全球數同行一同&#xff0c;從行業內部的深度分析和實用指南中受益。不要錯過這個機會&#xff0c;成為AI領…

年度總結(盡量簡短)

一.成長 1.對于U使用更熟練&#xff0c;能應付基本的開發。幾個項目的練習和磨練&#xff0c;基本達到了我今年的目標&#xff0c;自己可以應付項目。可以過度到底層的學習。 2.堅持寫帖子&#xff0c;雖然后半年的帖子發的沒有上半年勤快。但是也在堅持學東西 3.對于職場上…