IE盒子

搜索
查看: 178|回复: 16

C语言打飞机小游戏

[复制链接]

2

主题

6

帖子

10

积分

新手上路

Rank: 1

积分
10
发表于 2023-3-4 02:38:16 | 显示全部楼层 |阅读模式
在我实在无聊的情况下, 我看到了我的C语言书,遂我开始无聊之旅-2
<hr/>该程序属于也属于简单的循环结构,但是涉及多个循环进行判定和应用,对逻辑处理有一定的要求。
效果


Ps:使用 W 代表玩家控制的飞机^ 代表发射的子弹@ 代表 敌机。(以下都直接简写符号)
思路
想必大家都有玩过雷霆战机,那么脑子里应该有一个构思:
1、(制造飞机):需要使  W(飞机) 初始位置设定在界面正中央的下方位置
2、(控制飞机):需要使  W 动起来,总不能输出一次,动一下程序就关闭了吧
3、(发射子弹):需要让 W  可以点击某一固定按钮时发射   ^  (子弹)
4、(随机敌机):需要实现 @ 随机出现且子弹击中后必须消失。
过程
1、试着输出“飞机”(笔者使用W代表飞机),那么 printf("W")  就可以输出飞机,理论上可行,但是位置就会出现在第1行第1列,很明显哪有飞机游戏一开始飞机出现在最上面的呢,那么可以设定一个坐标轴(X,Y)。Ps:C语言中的坐标和生活中的坐标是相反的,想象一下二维数组 a[0][0]所在的位置,不难理解的。
因此在  飞机 前面输出  y  个空格,在  飞机 上面输出  x  个换行即可实现飞机出现在下侧中央
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

void main(void)
{
        int i, j;
        int x = 10,y = 8; //声明画布尺寸
        for (i = 0; i < x; i++)                //输出飞机上面的换行符号
                printf("\n");
        for (j = 0; j < y; j++)                //输出飞机前面的空格符号
                printf(" ");
        printf("W\n");              //输出飞机
        system("pause");

}        实现了 飞机 位置放置的效果


2、现在飞机已经成功输出了,但是游戏需要持续运行,总不能随便按个键就停止运行了吧?如何让其持续输出飞机呢,死循环可以做到。
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

void main(void)
{
        int i, j;
        int x = 10,y = 8; //声明画布尺寸
        while (1)                //死循环
        {
                for (i = 0; i < x; i++)                //输出飞机上面的换行符号
                        printf("\n");
                for (j = 0; j < y; j++)                //输出飞机前面的空格符号
                        printf(" ");
                printf("W\n");                //输出飞机符号
        }
}那么面临一个问题,死循环在每一次循环是不是整个界面全是飞机或者子弹,那么要引入一个新函数,清屏函数  system("cls"); 加入死循环中。
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>


void main(void)
{
        int i, j;
        int x = 10,y = 8;
        while (1)               
        {
                system("cls");                //清屏函数
                for (i = 0; i < x; i++)               
                        printf("\n");
                for (j = 0; j < y; j++)               
                        printf(" ");
                printf("W\n");               
        }
}此时飞机已经可以一直停留在DOS界面上,并且一闪一闪的,按任何按键也不会停止运行。那更进一步是不是需要“控制飞机”:
      根据我们第一步设置飞机出现在下侧中央的想法,我们只需要让飞机的坐标随着玩家按下W、A、S、D进行增减X、Y轴即可
输入S,X加一  //飞机下移一格
输入W,X减一  //飞机上移一格
输入A,Y减一  //飞机左移一格
输入D,Y加一  //飞机右移一格原理可行,那么进行实践:之前使用scanf_s() 函数就可以解决输入的问题,但是此函数需要进行回车程序才做出响应,很是影响游戏体验。C语言有个头文件可以解决这个问题,conio.h中的getch()函数就不需要按回车键,这从另一方面暗示这个函数只能单字符输入。
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>             //包含头文件


