C++编写实现飞机大战

 更新时间:2022年06月08日 10:30:21   作者:1coder.  
这篇文章主要为大家详细介绍了C++编写实现飞机大战,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了C++编写实现飞机大战的具体代码,供大家参考,具体内容如下

前几天看大佬写了个神经网络训练AI玩飞机大战,我想,凭我现有知识能不能也写一个飞机大战,就进行了尝试,成果如下。

#include<iostream>
#include<ctime>
#include<stdlib.h>
#include<windows.h>
using namespace std;
const int mapx = 40, mapy = 35, cost = 2, prise = 5;   //cost: cost of bullet,   prise: prise of killing a enemy.
class plane
{
    public:
        void start();
    private:
        void reset();
        void get_enemy(int &y);
        void print() const;
        void update_print();
        char map[mapx][mapy];/*      plane model:      /=|=\           */
        int plane_y, plane_x, score, cont;
};

到此我们设计了飞机的模型(我水平不够 整个游戏就用一个类了- -,这个类其实是整个游戏的类 不是飞机类)关于变量cont的说明我放在后面了 接下来我写了一个初始化函数,为类内变量初始化。

void plane::reset()
{
    for(int i = 0; i < mapx; i++)
    {
        for(int j = 0; j < mapy; j++)
        {
            if(!i || !j || j == mapy - 1)
            {
                map[i][j] = '#';
            }
            else
                map[i][j] = ' ';
        }
    }
    plane_x = mapx - 1;
    plane_y = mapy/2 - 2;
    score = cont = 0;
    map[plane_x][plane_y] = '/';
    map[plane_x][plane_y + 1] = map[plane_x][plane_y + 3] = '=';
    map[plane_x][plane_y + 2] = '|';
    map[plane_x][plane_y + 4] = '\\';
}

然后我利用时间参数的随机数得到敌机的位置,这里其实有个问题,因为时间是按一定顺序均匀变化的,我们如果直接用时间作随机数种子的话,敌机的出现会非常均匀,因此我引入了一个cont变量,用来打乱我们均匀的时间参数的个位数。具体使用见后文。

void plane::get_enemy(int &y) const
{
    srand(int(time(0)));
    int n = rand();
    if(cont%2)
        n -= cont;
    else
        n += cont;
    y = n % (mapy - 2) + 1;
}

这个函数就是随机生成敌机的位置,cont在此就起到打乱随机生成数的个位数的目的,每更新一次,cont++,为防止cont过大,我规定cont==10时,就将cont = 0,使其能在1到9变化,影响个位数。

void plane::print() const
{
    system("cls");
    for(int i = 0; i < mapx; i++)
    {
        for(int j = 0; j < mapy; j++)
        {
            cout<<map[i][j];
        }
        cout<<endl;
    }
    cout<<"Score : "<<score<<'.'<<endl<<"Pay "<<cost<<" scores to send '+' and get "<<prise<<" scores by killing enemies."<<endl;
}

这里是一个打印的函数,不赘述。

void plane::update_print()
{
    for(int i = 1; i < mapx; i++)
    {
        for(int j = 1; j < mapy - 1; j++)
        {
            if(map[i][j] == 'M')
            {
                if(i == mapx - 1)
                    map[i][j] = ' ';
                else if(map[i + 1][j] == '+')
                {
                    map[i][j] = map[i+1][j] = ' ';
                    score += prise;
                }
            }
            else if(map[i][j] == '+')
            {
                map[i][j] = ' ';
                if(i != 1)
                    map[i-1][j] = '+';
            }
        }
    }
    for(int i = mapx - 2; i > 0; i--)
    {
        for(int j = 1; j < mapy - 1; j++)
        {
            if(map[i][j] == 'M')
            {
                if(i != mapx - 1)
                    if(map[i+1][j] == '+')
                    {
                        map[i + 1][j] = ' ';
                        score += prise;
                    }
                    else
                        map[i + 1][j] = 'M';
                map[i][j] = ' ';
            }
        }
    }
    int enemy_y;
    get_enemy(enemy_y);
    if(map[1][enemy_y] == '+')
    {
        map[1][enemy_y] = ' ';
        score += prise;
    }
    else
        map[1][enemy_y] = 'M';
        
    for(int i = 0; i < 5; i++)
    {
        if(map[plane_x][plane_y + i] != 'M')
            map[plane_x][plane_y + i] = ' ';
    }
    bool jleft, jright, jup, jdown;
    jleft = jright = jup = jdown = false;

    if(GetAsyncKeyState(VK_LEFT) & 0x8000)
        if(plane_y != 1)
            jleft = true;
    if(GetAsyncKeyState(VK_RIGHT) & 0x8000)
        if(plane_y + 4 != mapy - 2)
            jright = true;
    if(GetAsyncKeyState(VK_UP) & 0x8000)
        if(plane_x != 1)
            jup = true;
    if(GetAsyncKeyState(VK_DOWN) & 0x8000)
        if(plane_x != mapx - 1)
            jdown = true;
    if(!(jleft && jright))
    {
        if(jleft)
            plane_y--;
        if(jright)
            plane_y++;
    }
    if(!(jup && jdown))
    {
        if(jup)
            plane_x--;
        if(jdown)
            plane_x++;
    }
    if(GetAsyncKeyState(VK_SPACE) & 0x8000)
        {
            score -= cost;
            if(map[plane_x - 1][plane_y + 2] == ' ')
                map[plane_x - 1][plane_y + 2] = '+';
            else if(map[plane_x - 1][plane_y + 2] == 'M')
            {
                map[plane_x - 1][plane_y + 2] = ' ';
                score += prise;
            }
        }

    if(map[plane_x][plane_y]=='M'||map[plane_x][plane_y+1]=='M'||
    map[plane_x][plane_y+2]=='M'||map[plane_x][plane_y+3]=='M'||map[plane_x][plane_y+4]=='M')
    {
        system("cls");
        for(int i = 0; i < mapx; i++)
        {
            cout<<"GAME OVER."<<endl;
        }
        cout<<"Your final scores are "<<score<<'.'<<endl;
        system("pause");
        exit(1);
    }
    map[plane_x][plane_y] = '/';
    map[plane_x][plane_y + 1] = map[plane_x][plane_y + 3] = '=';
    map[plane_x][plane_y + 2] = '|';
    map[plane_x][plane_y + 4] = '\\';
    cont++;
    if(cont == 10)
            cont = 0;
    print();
}

