前几天的实训我做了一个飞翔小鸟的游戏项目,技术性不高,但是我利用了图像处理函数在游戏里添加了声音和画面,看起来就好多了。
大家可以看一下游戏样例图片
这里如果你的电脑上又V C++6.0的话,直接下载我分分享的压缩包,把素材拉到桌面,安装ege图形处理函数,再打开我的源码可以直接运行,有兴趣的可以自己研究修改一下。
链接直通车
链接:https://pan.baidu.com/s/1HyP_jMbWzQ97YxVCOp8_8g
提取码:ilft
我不算是原创,我是根据河海大学童老师的网课给出的框架,然后又加上了自己的东西,算是改变吧,这里主要聊一下我对于我写的这个东西的理解,以及如何写出一个小游戏的理解。
对于一个小游戏可以使用一个固定的框架
int main()
{
HideCursor(); //隐藏光标
starup(); //游戏初始化
while(1) //循环刷新执行
{
show(); //显示画面,打印结果
updatewithinput(); //与用户输入无关的更新
updatewithoutinput(); //与用户输入有关的更新
}
return 0;
}
这个主函数的框架适用于许多的小游戏,当然如果游戏项目过大,可以自行添加其他的东西在主函数里,这里就不说很复杂的了。
我也是根据网课老师讲的按照函数封装的方法写的,这样的代码可读性更强,修改起来也跟方便。
下面先给大家看一下我的源码,这个是不能直接运行的吗,因为默图像处理函数的头文件是需要自己添加进去的。
程序源码:
#include <graphics.h>
#pragma comment(lib,"Winmm.lib")
#include<windows.h>
#include<conio.h>
int bird_y;
int bird_x;
//定义图片
IMAGE img_bk,img_bd1,img_bd2,img_bar1_up1,img_bar1_up2,img_bar1_down1,img_bar1_down2;
int y1=-300,y2=400; //初始位置
int k=0;
int randposition; //随机位置
int up1,down1; //上管口纵坐标和下管口纵坐标
int bar1_x1,bar1_x2,bar_top1,bar_top2,jianxi=100; //管子的横坐标和管子的左上角坐标
int randk=1; //randk每次会变成相反数
int p = 50;
IMAGE img_bar2_up1,img_bar2_up2,img_bar2_down1,img_bar2_down2;
int up2,down2;
void startup()//游戏初始化
{
mciSendString("open \"D:\\sucai\\background.mp3\" alias bkmusic", NULL, 0, NULL);//打开背景音乐
mciSendString("play bkmusic repeat", NULL, 0, NULL); // 循环播放
initgraph(350, 600);
//加载图片
loadimage(&img_bk, "D:\\sucai\\background.jpg");
loadimage(&img_bd1, "D:\\sucai\\bird1.jpg");
loadimage(&img_bd2, "D:\\sucai\\bird2.jpg");
loadimage(&img_bar1_up1, "D:\\sucai\\bar_up1.gif");
loadimage(&img_bar1_up2, "D:\\sucai\\bar_up2.gif");
loadimage(&img_bar1_down1, "D:\\sucai\\bar_down1.gif");
loadimage(&img_bar1_down2, "D:\\sucai\\bar_down2.gif");
bird_x = 10;
bird_y = 200;
bar1_x1=355;
bar_top1=y1;
bar_top2=y2;
jianxi=bar_top2-bar_top1;
up1=600+bar_top1;
down1=bar_top2;
BeginBatchDraw();
}
void s() //开始的加载界面
{
char input;
initgraph(350, 600);
IMAGE start,k;
loadimage(&start, "D:\\sucai\\title.png");
putimage(80, 420, &start);
loadimage(&k,"D:\\sucai\\tutorial.png");
putimage(100, 220, &k);
Sleep(5000);
BeginBatchDraw();
}
void show() //画面显示
{
putimage(0, 0, &img_bk); // 显示背景
putimage(bar1_x1,bar_top1, &img_bar1_up1,NOTSRCERASE); // 显示上一半的障碍物
putimage(bar1_x1,bar_top1,& img_bar1_up2,SRCINVERT);
putimage(bar1_x1 ,bar_top2,& img_bar1_down1,NOTSRCERASE); // 显示下一半的障碍物
putimage(bar1_x1,bar_top2,& img_bar1_down2,SRCINVERT);
putimage(bird_x, bird_y, &img_bd1,NOTSRCERASE); // 显示小鸟
putimage(bird_x, bird_y,&img_bd2,SRCINVERT);
FlushBatchDraw();
}
无关变量
void updateWithoutInput()
{
int randposition;
if (bird_y<600&&k==0)
bird_y = bird_y+5;
if(bird_y>=600&&k==1)
exit(0);
if(bird_x<=bar1_x2&&bird_x>=bar1_x1)
{
if(bird_y<=up1||bird_y>=down1)
{
exit(0);
}
}
if(bar1_x1>-145)
{
bar1_x1-=2;
}
else
{
bar1_x1=355;
randk=-randk;
randposition=rand()%150;
bar_top2=y2+randposition*randk;
down1=bar_top2;
up1=down1-100;
bar_top1=up1-600;
}
static int speed=0; //控制速度
if(speed<k)
{
speed++;
Sleep(10);
}
else
{
if(speed==k)
{
//根据速度更新位置
speed=0;
}
}
Sleep(30);
bar1_x2=bar1_x1+140;
}
有关变量
void updateWithInput()
{
char input;
if(kbhit()) // 判断是否有输入
{
input = getch();
if (input == ' ' && bird_y>10&&k==0)
{
bird_y = bird_y - 40;
mciSendString("close jpmusic", NULL, 0, NULL); // 先把前面一次的音乐关闭
mciSendString("open D:\\sucai\\Jump.mp3 alias jpmusic", NULL, 0, NULL); // 打开跳动音乐
mciSendString("play jpmusic", NULL, 0, NULL); // 仅播放一次
}
}
}
void gameover()
{
EndBatchDraw();
getch();
closegraph();
}
int main()
{
s();
startup(); // 数据初始化
while (1) // 游戏循环执行
{
show(); // 显示画面
updateWithoutInput(); // 与用户输入无关的更新
updateWithInput(); // 与用户输入有关的更新
}
gameover(); // 游戏结束、后续处理
return 0;
}
其实我觉得我写的代码还是比较清晰的,让我解释的话我也不知道从何讲起,每一个封装过的函数都是独立的,但是他们通过全局变量联系到一起,全局变量在updateWithoutInput()和updateWithInput()里发生变化,然后show()函数里的变量发生变化,打印的结果发生变化,对于如何安装图像处理函数的头文件,我之后的话会单独发一篇博客来教大家。