void main(void)
{
        int i, j;
        int x = 10,y = 8;
        char c;    //声明输入变量
        while (1)               
        {
                system("cls");               
                for (i = 0; i < x; i++)               
                        printf("\n");
                for (j = 0; j < y; j++)               
                        printf(" ");
                printf("W\n");       
                c = _getch();                //采集用户输入的数据
                if (c == 'w')                //判断是否上移
                        x--;
                if (c == 's')                //判断是否下移
                        x++;
                if (c == 'a')                //判断是否左移
                        y--;
                if (c == 'd')                //判断是否右移
                        y++;
        }
}飞机可以实现运动了,那么让它可以发射子弹,这里使用“^”代表子弹,一般子弹都是出现在飞机正上方的,这里引入一个双重循环可以做到:
          也就是在每行输入回车前,输入一定的空格,然后在输入“^”,最后回车
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

void main(void)
{
        int i, j;
        int x = 10, y = 8;
        char c;

        int number = 5, arm = 0;

        while (1)               
        {
                system("cls");                                       
        for (i = 0; i < x; i++)                        //这里引入双重循环,在每次回车前输入一定的空格
                {
                        for (j = 0; j < y; j++)                //输出飞机前面的空格符号
                                printf(" ");
                        printf("^\n");
                }
         for (j = 0; j < y; j++)                //输出飞机前面的空格符号
                        printf(" ");
                printf("W\n");               

                c = _getch();               
                if (c == 'w')               
                        x--;
                if (c == 's')               
                        x++;
                if (c == 'a')               
                        y--;
                if (c == 'd')               
                        y++;
        }
}

此时已经有了子弹,那么需要实现控制子弹的发射。这个用控制飞机的思路是一样的也很简单,只需要监控某一按键进行判断就行。这里使用空格键控制输出子弹。
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

void main(void)
{
        int i, j;
        int x = 10, y = 8;
        char c;
        int k = 0;        //声明判断变量,当k=0时输出回车,当=1时输出子弹


        while (1)               
        {
                system("cls");               

                if (k == 0)                                //当k=0时输出回车
                {
                        for (i = 0; i < x; i++)               
                                printf("\n");
                }


                if (k == 1)                               //当k=1时输出子弹
                {
                        for (i = 0; i < x; i++)
                        {
                                for (j = 0; j < y; j++)               
                                        printf(" ");
                                printf("^\n");
                        }
                        k = 0;                //每次输入完子弹后,将k归零
                        if (number == j)
                                arm = 1;

                }
                for (j = 0; j < y; j++)               
                        printf(" ");
                printf("W\n");               

                c = _getch();       
                if (c == 'w')               
                        x--;
                if (c == 's')               
                        x++;
                if (c == 'a')               
                        y--;
                if (c == 'd')               
                        y++;
                if (c == ' ')                //当用户输入空格是,将k的值更改为1
                        k = 1;

        }
}现在飞机和子弹都有了,就差敌机了,那该怎么实现呢?
               首先敌机需要具备两个特点:①随机出现  ②子弹打中就要消失
先定义一个固定的敌机出现在第一行,这里需要声明一个新的变量,打中消失需要判断子弹的Y值和敌机的Y值是否相等,如果相等敌机消失。
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

