网站接广告平台,创建视频网站,网站色差表,wordpress参考文件夹个人主页#xff1a;北海 #x1f390;CSDN新晋作者 #x1f389;欢迎 #x1f44d;点赞✍评论⭐收藏✨收录专栏#xff1a;C/C#x1f91d;希望作者的文章能对你有所帮助#xff0c;有不足的地方请在评论区留言指正#xff0c;大家一起学习交流#xff01;#x1f9… 个人主页北·海 CSDN新晋作者 欢迎 点赞✍评论⭐收藏✨收录专栏C/C希望作者的文章能对你有所帮助有不足的地方请在评论区留言指正大家一起学习交流 天天酷跑,一款童年游戏,主要是进行跳跃操作,和躲避障碍物,该结主要实现背景图的连续播放,跳跃,与障碍物创建 一.游戏的展示效果 二.本节开发日志 1.创建项目 2.导入素材 3.创建游戏界面 实际的开发流程 对于初学者,最好的开发方式,从用户界面入手 选择图形库或者其他引擎 天天酷跑,是基于easyx图形库的 1)创建游戏窗口 2)实现游戏背景 a.3重背景不同的速度同时移动 b.循环滚动背景的实现 3)实现游戏背景 a.加载背景资源 b.渲染 (背景知识 : 坐标) 遇到问题 : 背景图片的png格式图片出现黑色 使用putimagePNG2接口 4)创建人物 5)创建障碍物小乌龟 三.素材
在主页有放置
四.游戏实现 1)创建C项目将素材导入项目
#include iostreamusing namespace std;int main(){return 0;
} 2)游戏初始化
对于新手而言,建议拿到游戏的时候,从游戏的背景图进行入手,由于在游戏边玩边从磁盘加载资源,这样会影响游戏的体验,这也就是为什么王者荣耀进去时候要加载的原因,都是在开始游戏之前先把资源加载到项目里面,我们就可以在游戏开始之前进行创建一个用于初始化的函数,用于专门加载这些资源 需要用到的头文件 : graphics.h,这个需要安装easyx图形库,可在该官网进行下载安装 需要用到的函数 : loadimage用于将资源从磁盘加载进来 putimagePNG2,自定义的接口用于解决png图片出现黑边,和将加载的图片渲染到屏幕上,在主页文章有介绍该接口 initgraph : 用于创建游戏窗口 sprintf函数,可以对字符串进行格式化,改每个图片的路径 IMAGE: 用于存放图片资源 1.实现游戏窗口的创建与游戏背景的加载
#include iostream
#include graphics.h//窗口的大小,一般在开发中由项目经理规定,定义为宏不仅可以增强代码的可读性还可以增强代码的健壮性
#define WIN_WIDTH 1012
#define WIN_HEIGHT 396
using namespace std;IMAGE imgBg[3];void init(){//创建游戏窗口initgraph(WIN_WIDTH, WIN_HEIGHT);//加载游戏背景char name[64];for (int i 0; i 3; i) {//res/bg001.png res/bg002.pngsprintf_s(name, res/bg%03d.png, i 1);loadimage(imgBgs[i], name);}}int main(){init();//用于初始化return 0;
} 2.渲染游戏背景图,可以创建一个专门渲染图片的函数updataBg() 这边不太会搞视频展示图,所以就简单描述一下,背景图往左连绵不断的走,有三层,草坪,山,天空,既然能连绵不断,这个实现的方法拿图来解释 由于由三层,每层的y坐标都是不同的,y坐标可以测量出来,由于背景需要滚动,原理是移动当前背景图,使其向左移动,当图片的最右边达到游戏窗口的最左边时候,重新复原图片的位置,使图片的最左边到达窗口的最左边,进行循环,循环的时候,三层图片以不同的速度进行移动,所以创建一个数组bgSpeed,用于存放三个图片的速度,bgX数组用于存放当前的x值,由于游戏是个死循环,所以除了初始化,其余函数套在while(1)循环里 int bgSpeed[3] {1,2,4};
int bgX[3];//背景图片的x坐标//渲染游戏背景
void updateBg() {putimagePNG2(bgX[0], 0, WIN_WIDTH,imgBgs[0]);putimagePNG2(bgX[1], 119,WIN_WIDTH, imgBgs[1]);putimagePNG2 (bgX[2], 330, WIN_WIDTH,imgBgs[2]);}void init(){//for循环里,添加bgX[i] 0 ;给变量进行初始化}
int main(){
init();while(1){
updateBg();
}
...
} 3.由于上面渲染的渲染背景图还是静态的,没有移动,因为bgx并没有改变,此时需要一个专门改变游戏数据的函数,fly函数吧
void fly(){for(int i 0 ;i3;i){bgX[i] -bgSpeed[i];//使每层图片减去他对应的速度//做一个判断,当达到最左边时候,复位图片的位置if(bgX[i] -WIN_WIDTH){
bgX[i] 0;}}
}
4.此时的背景图已经开始滚动了,但是还有个小bug,因为这个渲染时用循环putimage上去的,就相当于将图片打印到上面,这也会出现的情况是每层图片之间会一闪一闪的,解决这个问题的方法,是先将他们输出到缓存区,一并打印出来,用到的函数如下: BeginBatchDraw() EndBatchDraw(); 此时就解决了背景的第一个问题
背景图实现,程序的进度: #include iostream
#includegraphics.h
#include tools.h#define WIN_WIDTH 1012
#define WIN_HEIGHT 396using namespace std;/*
1.先做背景
*/IMAGE imgBgs[3];
int bgSpeed[3] { 1,2,4 };
int bgX[3];void init() {//创建游戏窗口initgraph(WIN_WIDTH, WIN_HEIGHT);//加载背景图char name[64];for (int i 0; i 3; i) {//res/bg001.png res/bg002.pngsprintf_s(name, res/bg%03d.png, i 1);loadimage(imgBgs[i], name);bgX[i] 0;}}void updataBg() {putimagePNG2(bgX[0], 0,WIN_WIDTH, imgBgs[0]);putimagePNG2(bgX[1], 119,WIN_WIDTH, imgBgs[1]);putimagePNG2(bgX[2], 330,WIN_WIDTH, imgBgs[2]);
}void fly() {//背景图for (int i 0; i 3; i) {bgX[i] - bgSpeed[i];if (bgX[i] -WIN_WIDTH) {bgX[i] 0;}}
}
int main() {init();while (1) {BeginBatchDraw();updataBg();EndBatchDraw();fly();}system(pause);return 0;
} 3)创建玩家
1.由于图片在动,只需要将人物在原地就行,将人物放在最中间,由于要实现人物的运动,这个的原理是将人物的多组图片进行轮播,人物的x,y坐标可以通过数学进行算出来,此时我们先在初始化函数里加载图片,在初始化函数里计算出人物的x,y坐标,由于人物的轮播,可以传创建一个帧序列
//人物的背景图
IMAGE imgHero[12];
int heroX;
int heroY;
int heroIndex;//帧序号void init(){...
//加载人物的图片,仍然老套路,用到sprintf函数for (int i 0; i 12; i) {sprintf(name, res/hero%d.png, i 1);loadimage(imgHero[i], name);}//人物初始化heroX WIN_WIDTH * 0.5 - imgHero[0].getwidth() * 0.5;heroY 345 - imgHero[0].getheight();heroIndex 0;}
由于帧序列要改变才能实现轮播,所以需要在数据层的fly函数,进行修改帧序列
void fly(){....//修改帧序列,
/*heroIndex;//如果使用这种方法的话,当进行越界,我们需要的是从1-12进行循环,所以我们用取余数进行实现
*/heroIndex (heroIndex1)%12;}
数据也可也可以改变了,我们需要将人物的图片渲染在窗口中,在main函数中只需要一条代码
int main(){...//实现人物的奔跑
putimagePNG2(heroX, heroY, WIN_WIDTH , imgHero[heroIndex]);
...
}
效果图 这样人物就可以原地跑起来了,解决了第二个问题
4)实现玩家的跳跃
1.人物的跳跃是当玩家按下按键后,人物的y坐标开始上升,当达到某个高度后,然后下落
先来实现用户点击函数keyEvent(),由于只需要改变y坐标,底层的数据变化实在fly函数里面,我们只需要获取到用户的点击之后,给个可以改变y值得信号即可 用到的_kbhit()函数和_getch()函数都必须包含头文件conio.h 问题 : 都是从键盘获取一个字符为什么不用scanf()而用_getch() 答:如果使用scanf函数, 当输入数据,必须按回车,才能将数据输入进去,此时不按回车的话,程序会等待用户按回车键,此时的程序就卡在这里等待了,而用_hbhit()函数,不用等待,直接按下就可以输入进去 void keyEvent(){//先接收用户得鼠标消息char ch 0 ;if(_kbhit()){ch _getch();if(ch ){jump();}}
}
实现初始化顺便打开可跳跃得按钮
//全局变量
bool heroJump;//跳跃状态
int jumpHeightMax;//跳跃得最大高度
int heroJumpOff;//跳跃得偏移量void init(){...
//对跳跃得数据进行初始化//跳跃初始化heroJump false;jumpHeightMax 345 - imgHero[0].getheight() - 120;heroJumpOff -4;}void jump(){heroJump true;}
在fly函数里改变底层数据
void fly() {...//实现跳跃if (heroJump) {if (heroY jumpHeightMax) {heroJumpOff 4;// (-4)等于向上走,4等于向下走}heroY heroJumpOff;if (heroY 345 - imgHero[0].getheight()) {//达到地面heroJump false;heroJumpOff -4;}}
} 此时的英雄就可以进行跳跃了 这样人物就可以跳跃起来了,就能跳跃障碍物了,解决了第三个问题,此时还面临一个小bug,就是在当跳跃的途中,这个人物还处于一个跑步的状态,影响了用户体验,解决这个问题,我们就可以在改变底层数据里改部分代码,如果处于起跳状态则不更新帧序列,否则不跳的时候更新帧序列,以下是改变之后的渲染代码:
//人物跳跃if (heroJump) {if (heroY jumpHeightMax) {heroJumpOff 4;}heroY heroJumpOff;if (heroY 345 - imgHero[0].getheight()) {heroJump false;heroJumpOff -4;}}else {//heroIndex 这种方式会越界heroIndex (heroIndex 1) % 12;}
这样就解决了这个小bug,以上实现了背景图的轮播,人物的动态化,和人物的起跳,主要学到了,将渲染层,数据层分开,其他小的功能进行分支化,将main函数写的简介,实现功能模块化,接下来就可以实现障碍物了
5)障碍物小乌龟的实现
1.障碍物有许多种,先实现一种,其他的在做优化,依旧是老套路,初始化里面加载资源,渲染层进行打印图片,fly里面改变数据
2.先将小乌龟设置为静态的,优化时候也可加个帧序列实现动态的
定义小乌龟的变量
//全局状态
//小乌龟
IMAGE imgTortoise;
//小乌龟存在开关
bool torToiseExist;
int torToiseX;
int torToiseY; 将小乌龟进行初始化
//初始化小乌龟
void init(){...//小乌龟初始化loadimage(imgTortoise, res/t1.png);torToiseY 345 5 - imgTortoise.getheight();torToiseExist false;}
从底层数据方面对小乌龟进行创建与使其移动 编程技巧:在创建小乌龟时候,如果直接写 void fly(){
...//创建小乌龟static int frameCount 0;static int enemyFre 100;frameCount;if (frameCount enemyFre) {frameCount 0;enemyFre 100 rand() % 50;//创建障碍物if (!torToiseExist) {torToiseExist true;torToiseX WIN_WIDTH;}}//使小乌龟的运动,运动应该于草坪的移动速度保持一致,才能显得静止在草坪上if (torToiseExist) {torToiseX - bgSpeed[2];if (torToiseX -imgTortoise.getwidth()) {torToiseExist false;}}}
将小乌龟渲染出来
void updateEnemy() {//渲染小乌龟if (torToiseExist) {putimagePNG2(torToiseX, torToiseY,WIN_WIDTH, imgTortoise);}
} 将其函数在main函数中调用,和渲染人物一起渲染出来 此时代码进度为:
#include iostream
#includegraphics.h
#include conio.h
#include tools.h#define WIN_WIDTH 1012
#define WIN_HEIGHT 396using namespace std;/*
1.先做背景
2.创建玩家
3.实现玩家跳跃
*///背景
IMAGE imgBgs[3];
int bgSpeed[3] { 1,2,4 };
int bgX[3];//人物
IMAGE imgHero[12];
int heroX;
int heroY;
int heroIndex;//帧序列//跳跃
bool heroJump;//跳跃状态
int jumpHeightMax;//跳跃的最大高度
int heroJumpOff;//小乌龟
IMAGE imgTortoise;
//小乌龟存在开关
bool torToiseExist;
int torToiseX;
int torToiseY;void init() {//创建游戏窗口initgraph(WIN_WIDTH, WIN_HEIGHT);//加载背景图char name[64];for (int i 0; i 3; i) {//res/bg001.png res/bg002.pngsprintf_s(name, res/bg%03d.png, i 1);loadimage(imgBgs[i], name);bgX[i] 0;}//加载人物背景图for (int i 0; i 12; i) {sprintf(name, res/hero%d.png, i 1);loadimage(imgHero[i], name);}//人物的位置放在窗口的最中间,由于人物需要运动,用多组图片进行轮播,需要定义一个帧序列heroX WIN_WIDTH * 0.5 - imgHero[0].getwidth() * 0.5;heroY 345 - imgHero[0].getheight();heroIndex 0;//跳跃heroJump false;jumpHeightMax 345 - imgHero[0].getheight() - 120;heroJumpOff -4;//小乌龟初始化loadimage(imgTortoise, res/t1.png);torToiseY 345 5 - imgTortoise.getheight();torToiseExist false;}void updataBg() {putimagePNG2(bgX[0], 0, WIN_WIDTH, imgBgs[0]);putimagePNG2(bgX[1], 119, WIN_WIDTH, imgBgs[1]);putimagePNG2(bgX[2], 330, WIN_WIDTH, imgBgs[2]);
}void updateEnemy() {//渲染小乌龟if (torToiseExist) {putimagePNG2(torToiseX, torToiseY,WIN_WIDTH, imgTortoise);}
}void fly() {//背景图for (int i 0; i 3; i) {bgX[i] - bgSpeed[i];if (bgX[i] -WIN_WIDTH) {bgX[i] 0;}}//实现跳跃if (heroJump) {if (heroY jumpHeightMax) {heroJumpOff 4;// (-4)等于向上走,4等于向下走}heroY heroJumpOff;if (heroY 345 - imgHero[0].getheight()) {//达到地面heroJump false;heroJumpOff -4;}}else {//改变人物帧序列heroIndex (heroIndex 1) % 12;}//创建小乌龟static int frameCount 0;static int enemyFre 100;frameCount;if (frameCount enemyFre) {frameCount 0;enemyFre 100 rand() % 50;//创建障碍物if (!torToiseExist) {torToiseExist true;torToiseX WIN_WIDTH;}}//使小乌龟的运动,运动应该于草坪的移动速度保持一致,才能显得静止在草坪上if (torToiseExist) {torToiseX - bgSpeed[2];if (torToiseX -imgTortoise.getwidth()) {torToiseExist false;}}}void jump() {//跳跃只需要改变y值即可,在底层数据管理函数实现,此时只需要给出可以改数据的信号即可heroJump true;
}void keyEvent() {//获取玩家键盘事件char ch 0;if (_kbhit()) {ch _getch();if (ch ) {jump();}}}
int main() {init();while (1) {keyEvent();BeginBatchDraw();//渲染背景updataBg();//渲染人物putimagePNG2(heroX, heroY, imgHero[heroIndex]);//渲染障碍物updateEnemy();EndBatchDraw();fly();Sleep(30);}system(pause);return 0;
}
6)对代码进行优化
1.在main函数的最后用了一条函数sleep(30),会将程序休眠30毫秒,如果在此期间有用户的键盘输入,会降低游戏的体验性
2.在创建小乌龟时候,由于只演示了一种障碍物,而添加障碍物时候,应该建立一个专门创建障碍物的函数 先解决第一点 在tools.cpp里有getDalay,用于计算上一次调用到现在的间隔时间,在全局状态定义一个计时器timer,在定义一个刷新界面的变量update,如果update为真,则开始刷新界面,如果间隔大于30毫秒,则将刷新界面变量至于true状态,可以代替30ms的休眠间隔,增强体验感 int main() {init();while (true) {keyEvent();timer getDelay();if (timer 30) {timer 0;update true;}if (update) {update false;BeginBatchDraw();updataBg();//实现人物的奔跑putimagePNG2(heroX, heroY, imgHero[heroIndex]);//渲染障碍物updateEnemy();EndBatchDraw();fly();}}system(pause);return 0;
} 解决第二点,将创建小乌龟障碍物先封装为一个函数,在下一期进行改善为可随机创建多种障碍物 void creatObstacle() {//小乌龟初始化if (!torToiseExist) {torToiseExist true;torToiseX WIN_WIDTH;}} 在原来fly函数里面,用creatObstacle()代替上面函数体内的三条语句即可 五.本节总结 总结 : 这结实现了背景轮播图的实现,人物的创建,障碍物的创建,动态的原理就是改变帧序列,开发技巧是将渲染层,数据层分开,其他功能封装为函数,围绕这两个函数展开,将main函数变的简单明了,讲述了开发技巧,计时器的使用,改善休眠间隔的方法 文章转载自: http://www.morning.lthgy.cn.gov.cn.lthgy.cn http://www.morning.zmlnp.cn.gov.cn.zmlnp.cn http://www.morning.tqfnf.cn.gov.cn.tqfnf.cn http://www.morning.hkcjx.cn.gov.cn.hkcjx.cn http://www.morning.kgfsz.cn.gov.cn.kgfsz.cn http://www.morning.yuminfo.com.gov.cn.yuminfo.com http://www.morning.zqwp.cn.gov.cn.zqwp.cn http://www.morning.plhyc.cn.gov.cn.plhyc.cn http://www.morning.kntbk.cn.gov.cn.kntbk.cn http://www.morning.rbjf.cn.gov.cn.rbjf.cn http://www.morning.rbnnq.cn.gov.cn.rbnnq.cn http://www.morning.bpmtl.cn.gov.cn.bpmtl.cn http://www.morning.bgygx.cn.gov.cn.bgygx.cn http://www.morning.rlbfp.cn.gov.cn.rlbfp.cn http://www.morning.ns3nt8.cn.gov.cn.ns3nt8.cn http://www.morning.tmpsc.cn.gov.cn.tmpsc.cn http://www.morning.ylljn.cn.gov.cn.ylljn.cn http://www.morning.rnmmh.cn.gov.cn.rnmmh.cn http://www.morning.qcymf.cn.gov.cn.qcymf.cn http://www.morning.mqwdh.cn.gov.cn.mqwdh.cn http://www.morning.jpydf.cn.gov.cn.jpydf.cn http://www.morning.bphqd.cn.gov.cn.bphqd.cn http://www.morning.ckhry.cn.gov.cn.ckhry.cn http://www.morning.pdwzr.cn.gov.cn.pdwzr.cn http://www.morning.dcmnl.cn.gov.cn.dcmnl.cn http://www.morning.rwmqp.cn.gov.cn.rwmqp.cn http://www.morning.rynq.cn.gov.cn.rynq.cn http://www.morning.bzgpj.cn.gov.cn.bzgpj.cn http://www.morning.lkthj.cn.gov.cn.lkthj.cn http://www.morning.mlyq.cn.gov.cn.mlyq.cn http://www.morning.lmxrt.cn.gov.cn.lmxrt.cn http://www.morning.qpqwb.cn.gov.cn.qpqwb.cn http://www.morning.wdpt.cn.gov.cn.wdpt.cn http://www.morning.ybnzn.cn.gov.cn.ybnzn.cn http://www.morning.ryfpx.cn.gov.cn.ryfpx.cn http://www.morning.gnlyq.cn.gov.cn.gnlyq.cn http://www.morning.hwzzq.cn.gov.cn.hwzzq.cn http://www.morning.rrxgx.cn.gov.cn.rrxgx.cn http://www.morning.smxrx.cn.gov.cn.smxrx.cn http://www.morning.sbyhj.cn.gov.cn.sbyhj.cn http://www.morning.bxfy.cn.gov.cn.bxfy.cn http://www.morning.kbgzj.cn.gov.cn.kbgzj.cn http://www.morning.nqrlz.cn.gov.cn.nqrlz.cn http://www.morning.kpzrf.cn.gov.cn.kpzrf.cn http://www.morning.snyqb.cn.gov.cn.snyqb.cn http://www.morning.qmmfr.cn.gov.cn.qmmfr.cn http://www.morning.cjnfb.cn.gov.cn.cjnfb.cn http://www.morning.lcbt.cn.gov.cn.lcbt.cn http://www.morning.wjlkz.cn.gov.cn.wjlkz.cn http://www.morning.mfsxd.cn.gov.cn.mfsxd.cn http://www.morning.sqnxk.cn.gov.cn.sqnxk.cn http://www.morning.pdbgm.cn.gov.cn.pdbgm.cn http://www.morning.deupp.com.gov.cn.deupp.com http://www.morning.drbd.cn.gov.cn.drbd.cn http://www.morning.daidudu.com.gov.cn.daidudu.com http://www.morning.kbqqn.cn.gov.cn.kbqqn.cn http://www.morning.xkgyh.cn.gov.cn.xkgyh.cn http://www.morning.ryysc.cn.gov.cn.ryysc.cn http://www.morning.wnpps.cn.gov.cn.wnpps.cn http://www.morning.ydwsg.cn.gov.cn.ydwsg.cn http://www.morning.pcgjj.cn.gov.cn.pcgjj.cn http://www.morning.ttdbr.cn.gov.cn.ttdbr.cn http://www.morning.rynq.cn.gov.cn.rynq.cn http://www.morning.nqgjn.cn.gov.cn.nqgjn.cn http://www.morning.lkbdy.cn.gov.cn.lkbdy.cn http://www.morning.xnpj.cn.gov.cn.xnpj.cn http://www.morning.mbaiwan.com.gov.cn.mbaiwan.com http://www.morning.fswml.cn.gov.cn.fswml.cn http://www.morning.dtnzk.cn.gov.cn.dtnzk.cn http://www.morning.kkdbz.cn.gov.cn.kkdbz.cn http://www.morning.mgkcz.cn.gov.cn.mgkcz.cn http://www.morning.dbsch.cn.gov.cn.dbsch.cn http://www.morning.tkcz.cn.gov.cn.tkcz.cn http://www.morning.phnbd.cn.gov.cn.phnbd.cn http://www.morning.dglszn.com.gov.cn.dglszn.com http://www.morning.mpszk.cn.gov.cn.mpszk.cn http://www.morning.kgkph.cn.gov.cn.kgkph.cn http://www.morning.bfrsr.cn.gov.cn.bfrsr.cn http://www.morning.xrpjr.cn.gov.cn.xrpjr.cn http://www.morning.wpkr.cn.gov.cn.wpkr.cn