【C语言】飞机大战游戏还原,源码在文末,应用“循环”与“数组”实现游戏开发,一起玩一下经典小游戏吧

简介: 众所周知昂,飞机大战,重在大战嘛,你这一颗子弹一架敌机,打的那是一点儿激情也没有。所以我们这章内容,就来对前文做修改,运用上数组手法,给它盘圆咯在二维数组中存储游戏画面数据,元素为0时输出“ (空格)”,元素为1时输出大灰机“ * ”,元素为2输出子弹“¥”元素为3时输出敌机“@”定义二维数组存储游戏画面中元素的数组暂且定为4.基础功能的实现在飞机大战中,用人类语言来描述相关内容,则有以下这些,积分计算(包括击毁敌机,未击毁,飞机升级子弹,多架敌机产生……)这些我们都要一一实现多架敌机产生这块儿,

“前情概要”

首先先补充写游戏时的注意事项,在之前的文章中,复刻了一个飞机大战游戏,于是我心血来潮想给它补一个边界的样式,直观点看出边界的位置

但后面我发现,右边框和下边框始终无法显示

而后寻找“世外高人”指点,真的一语点破昂

image.gif编辑

补充:在进行循环时,先检查循环的范围!如上述代码

for(i=0;i<high;i++)
for(j=0;j<width;j++)

image.gif

这开头两句皆是 “<”,而我定义的high为20,width为30,此时的i和j仅能分别达到19和29,这就导致了程序的无法完整运行正确。

确定问题所在后,把范围稍加修改将"<"改为“<=”,如果不确定自己的长宽数值大小,可以将数值改为对应的变量名,让程序自己判断即可。

这不就好看多了

image.gif编辑

本文章关键内容

飞机大战进阶

众所周知昂,飞机大战,重在大战嘛,你这一颗子弹一架敌机,打的那是一点儿激情也没有。

image.gif编辑

所以我们这章内容,就来对前文做修改,运用上数组手法,给它盘圆咯

在二维数组中存储游戏画面数据,元素为0时输出“  (空格)”,元素为1时输出大灰机“ * ”,元素为2输出子弹“¥”元素为3时输出敌机“@”

1.定义二维数组

存储游戏画面中元素的数组暂且定为:

data[high][width] = {0};    //元素为0时输出“  (空格)”,元素为1时输出大灰机“ * ”

image.gif

飞机位置的数组则为:

play[px][py] =1;

image.gif

2.清屏防闪烁的实现

voidgotoxy(intx,inty)    //将光标移动到(x,y)位置{
HANDLEhandle=GetStdHandle(STD_OUTPUT_HANDLE);    //获取标准输出设备句柄COORDpos={x,y};      //坐标位置SetConsoleCursorPosition(handle,pos);   //设置控制台光标位置}
......
voidshow()
{
gotoxy(0,0);
    ......
}

image.gif

3.实现0,1不同输出

此处与之前直接使用i,j循环判断差不多,只不过是把条件给改了一下,原:

for(i=0;i<=high;i++)
    {
printf("#");
for(j=0;j<=width;j++)
        {
if((i==position_x)&&(j==position_y))
printf("*");    //输出飞机*elseif((i==enemy_x)&&(j==enemy_y))
printf("@");    //输出敌机elseif((i==bullet_x)&&(j==bullet_y))
printf("$");    //输出子弹elseif((i==0)||(i==high))
printf("#");
elseif(j==width)
printf("#");
elseprintf(" ");    //输出空格        }

image.gif

现:

for(i=0;i<high;i++)
{
for(j=0;j<width;j++)
    {
if(data[i][j]==0)
printf(" ");        //0输出空格—elseif(data[i][j]==1)
printf("*");        //1输出飞机*elseif(data[i][j]==2)
printf("¥");       //输出子弹¥elseif(data[i][j]==3) 
printf("@");        //输出敌机@    }
printf("\n");
}
printf("得分:%3d\n",score);
sleep(20)

image.gif

4.基础功能的实现

在飞机大战中,用人类语言来描述相关内容,则有以下这些,积分计算(包括击毁敌机,未击毁,飞机升级子弹,多架敌机产生……)这些我们都要一一实现

多架敌机产生这块儿,我们就需要掏一个新的二维数组出来

并且可以进行宏定义#define enemynum 5;

有关积分:积分达到一定程度时,增加敌机速度;积分增大到一定程度时子弹增多……

可以通过一个循环判断进行实现,运用之前所学到的除法计数,每%5=0或者%10=0,就进行相关数值的自增或自减

失败条件:敌机与我机碰撞

这个可以使用“==”对两者飞机坐标判断,相等即为碰撞

if((px==ex[k])&&(py==ey[k])
{
printf("失败!\n");
Sleep(3000);
system("pause");
exit(0);
}

image.gif

5.飞机移动

不同于使用循环判断,数组的飞机移动,代码量更大,得细致的看,一不小心就会有纰漏。

以一个方向位置左移为示例,其他方向类似:

if(input=='a'&&py>0)
{
data[px][py] =0;
py--;                //位置左移data[px][py] =1;
}

image.gif

此处为止,目前的代码也差不多了,在这其中,我认为还可添加生命值这一特点,举一反三的代码,实现这一功能或许不难,后续尝试修改,如果我这只小白摸索出来了,那再进行本文的内容补充修改,各位博主,就来欣赏代码的全貌吧⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇

#include<stdio.h>#include<stdlib.h>#include<conio.h>#include<windows.h>#define high 25     //游戏画面尺寸#define width 45#define enemynum 5  //敌机个数//全局变量intpx,py;      //飞机位置intex[enemynum],ey[enemynum];      //敌机位置intdata[high][width] = {0};        /*二维数组存储游戏画布中的元素0为空格,1为飞机,2为子弹,3为敌机*/intscore;      //得分intBW;         //子弹宽度intemsd;       //敌机移动速度voidgotoxy(intx,inty)
{
HANDLEhandle=GetStdHandle(STD_OUTPUT_HANDLE);
COORDpos;
pos.X=x;
pos.Y=y;
SetConsoleCursorPosition(handle,pos);
}
voidHideCursor()
{
CONSOLE_CURSOR_INFOcursor_info={1,0};  //0表示隐藏光标SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);
}
voidstart()        //数据初始化{
px=high-1;
py=width/2;
data[px][py] =1;
intk;
for(k=0;k<enemynum;k++)
    {
ex[k] =rand()%2;
ey[k] =rand()%width;
data[ex[k]][ey[k]] =3;
    }
score=0;
BW=0;
emsd=20;
}
voidshow()         //显示画面{
gotoxy(0,0);    //光标移动到原点位置,以下重画清屏inta,b;
for(a=0;a<high;a++)
    {
for(b=0;b<width;b++)
        {
if(data[a][b]==0)
printf(" ");        //输出空格elseif(data[a][b]==1)
printf("*");        //输出飞机elseif(data[a][b]==2)
printf("¥");        //输出子弹elseif(data[a][b]==3)
printf("@");        //输出敌机        }
printf("\n");
    }
printf("得分:%d\n",score);
Sleep(20);
}
voidwithout()
{
inta,b,k;
for(a=0;a<high;a++)
    {
for(b=0;b<width;b++)
        {
if(data[a][b]==2)
            {
for(k=0;k<ex[k];k++)
                {
if((a==ex[k])&&(b==ey[k]))
                    {
score++;
if(score%5==0&&emsd>3)
emsd--;
if(score%5==0)
BW++;
data[ex[k]][ey[k]] =0;
ex[k] =rand()%2;
ey[k] =rand()%width;
data[ex[k]][ey[k]] =3;
data[a][b] =0;
                    }
                }
//子弹向上移动data[a][b] =0;
if(a>0)
data[a-1][b] =2;
            }
        }
    }
staticintspeed=0;
if(speed<emsd)
speed++;
for(k=0;k<enemynum;k++)
    {
if((px==ex[k])&&(py==ey[k]))
        {
printf("失败!\n");
Sleep(3000);
system("pause");
exit(0);
        }
if(ex[k]>high)
        {
data[ex[k]][ey[k]] =0;
ex[k] =rand()%2;
ey[k] =rand()%width;
data[ex[k]][ey[k]] =3;
score--;
        }
if(speed==emsd)
        {
for(k=0;k<enemynum;k++)
            {
data[ex[k]][ey[k]] =0;
ex[k]++;
speed=0;
data[ex[k]][ey[k]] =3;
            }
        }
    }
}
voidwith()
{
charinput;
if(kbhit())
    {
input=getch();
if(input=='a'&&py>0)
        {
data[px][py] =0;
py--;                //位置左移data[px][py] =1;
        }
elseif(input=='d'&&py>0)
        {
data[px][py] =0;
py++;                //位置左移data[px][py] =1;
        }
elseif(input=='w'&&py>0)
        {
data[px][py] =0;
px--;                //位置左移data[px][py] =1;
        }
elseif(input=='s'&&py>0)
        {
data[px][py] =0;
px++;                //位置左移data[px][py] =1;
        }
elseif(input==' ')
        {
intleft=py-BW;
intright=py+BW;
if(left<0)
left=0;
if(right>width-1)
right=width-1;
intk;
for(k=left;k<=right;k++)
data[px-1][k] =2;
        }
    }
}
intmain()
{
start();
while(1)
    {
show();
without();
with();
HideCursor()
    }
return0;
}

image.gif

目测就是这样了,在末尾再补充一点,测试时我发现有光标闪烁,所以还是加上了HideCursor(),这样子看着舒服多了,不过缺点还是有的,就是这个子弹的碰撞体有点无语,当子弹升级为多个时,旁边边缘的子弹可能无法消灭敌机。嗯。。。

相关文章
|
19天前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
97 9
|
4天前
|
存储 人工智能 算法
数据结构实验之C 语言的函数数组指针结构体知识
本实验旨在复习C语言中的函数、数组、指针、结构体与共用体等核心概念,并通过具体编程任务加深理解。任务包括输出100以内所有素数、逆序排列一维数组、查找二维数组中的鞍点、利用指针输出二维数组元素,以及使用结构体和共用体处理教师与学生信息。每个任务不仅强化了基本语法的应用,还涉及到了算法逻辑的设计与优化。实验结果显示,学生能够有效掌握并运用这些知识完成指定任务。
28 4
|
18天前
|
存储 搜索推荐 算法
【数据结构】树型结构详解 + 堆的实现(c语言)(附源码)
本文介绍了树和二叉树的基本概念及结构,重点讲解了堆这一重要的数据结构。堆是一种特殊的完全二叉树,常用于实现优先队列和高效的排序算法(如堆排序)。文章详细描述了堆的性质、存储方式及其实现方法,包括插入、删除和取堆顶数据等操作的具体实现。通过这些内容,读者可以全面了解堆的原理和应用。
60 16
|
13天前
|
搜索推荐 算法 C语言
【排序算法】八大排序(上)(c语言实现)(附源码)
本文介绍了四种常见的排序算法:冒泡排序、选择排序、插入排序和希尔排序。通过具体的代码实现和测试数据,详细解释了每种算法的工作原理和性能特点。冒泡排序通过不断交换相邻元素来排序,选择排序通过选择最小元素进行交换,插入排序通过逐步插入元素到已排序部分,而希尔排序则是插入排序的改进版,通过预排序使数据更接近有序,从而提高效率。文章最后总结了这四种算法的空间和时间复杂度,以及它们的稳定性。
56 8
|
13天前
|
搜索推荐 算法 C语言
【排序算法】八大排序(下)(c语言实现)(附源码)
本文继续学习并实现了八大排序算法中的后四种:堆排序、快速排序、归并排序和计数排序。详细介绍了每种排序算法的原理、步骤和代码实现,并通过测试数据展示了它们的性能表现。堆排序利用堆的特性进行排序,快速排序通过递归和多种划分方法实现高效排序,归并排序通过分治法将问题分解后再合并,计数排序则通过统计每个元素的出现次数实现非比较排序。最后,文章还对比了这些排序算法在处理一百万个整形数据时的运行时间,帮助读者了解不同算法的优劣。
46 7
|
11天前
|
C语言 Windows
C语言课设项目之2048游戏源码
C语言课设项目之2048游戏源码,可作为课程设计项目参考,代码有详细的注释,另外编译可运行文件也已经打包,windows电脑双击即可运行效果
25 1
|
18天前
|
C语言
【数据结构】二叉树(c语言)(附源码)
本文介绍了如何使用链式结构实现二叉树的基本功能,包括前序、中序、后序和层序遍历,统计节点个数和树的高度,查找节点,判断是否为完全二叉树,以及销毁二叉树。通过手动创建一棵二叉树,详细讲解了每个功能的实现方法和代码示例,帮助读者深入理解递归和数据结构的应用。
66 8
|
20天前
|
存储 C语言
【数据结构】手把手教你单链表(c语言)(附源码)
本文介绍了单链表的基本概念、结构定义及其实现方法。单链表是一种内存地址不连续但逻辑顺序连续的数据结构,每个节点包含数据域和指针域。文章详细讲解了单链表的常见操作,如头插、尾插、头删、尾删、查找、指定位置插入和删除等,并提供了完整的C语言代码示例。通过学习单链表,可以更好地理解数据结构的底层逻辑,提高编程能力。
48 4
|
22天前
|
存储 C语言
【数据结构】顺序表(c语言实现)(附源码)
本文介绍了线性表和顺序表的基本概念及其实现。线性表是一种有限序列,常见的线性表有顺序表、链表、栈、队列等。顺序表是一种基于连续内存地址存储数据的数据结构,其底层逻辑是数组。文章详细讲解了静态顺序表和动态顺序表的区别,并重点介绍了动态顺序表的实现,包括初始化、销毁、打印、增删查改等操作。最后,文章总结了顺序表的时间复杂度和局限性,并预告了后续关于链表的内容。
56 3
|
30天前
|
C语言
【c语言】循环语句
循环结构是C语言中用于简化重复操作的重要工具,主要包括while循环、do-while循环和for循环。while循环是最基本的形式,通过不断检查条件来决定是否继续执行循环体。do-while循环则先执行循环体,再检查条件,至少执行一次。for循环逻辑更复杂,但使用频率最高,适合初始化、条件判断和更新变量的集中管理。此外,循环中还可以使用break和continue语句来控制循环的提前终止或跳过当前迭代。最后,循环可以嵌套使用,解决更复杂的问题,如查找特定范围内的素数。
37 6
下一篇
无影云桌面