首先展示一下游戏的效果图
在这个小游戏中,最重要的是能够实现游戏界面的刷新以及对每次输入之时隐藏光标的位置,从而防止当键盘控制小鸟位置的移动之时,从而使得屏幕出现刷新的情况
1、实现对屏幕的刷新使用的是win32中的一个函数,他是win32自带的库函数,能够实现对图形化界面的操作
void gotoxy(int x, int y)
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
COORD pos;
pos.X = x;
pos.Y = y;
SetConsoleCursorPosition(handle, pos);
}
2、实现对光标的隐藏,也是使用的是一个win32中的库函数,其实这些函数我也不是很理解,只是根据自己的需求在网上找的
//隐藏光标
void HideCursor()
{
CONSOLE_CURSOR_INFO cursor_info = { 1, 0 };
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
3、实现了上述的操作,此时我们就可以保证在形成一帧一帧的动态画面之时,不会因为上次画面的残留,从而对此次的画面造成影响
4、有了动态画面的确保,此时我们需要一个一个界面,从而能使得我们在这个区域中对我们小鸟的控制
//记录数据
void startMap()
{
int i, j;
for (i = 1; i <= high - 1; i++)
{
map[i][1] = 4;
for (j = 2; j <= width - 1; j++)
map[i][j] = 0;
map[i][width] = 4;
}
//下方围墙的初始化
i = high;
for (j = 1; j <= width; j++)
map[i][j] = 3;
//小鸟位置的初始化
map[bird_x][bird_y] = 1;
//墙的初始化
for (i = 1; i <= high - 1; i++)
{
map[i][wall] = 2;
flag[i][wall] = 1;
}
for (i = through - 2; i <= through + 2; i++)//通道的大小可以自定义.
{
map[i][wall] = 0;
flag[i][wall] = 0;
}
}
//输出
void show()
{
gotoxy(0, 0);
int i, j;
for (i = 1; i <= high; i++)
{
for (j = 1; j <= width; j++)
{
switch (map[i][j])
{
case 0:
printf(" ");
break;
case 1:
printf(">");
break;
case 2:
printf("$");
break;
case 3:
printf("-");
break;
case 4:
printf("|");
break;
}
}
printf("\n");
}
printf("你的分数是:%d\n\n", score);
printf("操作说明:字符a向上移动\n");
printf("操作说明:字符s向下移动\n");
printf("操作说明:字符p暂停游戏\n");
printf("操作说明:按任意键小鸟继续运动\n");
}
5、初步阶段,我们已经有了一个画面,此时,我们需要的就是对这个小鸟进行控制,在对小鸟的控制上,我们仍然使用的是win32中的函数调用,或许有人会问为什么不使用scanf作为输入的选择,如果在此处使用scanf函数作为小鸟的控制坐标,当键盘没有输入之时,按理说,我们的小鸟是自由下落的,但是此时我们的scanf并不能对此条件作为判断,再则,win32中的库函数,能够保证每次只要有键盘输入,就能对其做处理,而scanf不能确保,且scanf每次必须从光标闪烁的位置进行输入,而此时为一个动态画面,不能保证光标到底停留在那个地方,因此使用win32中的函数更为规范,下面就是对键盘输入时的读取
void UPdatewithinput()
{
char input;
if (_kbhit())//判断是否有键盘输入
{
input = _getch();
if (input == 'a')
bird_x -= 3;//小鸟向上蹦两格
if (input == 's')
{
bird_x += 1;
}
if (input == 'p')//实现游戏的暂停
{
system("pause");
}
}
}
6、有了键盘的输入,在此时,就必须对键盘输入的相关内容作出反应,此时便需要形成动态的画面,从而确保我们的动画效果可以正常实现,此时的状态与每一次程序的运行相关
void UPdatewithOutinput()
{
int i = 20;
int j = 2;
if (score >= i)
{
i += 2;
wall -= j;
++j;
speed++;
if (j > (width / 4 * 3))
{
j = 1;
}
}
else
{
wall--;//墙的移动。保证形成动态的画面
}
bird_x++;//确保鸟可以下降
//bird_x <= 0防止小鸟向上跑的太快
if (flag[bird_x][bird_y] == 1 || bird_x >= high || bird_x <= 0)//当小鸟死亡时
{
result = 1;
}
if (wall == bird_y)
score++;
//产生一个随机的墙
if (wall < 1)
{
srand(time(NULL));
through = rand() % high;//假定墙的高度为20,则空的高度为0~19
while (through <= 3 || through >= high - 2)//空开始的坐标
{
through = rand() % high;
}
}
//下一次墙出现的位置
if (wall < 1)
{
wall = width / 4 * 3;
}
memset(flag, 0, sizeof(flag));
Sleep(100);
}
7、至此,我们的游戏就大概实现了,对此项目,我还做了一个突破,利用c++11中的多线程,从而实现一边听歌一边玩游戏的操作,在实现多线程时,使用的是c++11中的类thread,从而实现多个线程的并发执行
这世上哪有什么奇迹,奇迹源于不放弃