C语言实现飞机大战程序设计

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

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

作业要求:

1.游戏当中出现多类型敌人
2.游戏中能进行存档和读档
3.玩家控制的飞机由多字符组成
4.游戏过程中没有出现BUG 
5.游戏显示制作者信息
6.游戏当中带有BGM
7.其他个性化设定

成效:

 代码:

#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<windows.h>
#include<mmsystem.h>                // 导入声音头文件
#pragma comment(lib,"Winmm.lib")    // 导入声音头文件库
 
#define High 20            // 游戏画面尺寸
#define Width 30
#define EnemyNum 5        // 敌机个数
#define BossNum 2        // Boss机个数
 
int flag;                // 飞机状态 
int color(int c);        // 更改文字颜色
void explation();        // 游戏提示
void show();            // 显示游戏界面
void endgame();            // 游戏结束
void startup();            // 数据初始化
void FileRead();        // 读档
 
// 全局变量
int position_x, position_y;                // 飞机位置
struct enemy{
    int x;
    int y;
    int life;
}Boss[BossNum], enemy[EnemyNum];        // 敌机位置
 
int canvas[High][Width] = {0};            // 二维数组存储游戏画布中对应的元素
                                        // 0为空格,1为飞机8,2为子弹o,3为敌机0 , 4为Boss敌机A
int score;                                // 得分
int number;                                // 销毁敌机数
int BulletWidth;                        // 子弹宽度
int EnemyMoveSpeed;                        // 敌机移动速度
 
// 光标移动到(x,y)位置
void gotoxy(int x, int y)
{
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    COORD pos;
    pos.X = x;
    pos.Y = y;
    SetConsoleCursorPosition(handle, pos);
}
 
// 更改文字颜色
int color(int c)
{
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c);
    return 0;
}
 
