package loon.action; import loon.geom.Vector2f; import loon.utils.Easing.EasingMode; import loon.utils.MathUtils; import loon.utils.timer.EaseTimer; /** * 让指定对象做环绕运动(与CircleTo差异在于CircleTo不会自行停止,且CircleTo仅以对象本身为中心做360度旋转),需要偏移或矫正显示位置时请设置setOffset参数 */ public class MoveRoundTo extends ActionEvent { private final float angle; private final float startAngle; private final float radius; private final float startRadius; private Vector2f startPoint,oldStartPoint; private Vector2f centerPoint,oldCenterPoint; private EaseTimer timer; public MoveRoundTo(float angle, float radius, Vector2f centerPoint, float duration, EasingMode easing) { this(0f, angle, 0f, radius, centerPoint, null, duration, 1f / 60f, easing); } public MoveRoundTo(float angle, float radius, Vector2f centerPoint, EasingMode easing) { this(0f, angle, 0f, radius, centerPoint, null, 1f, 1f / 60f, easing); } public MoveRoundTo(float angle, float radius, Vector2f centerPoint, float duration, float delay, EasingMode easing) { this(0f, angle, 0f, radius, centerPoint, null, duration, delay, easing); } public MoveRoundTo(float startAngle, float angle, float startRadius, float radius, Vector2f centerPoint) { this(startAngle, angle, startRadius, radius, centerPoint, null, 1f, 1f / 60f, EasingMode.Linear); } public MoveRoundTo(float startAngle, float angle, float startRadius, float radius, float duration, Vector2f centerPoint) { this(startAngle, angle, startRadius, radius, centerPoint, null, duration, 1f / 60f, EasingMode.Linear); } public MoveRoundTo(float startAngle, float angle, float startRadius, float radius, Vector2f centerPoint, Vector2f startPoint, float duration, float delay, EasingMode easing) { if (angle > 360) { angle = 360; } this.angle = angle; this.radius = radius; this.startAngle = startAngle; this.startRadius = startRadius; this.centerPoint = centerPoint; this.startPoint = startPoint; if (startPoint == null) { startPoint = new Vector2f(); } this.timer = new EaseTimer(duration, delay, easing); this.oldStartPoint = startPoint; this.oldCenterPoint = centerPoint; } @Override public void update(long elapsedTime) { timer.update(elapsedTime); if (timer.isCompleted()) { _isCompleted = true; float radian = MathUtils.toRadians(this.startAngle + this.angle); float x = this.centerPoint.x + MathUtils.cos(radian) * (this.startRadius + this.radius); float y = this.centerPoint.y + MathUtils.sin(radian) * (this.startRadius + this.radius); this.original.setLocation(x +original.getWidth()/2+ offsetX, y +original.getHeight()/2+ offsetY); return; } float currentRadius = this.startRadius + this.radius * timer.getProgress(); float currentAngle = this.startAngle + this.angle * timer.getProgress(); float radian = MathUtils.toRadians(currentAngle); this.startPoint.x = (this.centerPoint.x + MathUtils.cos(radian) * currentRadius); this.startPoint.y = (this.centerPoint.y + MathUtils.sin(radian) * currentRadius); this.original.setLocation(this.startPoint.x + offsetX, this.startPoint.y + offsetY); } @Override public void onLoad() { if (startPoint == null || startPoint.getX() == -1 || startPoint.getY() == -1) { this.startPoint = new Vector2f(original.getX(), original.getY()); } this.oldStartPoint.set(startPoint); this.oldCenterPoint.set(centerPoint); } @Override public boolean isComplete() { return _isCompleted; } @Override public ActionEvent cpy() { MoveRoundTo mover = new MoveRoundTo(startAngle, angle, startRadius, radius, oldCenterPoint, oldStartPoint, timer.getDuration(), timer.getDelay(), timer.getEasingMode()); mover.set(this); return mover; } @Override public ActionEvent reverse() { return cpy(); } @Override public String getName() { return "moveround"; } }