基于EasyX庫開發的球球大作戰游戲

目錄

球球大作戰

一、開發環境

二、流程圖預覽

三、代碼邏輯

1、初始化時間

2、設置開始界面大小

3、設置開始界面

4、讓玩家選擇速度

5、設置玩家小球、人機小球、食物的屬性

6、一次性把圖繪制到界面里

7、進入死循環

8、移動玩家小球

9、移動人機

10、食物刷新

11、畫出邊界、食物、人機、玩家、小地圖,添加擊殺數、半徑(質量)、玩家名字

12、將內存中的繪圖操作批量地繪制到屏幕上,從而提高繪圖效率

四、代碼預覽+運行結果


球球大作戰

一、開發環境

VisualStudio專業版:

所需依賴庫:EasyX庫

二、流程圖預覽

由于上面的比較模糊,下面分開截取流程圖圖片

三、代碼邏輯

1、初始化時間

starttime();

2、設置開始界面大小

initgraph(WIDTH, HEIGHT);

3、設置開始界面

void start() {setbkcolor(WHITE);                          // 白色背景cleardevice();                              // 初始化背景settextcolor(BLACK);                            // 改字體setbkmode(TRANSPARENT);                 //設置背景是透明的//加載背景圖片IMAGE image;loadimage(&image, _T("D:\\桌面\\file2\\球球大作戰\\source\\Ball Ball\\x64\\img\\10.jpg"), WIDTH, HEIGHT);//在當前設備上繪制指定圖像putimage(0, 0, &image);//加入提示信息settextcolor(WHITE);settextstyle(22, 0, _T("黑體"));outtextxy(50, 480, _T("請選擇關卡:"));outtextxy(50, 550, _T("1.小試牛刀"));outtextxy(200, 550, _T("2.爐火純青"));outtextxy(350, 550, _T("3.登峰造極"));settextstyle(15, 0, _T("宋體"));outtextxy(600, 550, _T("注:按序號選擇,默認選擇關卡1;游戲中按空格鍵可以暫停。"));settextcolor(BLACK);settextstyle(22, 0, _T("黑體"));TCHAR s[5];//_stprintf(s, _T("%d"), readCount());_stprintf_s(s, _countof(s), _T("%d"), readCount());outtextxy(810, 200, _T("歡迎進入游戲!"));outtextxy(810, 240, _T("游戲次數:"));outtextxy(910, 240, s);
}

4、讓玩家選擇速度

void ChooseSpeed() {switch (_getch()) {case 1:speed = 4;case 2:speed = 3;case 3:speed = 2;default:speed = 4;}
}

5、設置玩家小球、人機小球、食物的屬性