// 隐藏光标
void HideCursor()
{
    CONSOLE_CURSOR_INFO cursor_info = {1,0};
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
 
// 开始界面
void welcometogame()
{
    int n, i, j = 1;
    system("cls");
    color(15);
    gotoxy(33, 1);
    printf("飞机大战 Plane War");
    color(56);
    for (i = 3; i <= 26; i++)       // 输出上下边框
    {
        for (j = 6; j <= 80; j++)   // 输出左右边框
        {
            gotoxy(j, i);
            if (i == 3 || i == 26)
                printf(" ");
            else if (j == 6 || j == 80)
                printf(" ");
        }
    }
    color(14);
    gotoxy(38, 6);
    printf("基本操作\n");
    gotoxy(19, 8);
    printf("空格:发射子弹  W:前进  A:左移  D:右移  S:后退\n");
    gotoxy(34, 11);
    printf("1.开始游戏(play)");
    gotoxy(34, 13);
    printf("2.游戏规则(rule)");
    gotoxy(34, 15);
    printf("3.读取存档(read)");
    gotoxy(34, 17);
    printf("4.退出游戏(quit)");
    color(15);
    gotoxy(22, 24);
    printf("游戏制作人:李歆灵   学号:420240320   联系方式:13530656670");
    color(14);
    gotoxy(33, 20);
    printf("请选择 1 2 3 4: ");
    color(14);
    scanf("%d", &n);   // 输入选项
    switch (n)
    {
    case 1:
        flag = 1;
        system("cls");
        break;
    case 2:
        explation();   // 游戏规则
        break;
    case 3:
        system("cls"); // 读档
        break;
    case 4:
        gotoxy(30, 28);
        exit(0);       // 退出游戏
        break;
    default:
        color(9);
        gotoxy(33, 22);
        printf("请输入1-4之间的数");
        _getch();       // 输入任意键
        system("cls");  // 清屏
        welcometogame();
    }
}
 
// 游戏规则
void explation()
{
    int i, j = 1;
    system("cls");
    color(15);
    gotoxy(30, 1);
    printf("游戏规则 Rules of game");
    color(56);
    for (i = 3; i <= 26; i++)       // 输出上下边框
    {
        for (j = 6; j <= 80; j++)   // 输出左右边框
        {
            gotoxy(j, i);
            if (i == 3 || i == 26)
                printf(" ");
            else if (j == 6 || j == 80)
                printf(" ");
        }
    }
    color(14);
    gotoxy(10, 6);
    printf("1. W,A,S,D 分别是控制飞机的移动,空格发射子弹");
    gotoxy(10, 9);
    printf("2. O是普通敌机(需一发子弹),A是Boss敌机(需两发子弹)");
    gotoxy(10, 12);
    printf("3. 击败普通敌机可获得1分,击败Boss敌机可获得2分");
    gotoxy(10, 15);
    printf("4. 敌机进入下边界减1分");
    gotoxy(10, 18);
    printf("5. 飞机碰到敌机会坠落");
    gotoxy(10, 21);
    printf("6. 按Z存档,按P暂停游戏");
    color(15);
    gotoxy(25, 23);
    printf("/*****按任意键返回主页面*****/");
    _getch();  // 按任意键返回主界面
    system("cls");
    welcometogame();
}
 
// 数据初始化
void startup()
{
    mciSendString("open D:\\plane\\game.mp3 alias bkmusic ",NULL,0,NULL);    // 打开背景音乐
    mciSendString("play bkmusic",NULL,0,NULL); // 循环播放
    position_x = High / 2;
    position_y = Width / 2;
    canvas[position_x][position_y] = 3;
    canvas[position_x + 1][position_y - 1] = 3;
    canvas[position_x + 1][position_y] = 3;
    canvas[position_x + 1][position_y + 1] = 3;
 
    int k;
    for (k = 0; k < EnemyNum; k++)
    {
        enemy[k].x = rand() % 2;
        enemy[k].y = rand() % Width;
        canvas[enemy[k].x][enemy[k].y] = 3;
    }
    for (k = 0; k < BossNum; k++)
    {
        Boss[k].x = rand() % 2;
        Boss[k].y = rand() % Width;
        canvas[Boss[k].x][Boss[k].y] = 4;
        Boss[k].life = 2;
    }
    int score = 0;            // 成绩
    int number = 0;            // 销毁敌机数
    BulletWidth = 0;
    EnemyMoveSpeed = 30;
    HideCursor();            // 光标
}
 
// 存档代码
void FileWrite()
{
    FILE *fp;                            // 文件指针
    fp = fopen("D:\\game.data", "w");    // 打开文件 "w": write写入文件
    int i, j;
    for (i = 0; i < EnemyNum; i++)
    {
        fwrite(&enemy[i], sizeof(struct enemy), 1, fp);
    }
    for (j = 0; j < BossNum; j++)
    {
        fwrite(&Boss[j], sizeof(struct enemy), 1, fp);
    }
    fwrite(&position_x, sizeof(int), 1, fp);
    fwrite(&position_y, sizeof(int), 1, fp);
    fwrite(&score, sizeof(int), 1, fp);
    fwrite(&number, sizeof(int), 1, fp);
    fwrite(&BulletWidth, sizeof(int), 1, fp);
    fwrite(&EnemyMoveSpeed, sizeof(int), 1, fp);
    fclose(fp);  // 关闭文件
    printf("\n保存成功\n");
}
 
// 读档代码
void FileRead()
{
    FILE *fp;                            // 文件指针
    fp = fopen("D:\\game.data", "r");    // 打开文件 "r": read读取文件
    mciSendString("open D:\\plane\\game.mp3 alias bkmusic ",NULL,0,NULL);    // 打开背景音乐
    mciSendString("play bkmusic",NULL,0,NULL); // 循环播放
    if(fp == NULL)
        startup();
    else
    {
        int i, j;
        for (i = 0; i < EnemyNum; i++)
        {
            fread(&enemy[i], sizeof(struct enemy), 1, fp);
        }
        for (j = 0; j < BossNum; j++)
        {
            fread(&Boss[j], sizeof(struct enemy), 1, fp);
        }
        fread(&position_x, sizeof(int), 1, fp);
        fread(&position_y, sizeof(int), 1, fp);
        fread(&score, sizeof(int), 1, fp);
        fread(&number, sizeof(int), 1, fp);
        fread(&BulletWidth, sizeof(int), 1, fp);
        fread(&EnemyMoveSpeed, sizeof(int), 1, fp);
    }
    fclose(fp);  // 关闭文件
    canvas[position_x][position_y] = 1;
    canvas[position_x + 1][position_y - 1] = 1;
    canvas[position_x + 1][position_y] = 1;
    canvas[position_x + 1][position_y + 1] = 1;
 
    int k;
    for (k = 0; k < EnemyNum; k++)
    {
        canvas[enemy[k].x][enemy[k].y] = 3;
    }
    for (k = 0; k < BossNum; k++)
    {
        canvas[Boss[k].x][Boss[k].y] = 4;
        Boss[k].life = 2;
    }
 
    HideCursor();
}
 
// 显示画面
void show()
{
    color(112);
    gotoxy(0, 0); // 光标移动到原点位置,以下重画清屏
    int i, j;
    for (i = 0; i < High; i++)
    {
        for (j = 0; j < Width; j++)
        {
            if ((j == Width - 1) || (i == High - 1) || (j == 0) || (i == 0))
                printf("#");             // 打印边界#
            else if (canvas[i][j] == 1)
                printf("8");             // 输出飞机8
            else if (canvas[i][j] == 2)
                printf("o");             // 输出子弹o
            else if (canvas[i][j] == 3)
                printf("O");             // 输出敌机O
            else if (canvas[i][j] == 4)
                printf("A");             // 输出Boss敌机A
            else
                printf(" ");
        }
        printf("\n");
    }
    color(14);
    printf("\n");
    printf("游戏得分: %d\n", score);
    printf("销毁敌机: %d\n\n", number);
    Sleep(20);
}
 
// 与用户输入无关的更新
void updateWithoutInput()
{
    int i, j, k;
    for (i = 0; i < High; i++)
    {
        for (j = 0; j < Width; j++)
        {
            if (canvas[i][j] == 2)
            {
                for (k = 0; k < EnemyNum; k++)
                {
                    if ((i == enemy[k].x) && (j == enemy[k].y))            // 子弹击中敌机
                    {
                        mciSendString("close gemusic",NULL,0,NULL);        // 先把前面一次的音乐关闭
                        mciSendString("open D:\\plane\\gotEnemy.mp3 alias gemusic ",NULL,0,NULL);    // 打开音乐
                        mciSendString("play gemusic",NULL,0,NULL);        // 仅播放一次
                        score++;                                        // 分数加1
                        number++;                                        // 销毁敌机数加1
                        if (number % 6 == 0 && EnemyMoveSpeed > 3)        // 达到一定积分后,敌机变快
                            EnemyMoveSpeed--;
                        if (number % 12 == 0)                           // 达到一定积分后,子弹变厉害
                            BulletWidth++;
                        canvas[enemy[k].x][enemy[k].y] = 0;                // 残影问题
                        enemy[k].x = rand() % 2;                        // 产生新的敌机
                        enemy[k].y = rand() % Width;
                        canvas[enemy[k].x][enemy[k].y] = 3;
                        canvas[i][j] = 0;                                // 子弹消失
                    }
                }
                for (k = 0; k < BossNum; k++)
                {
                    if ((i == Boss[k].x) && (j == Boss[k].y))    // 子弹击中Boss敌机
                    {
                        mciSendString("close gemusic",NULL,0,NULL);        // 先把前面一次的音乐关闭
                        mciSendString("open D:\\plane\\gotEnemy.mp3 alias gemusic ",NULL,0,NULL);    // 打开音乐
                        mciSendString("play gemusic",NULL,0,NULL);        // 仅播放一次    
                        Boss[k].life--;                                // Boss敌机生命值减1
                        if (Boss[k].life == 0)
                        {
                            canvas[Boss[k].x][Boss[k].y] = 0;    // 残影问题
                            Boss[k].x = rand() % 2;                    // 产生新Boss敌机
                            Boss[k].y = rand() % Width;
                            canvas[Boss[k].x][Boss[k].y] = 4;
                            canvas[i][j] = 0;                            // 子弹消失
                            Boss[k].life = 2;
                            score++;score++;                            // 分数加2
                            number++;                                    // 销毁敌机数加1
                        }
                    }
                }
                // 子弹向上移动
                canvas[i][j] = 0;
                if (i > 0)
                    canvas[i - 1][j] = 2;
            }
        }
    }
    static int speed = 0;
    if (speed < EnemyMoveSpeed)
        speed++;
    for (k = 0; k < EnemyNum; k++)
    {
        // 敌机撞到我机
        if ((position_x == enemy[k].x) && (position_y == enemy[k].y) || (position_x + 1 == enemy[k].x) && (position_y - 1 == enemy[k].y) || (position_x + 1 == enemy[k].x) && (position_y + 1 == enemy[k].y) || (position_x + 2 == enemy[k].x) && (position_y + 1 == enemy[k].y) || (position_x + 2 == enemy[k].x) && (position_y - 1 == enemy[k].y))
        {
            mciSendString("close bkmusic",NULL,0,NULL);        // 先把前面一次的音乐关闭
            mciSendString("open D:\\plane\\explode.mp3 alias exmusic",NULL,0,NULL);        // 打开音乐
            mciSendString("play exmusic",NULL,0,NULL);        // 仅播放一次
            color(11);
            printf("\n游戏结束!\n");
            Sleep(3000);
            system("pause");
            exit(0);
        }
 
        // 敌机跑出显示屏幕
        if (enemy[k].x > High)
        {
            canvas[enemy[k].x][enemy[k].y] = 0;
            enemy[k].x = rand() % 2; // 产生新的敌机
            enemy[k].y = rand() % Width;
            canvas[enemy[k].x][enemy[k].y] = 3;
            score--; // 减分
        }
 
        if (speed == EnemyMoveSpeed)
        {
            // 敌机下落
            for (k = 0; k < EnemyNum; k++)
            {
                canvas[enemy[k].x][enemy[k].y] = 0;
                enemy[k].x++;
                speed = 0;
                canvas[enemy[k].x][enemy[k].y] = 3;
            }
 
            // Boss敌机下落
            for (k = 0; k < BossNum; k++)
            {
                canvas[Boss[k].x][Boss[k].y] = 0;
                Boss[k].x++;
                speed = 0;
                canvas[Boss[k].x][Boss[k].y] = 4;
            }
        }
    }
 
    for (k = 0; k < BossNum; k++)
    {
        // Boss敌机撞到我机
        if ((position_x == Boss[k].x) && (position_y == Boss[k].y) || (position_x + 1 == Boss[k].x) && (position_y - 1 == Boss[k].y) || (position_x + 1 == Boss[k].x) && (position_y + 1 == Boss[k].y) || (position_x + 2 == Boss[k].x) && (position_y + 1 == Boss[k].y) || (position_x + 2 == Boss[k].x) && (position_y - 1 == Boss[k].y))
        {
            mciSendString("close exmusic",NULL,0,NULL);        // 先把前面一次的音乐关闭
            mciSendString("open D:\\plane\\explode.mp3 alias exmusic",NULL,0,NULL);        // 打开音乐
            mciSendString("play exmusic",NULL,0,NULL);        // 仅播放一次
            color(11);
            printf("\n游戏结束!\n");
            Sleep(3000);
            system("pause");
            exit(0);
        }
 
        // Boss敌机跑出显示屏幕
        if (Boss[k].x > High)
        {
            canvas[Boss[k].x][Boss[k].y] = 0;
            Boss[k].x = rand() % 2; // 产生新的Boss敌机
            Boss[k].y = rand() % Width;
            canvas[Boss[k].x][Boss[k].y] = 4;
            score--; // 减分
        }
    }
}
 
// 与用户输入有关的更新
void updateWithInput()
{
    char input;
    if (_kbhit()) // 判断是否有输入
    {
        input = _getch(); // 根据用户的不同输入来移动,不必输入回车
        if (input == 'a'&& position_y > 1 || input == 'A')
        {
            canvas[position_x][position_y] = 0;
            canvas[position_x + 1][position_y - 1] = 0;
            canvas[position_x + 1][position_y] = 0;
            canvas[position_x + 1][position_y + 1] = 0;
            position_y--; // 位置左移
            canvas[position_x][position_y] = 1;
            canvas[position_x + 1][position_y - 1] = 1;
            canvas[position_x + 1][position_y] = 1;
            canvas[position_x + 1][position_y + 1] = 1;
        }
        else if (input == 'd' && position_y < Width - 2 || input == 'D')
        {
            canvas[position_x][position_y] = 0;
            canvas[position_x + 1][position_y - 1] = 0;
            canvas[position_x + 1][position_y] = 0;
            canvas[position_x + 1][position_y + 1] = 0;
            position_y++; // 位置右移
            canvas[position_x][position_y] = 1;
            canvas[position_x + 1][position_y - 1] = 1;
            canvas[position_x + 1][position_y] = 1;
            canvas[position_x + 1][position_y + 1] = 1;
        }
        else if (input == 'w'&& position_x > 1 || input == 'W')
        {
            canvas[position_x][position_y] = 0;
            canvas[position_x + 1][position_y - 1] = 0;
            canvas[position_x + 1][position_y] = 0;
            canvas[position_x + 1][position_y + 1] = 0;
            position_x--; // 位置上移
            canvas[position_x][position_y] = 1;
            canvas[position_x + 1][position_y - 1] = 1;
            canvas[position_x + 1][position_y] = 1;
            canvas[position_x + 1][position_y + 1] = 1;
        }
        else if (input == 's'&& position_x < High - 3 || input == 'S')
        {
            canvas[position_x][position_y] = 0;
            canvas[position_x + 1][position_y - 1] = 0;
            canvas[position_x + 1][position_y] = 0;
            canvas[position_x + 1][position_y + 1] = 0;
            position_x++; // 位置下移
            canvas[position_x][position_y] = 1;
            canvas[position_x + 1][position_y - 1] = 1;
            canvas[position_x + 1][position_y] = 1;
            canvas[position_x + 1][position_y + 1] = 1;
        }
        else if (input == ' ') // 发射子弹
        {
            int left = position_y - BulletWidth;
            int right = position_y + BulletWidth;
            if (left < 0)
                left = 0;
            if (right > Width - 1)
                right = Width - 1;
            int k;
            for (k = left; k <= right; k++)        // 发射闪弹
                canvas[position_x - 1][k] = 2;    // 发射子弹的初始位置在飞机的正上方
        }
        else if (input == 'P' || input == 'p')    // 按P暂停游戏
            system("pause");
        else if (input == 'Z' || input == 'z')    // 按Z存档
        {
            FileWrite();
            system("pause");
            exit(0);
        }
    }
}
 
 
int main()
{
    welcometogame();
    if (flag == 1)
        startup();                // 数据初始化
    else
        FileRead();                // 数据初始化
 
    while (1)                    // 游戏循环执行
    {
        show();                    // 显示画面
        updateWithoutInput();    // 与用户输入无关的更新
        updateWithInput();        // 与用户输入有关的更新
    }
    return 0;
}

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

相关文章

  • C语言中#define预处理语法总结

    C语言中#define预处理语法总结

    C语言里可以用#define定义一个标识符来表示一个常量。特点是:定义的标识符不占内存,只是一个临时的符号,预编译后这个符号就不存在了,也不做类型定义。预编译又叫预处理
    2021-11-11
  • MFC自定义消息的实现方法

    MFC自定义消息的实现方法

    这篇文章主要介绍了MFC自定义消息的实现方法,通过该示例可以更好的理解MFC的消息封装机制,以便更加灵活的打造个性化的windows应用程序,需要的朋友可以参考下
    2014-07-07
  • OpenCV图像处理之实现图像膨胀腐蚀操作

    OpenCV图像处理之实现图像膨胀腐蚀操作

    图像形态学操作是指基于形状的一系列图像处理操作的合集,主要是基于集合论基础上的形态学数学对图像进行处理。本文将为大家介绍一下如何利用OpenCV实现其中的腐蚀和膨胀操作,需要的可以参考一下
    2022-09-09
  • C++在成员函数中使用STL的find_if函数实例

    C++在成员函数中使用STL的find_if函数实例

    这篇文章主要介绍了C++在成员函数中使用STL的find_if函数实例,包括了STL中find_if函数的具体用法及相关的完整实例,非常具有参考借鉴价值,需要的朋友可以参考下
    2014-10-10
  • 一文带你掌握C语言中的文件操作

    一文带你掌握C语言中的文件操作

    文件通常是驻留在外部介质(如磁盘等)上的,在使用时才调入内存中来,本文主要来和大家介绍一下C语言中的文件操作,有需要的可以了解下
    2024-02-02
  • C++使用智能指针实现模板形式的单例类

    C++使用智能指针实现模板形式的单例类

    这篇文章主要为大家详细介绍了C++使用了智能指针实现模板形式的单例类,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-06-06
  • C语言入门篇--理解地址及内存

    C语言入门篇--理解地址及内存

    本篇文章是基础篇,适合c语言刚入门的朋友,本文主要介绍了c语言的内存及地址,帮助大家快速入门c语言的世界,更好的理解c语言
    2021-08-08
  • C++实现随机生成迷宫地牢

    C++实现随机生成迷宫地牢

    这篇文章主要介绍了C++实现随机生成迷宫地牢的相关资料及代码分享,推荐给大家,有需要的小伙伴可以参考下。
    2015-03-03
  • strcat 函数的使用指南

    strcat 函数的使用指南

    strcat是连接字符串的函数。函数返回指针,两个参数都是指针,第一个参数所指向的内存的地址必须能容纳两个字符串连接后的大小。
    2015-09-09
  • C++ Protobuf实现接口参数自动校验详解

    C++ Protobuf实现接口参数自动校验详解

    用C++做业务发开的同学是否还在不厌其烦的编写大量if-else模块来做接口参数校验呢?今天,我们就模拟Java里面通过注解实现参数校验的方式来针对C++ protobuf接口实现一个更加方便、快捷的参数校验自动工具,希望对大家有所帮助
    2023-04-04

最新评论