本人编程小白,在学完C语言后尝试学习制作了推箱子小游戏,途中收获颇多,在此对于整个过程做一回顾梳理,若有写的不对的地方,还望各位大佬指正。

本篇文章为1.0版本,没有关卡,但拥有推箱子游戏较核心的功能。


目录

一、开始前的准备

二、游戏设计思路梳理

1.小Tip

2.概述

三、详细过程

1.地图绘制

2.玩家移动模块

3.输赢判断模块

4.开始页面及音乐的添加

5.main函数部分

四、效果展示

五、作者的话


一、开始前的准备

本文使用的工具是vs2010+easyx编程。由于我之前没有安装easyx,所以去官网进行了安装。

官网链接:进入官网后,找到 下载easyx 并按照提示完成安装。点击进入官网

备注:安装时最好安装帮助文档,并去网上对于easyx进行简单的学习,了解常见函数的用法,以便更好地操作。

帮助文档:(可通过该文档了解学习)点击进入


二、游戏设计思路梳理

1.小Tip

首先我们可以分析一下这个游戏需要哪些模块,比如地图绘制,开始页面,玩家移动模块,输赢判断模块等等,再大概想一想各个模块都需要用到哪些东西,做一些准备,然后再开始上手。

2.概述

在概述这里简单说一下各模块都要什么:

1.地图绘制  通过easyx的相关功能把图片绘制出来,当然,要提前准备好素材以及地图(可以在网上随便搜一个)。

2.开始页面    这个页面看需求吧,需要的话可以根据自己的喜好设计一下。

3.玩家移动模块   这里要涉及到移动设计的逻辑问题,玩家在什么情况下可以移动,最简单的就是玩家前面是空地或者目的地,这个可以直接过去,其次就是当玩家面前有箱子(或箱子在目的地上)时,这就需要考虑箱子能不能推动,若箱子后面是空地或目的地,那可以过,若后面是墙或者还是箱子,这就过不去。设计的核心就在这里。

4.输赢判断模块    这里可设定的规则挺多,时间限制,步数限制,或者死角无法推动(本文用的这一个)等等,可以自行设计。


三、详细过程

1.地图绘制

首先我们要用图片加载函数把图片加载,然后才能开始在控制台上贴图。

IMAGE img[6];//图片对象指针
void begin()
{    loadimage(&img[0],L"land.jpg",60,60);//加载图片loadimage(&img[1],L"wall.jpg",60,60);//(IMAGE 对象指针,图片文件名,宽度,高度)loadimage(&img[2],L"BoxYellow.jpg",60,60);loadimage(&img[3],L"ManDOWN1.jpg",60,60);loadimage(&img[4],L"aim.jpg",60,60);loadimage(&img[5],L"BoxRed.jpg",60,60);//箱子在目的地时
}

加载完图片,就该绘制地图。但在此之前,我们需要规定一些数字来表示图片,以方便后续操作。

我们做出如下规定:

空地  0  ,墙  1,  箱子  2,  人物  3,  目的地  4,
很自然的, 人站在目的地 就是 3+4=7,而箱子到达目的地 便为  2+4=6。

规定完图片之后,我们就可以用数字把地图先搞出来:(地图上网随便找一个,按规定来就行)

int map[11][13] = {      //初始化地图   0,0,0,1,1,1,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0,1,0,0,0,1,0,0,0,4,1,1,1,0,1,0,0,0,1,0,1,0,1,0,0,0,0,1,1,0,0,1,0,1,0,2,0,2,1,4,0,1,0,0,1,0,1,0,0,6,0,0,1,0,1,0,0,1,0,4,1,2,0,2,0,1,0,1,0,0,1,1,0,0,0,0,1,0,1,0,1,1,1,0,1,0,1,1,1,4,0,0,0,0,0,1,0,1,0,0,0,0,0,1,1,0,0,3,1,0,1,1,1,1,1,1,1,1,1,1,1,1
};

