怀念童年,推箱子小游戏(vue版本)
前言最近都没有怎么写过文章,都断更很久了吧。学习前端一年多,快两年了,学习的热情相比一开始,自我感觉没有变化多少,但是学习的动力却好像时有时无。就好像是没了目标一样,不知道自己现在应该学些什么,从哪里提升自己,是为了工作,还是为了程序员这个职业。自己沉迷一段时间,真的出现一种躺平的状态。今天不知道怎么了,突然想起自己好久没有写过博客了,一边想着想写什么,一边找着以前自己的github项目,偶然间看
·
前言
最近都没有怎么写过文章,都断更很久了吧。学习前端一年多,快两年了,学习的热情相比一开始,自我感觉没有变化多少,但是 学习的动力却好像时有时无。 就好像是没了目标一样,不知道自己现在应该学些什么,从哪里提升自己,是为了工作,还是为了程序员这个职业。 自己沉迷一段时间,真的出现一种躺平的状态。今天不知道怎么了,突然想起自己好久没有写过博客了,一边想着想写什么,一边找着以前自己的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.mapElementName
switch (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(),不自禁的摇了摇头 大致上,一个基本的推箱子游戏就完成了,整体上难度不大,适合练手。最终的效果:
拓展
因为苦于推箱子的地图搜集(太耗时间了,而且不同的人心里面可能有着自己想过的关卡),同时为了增加游戏的灵活性,我当时自己有添加了 自己diy的模式,提供玩家自己设计地图。实现的思路大致上分为下面几步: 1. 提供选项,自己选择地图的大小; 2. 根据玩家的选择的地图大小,生成对应大小的地图方格,每个方格默认为墙内的空地,玩家可以点击方格,会出现可以设置为地图某个元素的选项,自由进行设计。 每个方格可以设置的元素不一样,是为了保证玩家设计出来的地图是可以玩的。当然,可以自由改动代码,生成的地图可以自由改变。 实现效果:
最后
从整体的实现上来看,推箱子的逻辑并不复杂,当然,因人而异,你们也可以设计得十分复杂。献上我的项目地址
原文链接
更多推荐
已为社区贡献2条内容
所有评论(0)