共计 3527 个字符,预计需要花费 9 分钟才能阅读完成。
前言
最近都没有怎么写过文章,都断更很久了吧。学习前端一年多,快两年了,学习的激情相比一开始,自我感觉没有变动多少,然而
学习的能源却如同时有时无。
就如同是没了指标一样,不晓得本人当初应该学些什么,从哪里晋升本人,是为了工作,还是为了程序员这个职业。
本人沉迷一段时间,真的呈现一种躺平的状态。明天不晓得怎么了,忽然想起本人良久没有写过博客了,一边想着想写什么,一边找着以前本人的 github 我的项目,
偶然间看见本人以前给他人写的一个推箱子小游戏,就写下了这篇文章。
思路
在咱们平时玩的推箱子游戏中,个别是由人,箱子,起点,在起点的箱子,空地和墙这几个元素组成,由玩家管制人的上下左右挪动从而推动箱子,只有所有的箱子都被推到起点,就算是游戏完结。当然,实现根本的游戏性能之后,咱们能够本人在开展设想,给本人写的货色增加一些乏味的元素。
规定
确定了根本元素,接下来就要确定游戏规则,这里我只是实现了最根本的规定,也能够本人适当的增加本人想要的规定下来:
- 人在空地上显示人,箱子在空地上显示箱子,起点在空地上显示起点;
- 人只能推动箱子,若箱子后面有障碍物(墙,箱子之类的),则无奈推动;
- 人,箱子,起点不能来到墙内;
能想到的规定目前就是这些,不是很具体,然而也没关系,反正咱们对这款游戏都是比拟相熟。
实现思路
- 首先是素材,并不难找,百度一下就能够找到根本实现游戏的一套素材,可能须要本人裁剪一下之类的。
- 人的挪动,这一块比拟容易实现,咱们能够定下键盘按下什么键,对应着什么样的操作,而咱们只须要监听键盘按下的动作即可。
- 接下来就是这个游戏中惟一的难点,如何走动这个动作。就比方,人通过一个空地,那么这里就会显示为人,人来到了,又会显示为空地,对于箱子,起点也是一样的。
物体挪动
在这里,我是将每一元素设置为一个数值。首先是将最根底的元素设置值,如 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(),不自禁的摇了点头(:clown_face::clown_face:)
大抵上,一个根本的推箱子游戏就实现了,整体上难度不大,适宜练手。最终的成果:
拓展
因为苦于推箱子的地图收集(太耗时间了,而且不同的人心外面可能有着本人想过的关卡),同时为了减少游戏的灵活性,我过后本人有增加了
本人 diy 的模式,提供玩家本人设计地图。实现的思路大抵上分为上面几步:
- 提供选项,本人抉择地图的大小;
- 依据玩家的抉择的地图大小,生成对应大小的地图方格,每个方格默认为墙内的空地,玩家能够点击方格,会呈现能够设置为地图某个元素的选项,自在进行设计。
每个方格能够设置的元素不一样,是为了保障玩家设计进去的地图是能够玩的。当然,能够自在改变代码,生成的地图能够自在扭转。
实现成果
最初
从整体的实现上来看,推箱子的逻辑并不简单,当然,因人而异,你们也能够设计得十分复杂。献上我的我的项目地址
原文链接