这下万事俱备,可以开始贴图,造地图了。

void drawmap()
{BeginBatchDraw();// 防止贴图过快for(int i=0;i<11;i++)//行{for(int j=0;j<13;j++)//列{//每行单独贴图switch(map[i][j]){case 0://空地  putimage(j*60,i*60,&img[0]);//(x坐标,y坐标,对象指针)break;case 1://墙 putimage(j*60,i*60,&img[1]);break;case 2://箱子  putimage(j*60,i*60,&img[2]);break;case 3:case 7://人物  putimage(j*60,i*60,&img[3]);break;case 4://目的地  putimage(j*60,i*60,&img[4]);break;case 6://箱子到达目的地  putimage(j*60,i*60,&img[5]);break;default:break;}}}EndBatchDraw();
}

备注:1.有关坐标的信息,可以在帮助文档中学习了解。

2.在绘制地图时,不要忘记加上easyx的头文件:

#include<easyx.h>
//或者这个#include <graphics.h>

3.在贴图前要注意把素材图片和项目代码放在同一个文件夹。

到了这里,地图的绘制就基本结束了。下面开启第二部分,也是最重要的一部分,玩家移动。

2.玩家移动模块

想要让玩家移动,首先我们要对玩家进行定位。

//找人的位置int x,y;for(int i=0;i<11;i++){for(int j=0;j<13;j++){if(map[i][j] == 3|| map[i][j] == 7){x=i;y=j;}}}

有了玩家的位置之后,我们便开始设计移动。

这里我们首先要获取玩家的按键,从而让玩家能够控制人物移动。

获取按键:这里要用到getch()  ,不要忘记添加头文件

#include<conio.h> //getch() 头文件

然后便开始设计按键的移动。这里需要注意的是:我们是通过数字的加减来实现玩家的移动的。

即:当玩家离开当前位置时,该位置减去3,而玩家即将到达的位置加上3。

然后我们开始设计移动,当玩家想要向上移动时,我们分情况来看:(在这里我们可以只考虑什么情况下玩家可以移动,不需要考虑无法移动的情况)

第一种:当玩家上方是空地或目的地时,玩家可以直接移动。

if(map[x-1][y]==0||map[x-1][y]==4)   //人上方是空地或目的地
{map[x-1][y]+=3;//人走上去 +3map[x][y]-=3;//原位置-3
}

第二种:当玩家上方为箱子或箱子在目的地上时,有两种可能性:

1.箱子上方为空地或目的地,人可以和箱子一起上去;

2.箱子上面为箱子或者墙壁(此时玩家不能移动,这种情况我们不做考虑)

if(map[x-1][y]==2||map[x-1][y]==6) //上方为箱子或箱子在目的地上
{if(map[x-2][y]==0||map[x-2][y]==4)  //箱子上方是空地或目的地{//人走上去,箱子也推上去map[x-2][y]+=2;map[x-1][y]+=1;//-2  +3 --+1map[x][y]-=3;}
}

到这个时候,我们便完成了向上这一按键的移动设计,而玩家也可以顺利向上移动。

至于向左,向右,向下三种情况与之类似,只需要改动一些坐标,所以我们不做详细分析,仅提供源代码以供参考。

玩家移动设计函数的完整代码:(这里我们使用wasd进行移动操作)

