人物移動在游戲中很常見,今天就簡單介紹一下在uniapp中如何實現(xiàn)讓一個“人物”沿著一條“路線”走的動畫毯欣。這個里面就需要用到animation里面的偏移方法底桂,偏移里面分幾種方式泉懦,有沿著X軸方向的偏移片部,也有沿著Y軸方向的偏移等等,下面我們就以一個demo例子來說明一下如何實現(xiàn)偏移動畫暇番。demo例子如下圖嗤放。
一、構(gòu)建路線數(shù)組
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, //每個格子的高度
}
})
二壁酬、執(zhí)行行走動畫
1.數(shù)據(jù)里面定義的一些變量
props: {
//父組件將地圖數(shù)組傳遞過來
mapList: {
type: Array,
default() {
return []
}
},
},
data() {
//所處的地圖的位置(所處地圖數(shù)組的位置)
position: {
//所在地圖索引
index: 0,
//已經(jīng)移動的X軸距離
x: 0,
//已經(jīng)移動的Y軸距離
y: 0
},
//動畫對象
animation: null,
//保存動畫數(shù)據(jù)
animationData: {},
//有沒有正在走
isRuning: false,
//每走一步的時間(單位毫秒)
timePerStep: 500,
...
}
2.行走方法
//設(shè)置角色人物前進
walk(step = 0) {
//1.假如正在行走
//2.未傳遞需要行走幾步
//3.地圖列表長度為空
//4.當前所在位置已經(jīng)走到頭了
if (
this.isRuning ||
!step ||
!this.mapList.length ||
this.position.index >= this.mapList.length - 1
) {
return
}
//移動到的目標位置
let targetPosition = this.position.index + step
//如果是前進
if (step > 0) {
//假如走到底需要計算退回的步數(shù)
let needBackNum = 0
//目標位置超過或者達到最后的節(jié)點
if (targetPosition >= this.mapList.length - 1) {
//計算出需要回退的步數(shù)
needBackNum = targetPosition - (this.mapList.length - 1)
//設(shè)置最后位置為最后的節(jié)點
targetPosition = this.mapList.length - 1
}
//執(zhí)行行走動畫
this.walkAnimation(this.position.index, targetPosition)
//如果存在需要回退的情況
if (needBackNum) {
//設(shè)置回退后的目標位置
let lastTargetPosition = targetPosition - needBackNum
//開啟行走動畫
this.walkAnimation(targetPosition, lastTargetPosition)
//設(shè)置最終的目標位置
targetPosition = lastTargetPosition
}
} else {
//如果退回的位置到了起點位置或者超過了起點位置則統(tǒng)一設(shè)置為最終位置就是起點位置
if (targetPosition <= 0) {
targetPosition = 0
}
//開始行走動畫
this.walkAnimation(this.position.index, targetPosition)
}
//導(dǎo)出動畫
this.animationData = this.animation.export()
//標記開始行走
this.isRuning = true
//通知父組件
this.$emit('runing')
//播放走路音效
this.playAudio('walk')
//設(shè)置當前的位置為新位置
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 })
}
}
}
}