C++怎么利用easyx图形库实现天天酷跑小游戏

未分类   2024年05月09日 14:58  

这篇文章主要介绍“C++怎么利用easyx图形库实现天天酷跑小游戏”,在日常操作中,相信很多人在C++怎么利用easyx图形库实现天天酷跑小游戏问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C++怎么利用easyx图形库实现天天酷跑小游戏”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

开发日志

1.创建项目

2.导入素材

3.创建游戏界面

从用户界面入手

选择图形库或者其他引擎,酷跑是基于“easyx”图形库的

1)创建游戏窗口

2)设计游戏背景

a.三重背景不同的速度移动

b.循环滚动背景的实现

3)实现游戏背景

a.加载背景资源

b.渲染(实现打印图片的效果)背景知识:坐标

遇到的问题:背景图片的png格式图片出现黑色

4.实现玩家奔跑

5.实现玩家跳跃

6.实现随机小乌龟

7.创建结构体结构类型

8.使用障碍物结构体后重新初始化

9.封装后多个障碍物的显示

10.实现玩家的下蹲技能

11.添加柱子障碍物

代码实现//#undefUNICODE//#undef_UNICODE#include<stdio.h>#include<graphics.h>#include<conio.h>#include<vector>//c++长度可变的数组#include"tools.h"usingnamespacestd;//声明命名空间#defineWIN_SCORE10#defineWIN_WIDTH1012//定义宏便于后期维护与处理#defineWIN_HEIGHT396#defineOBSTACLE_COUNT10IMAGEimgBgs[3];//背景图片——创建图片数组intbgX[3];//背景图片的X坐标(不断变化)intbgSpeed[3]={1,2,4};//控制3个背景不同速度IMAGEimgHeros[12];//人物不断奔跑的实现intheroX;//玩家的X坐标intheroY;//玩家的Y坐标intheroIndex;//玩家奔跑的图片帧序号boolheroJump;//表示玩家正在跳跃intjumpHeightMax;//跳跃的最大高度intheroJumpOff;//跳跃偏移量intupdate;//表示是否需要马上刷新画面//IMAGEimgTortoise;//小乌龟//inttorToiseX;//小乌龟的水平坐标//inttorToiseY;//小乌龟的竖直坐标//booltorToiseExist;//当前窗口是否有小乌龟intheroBlood;//定义玩家血量intscore;typedefenum{TORTOISE,//乌龟0LION,//狮子1HOOK1,HOOK2,HOOK3,HOOK4,OBSTACLE_TYPE_COUNT//边界6}obstacle_type;//相当于IMAGEobstacleImgs[3][5]vector<vector<IMAGE>>obstacleImgs;//二维数组存放所有障碍物的各个图片typedefstructobstacle{inttype;//障碍物的类型intimgIndex;//当前显示的图片的序号intx,y;//障碍物的坐标intspeed;intpower;//杀伤力boolexist;boolhited;//表示是否已经发生碰撞boolpassed;//表示是否已经被通过}obstacle_t;obstacle_tobstacles[OBSTACLE_COUNT];intlastObsIndex;//解决障碍物bug(柱子与狮子在一起)IMAGEimgHeroDown[2];boolheroDown;//表示玩家是否处于下蹲状态IMAGEimgSZ[10];//游戏的初始化voidinit(){//创建游戏窗口initgraph(WIN_WIDTH,WIN_HEIGHT,EW_SHOWCONSOLE);//加载背景资源charname[64];for(inti=0;i<3;i++){//路径"res/bg001.png""res/bg002.png""res/bg003.png"sprintf(name,"res/bg%03d.png",i+1);//%03d占3位,不足3位自动补0//#undef_UNICODEloadimage(&imgBgs[i],name);//把3个图片加载到了图片数组的位置bgX[i]=0;}//加载Hero奔跑的图片帧素材for(inti=0;i<12;i++){sprintf(name,"res/hero%d.png",i+1);loadimage(&imgHeros[i],name);}//设置玩家的初始位置heroX=WIN_WIDTH*0.5-imgHeros[0].getwidth()*0.5;//X坐标:屏幕宽度的一半减去人物宽度的一半heroY=345-imgHeros[0].getheight();//Y坐标:脚底坐标减去人物高度heroIndex=0;heroJump=false;jumpHeightMax=345-imgHeros[0].getheight()-120;heroJumpOff=-4;update=true;加载小乌龟素材//loadimage(&imgTortoise,"res/t1.png");//torToiseExist=false;//torToiseY=345-imgTortoise.getheight()+5;IMAGEimgTort;loadimage(&imgTort,"res/t1.png");vector<IMAGE>imgTortArray;imgTortArray.push_back(imgTort);//添加图片obstacleImgs.push_back(imgTortArray);IMAGEimgLion;vector<IMAGE>imgLionArray;for(inti=0;i<6;i++){sprintf(name,"res/p%d.png",i+1);loadimage(&imgLion,name);imgLionArray.push_back(imgLion);}obstacleImgs.push_back(imgLionArray);//初始化障碍物池for(inti=0;i<OBSTACLE_COUNT;i++){obstacles[i].exist=false;}//加载下蹲素材loadimage(&imgHeroDown[0],"res/d1.png");loadimage(&imgHeroDown[1],"res/d2.png");heroDown=false;//加载柱子图片IMAGEimgH;for(inti=0;i<4;i++){vector<IMAGE>imgHookArray;sprintf(name,"res/h%d.png",i+1);loadimage(&imgH,name,63,250,true);//图片进行缩化imgHookArray.push_back(imgH);obstacleImgs.push_back(imgHookArray);}heroBlood=100;//预加载音效preLoadSound("res/hit.mp3");//背景音乐mciSendString("playres/bg.mp3repeat",0,0,0);lastObsIndex=-1;score=0;//加载数字图片for(inti=0;i<10;i++){sprintf(name,"res/sz/%d.png",i);loadimage(&imgSZ[i],name);}}//随机创建障碍物voidcreatObstacle(){inti;for(i=0;i<OBSTACLE_COUNT;i++){if(obstacles[i].exist==false){break;}}if(i>=OBSTACLE_COUNT){return;}obstacles[i].exist=true;obstacles[i].hited=false;obstacles[i].imgIndex=0;//obstacles[i].type=(obstacle_type)(rand()%OBSTACLE_TYPE_COUNT);obstacles[i].type=(obstacle_type)(rand()%3);//如果上一个障碍物是柱子,下一个是狮子,判断距离,若很近,则狮子换为乌龟if(lastObsIndex>=0&&obstacles[lastObsIndex].type>=HOOK1&&obstacles[lastObsIndex].type<=HOOK4&&obstacles[i].type==LION&&obstacles[lastObsIndex].x>WIN_WIDTH-500){obstacles[i].type==TORTOISE;}lastObsIndex=i;if(obstacles[i].type==HOOK1){//降低柱子出现的频率obstacles[i].type+=rand()%4;//0-3}obstacles[i].x=WIN_WIDTH;obstacles[i].y=345+5-obstacleImgs[obstacles[i].type][0].getheight();if(obstacles[i].type==TORTOISE){obstacles[i].speed=0;obstacles[i].power=5;//随意}elseif(obstacles[i].type==LION){obstacles[i].speed=1;obstacles[i].power=20;}elseif(obstacles[i].type>=HOOK1&&obstacles[i].type<=HOOK4){obstacles[i].speed=0;obstacles[i].power=20;obstacles[i].y=0;}obstacles[i].passed=false;}voidcheckHit(){for(inti=0;i<OBSTACLE_COUNT;i++){if(obstacles[i].exist&&obstacles[i].hited==false){inta1x,a1y,a2x,a2y;intoff=30;if(!heroDown){//非下蹲奔跑跳跃a1x=heroX+off;a1y=heroY+off;a2x=heroX+imgHeros[heroIndex].getwidth()-off;a2y=heroY+imgHeros[heroIndex].getheight();}else{a1x=heroX+off;a1y=345-imgHeroDown[heroIndex].getheight();a2x=heroX+imgHeroDown[heroIndex].getwidth()-off;a2y=345;}IMAGEimg=obstacleImgs[obstacles[i].type][obstacles[i].imgIndex];//当前障碍物类型(的第几张图片)intb1x=obstacles[i].x+off;intb1y=obstacles[i].y+off;intb2x=obstacles[i].x+img.getwidth()-off;intb2y=obstacles[i].y+img.getheight()-10;if(rectIntersect(a1x,a1y,a2x,a2y,b1x,b1y,b2x,b2y)){heroBlood-=obstacles[i].power;printf("血量剩余%d\n",heroBlood);playSound("res/hit.mp3");obstacles[i].hited=true;}}}}//让背景动起来voidrun(){for(inti=0;i<3;i++){bgX[i]-=bgSpeed[i];//3个背景移动的速度不同if(bgX[i]<-WIN_WIDTH){bgX[i]=0;}}//实现跳跃if(heroJump){if(heroY<jumpHeightMax)//达到最大跳跃高度跳跃偏移量为正向下跳跃{heroJumpOff=4;}heroY+=heroJumpOff;if(heroY>345-imgHeros[0].getheight())//到达地面跳跃结束{heroJump=false;heroJumpOff=-4;//偏移量初始化}}elseif(heroDown){//人物下蹲staticintcount=0;intdelays[2]={8,30};//设置下蹲的时间不一样count++;if(count>=delays[heroIndex]){count=0;heroIndex++;if(heroIndex>=2){heroIndex=0;heroDown=false;}}}else{//不跳跃heroIndex=(heroIndex+1)%12;//12张图片循环播放完成一系列动作}//创建障碍物staticintframeCount=0;staticintenemyFre=50;frameCount++;if(frameCount>enemyFre){frameCount=0;//if(!torToiseExist){//避免屏幕同时出现多个小乌龟//torToiseExist=true;//torToiseX=WIN_WIDTH;//enemyFre=rand()%301+200;//每200-500帧随机出现一只龟//}enemyFre=rand()%50+50;creatObstacle();}//if(torToiseExist){////更新小乌龟位置//torToiseX-=bgSpeed[2];//if(torToiseX<-imgTortoise.getwidth()){//torToiseExist=false;//}//}//更新所有障碍物的坐标for(inti=0;i<OBSTACLE_COUNT;i++){if(obstacles[i].exist){obstacles[i].x-=obstacles[i].speed+bgSpeed[2];if(obstacles[i].x<-obstacleImgs[obstacles[i].type][0].getwidth()*2){obstacles[i].exist=false;}intlen=obstacleImgs[obstacles[i].type].size();obstacles[i].imgIndex=(obstacles[i].imgIndex+1)%len;}}//玩家和障碍物的“碰撞检测”处理checkHit();}//渲染“游戏背景”voidupdateBg(){//调整背景图片位置putimagePNG2(bgX[0],0,&imgBgs[0]);putimagePNG2(bgX[1],119,&imgBgs[1]);putimagePNG2(bgX[2],330,&imgBgs[2]);}//实现跳跃voidjump(){heroJump=true;update=true;//未处于刷新时也能跳跃}voiddown(){update=true;heroDown=true;heroIndex=0;}//处理用户按键的输入voidkeyEvent(){//charc;//scanf("%c",&c);会直接阻塞程序的执行if(GetAsyncKeyState(VK_UP)){//虚拟键jump();/*if(kbhit())//kbhit()判断有无键盘输入。若有按键按下,则kbhit()返回TRUE{charch=_getch();//不需要按下回车即可直接读取if(ch==''){//按下空格跳跃jump();}*/}elseif(GetAsyncKeyState(VK_DOWN)){down();}}voidupdateEnemy(){//渲染小乌龟/*if(torToiseExist){putimagePNG2(torToiseX,torToiseY,WIN_WIDTH,&imgTortoise);}*/for(inti=0;i<OBSTACLE_COUNT;i++){if(obstacles[i].exist){putimagePNG2(obstacles[i].x,obstacles[i].y,WIN_WIDTH,&obstacleImgs[obstacles[i].type][obstacles[i].imgIndex]);}}}voidupdateHero(){if(!heroDown){//不处于下蹲状态——奔跑跳跃putimagePNG2(heroX,heroY,&imgHeros[heroIndex]);}else{inty=345-imgHeroDown[heroIndex].getheight();putimagePNG2(heroX,y,&imgHeroDown[heroIndex]);}}voidupdateBloodBar(){drawBloodBar(10,10,200,10,2,BLUE,DARKGRAY,RED,heroBlood/100.0);}voidcheckOver(){if(heroBlood<=0){loadimage(0,"res/over.png");FlushBatchDraw();//刷新mciSendString("stopres/bg.mp3",0,0,0);//关掉背景音乐system("pause");//暂停之后,充币复活或者直接开始下一局heroBlood=100;score=0;mciSendString("playres/bg.mp3repeat",0,0,0);}}voidcheckScore(){for(inti=0;i<OBSTACLE_COUNT;i++){if(obstacles[i].exist&&obstacles[i].passed==false&&obstacles[i].x+obstacleImgs[obstacles[i].type][0].getwidth()<heroX&&obstacles[i].hited==false){score++;obstacles[i].passed=true;printf("score:%d\n",score);}}}voidupdateScore(){charstr[8];sprintf(str,"%d",score);intx=20;inty=25;for(inti=0;str[i];i++){intsz=str[i]-'0';putimagePNG(x,y,&imgSZ[sz]);x+=imgSZ[sz].getwidth()+5;}}voidcheckWin(){if(score>=WIN_SCORE){FlushBatchDraw();mciSendString("playres/win.mp3",0,0,0);Sleep(2000);loadimage(0,"res/win.png");FlushBatchDraw();mciSendString("stopres/bg.mp3",0,0,0);system("pause");heroBlood=100;score=0;mciSendString("playres/bg.mp3repeat",0,0,0);}}intmain(void){init();//显示初始化面loadimage(0,"res/over.png");system("pause");inttimer=0;while(1){keyEvent();timer+=getDelay();//此函数返回距离上一次调用间隔的时间,第一次返回0if(timer>30){//30毫秒刷新时间timer=0;update=true;}if(update){update=false;BeginBatchDraw();//这个函数用于开始批量绘图。执行后,任何绘图操作都将暂时不输出到绘图窗口上,直到执行FlushBatchDraw或EndBatchDraw才将之前的绘图输出。updateBg();//putimagePNG2(heroX,heroY,&imgHeros[heroIndex]);updateHero();updateEnemy();updateBloodBar();updateScore();checkWin();EndBatchDraw();//这个函数用于结束批量绘制,并执行未完成的绘制任务。这两个函数主要为了消除闪烁。checkOver();checkScore();run();}//Sleep(30);//休眠}system("pause");return0;}##tool头文件```javascript#include<stdio.h>#include<Windows.h>#include"tools.h"#include<mmsystem.h>#pragmacomment(lib,"winmm.lib")intgetDelay(){staticunsignedlonglonglastTime=0;unsignedlonglongcurrentTime=GetTickCount();if(lastTime==0){lastTime=currentTime;return0;}else{intret=currentTime-lastTime;lastTime=currentTime;returnret;}}//载入PNG图并去透明部分voidputimagePNG(intpicture_x,intpicture_y,IMAGE*picture)//x为载入图片的X坐标,y为Y坐标{DWORD*dst=GetImageBuffer();//GetImageBuffer()函数,用于获取绘图设备的显存指针,EASYX自带DWORD*draw=GetImageBuffer();DWORD*src=GetImageBuffer(picture);//获取picture的显存指针intpicture_width=picture->getwidth();//获取picture的宽度,EASYX自带intpicture_height=picture->getheight();//获取picture的高度,EASYX自带intgraphWidth=getwidth();//获取绘图区的宽度,EASYX自带intgraphHeight=getheight();//获取绘图区的高度,EASYX自带intdstX=0;//在显存里像素的角标//实现透明贴图公式:Cp=αp*FP+(1-αp)*BP,贝叶斯定理来进行点颜色的概率计算for(intiy=0;iy<picture_height;iy++){for(intix=0;ix<picture_width;ix++){intsrcX=ix+iy*picture_width;//在显存里像素的角标intsa=((src[srcX]&0xff000000)>>24);//0xAArrggbb;AA是透明度intsr=((src[srcX]&0xff0000)>>16);//获取RGB里的Rintsg=((src[srcX]&0xff00)>>8);//Gintsb=src[srcX]&0xff;//Bif(ix>=0&&ix<=graphWidth&&iy>=0&&iy<=graphHeight&&dstX<=graphWidth*graphHeight){dstX=(ix+picture_x)+(iy+picture_y)*graphWidth;//在显存里像素的角标intdr=((dst[dstX]&0xff0000)>>16);intdg=((dst[dstX]&0xff00)>>8);intdb=dst[dstX]&0xff;draw[dstX]=((sr*sa/255+dr*(255-sa)/255)<<16)//公式:Cp=αp*FP+(1-αp)*BP;αp=sa/255,FP=sr,BP=dr|((sg*sa/255+dg*(255-sa)/255)<<8)//αp=sa/255,FP=sg,BP=dg|(sb*sa/255+db*(255-sa)/255);//αp=sa/255,FP=sb,BP=db}}}}//适用于y<0以及x<0的任何情况voidputimagePNG2(intx,inty,IMAGE*picture){IMAGEimgTmp;if(y<0){SetWorkingImage(picture);getimage(&imgTmp,0,-y,picture->getwidth(),picture->getheight()+y);SetWorkingImage();y=0;picture=&imgTmp;}if(x<0){SetWorkingImage(picture);getimage(&imgTmp,-x,0,picture->getwidth()+x,picture->getheight());SetWorkingImage();x=0;picture=&imgTmp;}putimagePNG(x,y,picture);}//适用于y<0以及y>0的任何情况voidputimagePNG2(intx,inty,intwinWidth,IMAGE*picture){IMAGEimgTmp;if(y<0){SetWorkingImage(picture);getimage(&imgTmp,0,-y,picture->getwidth(),picture->getheight()+y);SetWorkingImage();y=0;picture=&imgTmp;}if(x<0){SetWorkingImage(picture);getimage(&imgTmp,-x,0,picture->getwidth()+x,picture->getheight());SetWorkingImage();x=0;picture=&imgTmp;}elseif(x>=winWidth){return;}elseif(x>winWidth-picture->getwidth()){SetWorkingImage(picture);getimage(&imgTmp,0,0,winWidth-x,picture->getheight());SetWorkingImage();picture=&imgTmp;}putimagePNG(x,y,picture);}//设A[x01,y01,x02,y02]B[x11,y11,x12,y12].boolrectIntersect(intx01,inty01,intx02,inty02,intx11,inty11,intx12,inty12){intzx=abs(x01+x02-x11-x12);intx=abs(x01-x02)+abs(x11-x12);intzy=abs(y01+y02-y11-y12);inty=abs(y01-y02)+abs(y11-y12);return(zx<=x&&zy<=y);}voidpreLoadSound(constchar*name){charcmd[512];sprintf_s(cmd,sizeof(cmd),"open%salias%s-1",name,name);mciSendString(cmd,0,0,0);sprintf_s(cmd,sizeof(cmd),"open%salias%s-2",name,name);mciSendString(cmd,0,0,0);}voidplaySound(constchar*name){staticintindex=1;charcmd[512];if(index==1){sprintf_s(cmd,sizeof(cmd),"play%s-1",name);mciSendString(cmd,0,0,0);sprintf_s(cmd,sizeof(cmd),"close%s-2",name);mciSendString(cmd,0,0,0);sprintf_s(cmd,sizeof(cmd),"open%salias%s-2",name,name);mciSendString(cmd,0,0,0);index++;}elseif(index==2){sprintf_s(cmd,sizeof(cmd),"play%s-2",name);mciSendString(cmd,0,0,0);sprintf_s(cmd,sizeof(cmd),"close%s-1",name);mciSendString(cmd,0,0,0);sprintf_s(cmd,sizeof(cmd),"open%salias%s-1",name,name);mciSendString(cmd,0,0,0);index=1;}}voiddrawBloodBar(intx,inty,intwidth,intheight,intlineWidth,intboardColor,intemptyColor,intfillColor,floatpercent){LINESTYLElineStyle;getlinestyle(&lineStyle);intlineColor=getlinecolor();intfileColor=getfillcolor();if(percent<0){percent=0;}setlinecolor(BLUE);setlinestyle(PS_SOLID|PS_ENDCAP_ROUND,lineWidth);setfillcolor(emptyColor);fillrectangle(x,y,x+width,y+height);setlinestyle(PS_SOLID|PS_ENDCAP_FLAT,0);setfillcolor(fillColor);setlinecolor(fillColor);if(percent>0){fillrectangle(x+0.5*lineWidth,y+lineWidth*0.5,x+width*percent,y+height-0.5*lineWidth);}setlinecolor(lineColor);setfillcolor(fillColor);setlinestyle(&lineStyle);}

到此,关于“C++怎么利用easyx图形库实现天天酷跑小游戏”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

域名注册
购买VPS主机

您或许对下面这些文章有兴趣:                    本月吐槽辛苦排行榜

  • 没有相关文章!
看贴要回贴有N种理由!看帖不回贴的后果你懂得的!


评论内容 (*必填):
(Ctrl + Enter提交)   

部落快速搜索栏

各类专题梳理

网站导航栏

X
返回顶部