上文(02.组件)中我们一已经实现了移动组件,本文中将优化该组件。
刚才实现的速度组件大致有以下几个问题
- 速度并非具有由快到慢的变化,转变十分生硬。
- 速度大小并不能自定义
- 在同时触发多个键时可能出现不同的移动情况。
实现思路: 在触发按键时,加速速度,并且将状态标记为主动变化。在按键结束时,触发被动减速。
修改后的moveComponment为:
package com.dam.wonder.component;
import com.almasb.fxgl.core.math.Vec2;
import com.almasb.fxgl.entity.component.Component;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@AllArgsConstructor
@NoArgsConstructor
@Slf4j
public class MoveComponent extends Component {
private double speedX = 0d;
private double speedY = 0d;
private double maxSpeed = 4d;
private double aTime = 1d;
private boolean speedXAdd;
private boolean speedYAdd;
@Override
public void onUpdate(double tpf) {
// log.info("当前状态下 x速度为=[{}], Y速度为=[{}] x加速状态为=[{}] Y加速状态为 =[{}]",speedX,speedY,speedXAdd,speedYAdd);
if (speedX != 0d) {
Vec2 dir = Vec2.fromAngle(entity.getRotation() - 360)
.mulLocal(speedX);
entity.translate(dir);
}
if (speedY != 0d) {
Vec2 dir = Vec2.fromAngle(entity.getRotation() - 90)
.mulLocal(speedY);
entity.translate(dir);
}
if (!speedXAdd) {
slowDownSpeed(true);
}
if (!speedYAdd) {
slowDownSpeed(false);
}
}
public void up() {
changeSpeed(true,false);
}
public void left() {
changeSpeed(false,true);
}
public void right() {
changeSpeed(true,true);
}
public void down(){
changeSpeed(false,false);
}
public void stop() {
speedX = 0d;
speedY = 0d;
}
public void stopX() {
speedXAdd = false;
}
public void stopY() {
speedYAdd = false;
}
/**
* 改变移动速度 主动改变
* @param upOrDown
* @param xOrY
*/
private void changeSpeed(boolean upOrDown,boolean xOrY) {
if (xOrY) {
speedXAdd = true;
if (upOrDown) {
if (speedX < maxSpeed) {
speedX = speedX + (float)maxSpeed/(10*aTime) + 0.01;
}
}else {
if (speedX > -maxSpeed) {
speedX = speedX - (float)maxSpeed/(10f*aTime) - 0.01;
}
}
}else {
speedYAdd = true;
if (upOrDown) {
if (speedY < maxSpeed) {
speedY = speedY + (float)maxSpeed/(10f*aTime) + 0.01;
}
}else {
if (speedY > -maxSpeed) {
speedY = speedY - (float)maxSpeed/(10f*aTime) - 0.01;
}
}
}
}
/**
* 速度减少 被动减速
* @param xOrY
*/
private void slowDownSpeed(boolean xOrY) {
if (xOrY) {
if (speedX > 0.5) {
speedX = speedX - (float)speedX/10 -0.01;}
else if (speedX< -0.5){
speedX = speedX - (float)speedX/10 +0.01;
}else {
speedX = 0d;
}
}else {
if (speedY > 0.5) {
speedY = speedY - (float)speedY/10 -0.01;}
else if (speedY< -0.5){
speedY = speedY - (float)speedY/10 +0.01;
}else {
speedY = 0d;
}
}
}
public double getSpeedX() {
return speedX;
}
public void setSpeedX(double speedX) {
this.speedX = speedX;
}
public double getSpeedY() {
return speedY;
}
public void setSpeedY(double speedY) {
this.speedY = speedY;
}
public double getMaxSpeed() {
return maxSpeed;
}
public void setMaxSpeed(double maxSpeed) {
this.maxSpeed = maxSpeed;
}
public double getaTime() {
return aTime;
}
public void setaTime(double aTime) {
this.aTime = aTime;
}
}
我增加了两个个全新的stop方法,用来标记该坐标轴上是否有按键在修改移动速度,如果没有则触发主动清空任务。并且给方法增加了加速时间atime这个属性,并增加了对应的全参数构造方法,熟悉lombok的同学可以很简单的理解这两个构造注解。
当然gameapp类也需要改变,会在文末突出。经过这个方法改造的组件将会有更流畅的操作体验,在飞机移动时的手感更佳。当然,除了自己书写相应的加减速规则之外,游戏引擎还提供了更加全功能的物理移动。还有物理碰撞检测等更加实用的组件。会在后文中一一指出。