“前情概要”
首先先补充写游戏时的注意事项,在之前的文章中,复刻了一个飞机大战游戏,于是我心血来潮想给它补一个边界的样式,直观点看出边界的位置
但后面我发现,右边框和下边框始终无法显示
而后寻找“世外高人”指点,真的一语点破昂
补充:在进行循环时,先检查循环的范围!如上述代码
for(i=0;i<high;i++)
for(j=0;j<width;j++)
这开头两句皆是 “<”,而我定义的high为20,width为30,此时的i和j仅能分别达到19和29,这就导致了程序的无法完整运行正确。
确定问题所在后,把范围稍加修改将"<"改为“<=”,如果不确定自己的长宽数值大小,可以将数值改为对应的变量名,让程序自己判断即可。
这不就好看多了
本文章关键内容
飞机大战进阶
众所周知昂,飞机大战,重在大战嘛,你这一颗子弹一架敌机,打的那是一点儿激情也没有。
所以我们这章内容,就来对前文做修改,运用上数组手法,给它盘圆咯
在二维数组中存储游戏画面数据,元素为0时输出“ (空格)”,元素为1时输出大灰机“ * ”,元素为2输出子弹“¥”元素为3时输出敌机“@”
1.定义二维数组
存储游戏画面中元素的数组暂且定为:
data[high][width] = {0}; //元素为0时输出“ (空格)”,元素为1时输出大灰机“ * ”
飞机位置的数组则为:
play[px][py] = 1;
2.清屏防闪烁的实现
void gotoxy(int x,int y) //将光标移动到(x,y)位置
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); //获取标准输出设备句柄
COORD pos={x,y}; //坐标位置
SetConsoleCursorPosition(handle,pos); //设置控制台光标位置
}
......
void show()
{
gotoxy(0,0);
......
}
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("*"); //输出飞机*
else if((i==enemy_x)&&(j==enemy_y))
printf("@"); //输出敌机
else if((i==bullet_x)&&(j==bullet_y))
printf("$"); //输出子弹
else if((i==0)||(i==high))
printf("#");
else if(j==width)
printf("#");
else
printf(" "); //输出空格
}
现:
for(i=0;i<high;i++)
{
for(j=0;j<width;j++)
{
if(data[i][j]==0)
printf(" "); //0输出空格—
else if(data[i][j]==1)
printf("*"); //1输出飞机*
else if(data[i][j]==2)
printf("¥"); //输出子弹¥
else if(data[i][j]==3)
printf("@"); //输出敌机@
}
printf("\n");
}
printf("得分:%3d\n",score);
sleep(20)
4.基础功能的实现
在飞机大战中,用人类语言来描述相关内容,则有以下这些,积分计算(包括击毁敌机,未击毁,飞机升级子弹,多架敌机产生……)这些我们都要一一实现
多架敌机产生这块儿,我们就需要掏一个新的二维数组出来
并且可以进行宏定义#define enemynum 5;
有关积分:积分达到一定程度时,增加敌机速度;积分增大到一定程度时子弹增多……
可以通过一个循环判断进行实现,运用之前所学到的除法计数,每%5=0或者%10=0,就进行相关数值的自增或自减
失败条件:敌机与我机碰撞
这个可以使用“==”对两者飞机坐标判断,相等即为碰撞
if((px==ex[k])&&(py==ey[k])
{
printf("失败!\n");
Sleep(3000);
system("pause");
exit(0);
}
5.飞机移动
不同于使用循环判断,数组的飞机移动,代码量更大,得细致的看,一不小心就会有纰漏。
以一个方向位置左移为示例,其他方向类似:
if(input == 'a'&&py>0)
{
data[px][py] = 0;
py--; //位置左移
data[px][py] = 1;
}
此处为止,目前的代码也差不多了,在这其中,我认为还可添加生命值这一特点,举一反三的代码,实现这一功能或许不难,后续尝试修改,如果我这只小白摸索出来了,那再进行本文的内容补充修改,各位博主,就来欣赏代码的全貌吧⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<windows.h>
#define high 25 //游戏画面尺寸
#define width 45
#define enemynum 5 //敌机个数
//全局变量
int px,py; //飞机位置
int ex[enemynum],ey[enemynum]; //敌机位置
int data[high][width] = {0}; /*二维数组存储游戏画布中的元素
0为空格,1为飞机,2为子弹,3为敌机*/
int score; //得分
int BW; //子弹宽度
int emsd; //敌机移动速度
void gotoxy(int x,int y)
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
COORD pos;
pos.X = x;
pos.Y = y;
SetConsoleCursorPosition(handle,pos);
}
void HideCursor()
{
CONSOLE_CURSOR_INFO cursor_info={1,0}; //0表示隐藏光标
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);
}
void start() //数据初始化
{
px = high - 1;
py = width/2;
data[px][py] = 1;
int k;
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;
}
void show() //显示画面
{
gotoxy(0,0); //光标移动到原点位置,以下重画清屏
int a,b;
for(a=0;a<high;a++)
{
for(b=0;b<width;b++)
{
if(data[a][b]==0)
printf(" "); //输出空格
else if(data[a][b]==1)
printf("*"); //输出飞机
else if(data[a][b]==2)
printf("¥"); //输出子弹
else if(data[a][b]==3)
printf("@"); //输出敌机
}
printf("\n");
}
printf("得分:%d\n",score);
Sleep(20);
}
void without()
{
int a,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;
}
}
}
static int speed = 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;
}
}
}
}
void with()
{
char input;
if(kbhit())
{
input = getch();
if(input == 'a'&&py>0)
{
data[px][py] = 0;
py--; //位置左移
data[px][py] = 1;
}
else if(input == 'd'&&py>0)
{
data[px][py] = 0;
py++; //位置左移
data[px][py] = 1;
}
else if(input == 'w'&&py>0)
{
data[px][py] = 0;
px--; //位置左移
data[px][py] = 1;
}
else if(input == 's'&&py>0)
{
data[px][py] = 0;
px++; //位置左移
data[px][py] = 1;
}
else if(input == ' ')
{
int left = py-BW;
int right= py+BW;
if(left<0)
left = 0;
if(right>width-1)
right = width-1;
int k;
for(k=left;k<=right;k++)
data[px-1][k] = 2;
}
}
}
int main()
{
start();
while(1)
{
show();
without();
with();
HideCursor()
}
return 0;
}
目测就是这样了,在末尾再补充一点,测试时我发现有光标闪烁,所以还是加上了HideCursor(),这样子看着舒服多了,不过缺点还是有的,就是这个子弹的碰撞体有点无语,当子弹升级为多个时,旁边边缘的子弹可能无法消灭敌机。嗯。。。