人物移动在游戏中很常见,今天就简单介绍一下在uniapp中如何实现让一个“人物”沿着一条“路线”走的动画。这个里面就需要用到animation里面的偏移方法,偏移里面分几种方式,有沿着X轴方向的偏移,也有沿着Y轴方向的偏移等等,下面我们就以一个demo例子来说明一下如何实现偏移动画。demo例子如下图。

一、构建路线数组
1. 假如每个格子的大小为112x116
#路线配置
let lineList =
[
{
left: 3, //基于父级的左边距几个格子
top: 0 //基于父级的上边距几个格子
},
{
left: 2,
top: 0
},
{
left: 1,
top: 0
},
...
]
//地图列表
let mapList = lineList.map((item, index) => {
return {
index: index,
left: item.left * this.cellWidth, //每个格子的宽度
top: item.top * this.cellHeight, //每个格子的高度
}
})
二、执行行走动画
1.数据里面定义的一些变量
props: {
//父组件将地图数组传递过来
mapList: {
type: Array,
default() {
return []
}
},
},
data() {
//所处的地图的位置(所处地图数组的位置)
position: {
//所在地图索引
index: 0,
//已经移动的X轴距离
x: 0,
//已经移动的Y轴距离
y: 0
},
//动画对象
animation: null,
//保存动画数据
animationData: {},
//有没有正在走
isRuning: false,
//每走一步的时间(单位毫秒)
timePerStep: 500,
...
}
2.行走方法
//设置角色人物前进
walk(step = 0) {
//1.假如正在行走
//2.未传递需要行走几步
//3.地图列表长度为空
//4.当前所在位置已经走到头了
if (
this.isRuning ||
!step ||
!this.mapList.length ||
this.position.index >= this.mapList.length - 1
) {
return
}
//移动到的目标位置
let targetPosition = this.position.index + step
//如果是前进
if (step > 0) {
//假如走到底需要计算退回的步数
let needBackNum = 0
//目标位置超过或者达到最后的节点
if (targetPosition >= this.mapList.length - 1) {
//计算出需要回退的步数
needBackNum = targetPosition - (this.mapList.length - 1)
//设置最后位置为最后的节点
targetPosition = this.mapList.length - 1
}
//执行行走动画
this.walkAnimation(this.position.index, targetPosition)
//如果存在需要回退的情况
if (needBackNum) {
//设置回退后的目标位置
let lastTargetPosition = targetPosition - needBackNum
//开启行走动画
this.walkAnimation(targetPosition, lastTargetPosition)
//设置最终的目标位置
targetPosition = lastTargetPosition
}
} else {
//如果退回的位置到了起点位置或者超过了起点位置则统一设置为最终位置就是起点位置
if (targetPosition <= 0) {
targetPosition = 0
}
//开始行走动画
this.walkAnimation(this.position.index, targetPosition)
}
//导出动画
this.animationData = this.animation.export()
//标记开始行走
this.isRuning = true
//通知父组件
this.$emit('runing')
//播放走路音效
this.playAudio('walk')
//设置当前的位置为新位置
this.position.index = targetPosition
//计算出总时长
let totalDuration = this.timePerStep * Math.abs(step)
//过了指定时间开放走路模式
setTimeout(() => {
//停止走路
this.isRuning = false
//停止音效
this.stopAudio()
//通知父组件,告知当前的位置
this.$emit('stop', this.position)
}, totalDuration)
},
//走路动画
walkAnimation(startPos = 0, endPos = 0) {
if (startPos == endPos) {
//原地不动
return
} else if (startPos < endPos) {
//前进
for (let index = startPos; index < endPos; index++) {
//计算出X轴需要移动的距离
let xDistance =
this.mapList[index + 1].left - this.mapList[index].left
//计算出Y轴需要移动的距离
let yDistance = this.mapList[index + 1].top - this.mapList[index].top
if (xDistance) {
this.position.x += xDistance
this.animation
.translateX(this.position.x + 'rpx')
.step({ duration: this.timePerStep })
} else {
this.position.y += yDistance
this.animation
.translateY(this.position.y + 'rpx')
.step({ duration: this.timePerStep })
}
}
} else {
//后退
for (let index = startPos; index > endPos; index--) {
//计算出X轴需要移动的距离
let xDistance =
this.mapList[index].left - this.mapList[index - 1].left
//计算出Y轴需要移动的距离
let yDistance = this.mapList[index].top - this.mapList[index - 1].top
if (xDistance) {
this.position.x -= xDistance
this.animation
.translateX(this.position.x + 'rpx')
.step({ duration: this.timePerStep })
} else {
this.position.y -= yDistance
this.animation
.translateY(this.position.y + 'rpx')
.step({ duration: this.timePerStep })
}
}
}
}
网友评论