vue实现推箱子小游戏
前言
最近都没有怎么写过文章,都断更很久了吧。学习前端一年多,快两年了,学习的热情相比一开始,自我感觉没有变化多少,但是
学习的动力却好像时有时无。
就好像是没了目标一样,不知道自己现在应该学些什么,从哪里提升自己,是为了工作,还是为了程序员这个职业。
自己沉迷一段时间,真的出现一种躺平的状态。今天不知道怎么了,突然想起自己好久没有写过博客了,一边想着想写什么,一边找着以前自己的github项目,
偶然间看见自己以前给别人写的一个推箱子小游戏,就写下了这篇文章。
思路
在我们平时玩的推箱子游戏中,一般是由人,箱子,终点,在终点的箱子,空地和墙这几个元素组成,由玩家控制人的上下左右移动从而推动箱子,只要所有的箱子都被推到终点,就算是游戏结束。当然,完成基本的游戏功能之后,我们可以自己在展开想象,给自己写的东西添加一些有趣的元素。
规则
确定了基本元素,接下来就要确定游戏规则,这里我只是完成了最基本的规则,也可以自己适当的添加自己想要的规则上去:
- 人在空地上显示人,箱子在空地上显示箱子,终点在空地上显示终点;
- 人只能推动箱子,若箱子前面有障碍物(墙,箱子之类的),则无法推动;
- 人,箱子,终点不能离开墙内;
实现思路
- 首先是素材,并不难找,百度一下就可以找到基本完成游戏的一套素材,可能需要自己裁剪一下之类的。
- 人的移动,这一块比较容易实现,我们可以定下键盘按下什么键,对应着什么样的操作,而我们只需要监听键盘按下的动作即可。
- 接下来就是这个游戏中唯一的难点,如何走动这个动作。就比如,人经过一个空地,那么这里就会显示为人,人离开了,又会显示为空地,对于箱子,终点也是一样的。
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:)
大致上,一个基本的推箱子游戏就完成了,整体上难度不大,适合练手。最终的效果:
文章图片
拓展 因为苦于推箱子的地图搜集(太耗时间了,而且不同的人心里面可能有着自己想过的关卡),同时为了增加游戏的灵活性,我当时自己有添加了
自己diy的模式,提供玩家自己设计地图。实现的思路大致上分为下面几步:
- 提供选项,自己选择地图的大小;
- 根据玩家的选择的地图大小,生成对应大小的地图方格,每个方格默认为墙内的空地,玩家可以点击方格,会出现可以设置为地图某个元素的选项,自由进行设计。
每个方格可以设置的元素不一样,是为了保证玩家设计出来的地图是可以玩的。当然,可以自由改动代码,生成的地图可以自由改变。
文章图片
最后
【vue实现推箱子小游戏】从整体的实现上来看,推箱子的逻辑并不复杂,当然,因人而异,你们也可以设计得十分复杂。献上我的项目地址
原文链接
推荐阅读
- vue-cli|vue-cli 3.x vue.config.js 配置
- 2020-04-07vue中Axios的封装和API接口的管理
- 关于QueryWrapper|关于QueryWrapper,实现MybatisPlus多表关联查询方式
- MybatisPlus使用queryWrapper如何实现复杂查询
- python学习之|python学习之 实现QQ自动发送消息
- 孩子不是实现父母欲望的工具——林哈夫
- opencv|opencv C++模板匹配的简单实现
- Node.js中readline模块实现终端输入
- java中如何实现重建二叉树
- 人脸识别|【人脸识别系列】| 实现自动化妆