switch(getch())
{case 'W':case 'w'://往上if(map[x-1][y]==0||map[x-1][y]==4)   //人上方是空地或目的地{map[x-1][y]+=3;//人走上去 +3map[x][y]-=3;//原位置-3}else if(map[x-1][y]==2||map[x-1][y]==6) //上方为箱子或箱子在目的地上{if(map[x-2][y]==0||map[x-2][y]==4)  //箱子上方是空地或目的地{//人走上去,箱子也推上去map[x-2][y]+=2;map[x-1][y]+=1;//-2  +3 --+1map[x][y]-=3;}}break;case 'S':case 's'://往下if(map[x+1][y]==0||map[x+1][y]==4)   //人下方是空地或目的地{map[x+1][y]+=3;//人走下去 +3map[x][y]-=3;//原位置-3}else if(map[x+1][y]==2||map[x+1][y]==6) //下方为箱子或箱子在目的地上{if(map[x+2][y]==0||map[x+2][y]==4)  //箱子下方是空地或目的地{//人走下去,箱子也推下去map[x+2][y]+=2;map[x+1][y]+=1;//-2  +3 --+1map[x][y]-=3;}}break;case 'A':case 'a'://往左if(map[x][y-1]==0||map[x][y-1]==4)   //人左方是空地或目的地{map[x][y-1]+=3;//人往左走 +3map[x][y]-=3;//原位置-3}else if(map[x][y-1]==2||map[x][y-1]==6) //左方为箱子或箱子在目的地上{if(map[x][y-2]==0||map[x][y-2]==4)  //箱子左方是空地或目的地{//人往左走,箱子也推向左边map[x][y-2]+=2;map[x][y-1]+=1;//-2  +3 --+1map[x][y]-=3;}}break;case 'D':case 'd'://往右if(map[x][y+1]==0||map[x][y+1]==4)   //人右方是空地或目的地{map[x][y+1]+=3;//人往右走 +3map[x][y]-=3;//原位置-3}else if(map[x][y+1]==2||map[x][y+1]==6) //右方为箱子或箱子在目的地上{if(map[x][y+2]==0||map[x][y+2]==4)  //箱子右方是空地或目的地{//人往右走,箱子也推向右边map[x][y+2]+=2;map[x][y+1]+=1;//-2  +3 --+1map[x][y]-=3;}}break;default :break;
}

备注:移动函数为模块的核心,至关重要。

此时玩家移动的设计便可以告一段落了,我们即将开始第三部分,输赢的判断。

3.输赢判断模块

有了地图,并且玩家可以移动,我们的游戏便成功了一半,而另一半来自于输赢的判断,大家玩游戏都希望赢,所以一个判断标准也很重要。上面我有提到几种可能性,在这里我用的标准是 :

【箱子碰到死角无法推动】为输,【地图上没有箱子】为赢

在这里我们可以用变量来标记三种状态:flag=0 游戏继续;flag=1 游戏失败;flag=2,游戏获胜。

下面做分类讨论:

首先是赢的条件:当地图上没有箱子时,游戏即获胜。即数字里面找不到2时;

其次是输的情况:要构成死角,则至少四个面中要有两个面是墙,如此之下,便无法移动。

下面是输赢判断标准部分的代码:

int flag;
void  judge()
{flag=2;//初值for(int i=0;i<11;i++)//行{for(int j=0;j<13;j++)//列{if(map[i][j]==2){//表明未结束flag=0;if(map[i-1][j]==1||map[i+1][j]==1){//找死角的墙if(map[i][j-1]==1||map[i][j-1]==1){//游戏结束                   flag=1;                        //flag 分类return;                        //=0 继续 //=1 结束//=2  赢}}}}}
}

有了判断标准,我们还需要提示框来告知玩家他是输是赢,所以需要再加上一些提示盒子。

