基于纯C的小游戏,基本思想就是使用system("cls")和printf()函数不断刷新界面,捕获键盘事件,然后修改显示数组,并刷新界面。
之前有一款特别火爆的小游戏FlyBird,我们可以使用纯C语言实现,希望对大家学习C语言有所帮助。游戏界面如下:
源码可以从我的博客主页下载:
FlyBird游戏点击下载
使用“#define”定义界面的宽和高:
#define HEIGHT 20
#define WIDTH 36
定义界面的存储数组,ASCII码中“ ”是32,“&”是38表示小鸟,“#”是35用来画柱子,并初始化数组:
char bird_desk[HEIGHT][WIDTH] = {{ 32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35 },{ 32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35 },{ 32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35 },{ 32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35 },{ 32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35 },{ 32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35 },{ 32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35 },{ 32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35 },{ 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,32,32 },{ 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,32,32 },{ 38,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 },{ 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 },{ 32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,35 },{ 32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,35 },{ 32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35 },{ 32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35 },{ 32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35 },{ 32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35 },{ 32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35 },{ 32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35 }, };
更新界面中的柱子,使用rand随机生成柱子位置,并更新数组中的35(#)
void newinterface(void)
{if (bird_desk[0][1] == 35 && num==0)//当矩阵第二列为黑色方块时,计算出下一次黑柱子上半部分的位置{black = 5 + rand() % 5;num = 2;//黑柱子是两列#组成,第二列与第一列位置一样,用num保证两列位置一致}for (int i = 0; i < HEIGHT; i++){for (int j = 0; j < WIDTH - 1; j++){bird_desk[i][j] = bird_desk[i][j + 1];}if (bird_desk[0][0] == 35 && (i < black || i>(black + 5)))//此时上面的第二列变成了第一列,更新下一个黑柱子,有了黑柱子上半部分位置+5即是下半部分的起始位置{bird_desk[i][WIDTH-1] = 35;}else{bird_desk[i][WIDTH-1] = 32;}}if (num > 0)num--;
}
响应键盘事件,并更新小鸟的位置,按一次空格或w健,小鸟位置上移3格,由于上端为数组的小数端,因此对小鸟位置参数减3。不按小鸟位置降落1格,对小鸟参数加1。
/*更新小鸟位置*/
void birdmove(void)
{for (int a = 0; a < 3; a++){if (a == 2 && p > 0)//减缓鸟的速度,使按键上跳速度是下落的4倍{p = p + 1;}if (_kbhit()){if (_getch() == ' ' || _getch() == 'w' || _getch() == 'W'){p = p - 3;}}}
}
当小鸟穿越柱子后进行积分,当小鸟撞到柱子或者跌到地面,小鸟死亡显示Game Over:
/*计分*/
void scoring(void)
{if (p > 20 || bird_desk[p][0] == 35){system("cls");printf("\n\n");printf(" Game Over!\n\n");printf(" Thank you!\n\n");printf(" Your score is:%d\n\n\n", score);p= HEIGHT/2 ;score=0;system("pause");}if (bird_desk[0][0] == 35 && bird_desk[0][1] == 32 )score++;
}
重构界面,将生成的桌面数组显示在界面上
/*重画界面*/
void show_desk(void)
{system("cls");printf(" FlyBird Game Author:Dog语言\n");printf(" 按\"w\"或\"空格键\"使小鸟飞起来,顺利穿越更多柱子\n");for (int i = 0; i < HEIGHT; i++){printf(" ");for (int j = 0; j < WIDTH; j++){if (i == p && j == 0 && bird_desk[p][0] != 35)printf("%c", 38);elseprintf("%c", bird_desk[i][j]);}printf("\n");}printf(" Score is:%d \n", score);
}
主循环循环调用上述函数,小鸟移动速度是柱子移动速度的4倍,因此循环一圈中嵌套4次小鸟移动函数。
int main(void)
{for(;;){newinterface();scoring();//过一个柱子计一次分,所以和柱子更新速度一致for (int i = 0; i < 4; i++)//小鸟的速度是柱子的4倍{birdmove();show_desk();Sleep(50);}}return 0;
}
源码如下:
BirdMain.c
/** \FlyBird小游戏** \作者:Dog语言* \文件:BirdMain.c* \日期:2020-8-18* \版本:V1.0.0**/
#include <stdio.h>
#include <windows.h>
#include "Interface.h"int main(void)
{for(;;){newinterface();scoring();//过一个柱子计一次分,所以和柱子更新速度一致for (int i = 0; i < 4; i++)//小鸟的速度是柱子的4倍{birdmove();show_desk();Sleep(50);}}return 0;
}
interface.c
/** \FlyBird小游戏** \作者:Dog语言* \文件:interface.c* \日期:2020-8-18* \版本:V1.0.0**/
#include <stdio.h>
#include <stdlib.h>
#include<conio.h>
#include "interface.h"char bird_desk[HEIGHT][WIDTH] = {{ 32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35 },{ 32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35 },{ 32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35 },{ 32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35 },{ 32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35 },{ 32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35 },{ 32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35 },{ 32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35 },{ 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,32,32 },{ 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,32,32 },{ 38,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 },{ 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 },{ 32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,35 },{ 32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,35 },{ 32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35 },{ 32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35 },{ 32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35 },{ 32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35 },{ 32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35 },{ 32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35,32,32,32,32,32,32,32,32,32,32,35,35 }, };
//初始界面矩阵,ASCII码中“ ”是32,“&”是38表示小鸟,“#”是35用来画柱子int num = 0;//用于计数输出并排两列黑柱子同一位置
int black;//黑方块位置
int p= HEIGHT/2 ;//小鸟初始位置
int score = 0;//分数/*更新界面各个柱子*/
void newinterface(void)
{if (bird_desk[0][1] == 35 && num==0)//当矩阵第二列为黑色方块时,计算出下一次黑柱子上半部分的位置{black = 5 + rand() % 5;num = 2;//黑柱子是两列#组成,第二列与第一列位置一样,用num保证两列位置一致}for (int i = 0; i < HEIGHT; i++){for (int j = 0; j < WIDTH - 1; j++){bird_desk[i][j] = bird_desk[i][j + 1];}if (bird_desk[0][0] == 35 && (i < black || i>(black + 5)))//此时上面的第二列变成了第一列,更新下一个黑柱子,有了黑柱子上半部分位置+5即是下半部分的起始位置{bird_desk[i][WIDTH-1] = 35;}else{bird_desk[i][WIDTH-1] = 32;}}if (num > 0)num--;
}/*更新小鸟位置*/
void birdmove(void)
{for (int a = 0; a < 3; a++){if (a == 2 && p > 0)//减缓鸟的速度,使按键上跳速度是下落的4倍{p = p + 1;}if (_kbhit()){if (_getch() == ' ' || _getch() == 'w' || _getch() == 'W'){p = p - 3;}}}
}/*计分*/
void scoring(void)
{if (p > 20 || bird_desk[p][0] == 35){system("cls");printf("\n\n");printf(" Game Over!\n\n");printf(" Thank you!\n\n");printf(" Your score is:%d\n\n\n", score);p= HEIGHT/2 ;score=0;system("pause");}if (bird_desk[0][0] == 35 && bird_desk[0][1] == 32 )score++;
}/*重画界面*/
void show_desk(void)
{system("cls");printf(" FlyBird Game Author:Dog语言\n");printf(" 按\"w\"或\"空格键\"使小鸟飞起来,顺利穿越更多柱子\n");for (int i = 0; i < HEIGHT; i++){printf(" ");for (int j = 0; j < WIDTH; j++){if (i == p && j == 0 && bird_desk[p][0] != 35)printf("%c", 38);elseprintf("%c", bird_desk[i][j]);}printf("\n");}printf(" Score is:%d \n", score);
}
interface.h
/** \FlyBird小游戏** \作者:Dog语言* \文件:interface.h* \日期:2020-8-18* \版本:V1.0.0**/
#ifndef INTERFACE_H
#define INTERFACE_H#define HEIGHT 20
#define WIDTH 36void InitialInterface(void);
void newinterface(void);
void birdmove(void);
void scoring(void);
void show_desk(void);#endif