C++实现雷霆战机可视化小游戏

用C++和easyx实现简单的雷霆战机小游戏

之前在网上看了许多关于c++或者是其他语言实现雷霆战机的帖子,大多不完整,或者是要付费才能阅读,现将源码展示如下,仅作学习交流之用。

基本原理

基本思路

代码如下

注意:运行代码所需环境为c++11或更高,代码中所涉及的图片、背景音乐等素材均需自行搜集并修改代码中的文件路径。

代码如有任何问题请在评论区指正,谢谢!

觉得帮到您了的话,可以考虑一下打赏博主呦,您的支持是我创作的最大动力!!!

/*seeting.h*/#pragma oncevoid set_textstyle(LOGFONT& f, int high, int wei); //设置输出文字形式void load_be_bk();      //加载初始背景void help();        //帮助界面void decorete(int x);      //初始界面装饰void home(int i);        //初始界面bool exit();        //退出游戏/*seeting.cpp*/#include <graphics.h>#include <conio.h>#include <ctime>#include <string.h>#include "setting.h"IMAGE be_bk01, be_bk02;static int i = 0; //装饰时计数void set_textstyle(LOGFONT& f, int high, int wei){ gettextstyle(&f);  // 获取当前字体设置 f.lfHeight = high;  // 设置字体高度为 48 f.lfWeight = wei; _tcscpy_s(f.lfFaceName, _T("宋体")); // 设置字体 f.lfQuality = ANTIALIASED_QUALITY; // 设置输出效果为抗锯齿 }void decorate(int x) //装饰{ if ((x/10) % 2 == 0) { setlinecolor(RGB(255, 250, 250)); line(202, 662, 71, 549); line(1157, 403, 1117, 259);  setlinecolor(RGB(0, 238, 0)); line(1004, 413, 1157, 403); line(1188, 504, 1020, 534); line(228, 388, 202, 131); setlinecolor(RGB(255, 69, 0)); line(202, 131, 404, 261); line(471, 493, 228, 388); line(1020, 534, 1307, 563); setlinecolor(RGB(0, 245, 255)); line(1303, 291, 1034, 332); line(66, 373, 437, 600); setlinecolor(RGB(191, 62, 255)); line(1178, 666, 1287, 616); line(404, 261, 202, 131); } else { setlinecolor(RGB(255, 218, 185)); line(1501, 155, 23, 213); line(437, 600, 471, 493); line(1287, 616, 1034, 644); setlinecolor(RGB(84, 255, 159)); line(348, 315, 103, 263); line(269, 606, 39, 697); line(1094, 462, 1004, 413); setlinecolor(RGB(30, 144, 255)); line(71, 549, 269, 606); line(103, 263, 66, 373); line(1307, 563, 1303, 291); setlinecolor(RGB(255, 255, 0)); line(1034, 640, 1188, 504); line(1034, 332, 985, 254); line(39, 697, 348, 315); setlinecolor(RGB(255, 0, 255)); line(1117, 259, 942, 593); line(942, 593, 1178, 666); line(985, 254, 1292, 105); } setlinecolor(RGB(255, 255, 255));}void load_be_bk() //加载帮助界面背景{ loadimage(&be_bk01, L"image\\be_bk01.jpg", 1360, 760); putimage(0, 0, &be_bk01);}void help() //帮助界面{ while (1) { BeginBatchDraw(); load_be_bk(); decorate(i); roundrect(526, 126, 834, 634, 30, 30); roundrect(528, 128, 832, 632, 30, 30); roundrect(530, 130, 830, 630, 30, 30); LOGFONT f; set_textstyle(f, 30, 5); settextstyle(&f);  // 设置字体样式 outtextxy(595, 170, _T("游 戏 须 知")); line(550, 220, 810, 220); set_textstyle(f, 20, 3); settextstyle(&f); outtextxy(555, 240, _T("① 按下 w a s d 移动飞机。")); outtextxy(555, 280, _T("② 按下 空格 发射子弹。")); outtextxy(555, 320, _T("③ 游戏中按 ESC 暂停。")); outtextxy(555, 360, _T("④ 每撞机一次,生命值减少20,")); outtextxy(555, 400, _T(" 通过本关,生命值恢复。")); set_textstyle(f, 15, 2); settextstyle(&f); outtextxy(625, 525, _T("按任意键返回")); line(550, 550, 810, 550); outtextxy(605, 570, _T("制作不易,请勿抄袭")); outtextxy(605, 600, _T("    ——木笔制作")); i++; EndBatchDraw(); Sleep(10); if (_kbhit()) { _getch(); break; } }}void home(int i) //初始界面{ BeginBatchDraw(); loadimage(&be_bk02, L"image\\be_bk02.jpg", 1360, 760); putimage(0, 0, &be_bk02); int m = 465, n = 515; //输出框上下边界 for (int t = 0; t < 4; t++) { for (int j = 0; j < 4; j++) { roundrect(1110 + j, m + j, 1300 - j, n - j, 30, 30); } m += 65; n += 65; } switch (i) { case 1: for (int j = 0; j < 30; j++) { setlinecolor(RGB(0+j*5, 255 - j * 4, 217 - j * 5)); line(1120, 475 + j, 1290, 475 + j); } break; case 2: for (int j = 0; j < 30; j++) { setlinecolor(RGB(0 + j * 5, 255 - j * 4, 217 - j * 5)); line(1120, 540 + j, 1290, 540 + j); } break; case 3: for (int j = 0; j < 30; j++) { setlinecolor(RGB(0 + j * 5, 255 - j * 4, 217 - j * 5)); line(1120, 605 + j, 1290, 605 + j); } break; case 4: for (int j = 0; j < 30; j++) { setlinecolor(RGB(0 + j * 5, 255 - j * 4, 217 - j * 5)); line(1120, 670 + j, 1290, 670 + j); } break; } setlinecolor(RGB(152, 245, 255)); LOGFONT f; gettextstyle(&f); f.lfHeight = 30; f.lfWeight = 7; _tcscpy_s(f.lfFaceName, _T("隶书"));  f.lfQuality = ANTIALIASED_QUALITY; settextstyle(&f); setbkmode(TRANSPARENT); //透明字体背景 settextcolor(RGB(255, 0, 0)); outtextxy(1125, 475, _T("简单模式(1)")); outtextxy(1125, 540, _T("困难模式(2)")); outtextxy(1125, 605, _T(" 帮 助 (3) ")); outtextxy(1125, 670, _T(" 退 出 (4) ")); f.lfHeight = 70; f.lfWeight = 30; _tcscpy_s(f.lfFaceName, _T("方正舒体")); settextstyle(&f); for (int j = 0; j < 5; j++) roundrect(950+j, 280+j, 1300-j, 410-j, 50, 50); settextcolor(RGB(255, 165, 0)); outtextxy(960, 300, _T("外星人入侵")); EndBatchDraw();}bool exit() //退出游戏{ loadimage(&be_bk02, L"image\\be_bk02.jpg", 1360, 760); putimage(0, 0, &be_bk02); LOGFONT f; set_textstyle(f, 50, 20); settextcolor(RGB(255, 255, 255)); outtextxy(390, 230, _T("是否要退出游戏?")); outtextxy(310, 320, _T("是(回车)否(任意键)")); FlushBatchDraw(); char hit = _getch(); if (hit == 13) return 1; else return 0;}
/*music.h*/#pragma once#include <wtypes.h>#include <string>typedef int(__stdcall* w32mci)(const char*, char*, int, int);typedef int(__stdcall* w32mcierror)(int, char*, int);using namespace std;class Mci{private: HINSTANCE hins; w32mci wmci; w32mcierror wmcierror;public: Mci(); ~Mci(); char buf[256]; bool send(string command);};class AudioClip{private: Mci mci; std::string filename; std::string alias; int length_ms;public: AudioClip(); ~AudioClip(); bool load(const std::string& _filename); bool play(int start_ms = 0, int end_ms = -1); bool stop(); bool pause(); bool unpause(); int milliseconds();};/*music.cpp*/#include "music.h"#include<iostream>#include <string>#include <cstring>#include<random>#include<time.h>Mci::Mci(){ HINSTANCE hins = LoadLibraryA("winmm.dll"); wmci = (w32mci)GetProcAddress(hins, "mciSendStringA"); wmcierror = (w32mcierror)GetProcAddress(hins, "mciGetErrorStringA");}Mci::~Mci(){ FreeLibrary(hins);}bool Mci::send(std::string command){ int errcode = wmci(command.c_str(), buf, 254, 0); if (errcode) { wmcierror(errcode, buf, 254); return false; } return true;}AudioClip::AudioClip(){ //do nothing}AudioClip::~AudioClip(){ std::string cmd; cmd = "close " + alias; mci.send(cmd);}bool AudioClip::load(const std::string& _filename){ filename = _filename; for (unsigned int i = 0; i < filename.length(); i++) { if (filename[i] == '/') filename[i] = '\\'; } alias = "mp3_"; srand(time(NULL)); char randstr[6]; _itoa_s(rand() % 65536, randstr, 10); alias.append(randstr); std::string cmd; cmd = "open " + filename + " alias " + alias; if (mci.send(cmd) == false) return false; cmd = "set " + alias + " time format milliseconds"; if (mci.send(cmd) == false) return false; cmd = "status " + alias + " length"; if (mci.send(cmd) == false) return false; length_ms = atoi(mci.buf); return true;}bool AudioClip::play(int start_ms, int end_ms){ if (end_ms == -1) end_ms = length_ms; std::string cmd; char start_str[16], end_str[16]; _itoa_s(start_ms, start_str, 10); _itoa_s(end_ms, end_str, 10); cmd = "play " + alias + " from "; cmd.append(start_str); cmd.append(" to "); cmd.append(end_str); return mci.send(cmd);}bool AudioClip::stop(){ std::string cmd; cmd = "stop " + alias; if (mci.send(cmd) == false) return false; cmd = "seek " + alias + " to start"; if (mci.send(cmd) == false) return false; return true;}bool AudioClip::pause(){ std::string cmd; cmd = "pause " + alias; if (mci.send(cmd) == false) return false; return true;}bool AudioClip::unpause(){ std::string cmd; cmd = "resume " + alias; if (mci.send(cmd) == false) return false; return true;}int AudioClip::milliseconds(){ return length_ms;}
/*alien.h*/#pragma once#include <graphics.h>class Alien{public: int alien_x = 0, alien_y = -40; //外星人坐标 IMAGE alien01;      //外星人图片 void load_alien();   //加载外星人图片 void show_alien();   //绘制外星人 Alien();};/*alien.cpp*/#include <deque>#include "alien.h"#include <graphics.h>void Alien::load_alien(){ loadimage(&alien01, L"image\\alien.jpg", 40, 40);}void Alien::show_alien(){ putimage(alien_x, alien_y, &alien01);}Alien::Alien(){ load_alien();}
/*airplane.h*/#pragma onceclass Airplane{public: int airplane_x = 650, airplane_y = 720; //飞机初始坐标 IMAGE plane01;       //飞机图片 IMAGE background;      //背景图 char key_hit;       //接受按键 int airplane_speed = 10;     //飞船移动速度 Airplane();  //构造函数 void load_image();//加载飞机图片 void show_plane();//绘制飞机图片 void show_bg(); //绘制背景图片 void key_Down(char hit); //按键响应};/*airplane.cpp*/#include <graphics.h>#include <conio.h>#include <Windows.h>#include "Airplane.h"void Airplane::load_image() //加载飞机图片和背景图{ loadimage(&plane01, L"image\\plane01.jpg", 60, 40); loadimage(&background, L"image\\background01.jpg", 1360, 760); rotateimage(&plane01, &plane01, 3.1415926);}void Airplane::show_bg() //绘制背景图{ putimage(0, 0, &background);}void Airplane::show_plane() //绘制飞机图片{ putimage(airplane_x, airplane_y, &plane01);}void Airplane::key_Down(char hit) //按键响应{ key_hit = hit; switch (key_hit) { case 'w': case 'W': if(airplane_y > 500) airplane_y-=airplane_speed; break; case 's': case 'S': if (airplane_y < 720) airplane_y+= airplane_speed; break; case 'a': case 'A': if (airplane_x > 0) airplane_x-= airplane_speed; break; case 'd': case 'D': if (airplane_x < 1300) airplane_x+= airplane_speed; break; default: break; }}Airplane::Airplane(){  load_image(); }
/*bullet.h*/#pragma onceclass Bullet{public: int bullet_x = 0, bullet_y = 0; //子弹坐标 IMAGE bullet01;     //子弹图片  int bullet_speed = 15;   //子弹速度 void load_bullet(); //加载子弹图片 void show_bullet(); //绘制子弹图片 Bullet();};/*bullet.cpp*/#include <graphics.h>#include "bullet.h"void Bullet::load_bullet(){ loadimage(&bullet01, L"image\\bullet.jpg", 10, 30);}void Bullet::show_bullet(){ putimage(bullet_x, bullet_y, &bullet01);}Bullet::Bullet(){ load_bullet();}
/*launch.h*/#pragma oncebool choose_all(char key, int &i); //初始选择界面按键处理void load_music01();     //加载初始界面音乐/*launch.cpp*/#include <iostream>#include <Windows.h>#include <graphics.h>#include <conio.h>#include<cstdlib>#include <deque>#include <vector>#include <ctime>#include <string>#include <tchar.h>#include "airplane.h"#include "bullet.h"#include "alien.h"#include "music.h"#include "setting.h"using namespace std;static int score = 0;  //得分int tx = 0;     //存储上次得分信息static int level = 1;  //关卡int player_eneygy = 100; //玩家血量static int alien_speed = 1; //外星人移动速度int alien_num = 5;   //初始外星人数量AudioClip mu_be01, choose, level13, level46, level710, bulbul, gameov, levelup;   //音乐void load_music01() //加载初始界面音乐{ mu_be01.load("music\\be_bg01.mp3"); mu_be01.play();}void trans_int_ch(wchar_t*& wides, int num) //将数字转换为能够被outtextxy输出的wchar_t型{ string temp = to_string(num); char s[100]; int i; for (i = 0; i < temp.length(); i++) s[i] = temp[i]; s[i] = '\0'; int n = MultiByteToWideChar(0, 0, s, -1, NULL, 0); wchar_t* wide = new wchar_t[n]; MultiByteToWideChar(0, 0, s, -1, wide, n); wides = wide;}void show_score_level()  //显示得分和关卡信息{ LOGFONT f; set_textstyle(f, 20, 5);     //设置字体信息 wchar_t* wides1 = NULL; trans_int_ch(wides1, score); roundrect(1220, 20, 1320, 50, 20, 20); //绘制得分信息框 rectangle(1215, 15, 1325, 55); settextstyle(&f); outtextxy(1235, 27, _T("得分: ")); settextstyle(&f); outtextxy(1290, 27, wides1); wchar_t* wides2 = NULL; trans_int_ch(wides2, level); roundrect(1220, 70, 1320, 100, 20, 20); //绘制得分信息框 rectangle(1215, 65, 1325, 105); settextstyle(&f); outtextxy(1235, 77, _T("关卡: ")); settextstyle(&f); outtextxy(1290, 77, wides2);}void show_energy() //显示玩家血量{ LOGFONT f; set_textstyle(f, 25, 5); settextstyle(&f); setbkmode(TRANSPARENT); //透明字体背景 wchar_t* ene = NULL; trans_int_ch(ene, player_eneygy); switch (player_eneygy) { case 100: setfillcolor(RGB(0, 238, 0)); rectangle(15, 15, 165, 55); solidroundrect(20, 20, 160, 50, 8, 8); outtextxy(70, 22, ene); break; case 80: setfillcolor(RGB(192, 255, 62)); rectangle(15, 15, 165, 55); solidroundrect(20, 20, 132, 50, 8, 8); outtextxy(70, 22, ene); break; case 60: setfillcolor(RGB(255, 215, 0)); rectangle(15, 15, 165, 55); solidroundrect(20, 20, 104, 50, 8, 8); outtextxy(70, 22, ene); break; case 40: setfillcolor(RGB(238, 238, 0)); rectangle(15, 15, 165, 55); solidroundrect(20, 20, 76, 50, 8, 8); outtextxy(70, 22, ene); break; case 20: setfillcolor(RGB(255, 0, 0)); rectangle(15, 15, 165, 55); solidroundrect(20, 20, 48, 50, 8, 8); outtextxy(70, 22, ene); break; case 0: settextstyle(&f); outtextxy(70, 22, ene); break; default: break; }}void get_Cours(Bullet &b) //获取鼠标信息{ HWND hwnd = GetHWnd();  //获取窗口句柄 POINT point;  //鼠标位置 GetCursorPos(&point); // 获取鼠标指针位置(屏幕坐标) ScreenToClient(hwnd, &point); // 将鼠标指针位置转换为窗口坐标 if (point.x >= 0 && point.x <= 1360 && point.y >= 500 && point.y <= 760) { b.bullet_x = point.x; b.bullet_y = point.y; }}void add_alien(deque<Alien>& a) //添加外星人{ Alien ali; int x = 0;  //作为随机数 while (1) { int i = 0; x = rand() % 1320; for (int k = 0; k < a.size(); k++) { if (x >= a[k].alien_x && x <= a[k].alien_x + 40) i++; } if (i == 0) break; else i = 0; } ali.alien_x = x; a.push_back(ali);}void update_level(deque<Alien>& a) //更新等级和外星人数量信息{ if (score > tx) if (score >= 10 && score % 10 == 0) { level++; levelup.load("music\\levelup.mp3"); levelup.play(); player_eneygy = 100; alien_speed *= 1.5; add_alien(a); tx = score; }}void update_energy(Airplane pl, deque<Alien> &a) //更新血量{ int i = 0, t = 0; for ( ; i < a.size(); i++) { if ((pl.airplane_x <= a[i].alien_x + 40 && pl.airplane_x + 60 >= a[i].alien_x && pl.airplane_y == a[i].alien_y + 30)|| (pl.airplane_y <= a[i].alien_y + 40 && pl.airplane_y + 40 >= a[i].alien_y &&  pl.airplane_x <= a[i].alien_x + 40 && pl.airplane_x + 60 >= a[i].alien_x)) { player_eneygy -= 20; t++; break; } } if (t != 0) { a.erase(a.begin() + i); add_alien(a); }}void draw_bu_al(deque<Alien>& a, deque<Bullet>& b)  //更新并绘制外星人和子弹{ vector<int> as; vector<int> bs; for (int i = 0; i < a.size(); i++) //判断子弹和外星人相撞 { for (int j = 0; j < b.size(); j++) { if (a[i].alien_x <= b[j].bullet_x + 10 && a[i].alien_x + 40 >= b[j].bullet_x && a[i].alien_y+40 >= b[j].bullet_y) { bulbul.load("music\\bullet.mp3"); bulbul.play(); as.push_back(i); bs.push_back(j); score++; } } } if (!as.empty()) for (int i = a.size() - 1; i >= 0; i--) //删除碰撞后的外星人 { int k = as.size() - 1; if (i == as[k]) { a.erase(a.begin() + i); k--; add_alien(a); //每次删除都新增一个外星人 } } if (!bs.empty()) for (int i = b.size() - 1; i >= 0; i--)  //删除碰撞后的子弹 { int k = bs.size() - 1; if (i == bs[k]) { b.erase(b.begin() + i); k--; } } if(!a.empty())   //删除飞出屏幕的外星人 if (a[0].alien_y > 720) { a.pop_front(); add_alien(a); //每次删除都新增一个外星人 } if (!b.empty())   //删除飞出屏幕的子弹 if (b[0].bullet_y < -20) b.pop_front(); for (int i = 0; i < a.size(); i++) //绘制外星人 { a[i].show_alien(); a[i].alien_y += alien_speed; } for (int i = 0; i < b.size(); i++) //绘制子弹 { if (b[i].bullet_x > 0 && b[i].bullet_x < 1350 && b[i].bullet_y > -29 && b[i].bullet_y < 730) b[i].show_bullet(); b[i].bullet_y -= b[i].bullet_speed; }}bool launch(int a) //游戏运行{ Airplane plane; Bullet bul; Alien ali; if (a == 1) { alien_speed = 3; alien_num = 5; plane.airplane_speed = 10; level13.load("music\\level01.mp3"); level13.play(); } if (a == 2) { alien_speed = 6; alien_num = 7; plane.airplane_speed = 20; level46.load("music\\level03.mp3"); level46.play(); } deque<Alien> aliens; deque<Bullet> bullets; ali.alien_x = rand() % 1320; aliens.push_back(ali);  //放入头,便于后续操作  for (int i = 0; i < alien_num - 1; i++) add_alien(aliens); char hit;      //记录按键 plane.show_bg(); plane.show_plane();  while (1) { BeginBatchDraw(); srand((unsigned)time(NULL)); //随机数种子 plane.show_bg(); update_energy(plane, aliens); show_energy(); if (player_eneygy == 0) { gameov.load("music\\gameover.mp3"); gameov.play(); LOGFONT f; set_textstyle(f, 150, 10); settextstyle(&f); settextcolor(RGB(255, 255, 255)); outtextxy(300, 230, _T("GAME OVER")); FlushBatchDraw(); Sleep(1000); return 1; } update_level(aliens); show_score_level(); get_Cours(bul); if (_kbhit()) { hit = _getch(); if (hit == ' ') //判断是否往队列里添加子弹 { bul.bullet_x = plane.airplane_x + 25; bul.bullet_y = plane.airplane_y ; bullets.push_back(bul); } else if (hit == 27) { LOGFONT f; set_textstyle(f,40,10); settextstyle(&f); settextcolor(RGB(255, 255, 255)); outtextxy(530, 230, _T("是否返回初始界面")); outtextxy(490, 320, _T("是(回车)否(任意键)")); FlushBatchDraw(); hit = _getch(); if (hit == 13)  return 1; } else plane.key_Down(hit); } draw_bu_al(aliens, bullets); FlushBatchDraw();  plane.show_plane(); EndBatchDraw(); //cleardevice(); //Sleep(100); system("cls"); } level13.stop(); level46.stop(); }bool choose_all(char key, int &i) //初始选择界面按键处理{ switch (key) { case 72: if (i >= 2) { choose.load("music\\choose.mp3"); choose.play(); i--; home(i); } return 0; break; case 80: if (i <= 3) { choose.load("music\\choose.mp3"); choose.play(); i++; home(i); } return 0; break; case 13: choose.play(); switch (i) { case 1: mu_be01.stop(); launch(1); return 0; break; case 2: mu_be01.stop(); launch(2); return 0; break; case 3: help(); return 0; break; case 4: if (exit()) return 1; break; } break; default: return 0; break; }}
/*main.cpp*/#include <iostream>#include <graphics.h>#include <conio.h>#include<windows.h>#include<Mmsystem.h>#include "launch.h"#include "setting.h"#pragma comment(lib,"winmm.lib")using namespace std;int main(){ int i = 1; char be_key; //初始界面按键输入 load_music01(); initgraph(1360, 760); home(1); while (1) { home(i); be_key = _getch(); if (choose_all(be_key, i)) return 0; } closegraph();}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

长江后浪催前浪,一辈新人换旧人。

C++实现雷霆战机可视化小游戏

相关文章:

你感兴趣的文章:

标签云: