项目实战-飞机大战【补档】
和项目实战-贪吃蛇大作战【补档】-CSDN博客一样,这也是一个我在大一和网友完成的项目的补档。Don't waste your youth—time flies.
目录
1.工具&环境
2.项目简介
3.需求文档
4.流程图
5.产品原型图
6.可行性分析
7.源代码
8.实战效果 编辑
9.心得
(10.AI测评)
1.工具&环境
工具名称 功能
gitee 代码合并
easyx C++图形绘图
Excel 需求文档
Processon 功能流程图
墨刀 产品原型图
环境
windows & C++环境
2.项目简介
飞机大战游戏是以太空主题的画面为游戏背景,模拟三体世界观的设定,是一个界面简洁流畅、游戏方式简单的小游戏,由玩家通过鼠标控制我方战机向三体文明发动进攻。战机初始有一定量的血量,屏幕上随机产生敌机,战机产生的数量和当前关卡,关卡越高,产生的敌机越多,游戏难度越大,玩家可通过氪金降低游戏难度。玩家需要操作战机躲避敌方子弹,战机可拾取装备提升战力。我方战机与敌机只要中弹都会减血,直至血槽为空,战机爆炸,关卡内所有敌机爆炸后通关,全部关卡通过后游戏结束。
3.需求文档
4.流程图
5.产品原型图
6.可行性分析
我找不到了ฅ(꒪˙꒳˙꒪ )ฅ ,不过肯定是可行性更大的doge
7.源代码
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<easyx.h>
#include<stdlib.h>
#include <time.h>
#include <conio.h>
#include <string.h>
#include <graphics.h>
#pragma comment(lib,"winmm.lib")
#pragma comment( lib, "MSIMG32.LIB")
#include <Windows.h> // 引入 Windows API 头文件
#define MAX_PLAYERS 20 // 最大玩家数量typedef struct {int score;
} Player;//玩家结构体Player leaderboard[MAX_PLAYERS];void transparentimage3(IMAGE* dstimg, int x, int y, IMAGE* srcimg);
void transparentimage3(IMAGE* dstimg, int x, int y, IMAGE* srcimg) //新版png
{HDC dstDC = GetImageHDC(dstimg);HDC srcDC = GetImageHDC(srcimg);int w = srcimg->getwidth();int h = srcimg->getheight();BLENDFUNCTION bf = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };AlphaBlend(dstDC, x, y, w, h, srcDC, 0, 0, w, h, bf);
}//输出透明贴图函数
#define MAX 100
IMAGE BOSS;
IMAGE ZHANJI;
IMAGE DIJI;
IMAGE JINGYING;
IMAGE ZIDAN;
IMAGE HEDAN;
IMAGE MYZIDAN;
int count = 0; //得分者的排号
int jiemian_x = 422; //界面宽度
int jiemian_y = 750; //界面长度
const clock_t FPS = 1000 / 60; //每一帧应该花费的时间
int speed = 10; //定义我方战机移动速度
int zidan_w = 25; //定义子弹宽度
int zidan_h = 25; //定义子弹长度
int zidan_sh = 10; //定义子弹伤害
int hedan_sh = 100; //定义核弹伤害
int w = 70; //定义战机宽度
int h = 70; //定义战机高度
int x = 200; //定义战机x坐标
int y = 700; //定义战机y坐标
int hp = 10;
ExMessage msg; //定义消息结构体
typedef struct
{int x;int y;int a; // 是否有出场权int hp; //血量int speed; //速度
}qwe; //定义敌机的参数
typedef struct
{int x;int y;int a;int hp;int speed;
}asd; //定义精英敌机的参数
typedef struct
{int x;int y;int w;int hp;int h;int a;int speed;
}zxc; //定义boss敌机的参数
typedef struct
{int x;int y;int a;int m; //标识符,0代表属于敌方,1代表属于我方
}rty; //定义敌方子弹参数
typedef struct
{int x;int y;int a;
}fgh; //定义核弹参数
zxc boss[10];
rty zidan[MAX];
fgh hedan[MAX];
asd jingying[MAX] = { 0 };
qwe diji[MAX] = { 0 };
int dan_speed;
struct MenuItem
{int x, y, width, height; // 选项的位置和宽、高COLOR16 bgColor; // 选项的背景色char text[100]; // 选项的文本
};void ishit();void win(int score);
void botton(int x, int y, int w, int h);
void menu();
void gameintroduce();
void finish();
bool shifou(int x, int y, int w, int h);
void shubiao(void);
void nomal_botton(int left, int top, int right, int bottom, const char* text);
void Game_Fighter(void); //游戏界面函数
void Game_xunhuan(void); //游戏界面的循环函数
void chushihua_diji(void); //敌机初始化函数
void gengxin_diji(void); //敌机参数更新函数
void chuchangquan_diji(void); //敌机出场权函数
void shifouxiaoshi_diji(void); //敌机是否消失函数
void yidong_zhanji(void); //我方战机移动函数
void chuchangquan_jingying(void);//精英敌机出场权函数
void dayinjiemian(int); //打印界面函数
void hedanchuchangquan(void); //核弹出场权函数
void zidanchuchangquan(void);//子弹出场权函数
void mydanchuchangquan(void); //我方子弹出场权函数
void hetiao(void); //boss横跳函数
void kouxue(void); //扣血机制函数
void suspend(); //暂停界面
int comparePlayers(const void* a, const void* b);
void updateLeaderboard(Player* players, int numPlayers);
void drawLeaderboard();
void Game_xunhuan(void)
{int starttime;int endtime;int k = 1; //计数器int m = 0;//boss技能启动装置while (true){starttime = clock();BeginBatchDraw();dayinjiemian(k);FlushBatchDraw();peekmessage(&msg, EX_KEY);k %= 1800;k++;//printf("%d\n",k);if (k % 600 == 0 && !m) //每隔10秒发动一次boss技能m = 1;if (m){m++;hetiao();if ((m - 1) % ((jiemian_x) / boss[0].speed) == 0)m = 0;}if (k % 5 == 0)//每隔一秒就自动生成一个敌机{mydanchuchangquan();if (k % 30 == 0 && !m) //每隔0.5秒生成一个核弹,同时boss不处于技能中hedanchuchangquan();if (k % 10 == 0 && m) //每隔0.1秒生成一个核弹,boss处于技能中hedanchuchangquan();if (k % 30 == 0)zidanchuchangquan(); //每隔0.5秒生成一个敌方的子弹if (k % 300 == 0) //每隔5秒生成一个精英战机chuchangquan_jingying();if (k % 600 == 0 && diji[0].speed < 3)//到一定速度之后,速度将不再变化{for (int i = 0; i < MAX; i++){diji[i].speed++;jingying[i].speed++;} //每隔10秒敌机速度加一dan_speed++;}if (k % 60 == 0) //每隔一秒生成一个普通敌机chuchangquan_diji();}yidong_zhanji();gengxin_diji();kouxue();shifouxiaoshi_diji();if (hp <= 0){updateLeaderboard(leaderboard + count, MAX_PLAYERS);win(leaderboard[count].score);//drawLeaderboard();count++;}msg.message = 0;endtime = clock();Sleep(FPS - (endtime - starttime));}
}
void kouxue(void)
{int i = 0;int j;for (i = 0; i < MAX; i++){if (i < MAX){if (hedan[i].a){int m_x = (hedan[i].x * 2 + w) / 2;int m_y = hedan[i].y;if (m_x <= x + w && m_x >= x && m_y <= y + h && m_y >= y){hedan[i].a = 0;hp--;}}}if (zidan[i].a){if (zidan[i].m){int m_x = (zidan[i].x * 2 + zidan_w) / 2;int m_y = zidan[i].y;if (m_x >= boss[0].x && m_x <= boss[0].x + boss[0].w && m_y <= boss[0].y + boss[0].h && m_y >= boss[0].y && boss[0].a){zidan[i].a = 0;zidan[i].m = 0;boss[0].hp--;continue;}for (j = 0; j < MAX; j++){if (diji[j].a || jingying[j].a){if (m_x >= diji[j].x && m_x <= diji[j].x + w && m_y <= diji[j].y + h && m_y >= diji[j].y && diji[i].a){zidan[i].a = 0;zidan[i].m = 0;diji[j].hp--;break;}if (m_x >= jingying[j].x && m_x <= jingying[j].x + w && m_y <= jingying[j].y + h && m_y >= jingying[j].y && jingying[i].a){zidan[i].a = 0;zidan[i].m = 0;jingying[j].hp--;break;}}}}if (!zidan[i].m){int m_x = (zidan[i].x * 2 + zidan_w) / 2;int m_y = zidan[i].y;if (m_x <= x + w && m_x > x && m_y <= y + h && m_y >= y){hp--;zidan[i].a = 0;}}}}
}
void mydanchuchangquan(void)
{for (int j = 0; j < MAX; j++){if (!zidan[j].a && !zidan[j].m){zidan[j].a = 1;zidan[j].m = 1;zidan[j].x = x + (w - zidan_w) / 2;zidan[j].y = y;break;}}
}
void hetiao(void)
{if (boss[0].a){boss[0].x += boss[0].speed;boss[0].x %= jiemian_x - boss[0].w;}
}
void hedanchuchangquan(void)
{if (boss[0].a){for (int i = 0; i < MAX; i++){if (!hedan[i].a){hedan[i].x = boss[0].x + (boss[0].w - w) / 2;hedan[i].y = boss[0].y + boss[0].h;hedan[i].a = 1;break;}}}
}
void zidanchuchangquan(void)
{for (int i = 0; i < MAX; i++){if (diji[i].a){for (int j = 0; j < MAX; j++){if (!zidan[j].a){zidan[j].a = 1;zidan[j].x = diji[i].x + (w - zidan_w) / 2;zidan[j].y = diji[i].y + h;break;}}}if (jingying[i].a){for (int j = 0; j < MAX; j++){if (!zidan[j].a){zidan[j].a = 1;zidan[j].x = jingying[i].x + (w - zidan_w) / 2;zidan[j].y = jingying[i].y + h;break;}}}}
}
void dayinjiemian(int k)
{//static int m = 0; //标识符cleardevice();if (k % 1800 == 0 && boss[0].a == 0){transparentimage3(NULL, boss[0].x, boss[0].y, &BOSS);boss[0].a = 1;}//30秒生成一个bossif (boss[0].a){transparentimage3(NULL, boss[0].x, boss[0].y, &BOSS);}transparentimage3(NULL, x, y, &ZHANJI); //打印我方战机for (int i = 0; i < MAX; i++) //打印敌方战机{if (diji[i].a)transparentimage3(NULL, diji[i].x, diji[i].y, &DIJI);if (jingying[i].a)transparentimage3(NULL, jingying[i].x, jingying[i].y, &JINGYING);if (hedan[i].a)transparentimage3(NULL, hedan[i].x, hedan[i].y, &HEDAN);}for (int i = 0; i < MAX; i++){if (zidan[i].a && !zidan[i].m)transparentimage3(NULL, zidan[i].x, zidan[i].y, &ZIDAN);if (zidan[i].a && zidan[i].m)transparentimage3(NULL, zidan[i].x, zidan[i].y, &MYZIDAN);}
}
void chushihua_diji(void) //敌机初始化函数
{int i;srand(time(NULL));for (i = 0; i < MAX; i++){diji[i].x = rand() % (jiemian_x - w);diji[i].y = rand() % (jiemian_y / 4);diji[i].a = 0;diji[i].hp = 1;diji[i].speed = 1;jingying[i].x = rand() % (jiemian_x - w);jingying[i].y = rand() % (jiemian_y / 4);jingying[i].a = 0;jingying[i].hp = 2;jingying[i].speed = 1;hedan[i].a = 0;}for (int i = 0; i < MAX; i++){zidan[i].a = 0;zidan[i].m = 0;}boss[0].x = ((jiemian_x - w) / 2);boss[0].y = (jiemian_y / 5);boss[0].hp = 1000;boss[0].w = 100;boss[0].h = 100;boss[0].a = 0;boss[0].speed = 5;loadimage(&BOSS, "tupian/boss.png", boss[0].w, boss[0].h);loadimage(&ZHANJI, "tupian/zhanji.png", w, h);loadimage(&DIJI, "tupian/diji.png", w, h);loadimage(&JINGYING, "tupian/jingying.png", w, h);dan_speed = 2 * diji[0].speed;loadimage(&ZIDAN, "tupian/zidan.png", zidan_w, zidan_h);loadimage(&HEDAN, "tupian/hedan.png", w, h);loadimage(&MYZIDAN, "tupian/myzidan.png", zidan_w, zidan_h);
}
void Game_Fighter(void) //游戏界面函数
{chushihua_diji();Game_xunhuan();
}void gengxin_diji(void)//敌机参数更新函数
{for (int i = 0; i < MAX; i++){if (diji[i].a)diji[i].y += diji[i].speed;if (jingying[i].a)jingying[i].y += jingying[i].speed;if (hedan[i].a)hedan[i].y += dan_speed;}for (int i = 0; i < MAX; i++){if (zidan[i].a && !zidan[i].m)zidan[i].y += dan_speed;if (zidan[i].a && zidan[i].m)zidan[i].y -= (dan_speed + 2);}
}void chuchangquan_diji(void)//敌机出场权函数
{for (int i = 0; i < MAX; i++){if (!diji[i].a){diji[i].a = 1;break;}}
}void chuchangquan_jingying(void)//精英敌机出场权函数
{for (int i = 0; i < MAX; i++){if (!jingying[i].a){jingying[i].a = 1;break;}}
}void shifouxiaoshi_diji(void)//敌机是否消失函数
{if (boss[0].hp <= 0){boss[0].a = 0;boss[0].hp = 1000;leaderboard[count].score += 10;}for (int i = 0; i < MAX; i++){if (diji[i].a){if (diji[i].y + h >= jiemian_y || diji[i].hp <= 0){if (diji[i].hp <= 0)leaderboard[count].score++;diji[i].a = 0;diji[i].x = rand() % (jiemian_x - w);diji[i].y = rand() % (jiemian_y / 4);diji[i].hp = 1;}}if (jingying[i].a){if (jingying[i].y + h >= jiemian_y || jingying[i].hp <= 0){if (jingying[i].hp <= 0)leaderboard[count].score++;jingying[i].a = 0;jingying[i].x = rand() % (jiemian_x - w);jingying[i].y = rand() % (jiemian_y / 4);jingying[i].hp = 2;}}if (hedan[i].a){if (hedan[i].y + h >= jiemian_y){hedan[i].a = 0;}}}for (int i = 0; i < MAX; i++){if (zidan[i].a && !zidan[i].m){if (zidan[i].y + zidan_h >= jiemian_y){zidan[i].a = 0;}}if (zidan[i].a && zidan[i].m){if (zidan[i].y <= 0){zidan[i].a = 0;zidan[i].m = 0;}}}
}void yidong_zhanji(void)//我方战机移动函数
{if (msg.message == WM_KEYDOWN){switch (msg.vkcode){case 'W':if (y - speed >= 0)y -= speed;break;case 'S':if (y + h + speed <= jiemian_y)y += speed;break;case 'A':if (x - speed >= 0)x -= speed;break;case 'D':if (x + w + speed <= jiemian_x)x += speed;break;case VK_ESCAPE: //按下esc键时暂停suspend();}}
}void suspend() {//initgraph(422, 750); // 初始化窗口大小为422*750setbkcolor(WHITE); // 设置背景// 设置字体颜色为蓝色settextcolor(BLUE);while (true){BeginBatchDraw();cleardevice(); // 清屏// 绘制暂停界面文字settextstyle(30, 0, _T("宋体"));outtextxy(130, 200, _T("游戏已暂停"));settextstyle(20, 0, _T("宋体"));outtextxy(150, 300, _T("按空格键继续"));FlushBatchDraw();msg.message = 0;peekmessage(&msg, EX_KEY);if (msg.vkcode == VK_SPACE)Game_xunhuan();}// 用sleep暂停等待空格键按下//while (!GetAsyncKeyState(VK_SPACE)) { //当空格键未按下时// Sleep(100); // 持续等待100毫秒//}//按下空格键后会跳出等待循环,接着进入游戏就好//closegraph(); // 关闭图形窗口}
void ishit() {while (true){if (peekmessage(&msg, EX_MOUSE)){if (msg.message == WM_LBUTTONDOWN && shifou(100, 300, 233, 40)) //诺鼠标在对应矩形内且按下左键的话,将要跳转当相应界面{drawLeaderboard();//跳转排行榜页面break;}if (msg.message == WM_LBUTTONDOWN && shifou(100, 400, 233, 40)) //诺鼠标在对应矩形内且按下左键的话,将要跳转当相应界面{menu();break;}}}
}void win(int score) {cleardevice();IMAGE background;loadimage(&background, "./menu1.jpg", 0, 0);putimage(0, 0, &background);settextstyle(35, 20, "微软雅黑");outtextxy(130, 100, "游戏胜利");botton(100, 200, 233, 40);outtextxy(100, 200, "当前得分:");//显示得分//nomal_botton(100, 300, 333, 340, "排行榜");botton(100, 400, 233, 40);nomal_botton(100, 400, 333, 440, "返回菜单");FlushBatchDraw();ishit();
}int comparePlayers(const void* a, const void* b) {return ((Player*)b)->score - ((Player*)a)->score;
}void updateLeaderboard(Player* players, int numPlayers) {// 复制玩家数据到排行榜数组memcpy(leaderboard, players, numPlayers * sizeof(Player));// 排序排行榜qsort(leaderboard, numPlayers, sizeof(Player), comparePlayers);
}void drawLeaderboard() {// 初始化图形窗口大小settextstyle(20, 0, _T("宋体")); // 设置字体样式setbkmode(TRANSPARENT); // 设置背景透明// 绘制标题outtext(_T("飞机大战排行榜"));// 绘制排行榜内容char buffer[50];for (int i = 0; i < MAX_PLAYERS; i++) {sprintf_s(buffer, sizeof(buffer), "%d. Score: %d", i + 1, leaderboard[i].score);outtextxy(100, 50 + i * 30, buffer);}// 等待用户点击关闭按钮while (!GetAsyncKeyState(VK_ESCAPE)) {Sleep(100);}}void botton(int x, int y, int w, int h)
{setlinecolor(BLACK);setfillcolor(RGB(195, 201, 201));fillroundrect(x, y, x + w, y + h, 5, 5);
}void menu()
{IMAGE img_mm;loadimage(&img_mm, "./menu1.jpg");putimage(0, 0, &img_mm);HWND startwindow = GetHWnd();//获取窗口句柄SetWindowText(startwindow, "飞机大战");//设置窗口标题BeginBatchDraw();botton(100, 100, 233, 40);//第一个按钮nomal_botton(100, 100, 333, 140, "开始游戏");botton(100, 200, 233, 40);//第二个按钮nomal_botton(100, 200, 333, 240, "排行榜");botton(100, 300, 233, 40);//第三个按钮nomal_botton(100, 300, 333, 340, "游戏介绍");删除以下按钮部分 botton(100, 400, 233, 40);nomal_botton(100, 400, 333, 440, "退出游戏");FlushBatchDraw();shubiao();
}
void gameintroduce()
{cleardevice();IMAGE background;loadimage(&background, "./menu1.jpg");putimage(0, 0, &background);outtextxy(140, 20, "游戏简介");settextstyle(20, 0, "宋文");outtextxy(0, 60, "飞机大战游戏是以太空主题的画面为游戏背景。");outtextxy(0, 80, "拟三体世界观的设定,是一个简洁流畅,游戏方式");outtextxy(0, 100, "式简单的小游戏,由玩家通过鼠标控制我方战机");outtextxy(0, 120, "通过鼠标控制我方战机向三体文明发动进攻。战");outtextxy(0, 140, "战机初始有一定量的血量,屏幕上随机产生敌机,");outtextxy(0, 160, "战机产生的数量和当前关卡难度有关,关卡越难");outtextxy(0, 180, "产生的敌机越多,游戏难度越大,玩家可通过氪");outtextxy(0, 200, "金降低游戏难度。游戏过程中玩家需要操作战机");outtextxy(0, 220, "躲避敌方子弹,战机可拾取装备提升战力。我方战机与敌机只要");outtextxy(0, 240, "中弹都会减血,直至血槽为空,战机爆炸,关卡");outtextxy(0, 260, "内所有敌机爆炸后通关,全部关卡通过后游戏结");outtextxy(0, 280, "束。");BeginBatchDraw();botton(230, 700, 180, 40);nomal_botton(230, 700, 410, 740, "返回菜单");FlushBatchDraw();while (1){if (peekmessage(&msg, EX_MOUSE)){if (msg.message == WM_LBUTTONDOWN && shifou(230, 700, 180, 40)) //诺鼠标在对应矩形内且按下左键的话,将要跳转当相应界面{menu();break;}}}
}
void finish()
{exit(0);
}bool shifou(int x, int y, int w, int h)
{if (msg.x >= x && msg.x <= x + w && msg.y >= y && msg.y <= y + h)return true;return false;
}void nomal_botton(int left, int top, int right, int bottom, const char* text)//正常状态按钮
{setbkmode(TRANSPARENT);//设置字体背景透明char lingshi_text[50] = { 0 };//按钮内容strcpy(lingshi_text, text);//获取内容settextstyle(35, 20, "微软雅黑");//设置字体settextcolor(BLACK);int text_x = left + (right - left - textwidth(lingshi_text)) / 2;//内容横坐标int text_y = top + (bottom - top - textheight(lingshi_text)) / 2;//内容纵坐标outtextxy(text_x, text_y, lingshi_text);
}void shubiao(void)
{while (true){//存放矩形相关参数if (peekmessage(&msg, EX_MOUSE)){if (msg.message == WM_LBUTTONDOWN && shifou(100, 100, 233, 40)) //诺鼠标在对应矩形内且按下左键的话,将要跳转当相应界面{Game_Fighter(); //关卡选择界面break;}if (msg.message == WM_LBUTTONDOWN && shifou(100, 200, 233, 40)) //诺鼠标在对应矩形内且按下左键的话,将要跳转当相应界面{drawLeaderboard();break;}if (msg.message == WM_LBUTTONDOWN && shifou(100, 300, 233, 40)) //诺鼠标在对应矩形内且按下左键的话,将要跳转当相应界面{gameintroduce();break;}if (msg.message == WM_LBUTTONDOWN && shifou(100, 400, 233, 40)) //诺鼠标在对应矩形内且按下左键的话,将要跳转当相应界面{finish();break;}}}
}int main()
{initgraph(422, 750, EX_SHOWCONSOLE);//400x600setbkcolor(WHITE);cleardevice();mciSendString("open ./background.WMA alias BGM", 0, 0, 0);mciSendString("play BGM repeat", 0, 0, 0);menu();getchar();closegraph();return 0;
}
//1.定义我方战机参数 hao
//2.用一个结构体来表示敌方战机参数 hao
//3.用结构体数组表示多个战机 hao
//4.用循环来同时打印多个地方战机 hao
//5.用随机函数来生成敌方战机的坐标 hao
//6.用取模函数来规范坐标范围 hao
//7.用更新函数更新敌方战机坐标hao
//8.按照一定频率来生成敌方战机 hao
//9.初始化敌方战机参数函数 hao
//10.给予敌方战机出场权 hao
//11.判断战机是否消失 hao
//12.敌方战机随着时间的增加,速度变得越来越快 hao
//13.隔比较长的时间会生成精英怪 hao
//14.再隔比较长的时间会生成boss,boss不会移动 hao
//15.定义子弹核弹的参数 hao
//16.子弹核弹的出场权函数 hao
//17.子弹核弹的更新函数 hao
//18.子弹核弹的消失函数 hao
//23.子弹核弹打印函数 hao
//19.boss隔一段时间会反复横跳 hao
//20.扣血机制 hao
//22.boss每隔一段时间五连发子弹
//23.飞机不能移动出界面外面 hao
//24.降低核弹的速度 降低子弹的速度 hao
// boss横跳技能时,攻击速度加快
//25.随着时间增加 血量增加 速度增加 boss数量增加
/*战机函数:打印战机:我方:按血量打印(完美/微瑕/战损/gg)敌方:按不同敌机类型打印(小怪/精英怪/boos)战机参数:血条,移速,攻速,攻击力,攻击类型移动方式:我方:使用wsad自由移动敌方:顶部有规律随机生成(按时间/游戏进程/击杀小怪数量/……),随敌机类型顶部生成后规律移动(缓慢直线下降/缓慢直线追踪下降/缓慢左右移动/……)*/
8.实战效果 
9.心得
相较于第一次项目项目实战-贪吃蛇大作战【补档】-CSDN博客,大一做第二次项目的我已经能够更加自如地和组员们进行交流协作,也再次感受到了沟通的魅力,最后还是想引用第一次项目的心得来结束:人生每个阶段都有各个阶段你会遇到的人,重要的是一起变得更好,一起向远方
(10.AI测评)
---
### **1. 项目结构**
- **头文件和库依赖**:
- 包含了 `easyx.h`、`Windows.h` 等头文件,使用了 EasyX 图形库进行图形绘制。
- 使用了 `mciSendString` 播放背景音乐。
- 通过 `#pragma comment` 链接了 `winmm.lib` 和 `MSIMG32.LIB`。
- **宏定义**:
- 定义了多个常量,如 `MAX_PLAYERS`(最大玩家数)、`MAX`(最大敌机数)、`FPS`(帧率控制)等。
- 使用了 `_CRT_SECURE_NO_WARNINGS` 禁用安全警告。
- **数据结构**:
- 定义了多个结构体(如 `Player`、`qwe`、`asd`、`zxc` 等)来表示玩家、敌机、子弹、核弹等游戏元素的参数。
---
### **2. 核心功能**
#### **2.1 游戏主循环**
- **`Game_xunhuan` 函数**:
- 控制游戏的主循环,包括帧率控制、敌机生成、子弹发射、碰撞检测等。
- 使用 `clock()` 和 `Sleep()` 实现帧率限制。
#### **2.2 游戏初始化**
- **`chushihua_diji` 函数**:
- 初始化敌机、精英敌机、核弹、子弹等参数。
- 使用 `rand()` 随机生成敌机的初始位置。
#### **2.3 界面绘制**
- **`dayinjiemian` 函数**:
- 绘制游戏界面,包括玩家战机、敌机、子弹、核弹等。
- 使用 `transparentimage3` 实现透明图像绘制。
#### **2.4 玩家操作**
- **`yidong_zhanji` 函数**:
- 通过键盘输入(`WASD`)控制玩家战机的移动。
- 按下 `ESC` 键时调用 `suspend` 函数暂停游戏。
#### **2.5 碰撞检测**
- **`kouxue` 函数**:
- 检测子弹、核弹与玩家战机、敌机、BOSS 的碰撞。
- 根据碰撞结果更新血量和状态。
#### **2.6 排行榜**
- **`updateLeaderboard` 和 `drawLeaderboard` 函数**:
- 使用 `qsort` 对玩家分数进行排序。
- 绘制排行榜界面。
#### **2.7 菜单和其他界面**
- **`menu` 函数**:
- 绘制主菜单,提供开始游戏、查看排行榜、游戏介绍、开发人员信息等选项。
- **`gameintroduce` 和 `Developer` 函数**:
- 分别显示游戏介绍和开发人员信息。
---
### **3. 优点**
1. **功能完整**:
- 包括游戏主循环、敌机生成、子弹发射、碰撞检测、排行榜等核心功能。
- 提供了暂停、菜单、排行榜等辅助功能。
2. **模块化设计**:
- 使用了多个函数和结构体,便于代码的维护和扩展。
3. **图形效果**:
- 使用 EasyX 图形库实现了透明图像绘制和界面美化。
4. **游戏逻辑清晰**:
- 通过计数器和时间控制实现了敌机生成、BOSS 技能等逻辑。
相关文章:
项目实战-飞机大战【补档】
和项目实战-贪吃蛇大作战【补档】-CSDN博客一样,这也是一个我在大一和网友完成的项目的补档。Dont waste your youth—time flies. 目录 1.工具&环境 2.项目简介 3.需求文档 4.流程图 5.产品原型图 6.可行性分析 7.源代码 8.实战效果 编辑 9.心得…...
算法基础学习|02归并排序——分治
一、思路 (1)确定分界点:mid(lr)/2 ——这里和快排不同 (2)递归排序(left right) (3)归并——合二为一 时间复杂度nlogn 二、题目练习 三、模板 归并排序 …...
测试基础笔记第十六天
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、UI自动化介绍1.认识UI自动化测试2.实施UI自动化测试前置条件3.UI自动化测试执行时机4.UI自动化测试核心作用和劣势 二、认识Web自动化测试工具-Selenium021.Sel…...
Android项目中使用ComposeUI
首先确认项目环境kotlin版本,以下是本机的版本 使用命令 ./gradlew -version 这里kotlin 版本是1.5.31 然后查看build.gradle sdk版本 这里是32 属于低版本 然后需要添加以下配置 buildFeatures {compose true}composeOptions {kotlinCompilerExtensionVersio…...
springboot中有关数据库信息转换的处理
现代项目一般都是前后端分离的,前端只负责展示数据,不负责对数据处理,所以所有数据处理工作都由后端进行 比如在仿京东中的status,审核信息展示,数据库中是以0/1显示,但是前端需要以"审核/未审核&quo…...
HHsuite同源序列搜索数据库构建
HHsuite 可用的数据库格式简介 HHsuite 是用于蛋白质序列比对和同源性检测的工具套件,它使用特定的数据库格式以实现高效的数据存储和快速的检索。HHsuite 常用的数据库格式主要基于 FFINDEX(Flat-File Index),这是一种简单而高效的文件索引系统,它将数据文件(如蛋白质序…...
大模型推理:Qwen3 32B vLLM Docker本地部署
Qwen3基础知识 此次Qwen3开源8个模型(MOE架构:Qwen3-235B-A22B、Qwen3-30B-A3B,Dense架构:Qwen3 0.6B/1.7B/4B/8B/14B/32B),新版本的Qwen3特性包括: 支持混合思维模式,即推理/非推…...
第十六届蓝桥杯 2025 C/C++B组 第二轮省赛 全部题解(未完结)
目录 前言: 试题A:密密摆放 试题B:脉冲强度之和 试题C:25之和 试题D:旗帜 试题H:破解信息 前言: 这是我后续刷到的第二轮省赛的题目,我自己也做了一下,和第一轮省赛…...
域名转移:什么是转移码/EPP码/授权码?
关于Dynadot Dynadot是通过ICANN认证的域名注册商,自2002年成立以来,服务于全球108个国家和地区的客户,为数以万计的客户提供简洁,优惠,安全的域名注册以及管理服务。 Dynadot平台操作教程索引(包括域名邮…...
Android 系统发展史
Android 1.0:2008年9月 全球第一台安卓设备是 HTC Dream Google地图、YouTube、HTML浏览器、Gmail、即使消息、短信、彩信、日历等 Android Market(应用程序商店) Android 1.1:2009年2月(Petit Four 花色小蛋糕&am…...
Python中的defaultdict方法
文章目录 核心特点基本语法常见使用场景1. 分组数据(默认值为列表)2. 计数(默认值为整数)3. 集合操作(默认值为集合)4. 嵌套字典 注意事项与普通字典对比总结1. 键(Key)的类型2. 值&…...
Android启动应用时屏蔽RecyclerView滑动,延时后再允许滑动,Kotlin
Android启动应用时屏蔽RecyclerView滑动,延时后再允许滑动,Kotlin var bCanScrollVertically falselifecycleScope.launch(Dispatchers.Default) {repeatOnLifecycle(Lifecycle.State.CREATED) {Log.d(TAG, "Lifecycle.State.CREATED")delay(…...
2025运维工程师面试题1(答案在后一张)
一、逻辑思维能力考核: 问题1: 3个人去投宿,一晚30元三个人每人掏了10元凑够30元交给了老板后来老板说今天优惠只要25元就够了,拿出5元命令服务生退还给他们,服务生偷偷藏起了2元,然后,把剩下…...
在网页中使用【LaTeX 数学公式块】的完整步骤总结
以下是在网页中使用 LaTeX 数学公式块的完整步骤总结,记录如何让网页正确渲染 LaTeX 数学表达式(如 \(H(X) -\sum p(x) \log p(x)\) 这样的公式): ✅ 使用 LaTeX 数学公式块的完整步骤(以 KaTeX 为例) &am…...
新人销售如何找精准客户?
深入了解自身产品或服务。 清晰掌握产品优势、应用场景和解决的问题,比如销售办公软件,要熟知其提升办公效率的具体功能,以此定位需求客户。 利用社交媒体平台。 像领英可完善资料,加入行业群组分享内容吸引潜在客户࿱…...
【Unity】使用Socket建立客户端和服务端并进行通信的例子
Socket服务端: using System; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; public class SocketServer { public static Socket listenSocket;//监听Socket public static List<Socket>…...
为什么要学习《易经》?
《易经》精华解读:变易之道与人生智慧 《易经》(《周易》)是中国最古老的经典之一,被誉为“群经之首,大道之源”。它不仅是占卜之书,更是一部哲学经典,揭示了宇宙运行的规律和人生处世的智慧。…...
13.继承、重载、重写、多态、抽象类、接口、final、Static的学习
一、继承 继承:你继承谁你就是谁,继承是一种严格的父子关系 (在父类里面抽取的属性和方法一定是所有子类所共有) (Student继承Person,那么Student就是人) UML: 类图(描述类和类之间的…...
SpringBoot Actuator未授权访问漏洞的全面解析与解决方案
引言 SpringBoot Actuator 作为应用监控与管理的核心组件,为开发者提供了丰富的系统自省和运维能力。然而,其默认配置中可能存在的未授权访问漏洞,已成为企业安全防护的潜在风险。本文将从漏洞原理、影响范围、检测方法到解决方案,系统性地剖析该问题,并提供覆盖开发、运维…...
使用C# ASP.NET创建一个可以由服务端推送信息至客户端的WEB应用(1)
背景 用户在WEB页面上点击按钮,服务端需要执行一系列操作,该操作系列步骤较多且耗时长,为了更好的给用户浏览体验,需要在每进行一个步骤由服务端推送消息给客户端(浏览器),避免一个长时间的操作…...
一网统管建设组织保障分工常见表
在 “一网统管” 建设进程中,强有力的组织保障体系与各业务部门间的紧密分工协作是确保建设成效的关键。 从组织保障层面来看,需建立专门的 “一网统管” 建设领导小组,由政府高层领导担任组长,各关键业务部门负责人作为组员,以此强化对整体建设工作的统筹规划与组…...
JVM | CMS垃圾收集器详解
目录 CMS垃圾回收器简介 为什么CMS图中初始标记的阶段是单线程?为啥不多线程?当然现在默认多线程了。 CMS的两种模式与一种特殊策略 Backgroud CMS 记忆集 卡表 ForeGroud CMS CMS的标记压缩算法 三色标记 (便于理解而被后人提出&am…...
android开发中的多线程、数据存储同步功能实现方案和应用场景
在Android开发中,多线程、数据存储与同步功能有多种实现方案,以下是详细介绍及其应用场景: 多线程 实现方案: Thread类与Runnable接口:通过继承Thread类并重写run方法,或实现Runnable接口并将其传入Threa…...
【C++初阶】--- 模板进阶
1.非类型模板参数 • 模板参数分类类型形参与非类型形参。 • 类型形参即:出现在模板参数列表中,跟在class或者typename之类的参数类型名称。 • 非类型形参,就是用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参…...
数据库所有知识
# 第一章 数据库-理论基础 ## 1.1 什么是数据库 数据: 描述事物的符号记录, 可以是数字、 文字、图形、图像、声音、语言等,数据有多种形式,它们都可以经过数字化后存入计算机。 数据库: 存储数据的仓库,…...
docker部署的Nextcloud,处于维护模式,如何解决
Nextcloud 在升级后卡在维护模式,以下是针对 Docker 部署的解决方案: 1. 通过 OCC 命令强制关闭维护模式 进入 Nextcloud 容器内部执行命令: # 替换 nextcloud 为你的容器名称 docker exec -it --user www-data nextcloud php occ maintena…...
mongoose插入文档,字段类型, 字段验证, 删除文档,更新文档,读取文档,查询文档的条件控制 ,字段筛选,数据排序,数据截取
、Mongoose 中与 文档操作(插入、查询、更新、删除)及其相关功能(字段类型、验证、条件筛选、排序、分页等)相关示例: 📋 一、字段类型定义(Schema Types) const mongoose require…...
源码编译安装LAMP
一:LAMP概述 LAMP架构是目前成熟的企业网站应用模式之一,指的是协同工作的一整套系统和相关软件,能够提供动态Web站点服务及其应用开发环境。LAMP是一个缩写词,具体包括Linux操作系统、Apache网站服务器、MySQL数据库服务器、PHP…...
C++每日训练 Day 18:构建响应式表单与数据验证(初学者友好)
📘 本篇目标:在前几日协程与事件驱动机制基础上,构建一个响应式表单系统,实现用户输入的异步验证与反馈。通过协程挂起/恢复机制,简化异步逻辑,提升代码可读性。 🔁 回顾 Day 17:响应…...
Linux环境变量以及进程虚拟地址原理
目录 一、介绍进程优先级 1.什么是优先级 2.为什么会有优先级 3.Linux中的优先级是怎么确定的 1)查看Linux中的优先级 2)计算优先级和更改优先级 二、环境变量 1.什么是环境变量 2.环境变量有什么作用 3.环境变量怎么做到的 1)查看系统已有的…...
基于非递归求解的汉诺塔超级计算机堆栈与数据区设计方案
基于非递归求解的汉诺塔超级计算机堆栈与数据区设计方案 一、设计背景与目标 汉诺塔问题存在非递归直接求解方法,相较于递归法具有明确移动规律和潜在性能优势。本设计旨在利用非递归求解规律,优化汉诺塔超级计算机的堆栈与数据区结构,降低…...
【Linux应用】在PC的Linux环境下通过chroot运行ARM虚拟机镜像img文件(需要依赖qemu-aarch64、不需要重新安装iso)
【Linux应用】在PC的Linux环境下通过chroot运行ARM虚拟机镜像img文件(需要依赖qemu-aarch64、不需要重新安装iso) qemu提供了运行ARM虚拟机的方法 具体的操作方式就是建立一个硬盘img 然后通过iso安装到img 最后再运行img即可 这种方式教程很多 很简单 …...
CISC与RISC详解:定义、区别及典型处理器
一、CISC(复杂指令集计算机) Complex Instruction Set Computer 核心思想:通过设计复杂的指令,减少程序指令数量,以硬件复杂度换取编程便利性。 主要特点: 指令复杂度高: 单条指令可完成多步操…...
数据库中DDL、DML、DCL的区别是什么?
数据库中DDL、DML、DCL的区别是什么? 在数据库的使用过程中,SQL(结构化查询语言)常常被用来执行不同的操作,主要分为三类:DDL(数据定义语言)、DML(数据操纵语言…...
【东枫电子】AI-RAN:人工智能 - 无线接入网络
太原市东枫电子科技有限公司,翻译 文章目录 1.概述1.1 什么是AI-RAN?1.2 为什么是AI-RAN?1.3 AI-RAN有哪些好处?1.4 为什么 AI-RAN 会给通信服务提供商 (CoSP) 带来变革?1.5 AIRAN 的构建模块是什么? 2. 参…...
实习技能记录【5】-----项目中消息传递到ui层的方法
代码 while (1){osEvent evt;evt osMailGet(ui_msg_mailbox, 0);if (evt.status osEventMail){UI_MSG_APP_T *msg (UI_MSG_APP_T *)evt.value.p;if (msg->cmd_type CMD_TYPE_INNER){if (msg->cmd_code CMD_CODE_INNER_REFRESH_NOW){lv_obj_invalidate(lv_scr_act()…...
4.29【Q】paraCompute
还是同样的要求,我要写实验报告,如何组织描述运行时间,加速比,效率等随数据规模,进程数,线程数变化的语言和逻辑,从而显得不冗余和精简?为我生成合理排版,布局的文字&…...
什么是布林带?
什么是布林带? 布林带是约翰布林格在20世纪80年代开发的一种广泛使用的技术分析工具。布林带由价格图表上的三条线组成:中轨、上轨和下轨。中轨通常是20天简单移动平均线(SMA),代表资产在此期间的平均价格。上轨和下轨…...
爬虫学习笔记(四)---request入门
例1 例1:写一个爬取百度搜索页面的程序,以搜索一个喜欢的明星为例(如在搜索框中输入周杰伦) 正常搜索 页面 爬虫思路: 1.用一个query变量,在控制台输入的方式更加灵活的输入想爬取的明星的百度搜索页面 …...
JSON配置文件格式全解析与多语言实战指南
JSON配置文件格式全解析与多语言实战指南 摘要 本文全面解析JSON配置文件的核心语法规范,深入探讨数据类型、转义机制及JSON5扩展特性,提供JavaScript/Python/Java等多语言解析方案。通过典型应用场景案例演示JSON的最佳实践,帮助开发者高效…...
JavaScript 中的类型转换机制?
一、类型转换的两种模式 1. 显式转换(手动翻译) 你主动告诉 JavaScript 如何转换类型,比如: let num Number("123"); // 字符串 → 数字:123 let str String(123); // 数字 → 字符串:&qu…...
【分享】音频音乐剪辑[特殊字符]人声分离伴奏提取[特殊字符]拼接合并
音频音乐剪辑是一款专业的剪辑软件。在剪辑过程中,它可以对音频进行拼接合成、音乐裁剪、变调变速、格式转换,同时音频音乐剪辑还是一款支持高清录音、音频降噪等众多功能于一体的音频制作软件。 【应用名称】:音频剪辑 【应用版本】…...
关于 const a 定义的数据 与 其渲染 的问题。即通过const定义的常量,会不会导致渲染不及时。
情况1 (同2、4结论一致) 定义:使用子hook,将数据 const a 【对stateX的一系列操作】 封存到子hook里。并return出去。结果:此种情况不影响实时渲染。缺点:只要stateX变更,一定展示c的最新数据…...
开源Kotlin从零单排0基础完美入门教程
🚀 Kotlin 从零单排 一个让你欲罢不能的 Kotlin 入门教程! 教程仓库地址 👋 Hey,你好啊! 如果你: 🤔 听说 Kotlin 很香,但不知道香在哪?😅 Java 写得头大&a…...
主流微前端框架比较
主流微前端框架比较 以下表格列出了当前主流微前端框架的核心对比信息,包括基本介绍、核心特性、适用场景、技术栈兼容性、优缺点、社区维护情况和典型应用案例等: 框架基本介绍核心特性与机制适用场景技术栈兼容性优缺点社区维护情况典型应用案例qiankun蚂蚁金服推出的生产…...
DOM 事件的处理通常分为三个阶段:捕获、目标、冒泡【前端示例】
如果神明还不帮你,说明他相信你。 目录 引言:捕获阶段:目标阶段:冒泡阶段:事件传播示意图:示例:代码:解读:输出: 引言: DOM 事件的处理通常分为三…...
C#实现对达索(Dassault)SolidWorks中3D图纸转化为手机可直接查看预览图纸格式
转化环境无需安装SolidWorks。 代码更新:暂不公开。 实现效果:...
Twitter 工作原理|架构解析|社交APP逻辑
这是对Twitter 工作原理|架构解析|社交APP逻辑_哔哩哔哩_bilibili的学习,感谢up小凡生一 在两年半前,埃隆马斯克收购了Twitter,并且进行了一系列重大改革。今天我们来解析一下这个全球知名社交平台的架构。首先&#x…...
模拟集成电路设计与仿真 : Feedback System
前情提要 此為作者針對迴授系統,進行資料統整,以便日後查詢 原理 1. The Whole System 更正 : V - V feedback 是 並 - 串 迴授 2. Feedback Block Beta 更正 : ,所以 the whole systemfeedback block左 2右 1 feedback block feed…...
Linux权限管理进阶:文件归属、特殊权限与ACL详解
一、文件归属管理:chown命令 1. 基础语法与作用 chown 命令用于修改文件或目录的 属主(Owner) 和 属组(Group),是Linux权限管理中调整资源归属的核心工具。 chown [选项] 新属主:新属组 文件/目录 常用…...