void  box()
{if(flag==1){MessageBox(GetHWnd(),L"抱歉,你输了。",L"LOSE",MB_OK);//头文件为windows.h   有图形库时可不加}else{MessageBox(GetHWnd(),L"恭喜,你赢了!",L"VICTORY",MB_OK); }
}

备注: 这里我们用到了MessageBox函数,使用该函数后将会弹出提示窗体,方便玩家看到结果,至于该函数的详细信息可以自行了解。

到了这里,整个输赢判断模块便真正结束了,而整个游戏的模块也基本成型了,下面我们将再添加一些优化,比如开始页面的添加,音乐的添加等。

4.开始页面及音乐的添加

我们在最开始可以添加一个开始页面,给玩家一些提示,并且进一步完善游戏的模块。

备注:该模块的添加可根据需求自行设计。

我所添加的开始页面代码如下:


IMAGE iae;
void tip()
{loadimage(&iae,L"logo.jpg",780,360);putimage(0,0,&iae);settextcolor(LIGHTCYAN);settextstyle(24,0,_T("黑体"));outtextxy(240,360,_T("开始游戏    请按 B/b "));outtextxy(240,420,_T("移动请按   wasd/WASD"));outtextxy(240,480,_T("!试试把箱子推到目的地!"));outtextxy(480,600,_T("------拾光异世出品------"));
}

备注:这里有用到在图形库下的文字输出及格式和颜色设置。

除了开始页面,我们还可以加一些音乐,比如游戏进行时的音乐,玩家移动时的音乐,游戏胜利时的音乐等。

在添加音乐之前我们需要添加一些头文件和库:

//加音乐的头文件与库
#include<mmsystem.h>
#pragma comment(lib,"WINMM.LIB")

然后是加音乐:可以分别在图片加载函数,移动设计函数,提示盒子函数里添加相对应的音乐。

//图片加载函数
mciSendString(L"open back.mp3  alias bgm",0,0,0);//具体用法可从帮助文档中了解
mciSendString(L"play bgm repeat",0,0,0);
//移动设计函数
PlaySound(L"Boxmove.WAV",nullptr,SND_FILENAME | SND_ASYNC);
//提示盒子函数
PlaySound(L"success.wav",nullptr,SND_FILENAME | SND_ASYNC);

进行完上述四个部分,我们便完成了大部分的设计任务,只剩下最后一步,把各个模块之间通过main函数组合起来。

5.main函数部分

在用main函数组合之前,我们需要考虑一个问题,我们要如何组织这几大模块,

仔细思考,应该先是开始页面,再然后的话,因为我们是要每移动一次便绘制一次地图,所以应该是在一个循环里面绘图(初始化),移动,绘图。判断,移动······

main函数部分代码(考虑到与开始页面的衔接,我们可以加一些衔接代码):

int main()
{initgraph(780,660);//每个方块大小60*60   窗口大小780*660tip();if(getch()=='B'||getch()=='b'){begin();while(1){drawmap();judge();if(flag)  break;//判断是否结束play();}box();}getchar();closegraph();//关闭窗口return 0;
}

备注:用easyx进行绘图时,要先建立绘图窗口,并且在游戏结束后关闭该窗口。

在将几大模块组合在一起时,整个设计过程便可以说接近尾声,我们的游戏便可以正常运行了。


四、效果展示

最后我们一起看看效果图:

如果需要素材或者参考源码的话,可以通过网盘提取:

链接:https://pan.baidu.com/s/153nVLE8htqaeDuBSzYuyMA 
提取码:a8u1


五、作者的话

虽然说上面的游戏到最后仍然很简陋,有着各种问题,诸如无法重新开始,判断机制不够完善等,但是也实现了推箱子游戏的最基本的功能,任务呢,也算是圆满完成啦。至于后续的优化,代码添加,我会继续努力的!!!

最后再说一句:希望自己在学习编程的道路上继续前进!  加油,少年!!!

C语言+easyx图形库 推箱子游戏1.0相关推荐

  1. C语言开发《推箱子游戏》,亲自手把手教会大家

    [C语言经典算法100道实战题]适合具备C语言基础语法的同学学习,提高编写程序的逻辑思维能力和算法设计能力专门精心设计.100个经典的算法供大家练习及配套对应的录播视频.为我们今后学习其它的编程语言和 ...

  2. EasyX实现推箱子游戏

    文章目录 1 项目需求 2 模块划分 3 项目实现 3.1 地图初始化 3.2 热键控制 3.3 推箱子控制 3.4 游戏结束 1 项目需求 实现一款推箱子游戏,效果如下图所示,具体规则: 箱子只能推 ...

  3. c语言 游戏程序,C语言做的推箱子游戏源程序

    #include #include #include //图形界面 #include #include using namespace std; #define VK_SHIFT  0x10 #pra ...

  4. c语言基于easyX樱花特效,C++基于easyx图形库实现推箱子游戏

    本文实例为大家分享了C++实现推箱子游戏的具体代码,供大家参考,具体内容如下 头文件: #include #include //#include #include #include #include ...

  5. 用easyx做推箱子小游戏

    学了一两个月C语言了,做完了黑窗口版本的推箱子,今天尝试用easyx图形库,收获很不错.其中还有很多可以改进的地方,希望大家能多多指导 推箱子游戏主要步骤 1.加载图片资源 2.绘制游戏地图 3.按键 ...

  6. 推箱子游戏(C语言版)

    [C语言经典算法100道实战题]点击链接即可在线学习: https://edu.csdn.net/course/detail/37564 一.推箱子游戏C语言版[运行效果如下]** 二.安装图形库 我 ...

  7. c语言语音控制游戏文献,C语言课程设计-基于C语言推箱子游戏设计-毕业论文文献.doc...

    gd工程职业技术学院毕业论文 基于C语言的推箱子游戏设计 Design of the push box Based on Combined Language 作者姓名: 学科专业: 应用电子技术 学院 ...

  8. c语言推箱子游戏实习报告,用C语言编写推箱子游戏

    本文实例为大家分享了C语言推箱子游戏的具体实现代码,供大家参考,具体内容如下 #include #include #include #include //行和列 #define ROW 10 #def ...

  9. c 语言推箱子vs,基于C语言实现推箱子游戏

    本文实例为大家分享了C语言实现推箱子游戏的具体代码,供大家参考,具体内容如下 代码在vs2013上测试运行. 思想: 1):地图用二维数组实现,箱子.墙壁.人等事物用不同的数字表示,遍历二维数组,遇到 ...

