diff options
Diffstat (limited to 'core/src/org/snoopdesigns')
6 files changed, 164 insertions, 144 deletions
diff --git a/core/src/org/snoopdesigns/endless/physics/PhysicalBody.java b/core/src/org/snoopdesigns/endless/physics/PhysicalBody.java index 914d06a..31204a9 100644 --- a/core/src/org/snoopdesigns/endless/physics/PhysicalBody.java +++ b/core/src/org/snoopdesigns/endless/physics/PhysicalBody.java @@ -37,7 +37,6 @@ public abstract class PhysicalBody {      public void limitVelocity() {          if (getBody().getLinearVelocity().len() > getMaxVelocity()) { -            System.out.println("Limit velocity" + getMaxVelocity());              getBody().setLinearVelocity(getBody().getLinearVelocity().limit(getMaxVelocity()));          }      } diff --git a/core/src/org/snoopdesigns/endless/world/ObjectsRenderer.java b/core/src/org/snoopdesigns/endless/world/ObjectsRenderer.java index 3afea26..3055532 100644 --- a/core/src/org/snoopdesigns/endless/world/ObjectsRenderer.java +++ b/core/src/org/snoopdesigns/endless/world/ObjectsRenderer.java @@ -20,7 +20,7 @@ public class ObjectsRenderer implements Renderer {          batch = new SpriteBatch();          renderables.add(Context.getInstance().getPlayerShip()); -        IntStream.range(0, 1).forEach(i -> +        IntStream.range(0, 3).forEach(i ->                  renderables.add(new SteerableEnemyShip()));          renderables.forEach(Renderable::create); diff --git a/core/src/org/snoopdesigns/endless/world/ship/SteerableEnemyShip.java b/core/src/org/snoopdesigns/endless/world/ship/SteerableEnemyShip.java index 6db087e..e8d429c 100644 --- a/core/src/org/snoopdesigns/endless/world/ship/SteerableEnemyShip.java +++ b/core/src/org/snoopdesigns/endless/world/ship/SteerableEnemyShip.java @@ -1,14 +1,6 @@  package org.snoopdesigns.endless.world.ship; -import java.util.List; -  import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.ai.steer.SteeringAcceleration; -import com.badlogic.gdx.ai.steer.SteeringBehavior; -import com.badlogic.gdx.ai.steer.behaviors.Arrive; -import com.badlogic.gdx.ai.steer.behaviors.BlendedSteering; -import com.badlogic.gdx.ai.steer.behaviors.Face; -import com.badlogic.gdx.ai.utils.Location;  import com.badlogic.gdx.graphics.Texture;  import com.badlogic.gdx.graphics.g2d.Sprite;  import com.badlogic.gdx.graphics.g2d.SpriteBatch; @@ -17,28 +9,18 @@ import com.badlogic.gdx.math.Vector2;  import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;  import com.badlogic.gdx.physics.box2d.CircleShape;  import com.badlogic.gdx.physics.box2d.FixtureDef; -import org.snoopdesigns.endless.context.Context; -import org.snoopdesigns.endless.physics.Box2DLocation;  import org.snoopdesigns.endless.physics.SteerablePhysicalBody;  import org.snoopdesigns.endless.world.Renderable;  import org.snoopdesigns.endless.world.effects.EngineEffect; +import org.snoopdesigns.endless.world.steering.ChaseSteering; +import org.snoopdesigns.endless.world.steering.Steering; +import org.snoopdesigns.endless.world.steering.SteeringApplicator;  public class SteerableEnemyShip extends SteerablePhysicalBody implements Renderable {      private Sprite sprite; -    private Sprite targetSprite; //target position -    private Sprite farAttackPointSprite; //farAttackPoint -    private Sprite faceSprite; //face position -    private final SteeringAcceleration<Vector2> steeringOutput = new SteeringAcceleration<>(new Vector2()); -    private BlendedSteering<Vector2> steeringCombination; - -    private Location<Vector2> positionTarget; -    private Location<Vector2> faceTarget; -    private float targetDirection; - -    private final Vector2 lastVelocity = new Vector2(0f, 0f); -      private EngineEffect engineEffect; +    private Steering steering;      @Override      public BodyType getBodyType() { @@ -55,21 +37,6 @@ public class SteerableEnemyShip extends SteerablePhysicalBody implements Rendera      }      @Override -    public float getMass() { -        return 10000; -    } - -    @Override -    public float getLinearDamping() { -        return 1.5f; -    } - -    @Override -    public float getMaxVelocity() { -        return 80f; -    } - -    @Override      public Vector2 getInitialPosition() {          return new Vector2(MathUtils.random(150), MathUtils.random(150));      } @@ -77,6 +44,7 @@ public class SteerableEnemyShip extends SteerablePhysicalBody implements Rendera      @Override      public void create() {          initBody(); +          final Texture texture = new Texture(Gdx.files.internal("ship.png"));          sprite = new Sprite(texture);          final float expectedSizeInMeters = 15f; @@ -86,73 +54,40 @@ public class SteerableEnemyShip extends SteerablePhysicalBody implements Rendera          sprite.setScale(scale.x, scale.y);          sprite.setRotation(MathUtils.radDeg * getBody().getAngle()); -        final Texture targetTexture = new Texture(Gdx.files.internal("target.png")); -        targetSprite = new Sprite(targetTexture); -        targetSprite.setScale(0.03f); -        farAttackPointSprite = new Sprite(targetTexture); -        farAttackPointSprite.setScale(0.02f); -        faceSprite = new Sprite(new Texture(Gdx.files.internal("face.png"))); -        faceSprite.setScale(0.02f); +        engineEffect = new EngineEffect(this); +        steering = new ChaseSteering(this, 120f, 90f, new SteeringApplicator() { -        positionTarget = new Box2DLocation(); -        faceTarget = new Box2DLocation(); +            private boolean speedUp = false; -        engineEffect = new EngineEffect(this); +            @Override +            public void applyAngularVelocity(float angular) { +                getBody().setAngularVelocity(angular); +            } -        steeringCombination = new BlendedSteering<>(this); -        getSteeringBehaviours().forEach(steeringBehaviour -> -                steeringCombination.add(steeringBehaviour, 0.5f)); +            @Override +            public void applyLinearVelocity(Vector2 linear) { +                speedUp(linear); +                if (!speedUp) { +                    engineEffect.start(); +                } +                speedUp = true; +            } -        targetDirection = MathUtils.random(MathUtils.PI2); +            @Override +            public void stopLinearVelocity() { +                engineEffect.stop(); +                speedUp = false; +            } +        });      }      @Override      public void render(SpriteBatch batch) { -        final float maxDistance = 100f; -        final float minDistance = 70f; -        final Vector2 targetDisplacement = new Vector2(maxDistance, 0f).rotateRad(targetDirection); -        final Vector2 farAttackPoint = new Vector2( -                Context.getInstance().getPlayerShip().getBody().getPosition().x + targetDisplacement.x, -                Context.getInstance().getPlayerShip().getBody().getPosition().y + targetDisplacement.y); -        final float distanceToPlayer = new Vector2( -                getBody().getPosition().x - Context.getInstance().getPlayerShip().getBody().getPosition().x, -                getBody().getPosition().y - Context.getInstance().getPlayerShip().getBody().getPosition().y) -                .len(); -        if (distanceToPlayer > maxDistance + 10f) { -            // Rotate target rotation point only of player is far away -            targetDirection += Gdx.graphics.getDeltaTime() / 2f; -        } -        final Vector2 displacement = targetDisplacement.limit(Math.max(0, distanceToPlayer - minDistance)); -        final Vector2 targetPos = new Vector2( -                Context.getInstance().getPlayerShip().getBody().getPosition().x + displacement.x, -                Context.getInstance().getPlayerShip().getBody().getPosition().y + displacement.y); - -        positionTarget.getPosition().set(targetPos); -        //positionTarget.setOrientation(Context.getInstance().getPlayerShip().getBody().getAngle()); -        faceTarget.getPosition().set(positionTarget.getPosition()); - -        steeringCombination.calculateSteering(steeringOutput); -        if (distanceToPlayer <= minDistance) { // do not move, if close to player, only rotate -            steeringOutput.linear.setZero(); -        } -        applySteering(); +        steering.calculate();          sprite.setCenter(getBody().getPosition().x, getBody().getPosition().y);          sprite.setRotation(MathUtils.radDeg * getBody().getAngle());          sprite.draw(batch); -        farAttackPointSprite.setCenter( -                farAttackPoint.x, -                farAttackPoint.y); -        farAttackPointSprite.draw(batch); -        targetSprite.setCenter( -                positionTarget.getPosition().x, -                positionTarget.getPosition().y); -        targetSprite.draw(batch); -        faceSprite.setCenter( -                faceTarget.getPosition().x, -                faceTarget.getPosition().y); -        faceSprite.draw(batch); -          engineEffect.render(batch);          // TODO @@ -163,66 +98,30 @@ public class SteerableEnemyShip extends SteerablePhysicalBody implements Rendera      public void dispose() {      } -    private List<SteeringBehavior<Vector2>> getSteeringBehaviours() { -        return List.of( -                new Face<>(this, faceTarget), -                new Arrive<>(this, positionTarget) -                        .setTimeToTarget(0.1f) -                        .setArrivalTolerance(10f) -                        .setDecelerationRadius(100f) -        ); -    } - -    private void applySteering() { -        // Update position and linear velocity. -        if (steeringOutput.angular != 0) { -            // this method internally scales the torque by deltaTime -            getBody().setAngularVelocity(steeringOutput.angular); -        } else { -            // Update orientation and angular velocity -            final Vector2 linearVelocity = getLinearVelocity(); -            if (!linearVelocity.isZero(getZeroLinearSpeedThreshold())) { -                float newOrientation = linearVelocity.angleRad(); -                getBody().setAngularVelocity( -                        getMaxRotationAcceleration() * -                        angleDifference(newOrientation, getBody().getAngle())); -            } -        } - -        if (!steeringOutput.linear.isZero()) { -            if (steeringOutput.linear.len() >= lastVelocity.len() - 10) { -                speedUp(steeringOutput.linear); -                engineEffect.start(); -            } else { -                engineEffect.stop(); -            } -            lastVelocity.x = steeringOutput.linear.x; -            lastVelocity.y = steeringOutput.linear.y; -        } else { -            engineEffect.stop(); -        } -    } -      private void speedUp(final Vector2 force) { -        /*getBody().applyForceToCenter( -                force.x * 10000, -                force.y * 10000, -                true);*/ -          final float forceToApply = getBody().getMass() * 200; // force 200x times more than self mass          final Vector2 impulse = new Vector2(forceToApply, 0).rotateRad(getBody().getAngle());          getBody().applyForceToCenter(impulse, true);      } -    // TODO common -    private float angleDifference(float angle1, float angle2) { -        float diff = (angle1 - angle2) % (MathUtils.PI * 2); -        return diff < -1 * MathUtils.PI ? diff + 2 * MathUtils.PI : diff; +    @Override +    public float getMass() { +        return 10000; +    } + +    @Override +    public float getLinearDamping() { +        return 1.5f; +    } + +    @Override +    public float getMaxVelocity() { +        return getMaxSpeed();      }      @Override      public float getMaxSpeed() { -        return 100f; +        return 90f;      }      @Override diff --git a/core/src/org/snoopdesigns/endless/world/steering/ChaseSteering.java b/core/src/org/snoopdesigns/endless/world/steering/ChaseSteering.java new file mode 100644 index 0000000..3ac3ac7 --- /dev/null +++ b/core/src/org/snoopdesigns/endless/world/steering/ChaseSteering.java @@ -0,0 +1,108 @@ +package org.snoopdesigns.endless.world.steering; + +import java.util.List; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.ai.steer.SteeringAcceleration; +import com.badlogic.gdx.ai.steer.SteeringBehavior; +import com.badlogic.gdx.ai.steer.behaviors.Arrive; +import com.badlogic.gdx.ai.steer.behaviors.BlendedSteering; +import com.badlogic.gdx.ai.steer.behaviors.Face; +import com.badlogic.gdx.ai.utils.Location; +import com.badlogic.gdx.math.MathUtils; +import com.badlogic.gdx.math.Vector2; +import org.snoopdesigns.endless.context.Context; +import org.snoopdesigns.endless.physics.Box2DLocation; +import org.snoopdesigns.endless.physics.SteerablePhysicalBody; + +public class ChaseSteering implements Steering { + +    private final SteeringAcceleration<Vector2> steeringOutput = new SteeringAcceleration<>(new Vector2()); +    private final BlendedSteering<Vector2> steeringCombination; +    private final Location<Vector2> positionTarget; +    private final Location<Vector2> faceTarget; +    private final SteeringApplicator steeringApplicator; +    private final SteerablePhysicalBody steerablePhysicalBody; +    private final Vector2 lastVelocity = new Vector2(0f, 0f); +    private final float maxDistance; +    private final float minDistance; +    private float targetDirection; + +    public ChaseSteering(final SteerablePhysicalBody steerablePhysicalBody, +                         final float maxDistance, +                         final float minDistance, +                         final SteeringApplicator steeringApplicator) { +        this.steerablePhysicalBody = steerablePhysicalBody; +        this.maxDistance = maxDistance; +        this.minDistance = minDistance; +        this.steeringApplicator = steeringApplicator; + +        positionTarget = new Box2DLocation(); +        faceTarget = new Box2DLocation(); + +        steeringCombination = new BlendedSteering<>(steerablePhysicalBody); +        getSteeringBehaviours().forEach(steeringBehaviour -> +                steeringCombination.add(steeringBehaviour, 0.5f)); + +        targetDirection = MathUtils.random(MathUtils.PI2); +    } + +    @Override +    public void calculate() { +        final Vector2 targetDisplacement = new Vector2(maxDistance, 0f).rotateRad(targetDirection); +        final float distanceToPlayer = new Vector2( +                steerablePhysicalBody.getBody().getPosition().x - +                        Context.getInstance().getPlayerShip().getBody().getPosition().x, +                steerablePhysicalBody.getBody().getPosition().y - +                        Context.getInstance().getPlayerShip().getBody().getPosition().y) +                .len(); +        if (distanceToPlayer > maxDistance + 10f) { +            // Rotate target rotation point only of player is far away +            targetDirection += Gdx.graphics.getDeltaTime() / 1f; +        } +        final Vector2 displacement = targetDisplacement.limit(Math.max(0, (distanceToPlayer - minDistance))); +        final Vector2 targetPos = new Vector2( +                Context.getInstance().getPlayerShip().getBody().getPosition().x + displacement.x, +                Context.getInstance().getPlayerShip().getBody().getPosition().y + displacement.y); + +        positionTarget.getPosition().set(targetPos); +        faceTarget.getPosition().set(positionTarget.getPosition()); + +        steeringCombination.calculateSteering(steeringOutput); +        if (distanceToPlayer <= minDistance) { // do not move, if close to player, only rotate +            steeringOutput.linear.setZero(); +        } + +        applySteering(); +    } + +    private void applySteering() { +        // Update position and linear velocity. +        if (steeringOutput.angular != 0) { +            // this method internally scales the torque by deltaTime +            steeringApplicator.applyAngularVelocity(steeringOutput.angular); +        } + +        if (!steeringOutput.linear.isZero()) { +            if (steeringOutput.linear.len() >= lastVelocity.len() - 10) { +                steeringApplicator.applyLinearVelocity(steeringOutput.linear); +            } else { +                steeringApplicator.stopLinearVelocity(); +            } +            lastVelocity.x = steeringOutput.linear.x; +            lastVelocity.y = steeringOutput.linear.y; +        } else { +            steeringApplicator.stopLinearVelocity(); +        } +    } + +    private List<SteeringBehavior<Vector2>> getSteeringBehaviours() { +        return List.of( +                new Face<>(steerablePhysicalBody, faceTarget), +                new Arrive<>(steerablePhysicalBody, positionTarget) +                        .setTimeToTarget(0.1f) +                        .setArrivalTolerance(10f) +                        .setDecelerationRadius(100f) +        ); +    } +} diff --git a/core/src/org/snoopdesigns/endless/world/steering/Steering.java b/core/src/org/snoopdesigns/endless/world/steering/Steering.java new file mode 100644 index 0000000..c13b575 --- /dev/null +++ b/core/src/org/snoopdesigns/endless/world/steering/Steering.java @@ -0,0 +1,5 @@ +package org.snoopdesigns.endless.world.steering; + +public interface Steering { +    void calculate(); +} diff --git a/core/src/org/snoopdesigns/endless/world/steering/SteeringApplicator.java b/core/src/org/snoopdesigns/endless/world/steering/SteeringApplicator.java new file mode 100644 index 0000000..d683465 --- /dev/null +++ b/core/src/org/snoopdesigns/endless/world/steering/SteeringApplicator.java @@ -0,0 +1,9 @@ +package org.snoopdesigns.endless.world.steering; + +import com.badlogic.gdx.math.Vector2; + +public interface SteeringApplicator { +    void applyAngularVelocity(float angular); +    void applyLinearVelocity(Vector2 linear); +    void stopLinearVelocity(); +}  | 
