首先声明,本人对于编程而言还是新手,所以代码可能没有很多炫酷的写法,也不够简练,但是下面的代码我在VC++6上是编译通过的,我也尽量修改了能发现的Bug,在DEV C++上应当也能编译通过。
这只是一个很简单的小游戏,附图。
关于游戏作出一些说明,开始游戏时首先按‘shift’键,w、s、a、d分别为上下左右键,一开始会有一架敌机从中间下落,若是碰到飞机机身或者下边沿,游戏就结束了。我们可以按空格键发射子弹击落敌机,然后敌机会在上边沿的任意位置刷新,与此同时,分数加一。随着分数的增加,敌机下落的速度会越来越快。
关于游戏设计,采用了goto原点重新打印的方式使得屏幕不会一直闪烁。敌机,飞机机头,子弹,分数,游戏是否结束以及速度等级都被我设为了全局变量,好处就是任意函数对其更改都会影响其它地方,这样在show()函数中打印的话就是实时的位置了。
主函数中包含了startup(),这里面对全局变量进行了初始化,另外startup函数中包含了HideCursor()函数,这可以隐藏闪烁的光标。死循环中包含了show()打印函数,每次循环重新打印边框,敌机,子弹,机身,这样就实现了它们的位移,我们也无需消去原来的这些要素,因为整块区域都重新打印了。我之前因为担心闪烁,采用了打印一次边框,然后里面的飞机,子弹之类的位置改变后我就在原来的位置打印空格字符,后来发现有解决不掉的Bug,而且很麻烦,就换了种方式。WordsOnRight()就是用来打印一些提示以及分数的,放在了show()函数中,没什么好说的。
updateWithoutInput()函数中是一些不要键盘交互的行为,例如子弹移动,敌机移动以及调整它们的速度,最后还有判断是否游戏失败,失败的话调用finish()函数显示游戏结束,另外附给gameover变量1,主函数中就会跳出循环。
updateWithInput()函数包含了一些键盘交互的行为,例如上下左右移动,发射子弹以及暂停。这里用到了kbhit()函数监听是否有键盘输入,然后用getch()函数得到输入值。
非常简单的小游戏,如果有和我一样的新人,也可以对照着编写一下。然后我之前想实现之前发射的子弹保留以及游戏结束能够点击再次游戏。前者由于我的子弹的全局变量只有一个,还不知道怎么实现,后者还有一些地方没有掌握,所以也没有编写,如果有人有兴趣,可以尝试。
代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <conio.h>
void startup();
void gotoxy(int x, int y);
void HideCursor();
void WordsOnRight();
void show();
void updateWithoutInput();
void updateWithInput();
void finish();
//全局变量
int position_x, position_y;
int bullet_x, bullet_y;
int enemy_x, enemy_y;
int high, width;
int score;
int gameOver;
int speed_level;
int main()
{
startup();
while (1)
{
show();
updateWithoutInput();
updateWithInput();
if (gameOver == 1)
break;
}
return 0;
}
void startup()
{
high = 20;
width = 30;
position_x = high - 5;
position_y = width / 2;
bullet_x = -1;
bullet_y = -1;
enemy_x = 1;
enemy_y = position_y;
score = 0;
gameOver = 0;
speed_level = 40;
HideCursor();
}
void gotoxy(int x, int y)
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
COORD pos;
pos.X = y;
pos.Y = x;
SetConsoleCursorPosition(handle, pos);
}
void HideCursor()
{
CONSOLE_CURSOR_INFO cursor_info = {1, 0};
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
void WordsOnRight()
{
gotoxy((high / 3 - 2), (width + 5));
printf("* Attention:Please press 'shift' first!!!\n");
gotoxy((high / 3), (width + 5));
printf("* w:up s:down a:left d:right\n");
gotoxy((high / 3 + 2), (width + 5));
printf(" space:shoot esc:pause\n");
gotoxy((high / 3 + 4), (width + 5));
printf("* Care:Don't let the enemy touch your\n");
gotoxy((high / 3 + 6), (width + 5));
printf(" plane or the bottom!!!\n");
gotoxy((high / 3 + 8), (width + 5));
printf("* score : %d\n", score);
}
void show()
{
int i, j;
gotoxy(0,0);
for (i = 0; i <= high; i++)
{
for (j = 0; j <= width; j++)
{
if (((i == position_x) && (j == position_y)) ||
((i == position_x + 1) && (j == position_y - 2 || j == position_y - 1 ||
j == position_y || j == position_y + 1 || j == position_y + 2)) ||
((i == position_x + 2) && (j == position_y - 1 || j == position_y + 1)))
{
putchar('*');
}
else if ((i == enemy_x) && (j == enemy_y))
{
putchar('#');
}
else if ((i == bullet_x) && (j == bullet_y))
{
putchar('|');
}
else if (i == 0 || i == high) //打印上下边框
{
putchar('-');
}
else if (j == 0 || j == width) //打印左右边框
{
putchar('|');
}
else
{
putchar(' ');
}
}
printf("\n");
}
WordsOnRight();
}
void updateWithoutInput()
{
static int speed_e = 0;
static int speed_b = 0;
if (speed_b < 10)
speed_b++;
if (speed_b == 10)
{
if (bullet_x > -1)
{
bullet_x--;
}
speed_b = 0;
}
if ((bullet_x == enemy_x) && (bullet_y == enemy_y))
{
score++;
enemy_x = 1;
enemy_y = rand() % ((width - 3) - 3) + 3;
bullet_x = -1;
}
if (enemy_x >= high)
{
enemy_x = 1;
enemy_y = rand() % ((width - 3) - 3) + 3;
}
if (score >= 0 && score <= 10)
{
speed_level = 40;
}
else if (score > 10 && score <= 20 && speed_e < 30)
{
speed_level = 30;
}
else if (score > 20 && score <= 30 && speed_e < 20)
{
speed_level = 20;
}
else if (score > 30 && speed_e < 10)
{
speed_level = 10;
}
if (speed_e < speed_level)
speed_e++;
if (speed_e == speed_level)
{
enemy_x++;
speed_e = 0;
}
if ((enemy_x == position_x && enemy_y == position_y) ||
((enemy_x == position_x + 1) && (enemy_y == position_y - 2 || enemy_y == position_y - 1 ||
enemy_y == position_y || enemy_y == position_y + 1 || enemy_y == position_y + 2)) ||
((enemy_x == position_x + 2) && (enemy_y == position_y - 1 || enemy_y == position_y + 1)) ||
(enemy_x == high))
{
finish();
gameOver = 1;
}
}
void updateWithInput()
{
char input;
if (kbhit())
{
input = getch();
if (input == 'a' && position_y - 2 > 1)
position_y--;
if (input == 'd' && position_y + 2 < width - 1)
position_y++;
if (input == 'w' && position_x > 1)
position_x--;
if (input == 's' && position_x + 2 < high - 1)
position_x++;
if (input == ' ')
{
bullet_x = position_x - 1;
bullet_y = position_y;
}
if (input == 27) //按ESC键暂停,任意键恢复
{
getch();
}
}
}
void finish()
{
system("cls");
gotoxy(10, 25);
printf("**************************************\n");
gotoxy(13, 38);
printf("Game Over!\n");
gotoxy(16, 36);
printf("Your score is %d\n", score);
gotoxy(19, 25);
printf("**************************************\n");
Sleep(5000);
}