void setall() {srand((unsigned)time(NULL));                    // 隨機數mover.color = RGB(rand() % 256, rand() % 256, rand() % 256);        // 隨機顏色mover.life = 1;                             // 賦初值1//把玩家的球一直放在屏幕中央mover.x = int(WIDTH * 0.5);mover.y = int(HEIGHT * 0.5);//設置半徑mover.r = 20;
?for (int i = 0; i < AINUM; i++) {               // AI 的屬性ai[i].life = 1;ai[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);//ai[i].r = float(rand() % 10 + 10);ai[i].r = 20;ai[i].x = rand() % (MAPW - int(ai[i].r + 0.5)) + int(ai[i].r + 0.5);ai[i].y = rand() % (MAPH - int(ai[i].r + 0.5)) + int(ai[i].r + 0.5);}
?for (int i = 0; i < FNUM; i++) {                // 食物的屬性food[i].eat = 1;food[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);food[i].x = rand() % MAPW;food[i].y = rand() % MAPH;food[i].type = rand() % 10 + 1;}
?pBuffer = GetImageBuffer(NULL);                 // 獲取顯存指針setbkcolor(WHITE);                          // 白色背景cleardevice();                              // 初始化背景settextcolor(LIGHTRED);                     // 改字體//設置背景是透明的setbkmode(TRANSPARENT);settextstyle(16, 0, _T("宋體"));
?
}

6、一次性把圖繪制到界面里

BeginBatchDraw();

7、進入死循環

8、移動玩家小球

void move(BALL* ball) {if (ball->r <= 0)ball->life = false;if (ball->life == false) {                      // 判定游戲是否接束HWND hwnd = GetHWnd();MessageBox(hwnd, _T("你被吃了"), _T("游戲結束"), MB_ICONEXCLAMATION);endtime();
?}
?if (eaten + ai_eaten == AINUM)                  // 是否吃掉所有 AI{HWND hwnd = GetHWnd();MessageBox(hwnd, _T("恭喜過關"), _T("游戲結束"), MB_OK | MB_ICONEXCLAMATION);   // 結束endtime();}
?for (int i = 0; i < AINUM; i++) {               // 玩家吃 AI 判定if (ball->r >= ai[i].r) {if (ai[i].life == 0)    continue;if (DISTANCE(ball->x, ball->y, ai[i].x, ai[i].y) < (4 / 5.0 * (ball->r + ai[i].r))) {ai[i].life = 0;                 //AI被吃ball->r = sqrt(ai[i].r * ai[i].r + ball->r * ball->r);eaten++;}}}
?for (int n = 0; n < FNUM; n++) {                // 玩家吃食物if (food[n].eat == 0)   continue;if (DISTANCE(ball->x, ball->y, food[n].x, food[n].y) < ball->r) {ball->r += 4 / ball->r;             // 增加面積food[n].eat = 0;                        // 食物被吃}}
?static int mx = 0, my = 0;                      // 記錄偏移量
?//判斷怎么移動if (GetAsyncKeyState(VK_UP) && (ball->y - ball->r > 0 && ball->y <= (MAPH - ball->r + 10))) {ball->y -= speed;my += speed;}if (GetAsyncKeyState(VK_DOWN) && (ball->y - ball->r >= -10 && ball->y < (MAPH - ball->r))) {ball->y += speed;my -= speed;}if (GetAsyncKeyState(VK_LEFT) && ball->x - ball->r > 0 && (ball->x <= (MAPW - ball->r + 10))) {ball->x -= speed;mx += speed;}if (GetAsyncKeyState(VK_RIGHT) && ball->x - ball->r >= -10 && (ball->x < (MAPW - ball->r))) {ball->x += speed;mx -= speed;}
?//判斷是否輸入其他用于退出、暫停、繼續的按鍵if (GetAsyncKeyState(VK_SPACE)) {settextcolor(WHITE);settextstyle(32, 0, _T("宋體"));outtextxy(384 - mx, 350 - my, _T("游戲已暫停!"));outtextxy(20 - mx, 500 - my, _T("(ESC)退出"));outtextxy(780 - mx, 500 - my, _T("(回車鍵)繼續"));FlushBatchDraw();_getch();if (GetAsyncKeyState(VK_ESCAPE))exit(0);else_getch();}
?setorigin(mx, my);                          //坐標修正
}

9、移動人機

void AI() {for (int i = 0; i < AINUM; i++) {               // AI 吃玩家if (ai[i].r > mover.r) {if (DISTANCE(mover.x, mover.y, ai[i].x, ai[i].y) < (ai[i].r + mover.r)) {ai[i].r = sqrt(ai[i].r * ai[i].r + mover.r * mover.r);mover.life = 0;mover.r = 0;}}for (int j = 0; j < AINUM; j++) {           // AI 吃 AIif (ai[i].r > ai[j].r) {if (ai[j].life == 0) continue;if (DISTANCE(ai[i].x, ai[i].y, ai[j].x, ai[j].y) < (ai[i].r + ai[j].r)) {ai[i].r = sqrt(ai[i].r * ai[i].r + ai[j].r * ai[j].r);ai[j].life = 0;ai[j].r = 0;ai_eaten++;}}}
?double min_DISTANCE = 100000;int min = -1;for (int k = 0; k < AINUM; k++) {           // AI 靠近 AIif (ai[i].r > ai[k].r && ai[k].life != 0) {if (DISTANCE(ai[i].x, ai[i].y, ai[k].x, ai[k].y) < min_DISTANCE) {min_DISTANCE = DISTANCE(ai[i].x, ai[i].y, ai[k].x, ai[k].y);min = k;}}}if ((min != -1) && (rand() % 2 == 1) && (ai[i].y - ai[i].r > 0 && ai[i].y <= (MAPH - ai[i].r + 10))) {if (rand() % 2) {if (ai[i].x < ai[min].x)ai[i].x += speed ;elseai[i].x -= speed ;}else {if (ai[i].y < ai[min].y)ai[i].y += speed ;elseai[i].y += speed ;}}for (int n = 0; n < FNUM; n++) {            // AI 吃食物if (food[n].eat == 0) continue;if (DISTANCE(ai[i].x, ai[i].y, food[n].x, food[n].y) < ai[i].r) {ai[i].r += 4 / ai[i].r;food[n].eat = 0;}}}
}

10、食物刷新

void Food() {for (int i = 0; i < FNUM; i++) {				// 食物刷新if (food[i].eat == 0) {food[i].eat = 1;food[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);food[i].x = rand() % MAPW;food[i].y = rand() % MAPH;food[i].type = rand() % 10 + 1;}}
}

11、畫出邊界、食物、人機、玩家、小地圖,添加擊殺數、半徑(質量)、玩家名字

void draw() {float asp = 1;//清空裁剪區,超出區域的繪圖操作將被裁剪掉clearcliprgn();IMAGE image;loadimage(&image, _T(""), WIDTH * 4, HEIGHT * 4);putimage(0, 0, &image);//繪畫出一個矩形框setlinestyle(PS_SOLID | PS_JOIN_BEVEL, 20);		// 改變筆的顏色、狀態setlinecolor(RGB(0, 100, 0));line(-20, MAPH + 20, -20, -20);				// 左豎line(-20, MAPH + 20, MAPW + 20, MAPH + 20);		// 上橫line(-20, -20, MAPW + 20, -20);				// 下橫line(MAPW + 20, -20, MAPW + 20, MAPH + 20);		// 右豎setfillcolor(GREEN);//當球接近邊界時,會在邊界外側繪制一個綠色的填充矩形,// 是用來表示碰撞或者邊界的視覺效果if (mover.x - 0.5 * WIDTH / asp < -20)floodfill(-20 - 11, mover.y, RGB(0, 100, 0));if (mover.x + 0.5 * WIDTH / asp > MAPW + 20)floodfill(MAPW + 20 + 11, mover.y, RGB(0, 100, 0));if (mover.y - 0.5 * HEIGHT / asp < -20)floodfill(mover.x, -20 - 11, RGB(0, 100, 0));if (mover.y + 0.5 * HEIGHT / asp > MAPH + 20)floodfill(mover.x, MAPH + 20 + 11, RGB(0, 100, 0));setlinecolor(WHITE);setlinestyle(PS_NULL);for (int i = 0; i < FNUM; i++) {				// 畫出食物if (food[i].eat == 0) continue;setfillcolor(food[i].color);switch (food[i].type) {					// 形狀case 1:		solidellipse(food[i].x, food[i].y, food[i].x + 2, food[i].y + 4); break;case 2:		solidellipse(food[i].x, food[i].y, food[i].x + 4, food[i].y + 2);	break;case 3:		solidrectangle(food[i].x, food[i].y, food[i].x + 4, food[i].y + 2); break;case 4:		solidrectangle(food[i].x, food[i].y, food[i].x + 2, food[i].y + 4); break;case 5:		solidroundrect(food[i].x, food[i].y, food[i].x + 2, food[i].y + 4, 2, 2); break;case 6:		solidroundrect(food[i].x, food[i].y, food[i].x + 4, food[i].y + 2, 2, 2); break;case 7:		solidroundrect(food[i].x, food[i].y, food[i].x + 4, food[i].y + 2, 4, 2); break;case 8:		solidroundrect(food[i].x, food[i].y, food[i].x + 4, food[i].y + 2, 2, 4); break;case 9:		solidroundrect(food[i].x, food[i].y, food[i].x + 4, food[i].y + 2, 1, 1); break;case 10:	fillcircle(food[i].x, food[i].y, 4); break;}}for (int i = 0; i < AINUM; i++) {				// 畫 AIif (ai[i].life == 0) continue;setfillcolor(ai[i].color);//繪圓fillcircle(ai[i].x, ai[i].y, int(ai[i].r + 0.5));}setfillcolor(mover.color);						// 畫玩家fillcircle(mover.x, mover.y, int(mover.r + 0.5));IMAGE map(150, 100);							// 小地圖SetWorkingImage(&map);setbkcolor(RGB(120, 165, 209));					// 淺灰色背景cleardevice();for (int i = 0; i < AINUM; i++)				// 畫 AI(小地圖){if (ai[i].life == 0) continue;setfillcolor(ai[i].color);fillcircle(ai[i].x * 150 / WIDTH / 4, ai[i].y * 100 / HEIGHT / 4, int(ai[i].r / 28 + 1.5));}setfillcolor(mover.color);						// 畫玩家(小地圖)fillcircle(mover.x * 150 / WIDTH / 4, mover.y * 100 / HEIGHT / 4, int(mover.r / 28 + 3.5));setlinecolor(RGB(0, 100, 0));SetWorkingImage();							// 恢復繪圖背景putimage(mover.x + int(0.5 * WIDTH) - 150, mover.y - int(0.5 * HEIGHT), 150, 100, &map, 0, 0);						// 畫出小地圖setlinecolor(LIGHTBLUE);setlinestyle(PS_SOLID | PS_JOIN_BEVEL, 4);line(mover.x + int(0.5 * WIDTH) - 151, mover.y - int(0.5 * HEIGHT), mover.x + int(0.5 * WIDTH) - 151, mover.y - int(0.5 * HEIGHT) + 99);	// 地圖邊框線line(mover.x + int(0.5 * WIDTH) - 151, mover.y - int(0.5 * HEIGHT) + 99, mover.x + int(0.5 * WIDTH), mover.y - int(0.5 * HEIGHT) + 99);	// 地圖邊框線setlinestyle(PS_NULL);							// 恢復筆TCHAR str[32];swprintf_s(str, _T("質量:%.1fg  擊殺:%d"), mover.r, eaten);settextcolor(WHITE);							// 改字體outtextxy(mover.x - int(0.5 * WIDTH), mover.y - int(0.5 * HEIGHT), str);settextcolor(WHITE);outtextxy(mover.x - 20, mover.y, _T("itlsl"));
}

12、將內存中的繪圖操作批量地繪制到屏幕上,從而提高繪圖效率

FlushBatchDraw();

四、代碼預覽+運行結果

源代碼+流程圖+README資源:https://download.csdn.net/download/2403_82436914/90623088?spm=1001.2014.3001.5503

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

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

相關文章

aslist和list的區別

?Arrays.asList和List的主要區別在于它們的固定長度和不可變性、與原始數組的關系、性能以及使用場景。 一、固定長度和不可變性 ?Arrays.asList?&#xff1a;通過Arrays.asList方法創建的List是一個固定長度的List&#xff0c;其長度與原始數組相同。這意味著你不能通過添…

大模型預標注和自動化標注在OCR標注場景的應用

OCR&#xff0c;即光學字符識別&#xff0c;簡單來說就是利用光學設備去捕獲圖像并識別文字&#xff0c;最終將圖片中的文字轉換為可編輯和可搜索的文本。在數字化時代&#xff0c;OCR&#xff08;光學字符識別&#xff09;技術作為處理圖像中文字信息的關鍵手段&#xff0c;其…

stm32工程,拷貝到另一臺電腦編譯,錯誤提示頭文件找不到cannot open source input file “core_cm4.h”

提示 cannot open source input file “core_cm4.h” ,找不到 [ core_cm4.h ] 這個頭文件 . 于是我在原電腦工程文件里找也沒有找到這個頭文件 接下來查看原電腦keil的頭文件引入配置,發現只引入了工程文件下的頭文件, 那么core_cm4.h到底哪里來的? (到現在我也不清楚怎…

STM32 模塊化開發指南 · 第 2 篇 如何編寫高復用的外設驅動模塊(以 UART 為例)

本文是《STM32 模塊化開發實戰指南》的第 2 篇,聚焦于“串口驅動模塊的設計與封裝”。我們將從一個最基礎的裸機 UART 初始化開始,逐步實現:中斷支持、環形緩沖收發、模塊接口抽象與測試策略,構建一個可移植、可擴展、可復用的 UART 驅動模塊。 一、模塊化 UART 的設計目標…

【NLP 59、大模型應用 —— 字節對編碼 bpe 算法】

目錄 一、詞表的構造問題 二、bpe(byte pair encoding) 壓縮算法 算法步驟 示例&#xff1a; 步驟 1&#xff1a;初始化符號表和頻率統計 步驟 2&#xff1a;統計相鄰符號對的頻率 步驟 3&#xff1a;合并最高頻的符號對 步驟 4&#xff1a;重復合并直至終止條件 三、bpe在NLP中…

TMS320F28P550SJ9學習筆記15:Lin通信SCI模式結構體寄存器

今日初步認識與配置使用Lin通信SCI模式&#xff0c;用結構體寄存器的方式編程 文章提供完整工程下載、測試效果圖 我的單片機平臺是這個&#xff1a; LIN通信引腳&#xff1a; LIN通信PIE中斷&#xff1a; 這個 PIE Vector Table 表在手冊111頁&#xff1a; 這是提到LINa的PI…

linux-設置每次ssh登錄服務器的時候提醒多久需要修改密碼

在 Linux 系統中,你可以通過設置 motd(Message of the Day)或 sshd 配置來在用戶通過 SSH 登錄時提醒他們密碼即將過期。以下是具體步驟: 方法 1: 使用 motd 文件 motd 文件在用戶登錄時顯示,你可以通過腳本動態生成內容,提醒用戶密碼過期時間。 編輯 /etc/motd 文件:…

matlab求和∑函數方程編程?

matlab求和∑函數方程編程&#xff1f; 一 題目&#xff1a;求下列函數方程式的和 二&#xff1a;代碼如下&#xff1a; >> sum_result 0; % 初始化求和變量 for x 1:10 % 設…

electron桌面端開發-打開指定軟件和文件

electron桌面端開發 現在越來越多的軟件開發已經趨向于簡單化&#xff0c;桌面端開發已經不在依賴之前的java、c等主流技術&#xff0c;目前基于node的開發越來越廣泛。功能點也越來越多元化。 文章目錄 electron桌面端開發前言一、打開文件的方式&#xff1f;二、exec使用步驟…

ShenNiusModularity項目源碼學習(17:ShenNius.Admin.Mvc項目分析-2)

ShenNiusModularity項目的后臺管理主頁面如下圖所示&#xff0c;該頁面為ShenNius.Admin.Mvc項目的Views\Home\Index.cshtml&#xff0c;使用的是layuimini后臺模板&#xff08;參考文獻2&#xff09;&#xff0c;在layuimini的GitHub主頁中提供有不同樣式的頁面模版鏈接&#…

SpringBoot 與 Vue3 實現前后端互聯全解析

在當前的互聯網時代&#xff0c;前后端分離架構已經成為構建高效、可維護且易于擴展應用系統的主流方式。本文將詳細介紹如何利用 SpringBoot 與 Vue3 構建一個前后端分離的項目&#xff0c;展示兩者如何通過 RESTful API 實現無縫通信&#xff0c;讓讀者了解從環境搭建、代碼實…

portainer.io篇

Portainer?是一個輕量級的容器管理工具&#xff0c;支持Docker、Kubernetes、Docker Swarm、ACI和Nomad等多種平臺。它提供了一個直觀的Web界面&#xff0c;使用戶能夠輕松地管理和監控容器&#xff0c;包括創建、啟動、停止、刪除容器&#xff0c;以及查看容器的日志和配置信…

Dockerfile 文件常見命令及其作用

Dockerfile 文件包含一系列命令語句&#xff0c;用于定義 Docker 鏡像的內容、配置和構建過程。以下是一些常見的命令及其作用&#xff1a; FROM&#xff1a;指定基礎鏡像&#xff0c;后續的操作都將基于該鏡像進行。例如&#xff0c;FROM python:3.9-slim-buster 表示使用 Pyt…

Android Studio開發知識:從基礎到進階

引言 Android開發作為移動應用開發的主流方向之一&#xff0c;曾吸引了無數開發者投身其中。然而&#xff0c;隨著市場飽和和技術迭代&#xff0c;當前的Android開發就業形勢并不樂觀&#xff0c;競爭日益激烈。盡管如此&#xff0c;掌握扎實的開發技能仍然是脫穎而出的關鍵。本…

大表查詢的優化方案

?單表優化?&#xff1a; ?字段選擇?&#xff1a;盡量使用TINYINT、SMALLINT、MEDIUMINT作為整數類型&#xff0c;而非INT&#xff1b;如果字段值非負&#xff0c;可以使用UNSIGNED。對于字符串字段&#xff0c;使用枚舉或整數代替字符串類型&#xff0c;使用TIMESTAMP而非D…

常見MQ及類MQ對比:Redis Stream、Redis Pub/Sub、RocketMQ、Kafka 和 RabbitMQ

常見MQ及類MQ對比 基于Grok調研 Redis Stream、Redis Pub/Sub、RocketMQ、Kafka 和 RabbitMQ 關鍵點&#xff1a; Redis Pub/Sub 適合簡單實時消息&#xff0c;但不持久化&#xff0c;消息可能丟失。Redis Stream 提供持久化&#xff0c;適合需要消息歷史的場景&#xff0c;但…

DAPP實戰篇:使用ethersjs連接智能合約并輸入地址查詢該地址余額

本系列目錄 專欄:區塊鏈入門到放棄查看目錄-CSDN博客文章瀏覽閱讀400次。為了方便查看將本專欄的所有內容列出目錄,按照順序查看即可。后續也會在此規劃一下后續內容,因此如果遇到不能點擊的,代表還沒有更新。聲明:文中所出觀點大多數源于筆者多年開發經驗所總結,如果你…

庫magnet使用指南

Magnet 多線程控制庫使用指南 目錄 庫功能概述環境配置核心類與接口基礎使用示例代碼生成工具高級功能與改進建議完整示例代碼常見問題解答 https://blink.csdn.net/details/1872803?spm1001.2014.3001.5501 1. 庫功能概述 Magnet 庫提供以下核心功能&#xff1a; 多線程…

SpringCloud-快速通關(三)

SpringCloud-快速通關(一) SpringCloud-快速通關(二) SpringCloud-快速通關(三) SpringCloud-快速通關(三) 七、Seata - 分布式事務7.1、環境搭建7.1.1、簡介7.1.2、環境搭建7.1.3、seata-server7.1.4、微服務配置7.1.5、測試7.2、事務模式7.2.1、AT模式7.2.2、XA模式…

STM32 TDS+溫度補償

#define POLAR_CONSTANT (513385) /* 電導池常數&#xff0c;可通過與標準TDS測量儀對比計算反推 */ #define TDS_COEFFICIENT (55U) /* TDS 0.55 * 電子傳導率*/void TDS_Value_Conversion() {u32 ad0;u8 i;float compensationCoefficient;float compens…