本文作者:克隆窝
本文代码适合编译环境:DEV-C++
✨温馨提示:此文乃作者心血,如要转载请标注版权,否则视为抄袭!
⚽注意:本文参与了CSDN世界杯征文,支持一下没问题吧~
估计这个月球迷们很兴奋吧??
没错——世界杯!
那么这篇文章窝窝就教大家如何用C++的easyx图形库做一个世界杯主题的跑酷小游戏吧!
首先,窝窝来给大家科普点世界杯小知识~
下面是本次卡塔尔世界杯的奖杯:
是不是很好看?
下面贴出窝窝后面三天的赛程:
为了给我们下面的小游戏做铺垫,窝窝这里先教大家一个神奇的代码:怎么做一个物理足球。
但是,有的人就说了:快给我的代码!我要放DEV-C++里运行!!
咳咳,别急!你还没装这个——Easyx图形库
下面先教大家如何在DEV-C++里安装Easyx图形库。
先进入Easyx官网:EasyX Graphics Library for C++
然后点击上面的“下载”,如图1-1
进入之后点击“More”,如图1-2
然后往下拉,找到如图1-3链接(因为你要装在DEV-C++,如果是VS,选上面的链接)
然后会跳转到如图1-4的页面,点击箭头指向的链接
然后找到下载的压缩包,打开,如图1-5
打开之后,按如下步骤把文件拷贝进不同文件夹:
然后就是配置:
(1)新建一个空项目:点击文件–>新建–>项目,会弹出如下界面,然后点“Empty Project”:
(2)设置链接库:点击项目–> 项目属性,选择参数,然后在链接里面输入-leasyx -lgdi32 -lole32,完成。(如图1-6)
(3)生成项目模版,简化操作步骤:
通过前面两步已经可以使用 Easyx了。但是,每次写新项目都要设置链接库。可以通过生成项目模版简化该过程:
点击文件–>新建–>模板,填写模版名称:EasyX Application(这里按自己意愿),其他选项可以根据自己喜好填写。如下图:
这样下次再要建项目是,只需要点击文件–>新建–>项目,然后选择你刚刚新建的项目,就可以直接创建啦!
那么以上就是如何在DEV-C++里配置Easyx库了。(这里我用的是DEV-C++5.11版本)
好,那么现在我们就能写代码了!
那么,如果要实现一个可以反弹的物理足球
,该问么办呢?下面给出项目流程:
是不是一下子就明白了?下面给出代码+注释:
#include//Easyx图形库头文件
#include//getchar()需要的头文件,每个Easyx项目都有
#include//万能头
using namespace std;
struct Ball{//结构体
double x,y,vx,vy;//x,y--足球的坐标,vx,vy--足球的移动速度
}football;
IMAGE img,img1;//图像变量
void ready(){//准备工作处理函数
srand(time(NULL));//随机坐标
football.x=rand()%480+20;//足球随机坐标x
football.y=rand()%480+20;//足球随机坐标y
football.vx=0.4;football.vy=0.4;//足球移动速度
loadimage(&img,"D:\\code\\开发项目\\项目1\\1.png",40,40);//加载足球图像(请先把照片放入项目文件夹!)
loadimage(&img1,"D:\\code\\开发项目\\项目1\\2.png",40,40);//加载遮盖图像(请先把照片放入项目文件夹!)
}
void ball_move(){//足球移动函数
putimage(football.x,football.y,&img);//输出足球照片
FlushBatchDraw();//解决闪烁
putimage(football.x,football.y,&img1);//输出掩盖照片
football.x=football.x+football.vx;//移动
football.y=football.y+football.vy;//移动
if(football.x<=0||football.x>=540)football.vx=-football.vx;//是否反弹判断
if(football.y<=0||football.y>=460)football.vy=-football.vy;//是否反弹判断
}
int main()
{
initgraph(500,500);//新建500*500的画布
ready();
BeginBatchDraw();//解决闪烁
while(true){//永久循环
ball_move();
}
EndBatchDraw();//解决闪烁
getch();
closegraph();//关闭画布
}
那么图片放哪呢?图片应该放在项目文件夹,如图2-1:
下面给出原图和掩盖图:
原图:
掩盖图:
放到项目文件夹里
注意!!
代码中的“loadimage(&img,“D:\code\开发项目\项目1\1.png”,40,40);
loadimage(&img1,“D:\code\开发项目\项目1\2.png”,40,40);”
这两个函数中的“D:\……”指向的是你照片所在的项目文件夹的路径!不要搞错了哦~
最终效果:
嘿嘿,怎么样?那么我接下来就趁热打铁,制作我们的小游戏吧!
先给大家看看效果:
怎么样?是不是很想玩?
那么话不多说,走起!
(1)足球跳跃实现
足球跳跃的思路是这样的:(可能描述的不好,见谅)
那么,上代码和注释:
#include//Easyx库头文件
#include
#include
using namespace std;
struct Ball{
double x,y,vy;//足球x,y坐标,跳跃速度vy
}football;
IMAGE img,img1;
double width=500,high=500,gra=0.6;//gra为重力
char keyboard;//获取键盘消息变量
void ready(){//准备工作
football.x=width/4;//初始x
football.y=high-40;//初始y
football.vy=0;//速度为0
loadimage(&img,"D:\\code\\开发项目\\项目1\\1.png",40,40);//加载图片
}
void ball_jump(){//跳跃实现
if(_kbhit()){//如果收到消息
keyboard=getch();//获取
if(keyboard==' '||keyboard=='w'){//判断
football.vy=-16;//向上速度
}
}
football.vy+=gra;//否则加重力
football.y+=football.vy;//向下
if(football.y>=high-40){//如果脱离地面
football.vy=0;//速度为0
football.y=high-40;
}
}
int main()
{
initgraph(width,high);//新建500*500画布
ready();
BeginBatchDraw();//解决闪烁
while(true){//循环
ball_jump();
cleardevice();//清屏
putimage(football.x,football.y,&img);//放上照片
FlushBatchDraw();//解决闪烁
Sleep(10);//这个很重要,如果没有就会出bug
}
EndBatchDraw();//解决闪烁
getch();
closegraph();
return 0;
}
中间这个Sleep(10)非常重要,没有就会出bug,因为没有延迟。
看看效果:
(2)障碍的绘制
那么障碍怎么绘制呢?又怎么实现他的移动呢?
其实这里采用的原理和《超级马里奥》一样。
《超级马里奥》的原理就是在移动的时候,看起来马里奥在向前移动,实际上马里奥根本没动,他只会在原地跳跃,而实现这一效果的是移动屏幕,这样马里奥就是看起来在移动了
那么,我们也可以使用这种原理。
思路:
1.障碍的属性有啥呢?那么如果是两个障碍呢?
定义两个结构体,一个上柱,一个下柱,都有如下属性:x1,y1,x2,y2,vx
其中x1,y1,x2,y2都是障碍的四个顶点,而vx是障碍向左的移动速度。
2.如何实现障碍的移动呢?
上柱和下柱都加上速度,然后每次判断:如果超出屏幕,就更新下一个障碍的属性。
3.那么如何实现障碍高度随机化呢?
rect_h=rand()%int(high/5.5)+high/5.5;
代码+注释:
#include//Easyx图形库头文件
#include
#include
using namespace std;
struct Ball{//足球属性
double x,y,vy;
}football;
struct Rect1{//上柱属性
double x1,y1,x2,y2,vx;
}rect1;
struct Rect2{//下柱属性
double x1,y1,x2,y2,vx;
}rect2;
IMAGE img,img1;
double width=500,high=500,gra=0.6,rect_h;//rect_h为障碍高度
char keyboard;
void ready(){//初始化
football.x=width/4;
football.y=high-40;
football.vy=0;
loadimage(&img,"D:\\code\\开发项目\\项目1\\1.png",40,40);
rect1.x1=width*3/4;
rect1.y1=0;
rect1.x2=rect1.x1+30;
rect1.y2=rect1.y1+rect_h;
rect2.x1=width*3/4;
rect2.y1=high-rect_h;
rect2.x2=rect2.x1+30;
rect2.y2=high;
rect1.vx=rect2.vx=-3;
}
void ball_jump(){//足球跳跃
if(_kbhit()){
keyboard=getch();
if(keyboard==' '||keyboard=='w'){
football.vy=-10;
}
}
football.vy+=gra;
football.y+=football.vy;
if(football.y>=high-40){
football.vy=0;
football.y=high-40;
}
}
void rec_move(){//障碍移动
rect1.x1+=rect1.vx;//加速度
rect1.x2+=rect1.vx;//加速度
rect2.x1+=rect2.vx;//加速度
rect2.x2+=rect2.vx;//加速度
if(rect1.x1+30<0&&rect2.x1+30<0){//判断是否超出屏幕
//更新
rect1.x1=rect2.x1=width-30;
rect1.x2=rect2.x2=width;
rect_h=rand()%int(high/5.5)+high/5.5;
rect1.y2=rect_h;
rect2.y1=high-rect_h;
}
}
void draw(){//输出画面
putimage(football.x,football.y,&img);
setfillcolor(YELLOW);
fillrectangle(rect1.x1,rect1.y1,rect1.x2,rect1.y2);
fillrectangle(rect2.x1,rect2.y1,rect2.x2,rect2.y2);
}
int main()
{
initgraph(width,high);//创建一个500*500的画布
ready();
BeginBatchDraw();//解决闪烁
while(true){
ball_jump();
rec_move();
cleardevice();//清屏
draw();
FlushBatchDraw();//解决闪烁
Sleep(10);
}
EndBatchDraw();//解决闪烁
getch();
closegraph();
return 0;
}
效果:
(3)背景+计分
放背景只需要再搞个图像变量就行了。
那么,计分呢?
其实计分只需要在更新里++就行了。
但是后面还要加个失分判断,就是当……就清零。
但是还有个问题,outtextxy函数只能输出字符,不能输出int,这该怎么办?
这里又要用到一个函数:sprintf数转串函数。
格式:
char s[10010]; sprintf(s,"%d",score);
这样就能实现输出了!
最终完整代码+注释:
#include//Easyx图形库头文件
#include
#include
using namespace std;
struct Ball{//足球属性
double x,y,vy;
}football;
struct Rect1{//上柱属性
double x1,y1,x2,y2,vx;
}rect1;
struct Rect2{//下柱属性
double x1,y1,x2,y2,vx;
}rect2;
IMAGE img1,img_ball2,img_ball3;
double width=640,high=480,gra=0.6,rect_h;
char keyboard;
int score=-1;//积分
string s;
void ready(){//初始化
setbkmode(TRANSPARENT);
football.x=width/4;
football.y=high-40;
football.vy=0;
loadimage(&img1,"D:\\code\\开发项目\\项目1\\wall.png",640,480);
loadimage(&img_ball2,"D:\\code\\开发项目\\项目1\\2.png",40,40);
loadimage(&img_ball3,"D:\\code\\开发项目\\项目1\\3.png",40,40);
rect1.x1=width*3/4;
rect1.y1=0;
rect1.x2=rect1.x1+40;
rect1.y2=rect1.y1+rect_h;
rect2.x1=width*3/4;
rect2.y1=high-rect_h;
rect2.x2=rect2.x1+40;
rect2.y2=high;
rect1.vx=rect2.vx=-4;
}
void ball_jump(){//足球运动
if(_kbhit()){
keyboard=getch();
if(keyboard==' '||keyboard=='w'){
football.vy=-10;
}
}
football.vy+=gra;
football.y+=football.vy;
if(football.y>=high-40){
football.vy=0;
football.y=high-40;
}
}
void rec_move(){//障碍移动
rect1.x1+=rect1.vx;
rect1.x2+=rect1.vx;
rect2.x1+=rect2.vx;
rect2.x2+=rect2.vx;
if(rect1.x1+40<0&&rect2.x1+40<0){
rect1.x1=rect2.x1=width-40;
rect1.x2=rect2.x2=width;
score++;//加分
rect_h=rand()%int(high/5.5)+high/5.5;
rect1.y2=rect_h;
rect2.y1=high-rect_h;
}
if(football.x>=rect1.x1&&football.x<=rect1.x2){//判断是否清零
if(football.y<=rect1.y2||football.y>=rect2.y1){
score=0;
}
}
}
void draw(){//输出
putimage(0,0,&img1);
putimage(football.x,football.y,&img_ball2,SRCAND);
putimage(football.x,football.y,&img_ball3,SRCPAINT);
setfillcolor(YELLOW);
fillrectangle(rect1.x1,rect1.y1,rect1.x2,rect1.y2);
fillrectangle(rect2.x1,rect2.y1,rect2.x2,rect2.y2);
settextcolor(RED);
settextstyle(50,0,"楷体");
outtextxy(0,0,"分数:");
char s[10010];
sprintf(s,"%d",score);
if(score==-1){
s[0]='0';
s[1]=' ';
}
outtextxy(150,0,s);
}
int main()
{
initgraph(width,high);//新建一个500*500的画布
ready();
BeginBatchDraw();//解决闪烁
while(true){
ball_jump();
rec_move();
cleardevice();//清屏
draw();
FlushBatchDraw();//解决闪烁
Sleep(10);
}
EndBatchDraw();//解决闪烁
getch();
closegraph();
return 0;
}
项目文件夹:
用到的图片:
(足球)原图:
足球掩码图:
黑底彩图:
背景:
1.如果我的博客对你有帮助、如果你喜欢我的博客内容,请 “
点赞
” “✍️评论
” “收藏
” 一键三连哦!2.
❤️【关注我| 获取更多源码 | 优质文章】
带您学习各种前端插件、3D炫酷效果、图片展示、文字效果、以及整站模板 、大学生毕业HTML模板 、期末大作业模板 、等! 「在这里有好多 前端 开发者,一起探讨 前端 Node 知识,互相学习」!3.以上内容技术相关问题欢迎一起交流学习