var DegToRad = require('../../math/DegToRad'); var GetBoolean = require('../../tweens/builders/GetBoolean'); var GetValue = require('../../utils/object/GetValue'); var TWEEN_CONST = require('../../tweens/tween/const'); var Vector2 = require('../../math/Vector2'); var PathFollower = { path: null , rotateToPath: false , pathRotationOffset: 0, pathOffset: null , pathVector: null , pathDelta: null , pathTween: null , pathConfig: null , _prevDirection: TWEEN_CONST.PLAYING_FORWARD, setPath: function (path, config){ if (config === undefined) { config = this.pathConfig; } var tween = this.pathTween; if (tween && tween.isPlaying()) { tween.stop(); } this.path = path; if (config) { this.startFollow(config); } return this; } , setRotateToPath: function (value, offset){ if (offset === undefined) { offset = 0; } this.rotateToPath = value; this.pathRotationOffset = offset; return this; } , isFollowing: function (){ var tween = this.pathTween; return (tween && tween.isPlaying()); } , startFollow: function (config, startAt){ if (config === undefined) { config = { } ; } if (startAt === undefined) { startAt = 0; } var tween = this.pathTween; if (tween && tween.isPlaying()) { tween.stop(); } if (typeof config === 'number') { config = { duration: config} ; } config.from = GetValue(config, 'from', 0); config.to = GetValue(config, 'to', 1); var positionOnPath = GetBoolean(config, 'positionOnPath', false ); this.rotateToPath = GetBoolean(config, 'rotateToPath', false ); this.pathRotationOffset = GetValue(config, 'rotationOffset', 0); var seek = GetValue(config, 'startAt', startAt); if (seek) { config.onStart = function (tween){ var tweenData = tween.data[0]; tweenData.progress = seek; tweenData.elapsed = tweenData.duration * seek; var v = tweenData.ease(tweenData.progress); tweenData.current = tweenData.start + ((tweenData.end - tweenData.start) * v); _AN_Read_target('target', tweenData)[tweenData.key] = tweenData.current; } ; } if (!this.pathOffset) { this.pathOffset = new Vector2(this.x, this.y); } if (!this.pathVector) { this.pathVector = new Vector2(); } if (!this.pathDelta) { this.pathDelta = new Vector2(); } this.pathDelta.reset(); this.pathTween = this.scene.sys.tweens.addCounter(config); this.path.getStartPoint(this.pathOffset); if (positionOnPath) { this.x = this.pathOffset.x; this.y = this.pathOffset.y; } this.pathOffset.x = this.x - this.pathOffset.x; this.pathOffset.y = this.y - this.pathOffset.y; this._prevDirection = TWEEN_CONST.PLAYING_FORWARD; if (this.rotateToPath) { var nextPoint = this.path.getPoint(0.1); this.rotation = Math.atan2(nextPoint.y - this.y, nextPoint.x - this.x) + DegToRad(this.pathRotationOffset); } this.pathConfig = config; return this; } , pauseFollow: function (){ var tween = this.pathTween; if (tween && tween.isPlaying()) { tween.pause(); } return this; } , resumeFollow: function (){ var tween = this.pathTween; if (tween && tween.isPaused()) { tween.resume(); } return this; } , stopFollow: function (){ var tween = this.pathTween; if (tween && tween.isPlaying()) { tween.stop(); } return this; } , pathUpdate: function (){ var tween = this.pathTween; if (tween) { var tweenData = tween.data[0]; var pathDelta = this.pathDelta; var pathVector = this.pathVector; pathDelta.copy(pathVector).negate(); if (tweenData.state === TWEEN_CONST.COMPLETE) { this.path.getPoint(1, pathVector); pathDelta.add(pathVector); pathVector.add(this.pathOffset); this.setPosition(pathVector.x, pathVector.y); return ; } else if (tweenData.state !== TWEEN_CONST.PLAYING_FORWARD && tweenData.state !== TWEEN_CONST.PLAYING_BACKWARD) { return ; } this.path.getPoint(tween.getValue(), pathVector); pathDelta.add(pathVector); pathVector.add(this.pathOffset); var oldX = this.x; var oldY = this.y; this.setPosition(pathVector.x, pathVector.y); var speedX = this.x - oldX; var speedY = this.y - oldY; if (speedX === 0 && speedY === 0) { return ; } if (tweenData.state !== this._prevDirection) { this._prevDirection = tweenData.state; return ; } if (this.rotateToPath) { this.rotation = Math.atan2(speedY, speedX) + DegToRad(this.pathRotationOffset); } } } } ; module.exports = PathFollower;