vue实现推箱子小游戏

前言 最近都没有怎么写过文章,都断更很久了吧。学习前端一年多,快两年了,学习的热情相比一开始,自我感觉没有变化多少,但是
学习的动力却好像时有时无。
就好像是没了目标一样,不知道自己现在应该学些什么,从哪里提升自己,是为了工作,还是为了程序员这个职业。
自己沉迷一段时间,真的出现一种躺平的状态。今天不知道怎么了,突然想起自己好久没有写过博客了,一边想着想写什么,一边找着以前自己的github项目,
偶然间看见自己以前给别人写的一个推箱子小游戏,就写下了这篇文章。
思路 在我们平时玩的推箱子游戏中,一般是由人,箱子,终点,在终点的箱子,空地和墙这几个元素组成,由玩家控制人的上下左右移动从而推动箱子,只要所有的箱子都被推到终点,就算是游戏结束。当然,完成基本的游戏功能之后,我们可以自己在展开想象,给自己写的东西添加一些有趣的元素。
规则
确定了基本元素,接下来就要确定游戏规则,这里我只是完成了最基本的规则,也可以自己适当的添加自己想要的规则上去:

  1. 人在空地上显示人,箱子在空地上显示箱子,终点在空地上显示终点;
  2. 人只能推动箱子,若箱子前面有障碍物(墙,箱子之类的),则无法推动;
  3. 人,箱子,终点不能离开墙内;
能想到的规则目前就是这些,不是很详细,但是也没关系,反正我们对这款游戏都是比较熟悉。
实现思路
  1. 首先是素材,并不难找,百度一下就可以找到基本完成游戏的一套素材,可能需要自己裁剪一下之类的。
  2. 人的移动,这一块比较容易实现,我们可以定下键盘按下什么键,对应着什么样的操作,而我们只需要监听键盘按下的动作即可。
  3. 接下来就是这个游戏中唯一的难点,如何走动这个动作。就比如,人经过一个空地,那么这里就会显示为人,人离开了,又会显示为空地,对于箱子,终点也是一样的。
物体移动 在这里,我是将每一元素设置为一个数值。首先是将最基础的元素设置值,如 1 表示箱子。下面的代码就是我对不同状态下的元素进行的一个简单配置:
mapElementName: { 0: { name: '墙内空地', icon: require('@/assets/image/墙内空地.png'), type: 'move' // 可移动类型,表示任何情况下可以移动 }, 1: { name: '箱子', icon: require('@/assets/image/箱子.png'), type: 'MF' // move&&fix,表示不确定类型,可移动或者是不可移动 }, 2: { name: '终点', icon: require('@/assets/image/终点.png'), type: 'move' }, 3: { name: '箱子&&终点', icon: require('@/assets/image/箱子&&终点.png'), type: 'MF' }, 10: { name: '人', icon: require('@/assets/image/人.png'), type: 'fix' }, 12: { name: '人', icon: require('@/assets/image/人.png'), type: 'fix' }, 109: { name: '人', icon: require('@/assets/image/人.png'), type: 'fix' }, 98: { name: '墙', icon: require('@/assets/image/墙.png'), type: 'fix' }, 99: { name: '墙外空地', icon: require('@/assets/image/墙外空地.png'), type: 'move' } },

简单解释就是:2表示终点,10表示人,人移动到终点那里,就是10+2=12,那么12表人移动到终点的时候,人一旦离开,就会是12-10=2,2表示终点
上面的思路理解了,接下来就可以写代码了。
相关的实现代码 监听键盘敲下上下左右
// 循环判断当前的人所处的位置 this.mapArray.forEach((item, index) => { item.forEach((array, temp) => { if (this.mapElementName[array].name === '人') { this.manPosition = [index, temp] } }) }) //判断点击的键盘 // 传递的参数:人所在的位置, 人要移动到的位置的相关元素信息以及下一个信息 const man = this.manPosition const array = this.mapArray const name = this.mapElementNameswitch (e.keyCode) { case 38: this.toTop(name[array[man[0] - 1][man[1]]], man[0] - 2 < 0 ? false : name[array[man[0] - 2][man[1]]]) break case 40: this.toBottom( name[array[man[0] + 1][man[1]]], man[0] + 3 > this.maxRow ? false : name[array[man[0] + 2][man[1]]] ) break case 37: this.toLeft(name[array[man[0]][man[1] - 1]], man[1] - 2 < 0 ? false : name[array[man[0]][man[1] - 2]]) break case 39: this.toRight( name[array[man[0]][man[1] + 1]], man[1] + 3 > this.maxColumn ? false : name[array[man[0]][man[1] + 2]] ) }

当键盘敲击的时候,因为我们控制的是人,所以先循环判断当前人所处的位置,然后在进行移动。这段代码可以很明显看出来,每次敲击键盘的时候都要去循环找出人的位置,这一点处理得不合理,我们可以
定义一个变量将当前人的位置储存起来。(以前的代码,不想改动,只做说明:clown_face::clown_face:)
接着根据点击不同的键进行不同的操作,下面是向下操作的代码(其他的操作类型):
//1.人的下边是墙 if (next.type === 'fix') { return } //2.人的下边是箱子,箱子的下边是箱子或者是箱子&&终点或者是墙 if (next.type === 'MF' && doubleNext) { if (doubleNext.type === 'MF' || doubleNext.type === 'fix') { return } //开始移动 //人的位置减去10,下面的位置减去箱子加上人,下下面的位置加上箱子 this.mapArray[this.manPosition[0]][this.manPosition[1]] -= 10 this.mapArray[this.manPosition[0] + 1][this.manPosition[1]] -= 1 this.mapArray[this.manPosition[0] + 1][this.manPosition[1]] += 10 this.mapArray[this.manPosition[0] + 2][this.manPosition[1]] += 1 } //3.人的下边是空地或者是终点 if (next.type === 'move') { //人的位置减去10, 下边位置加上10 this.mapArray[this.manPosition[0]][this.manPosition[1]] -= 10 this.mapArray[this.manPosition[0] + 1][this.manPosition[1]] += 10 } //刷新页面 this.$forceUpdate()

嗯,有这么几种情况,但当我看到 this.$forceUpdate(),不自禁的摇了摇头(:clown_face::clown_face:)
大致上,一个基本的推箱子游戏就完成了,整体上难度不大,适合练手。最终的效果:
vue实现推箱子小游戏
文章图片

拓展 因为苦于推箱子的地图搜集(太耗时间了,而且不同的人心里面可能有着自己想过的关卡),同时为了增加游戏的灵活性,我当时自己有添加了
自己diy的模式,提供玩家自己设计地图。实现的思路大致上分为下面几步:
  1. 提供选项,自己选择地图的大小;
  2. 根据玩家的选择的地图大小,生成对应大小的地图方格,每个方格默认为墙内的空地,玩家可以点击方格,会出现可以设置为地图某个元素的选项,自由进行设计。
    每个方格可以设置的元素不一样,是为了保证玩家设计出来的地图是可以玩的。当然,可以自由改动代码,生成的地图可以自由改变。
实现效果
vue实现推箱子小游戏
文章图片

最后
【vue实现推箱子小游戏】从整体的实现上来看,推箱子的逻辑并不复杂,当然,因人而异,你们也可以设计得十分复杂。献上我的项目地址
原文链接

    推荐阅读