这个函数我其实感觉自己写的太大了,应该进一步分装,这确实是个不足之处。具体操作就是每轮对飞机的移动,还有子弹和敌机的前进以及判断子弹是否达到敌机和我们的飞机是否撞到敌机。其中我用到了windows.h文件中的GetAsyncKeyState函数,其参数为键盘某个键的VK值(可查表),返回一个16个位的数(因操作系统不同而不同,我的计算机是返回16位)。若该键在上次判断到此次判断之间被按下过,则0号位为1,反之为0;若该键正在被按下,则15号位为1,反之为0.将返回值与0x8000作“与&”操作,则第一位的数字决定了我们&操作的结果。因为XXXX XXXX XXXX XXXX & 1000 0000 0000 0000 == X000 0000 0000 0000.从而操控我们的飞机。

void plane::start()
{
    reset();
    while(1)
    {
        Sleep(50);
        update_print();
    }
}

开始函数,用以从类外部访问类内的private函数,并且组织起循环。
然后 用主函数运行即可。

int main()
{
    plane plane_game;
    plane_game.start();
    return 0;
}

效果如下:

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

相关文章

  • C++ assert()函数用法案例详解

    C++ assert()函数用法案例详解

    这篇文章主要介绍了C++ assert()函数用法案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-09-09
  • 基于C++中常见内存错误的总结

    基于C++中常见内存错误的总结

    本篇文章是对C++中常见的内存错误进行了总结介绍。需要的朋友参考下
    2013-05-05
  • C++实现LeetCode(22.生成括号)

    C++实现LeetCode(22.生成括号)

    这篇文章主要介绍了C++实现LeetCode(22.生成括号),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • C/C++中文件的随机读写详解及其作用介绍

    C/C++中文件的随机读写详解及其作用介绍

    这篇文章主要介绍了C/C++中文件的随机读写详解及其作用,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-09-09
  • C++基于消息队列的多线程实现示例代码

    C++基于消息队列的多线程实现示例代码

    这篇文章主要给大家介绍了关于C++基于消息队列的多线程实现的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用C++具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-04-04
  • 基于Matlab绘制小提琴图的示例代码

    基于Matlab绘制小提琴图的示例代码

    这篇文章主要介绍了如何利用Matlab实现小提琴图的绘制,文中的示例代码讲解详细,对我们学习Matlab有一定的帮助,需要的可以参考一下
    2022-05-05
  • Qt使用SqlLite实现权限管理的示例代码

    Qt使用SqlLite实现权限管理的示例代码

    本文主要介绍了Qt使用SqlLite实现权限管理的示例代码,管理员针对不同人员进行权限设定,具有一定的参考价值,感兴趣的可以了解一下
    2023-09-09
  • Cocos2d-x学习笔记之开发环境搭建

    Cocos2d-x学习笔记之开发环境搭建

    这篇文章主要介绍了Cocos2d-x学习笔记之开发环境搭建,本文使用Visual Studio作为开发IDE,是不同于其它教程的,需要的朋友可以参考下
    2014-09-09
  • 减小VC6编译生成的exe文件的大小的方法

    减小VC6编译生成的exe文件的大小的方法

    这篇文章主要介绍了减小VC6编译生成的exe文件的大小的方法,需要的朋友可以参考下
    2015-01-01
  • C语言字符串与字符数组面试题中最易错考点详解

    C语言字符串与字符数组面试题中最易错考点详解

    这篇文章主要介绍了C语言字符串与字符数组面试题中最易错考点,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-09-09

最新评论