void main(void)
{
        int i, j;
        int x = 10, y = 8;
        char c;
        int k = 0;       
        int number = 5, arm = 0;  //定义飞机前面的空格;判断敌机是否输出,为0输出,为1不输出敌机


        while (1)               
        {
                system("cls");       
                if (arm == 0)                //现在判断是否输出敌机
                {
                        for (i = 0; i < number; i++)
                                printf(" ");
                        printf("@\n");
                }


                if (k == 0)                                  
                {
                        for (i = 0; i < x; i++)                 
                                printf("\n");
                }


                if (k == 1)                 
                {
                        for (i = 0; i < x; i++)                                 
                        {
                                for (j = 0; j < y; j++)                 
                                        printf(" ");
                                printf("^\n");
                        }
                        k = 0;                 
                        if (number == j)   //判断子弹是否击中敌机
                                arm = 1;

                }
                for (j = 0; j < y; j++)                 
                        printf(" ");
                printf("W\n");                 
                c = _getch();                 
                if (c == 'w')                 
                        x--;
                if (c == 's')                 
                        x++;
                if (c == 'a')                 
                        y--;
                if (c == 'd')         
                        y++;
                if (c == ' ')                 
                        k = 1;

        }
}

具体功能已经实现,但是问题又来了,敌机位置是我们自己定义的,也就只有一个敌机。这样的游戏就没有任何意义。
     那接下来就需要解决敌机随机出现,且击中一个敌机后,下一个敌机会立刻出现:
随机数的产生在C语言中可以使用rand()函数,但是这个函数只有第一次会随机,以后的每一次输出的随机数都和第一次是一致的。那么就需要对其进行初始化srand((unsigned)time(NULL)),这样每次都不一样了。初始化需要引入头文件<time.h>。
要想敌机随机出现,应该将随机数赋值给谁呢?很明显决定敌机出现位置的循环是:敌机前面的空格的多少,那就是number。同时还需要设置一个变量让敌机被击中后立刻刷新。
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h>    //引入

void main(void)
{
        int i, j;
        int x = 10, y = 8;
        char c;
        int k = 0;       
        int number = 5, arm = 0;   
        int l = 0;                        //判断是否需要改变敌机的位置,为0不改,为1更改
        srand((unsigned)time(NULL));        //初始化随机函数

        while (1)               
        {
                system("cls");       
                if (l == 1)                        //等于1的时候更改敌机的位置
                {
                        number = rand() % 10;                        //产生一个0~10的随机整数
                        l = 0;
                }       
                if (arm == 0)                 
                {
                        for (i = 0; i < number; i++)
                                printf(" ");
                        printf("@\n");
                }


                if (k == 0)                                  
                {
                        for (i = 0; i < x; i++)                 
                                printf("\n");
                }


                if (k == 1)                 
                {
                        for (i = 0; i < x; i++)                                 
                        {
                                for (j = 0; j < y; j++)                 
                                        printf(" ");
                                printf("^\n");
                        }
                        k = 0;                 
                        if (number == j)
                        {
                                arm = 0;                //由于始终显示敌机,因此设置为0
                                l = 1;                        //击中敌机的时候,更改敌机位置
                        }

                }
                for (j = 0; j < y; j++)                 
                        printf(" ");
                printf("W\n");                 
                c = _getch();                 
                if (c == 'w')                 
                        x--;
                if (c == 's')                 
                        x++;
                if (c == 'a')                 
                        y--;
                if (c == 'd')         
                        y++;
                if (c == ' ')                 
                        k = 1;

        }
}实现了全部效果,飞机、子弹、敌机  功能有限,有想法完善的同学可以进行优化:
比如:

  • 敌机也可以发射子弹?
  • 敌机可以根据某一速度进行移动(移动靶子)?
  • 子弹是一颗颗发的,不是“激光”?
  • 敌机会有概率出现BOSS?击中两次才回消失
  • 加入分数指示器?
  • 血条?
这些需要整体优化,我这个代码不能实现。
完整代码:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h>