最新文章

  1. 图像分类:CVPR2020论文解读
  2. windows2012挂linux盘阵,磁盘阵(IPSAN)挂载Windows和Linux测试过程.doc
  3. Hadoop Writable机制
  4. PHP中的foreach循环
  5. Gym-101466K Random Numbers(线段树,数学,唯一分解定理)
  6. hash table(全域散列法实现的哈希表)
  7. 计算机管理员无法创建密码,找到电脑管理员的密码
  8. Java可以用到军事方面吗_恭喜遥三运载火箭发射成功,浅谈java在军事方面的运用!...
  9. Git 代码管理常用命令
  10. (五)cobbler自定义系统安装
  11. WPF-创建超链接文本
  12. http抓包实践--(五)-常用的操作
  13. 2014手机号码归属地数据库
  14. AirDisk创建网盘
  15. 编写matlab程序设计状态反馈增益阵,利用MATLAB设计状态观测器.pdf
  16. Java扫码登录原理
  17. 一文弄懂调节器的PID自整定原理和方法
  18. 5年软件渗透测试工程师的从业经验分享,值得借鉴
  19. 计算机毕业设计django基于python商品比价平台
  20. clang fatal error: ‘stdio.h‘ file not found

热门文章

  1. 三分屏课件制作_不是所有的AMOLED手机屏都一样!实测华为P30用了怎样一块屏
  2. ACD Systems ACDSee v7.0 PowerPack发布
  3. 高德纳谈《具体数学》的诞生
  4. r语言dataellipse_几行R语言代码搞定菌群与环境因子或临床指标相关性的可视化...
  5. axure命令行_Axure RP Pro 4原创教程:(二)界面与功能
  6. Effective Java 2.0_中英文对照_Item 5
  7. 手机文件服务器app,有没有什么软件可以让手机和电脑相互传东西的?拜托各位大神?...
  8. 通话记录分析 --- 通话详情 之一
  9. python 实现 frontCon 函数,画 马克韦茨 有效前沿和求切线 思路
  10. 梅州组织培养实验室之室内布局建设