卡盟辅助自动发卡]标签的文章】" target="_blank">王者荣耀卡盟辅助自动发卡
经典的推箱子是一个很古老的游戏了,相信大家都不陌生。其目的是在训练我们的逻辑思考能力。在一个狭小的仓库中,要求把木箱放到指定的位置,稍不小心就会出现箱子无法移动或者通道被堵住的情况,所以需要巧妙的利用有限的空间和通道,合理安排移动的次序和位置,才能顺利的完成任务。
我们将编写推箱子游戏,玩家键盘控制游戏角色将所有黄色箱子推到白色方块处,效果如图所示:
操作方法:方向键↑↓←→控制移动推箱子,将箱子推到对应位置。
首先学习字符串与字符数组的概念,并应用字符数组初始化关卡数据;然后利用键盘控制游戏角色移动,实现地图元素更新和游戏胜利的判断;接着利用三维字符数组,实现多关卡的游戏;最后学习基于文件的关卡数据读取,利用枚举类型改进游戏代码。
源码:
#include #include #include #define B_SIZE 60 // 方块大小#define B_NUM 8 // 方块个数,一共8*8个方块struct Player // 结构体,用于记录玩家位置{int i;int j;};Player player; // 玩家全局变量enum Element // 定义枚举类型,小方块所有的可能的种类{wall,target,box,empty,achieved,role};// 用于存储地图数据,用枚举类型实现Element level[B_NUM][B_NUM] = {{wall,wall,wall,wall,wall,wall,wall,wall},{wall,wall,wall,target,box,empty,empty,wall},{wall,empty,empty,empty,empty,empty,empty,wall},{wall,empty,empty,empty,empty,empty,empty,wall},{wall,empty,empty,empty,empty,empty,empty,wall},{wall,role,empty,box,target,wall,wall,wall},{wall,empty,empty,empty,empty,wall,wall,wall},{wall,wall,wall,wall,wall,wall,wall,wall}};int targetNum,achievedNum; // 目标位置个数、完成目标个数void startup() // 初始化函数{initgraph(B_NUM*B_SIZE,B_NUM*B_SIZE); // 新开一个画面setbkcolor(RGB(150,150,150)); // 灰色背景BeginBatchDraw(); // 开始批量绘图int i,j;targetNum = 0; // 目标个数,初始为0// 对二维数组遍历for (i=0;i<B_NUM;i )for (j=0;j<B_NUM;j ){if (level[i][j]==role) // 找到地图中player位置{player.i = i; // 设定player位置player.j = j; // level[i][j]=empty; // 把地图元素变成空白empty}else if (level[i][j]==target || level[i][j]==achieved ) // 如果元素是target或achievedtargetNum ; // 目标个数 1}}void show() // 绘制函数{int i,j;cleardevice(); // 以背景颜色清空屏幕// 遍历关卡二维数组数据for (i=0;i<B_NUM;i ){for (j=0;j<B_NUM;j ){if (level[i][j]==empty) // empty 元素是空白区域{setfillcolor(RGB(150,150,150));apex挂 // 绘制灰色地面setlinecolor(RGB(150,150,150));fillrectangle(j*B_SIZE,i*B_SIZE,(j 1)*B_SIZE,(i 1)*B_SIZE);}else if (level[i][j]==wall) // wall 元素是墙{setfillcolor(RGB(155,0,0));setlinecolor(RGB(150,150,150)); // 绘制淡红色、灰色线的方框fillrectangle(j*B_SIZE,i*B_SIZE,(j 1)*B_SIZE,(i 1)*B_SIZE);}else if (level[i][j]==box) // box 元素是可移动的箱子{setfillcolor(RGB(255,255,0)); // 绘制一个黄色的方块setlinecolor(RGB(150,150,150));fillrectangle(j*B_SIZE,i*B_SIZE,(j 1)*B_SIZE,(i 1)*B_SIZE);}else if (level[i][j]==target) // target 元素是目标{setfillcolor(RGB(250,250,250)); // 绘制一个白色的小方块fillrectangle((j 0.3)*B_SIZE,(i 0.3)*B_SIZE,(j 0.7)*B_SIZE,(i 0.7)*B_SIZE);}else if (level[i][j]==achieved) // achieved 元素是已完成目标{setlinecolor(RGB(150,150,150));setfillcolor(RGB(255,255,0)); // 绘制一个黄色的方块fillrectangle(j*B_SIZE,i*B_SIZE,(j 1)*B_SIZE,(i 1)*B_SIZE);setfillcolor(RGB(250,250,250)); // 绘制一个白色的小方块fillrectangle((j 0.3)*B_SIZE,(i 0.3)*B_SIZE,(j 0.7)*B_SIZE,(i 0.7)*B_SIZE);}}}// 以下绘制玩家,绘制一个人脸图案i = player.i; j = player.j;setfillcolor(RGB(255,0,0));fillcircle((j 0.5)*B_SIZE,(i 0.5)*B_SIZE,0.4*B_SIZE);//一个红色圆脸setfillcolor(RGB(80,80,80));setlinecolor(RGB(80,80,80));fillcircle((j 0.3)*B_SIZE,(i 0.45)*B_SIZE,0.08*B_SIZE);//两个黑色眼睛fillcircle((j 0.7)*B_SIZE,(i 0.45)*B_SIZE,0.08*B_SIZE); setlinestyle(PS_SOLID,3);line((j 0.35)*B_SIZE,(i 0.7)*B_SIZE,(j 0.65)*B_SIZE,(i 0.7)*B_SIZE);//深灰色嘴巴setlinestyle(PS_SOLID,1);if (achievedNum==targetNum) // 如完成目标个数==目标个数{setbkmode(TRANSPARENT); // 透明显示文字settextcolor(RGB(0,255,255)); // 设置字体颜色settextstyle(80, 0, _T(\"宋体\")); // 设置字体大小、样式outtextxy(80,200,_T(\"游戏胜利\")); // 显示游戏胜利文字}FlushBatchDraw(); // 开始批量绘制}void update() // 每帧更新运行{if(kbhit() && (achievedNum<targetNum) ) // 如果按键,并且游戏没有胜利{char input = getch(); // 获取按键if (input==\'a\' || input==\'s\' || input==\'d\' || input==\'w\') // 如果是有效按键{int goal_i = player.i; // 移动的目标位置int goal_j = player.j;int goalNext_i = goal_i; // 目标位置再向前的一个位置int goalNext_j = goal_j;// 根据用户的不同按键输入,获得目标位置、再向前的一个位置if (input==\'a\') // 向左{goal_j = player.j -1 ; // 目标位置在玩家位置的左边goalNext_j = goal_j-1; // 目标的下一个位置,在其再左边}else if (input==\'d\') // 向右{goal_j = player.j 1 ; // 目标位置在玩家位置的右边 goalNext_j = goal_j 1; // 目标的下一个位置,在其再右边}else if (input==\'s\') // 向下{goal_i = player.i 1; // 目标位置在玩家位置的下边 goalNext_i = goal_i 1; // 目标的下一个位置,在其再下边 }else if (input==\'w\') // 向上{goal_i = player.i-1; // 目标位置在玩家位置的上边 goalNext_i = goal_i-1; // 目标的下一个位置,在其再上边 }// 根据不同地图元素的情况,判断如何移动角色和更新地图元素if (level[goal_i][goal_j]==empty || level[goal_i][goal_j]==target ) {// 如果目标位置是empty,或者targetplayer.i = goal_i; // 玩家移动到目标位置player.j = goal_j; }else if (level[goal_i][goal_j]==box && level[goalNext_i][goalNext_j]==empty ) {// 如果目标位置是box,再前面一个是emptyplayer.i = goal_i; // 玩家移动到目标位置player.j = goal_j; level[goal_i][goal_j]=empty; // 目标位置变成emptylevel[goalNext_i][goalNext_j]=box; // 再前面变成box}else if (level[goal_i][goal_j]==box && level[goalNext_i][goalNext_j]==target) {// 如果目标位置是box,再前面一个是targetplayer.i = goal_i; // 玩家移动到目标位置player.j = goal_j;level[goal_i][goal_j] = empty; // 目标位置变成empty level[goalNext_i][goalNext_j] = achieved;// 再前面变成achieved}else if (level[goal_i][goal_j]==achieved && level[goalNext_i][goalNext_j]== empty) {// 如果目标位置是achieved,再前面一个是emptyplayer.i = goal_i; // 玩家移动到目标位置player.j = goal_j; level[goal_i][goal_j] = target; // 目标位置变成target level[goalNext_i][goalNext_j] = box; // 再前面变成box }else if (level[goal_i][goal_j]==achieved && level[goalNext_i][goalNext_j]== target) {// 如果目标位置是achieved,再前面一个是targetplayer.i = goal_i; // 玩家移动到目标位置player.j = goal_j;level[goal_i][goal_j] = target;lol卡盟 // 目标位置变成target level[goalNext_i][goalNext_j] = achieved; // 再前面变成achieved }else // 其他情况都推不动return; // 不做任何处理,函数直接返回}achievedNum = 0; // 完成目标个数,初始为0int i,j;for (i=0;i<B_NUM;i ) // 对二维数组遍历for (j=0;j<B_NUM;j ) // if (level[i][j]==achieved) // 如果元素是achievedachievedNum ; // 完成目标个数 1}}int main() // 主函数{startup(); // 初始化while (1) // 游戏主循环{show();// 绘制update(); // 更新}return 0;}
主要讲解了字符串与字符数组、文件读写、枚举类型等语法知识,实现了推箱子游戏。读者可以尝试在本章代码基础上继续改进:
1、实现多关卡的选择界面;
2、实现某一步移动的撤销功能(类似于下棋游戏中的悔棋功能);
3、实现按\’h\’键后进行提示,播放正确步骤动画的功能;
4、实现一个图形编辑器,并将设计的关卡信息保存为txt文件。
作者:童晶
希望对大家有帮助!
此外,我也给大家分享我收集的其他资源,从最零基础开始的教程到C语言C 项目案例,帮助大家在学习C语言的道路上披荆斩棘!
编程学习书籍分享:
编程学习视频分享:
整理分享(多年学习的源码、项目实战视频、项目笔记,基础入门教程)最重要的是你可以在群里面交流提问编程问题哦!
对于C/C 感兴趣可以关注小编在后台私信我:【编程交流】一起来学习哦!可以领取一些C/C 的项目学习视频资料哦!已经设置好了关键词自动回复,自动领取就好了!