void main(void)
{
        int i, j;
        int x = 10, y = 8; //声明画布尺寸
        char c;
        int k = 0;        //声明判断变量,当k=0时输出回车,当=1时输出子弹
        int number = 5, arm = 0;                //定义飞机前面的空格;判断敌机是否输出,为0输出,为1不输出敌机
        int l = 0;                                        //判断是否需要改变敌机的位置,为0不改,为1更改
        srand((unsigned)time(NULL));        //初始化随机函数


        while (1)                //死循环
        {
                system("cls");                //清屏函数
                if (l == 1)                        //等于1的时候更改敌机的位置
                {
                        number = rand() % 10;                        //产生一个0~10的随机整数
                        l = 0;
                }

                if (arm == 0)                //现在判断是否输出敌机
                {
                        for (i = 0; i < number; i++)
                                printf(" ");
                        printf("@\n");
                }


                if (k == 0)                                //当k=0时输出回车
                {
                        for (i = 0; i < x; i++)                //输出飞机上面的换行符号
                                printf("\n");
                }


                if (k == 1)                //当k=1时输出子弹
                {
                        for (i = 0; i < x; i++)                                //这里引入双重循环,在每次回车前输入一定的空格
                        {
                                for (j = 0; j < y; j++)                //输出飞机前面的空格符号
                                        printf(" ");
                                printf("^\n");
                        }
                        k = 0;                //每次输入完子弹后,将k归零
                        if (number == j)//判断子弹是否击中敌机
                        {
                                arm = 0;                //由于始终显示敌机,因此设置为0
                                l = 1;                        //击中敌机的时候,更改敌机位置
                        }
                }
                for (j = 0; j < y; j++)                //输出飞机前面的空格符号
                        printf(" ");
                printf("W\n");                //输出飞机符号

                c = _getch();                //采集用户输入的数据
                if (c == 'w')                //判断是否上移
                        x--;
                if (c == 's')                //判断是否下移
                        x++;
                if (c == 'a')                //判断是否左移
                        y--;
                if (c == 'd')                //判断是否右移
                        y++;
                if (c == ' ')                //当用户输入空格是,将k的值更改为1
                        k = 1;

        }
}<hr/>一闪而过解决办法:
回复

使用道具 举报

2

主题

10

帖子

15

积分

新手上路

Rank: 1

积分
15
发表于 2023-3-4 02:38:54 | 显示全部楼层
写完之后怎么变成游戏  运行就黑屏了
回复

使用道具 举报

2

主题

8

帖子

15

积分

新手上路

Rank: 1

积分
15
发表于 2023-3-4 02:39:52 | 显示全部楼层
运行就出啊   你哪里出错没写好
回复

使用道具 举报

1

主题

2

帖子

3

积分

新手上路

Rank: 1

积分
3
发表于 2023-3-4 02:40:08 | 显示全部楼层
编译没有错误,运行就黑屏,是不是学校电脑老的问题
回复

使用道具 举报

3

主题

8

帖子

16

积分

新手上路

Rank: 1

积分
16
发表于 2023-3-4 02:41:03 | 显示全部楼层
写完飞机动不了是怎么回事[好奇][好奇]
回复

使用道具 举报

4

主题

13

帖子

24

积分

新手上路

Rank: 1

积分
24
发表于 2023-3-4 02:41:26 | 显示全部楼层
写完  出现DOS界面  能看到画面就没有问题   你需要动起来  你要点击一下那个DOS界面  才可以进行监控键盘动作
回复

使用道具 举报

0

主题

3

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2023-3-4 02:42:26 | 显示全部楼层
是一闪而过?    你在结尾加上一句这个  试试看  system(“pause”);  或者自己点击运行 别用快捷键
回复

使用道具 举报

2

主题

9

帖子

15

积分

新手上路

Rank: 1

积分
15
发表于 2023-3-4 02:42:39 | 显示全部楼层
我不知道用什么那种工具,而且我用的是C++,是一样运行吗?
回复

使用道具 举报

0

主题

4

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2023-3-4 02:42:53 | 显示全部楼层
我使用的是  VS
回复

使用道具 举报

4

主题

10

帖子

20

积分

新手上路

Rank: 1

积分
20
发表于 2023-3-4 02:43:19 | 显示全部楼层
为啥我这编译出来有一个错误啊!能不能帮我指一下
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表