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

2022-11-13 09:11:29 飞机 程序设计 大战

本文实例为大家分享了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;
}

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

相关文章