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

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

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

基本原理

基本思路

代码如下

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

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

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

/*seeting.h*/

#pragma once

void 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 once

class 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 once

class 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 once

bool 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++实现雷霆战机可视化小游戏 的全部内容, 来源链接: utcz.com/p/245657.html

回到顶部