So I follow the original gdx-ai documentation and created 2 circles to test Steering behavior.

enter image description here The image shows arrival behaviour but I am still quite lost about how they work.

Screen class:

public void show() {
        pCircle = new ShapeRenderer();
        pCircle.setProjectionMatrix(mCamera.combined);
        sCircle = new SteeringCircle(pCircle, 15, 128*5, 128, Color.BLUE);

        target = new SteeringCircle(pCircle, 15, 128,128*3 , Color.CYAN);
        /*
        Wander<Vector2> wanderSB = new Wander<Vector2>(sCircle);
        wanderSB.setEnabled(true);
        wanderSB.setTarget(target);*/
        Arrive<Vector2> arriveSB = new Arrive<Vector2>(sCircle, target).setTimeToTarget(0.1f).setArrivalTolerance(10f).setDecelerationRadius(25f);

        sCircle.setBehavior(arriveSB);
}

   @Override
    public void render(float delta) {

        Gdx.gl.glClearColor(63 / 255f, 128 / 255f, 70 / 255f, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        mCamera.update();
        mTiledMapRenderer.setView(mCamera);

        mTiledMapRenderer.render();

        sCircle.update(delta);
        sCircle.render();

        target.render();

        mBatch.setProjectionMatrix(mCamera.combined);

        mBatch.begin();
        mBatch.draw(img, 128, 0);

        mBatch.end();

    }

SteeringCircle class:

   public SteeringCircle(ShapeRenderer circle ,float boundingRadius, float x, float y, Color color) {
        pCircle = circle;
        mColor = color;
        this.position = newVector();
        this.position.x = x;
        this.position.y = y;
        this.boundingRadius = boundingRadius;
        this.maxLinearSpeed = 50;
        this.maxLinearAcceleration = 5000;
        this.linearVelocity = new Vector2(15,15);
        this.maxAngularSpeed = 30;
        this.maxLinearAcceleration = 5;

        this.tagged = false;

        this.steeringOutput = new SteeringAcceleration<Vector2>(new Vector2());

    }

@Override
    public Location<Vector2> newLocation() {

        return null;
    }

public void update (float delta) {
        if (steeringBehavior != null) {
            // Calculate steering acceleration
            steeringBehavior.calculateSteering(steeringOutput);

            // Apply steering acceleration to move this agent
            applySteering(steeringOutput, delta);
        }
    }

    private void applySteering (SteeringAcceleration<Vector2> steering, float time) {
        // Update position and linear velocity. Velocity is trimmed to maximum speed
        this.position.mulAdd(linearVelocity, time);
        this.linearVelocity.mulAdd(steering.linear, time).limit(this.getMaxLinearSpeed());

        // Update orientation and angular velocity
        if (independentFacing) {
            this.orientation += angularVelocity * time;
            this.angularVelocity += steering.angular * time;
        } else {
            // For non-independent facing we have to align orientation to linear velocity
            float newOrientation = calculateOrientationFromLinearVelocity(this);
            if (newOrientation != this.orientation) {
                this.angularVelocity = (newOrientation - this.orientation) * time;
                this.orientation = newOrientation;
            }
        }
    }
  1. For the arrival behaviour, the blue circle will move from the original position towards the Cyan circle and comes back to the circle back and forth. I thought the blue circle is supposed to stop when arriving the cyan circle which it didn't. How can I make it stop at arrival? what's wrong with the codes?

  2. For the wander behaviour, the blue circle just moves north-east direction and never goes back to the cyan circle. I thought it will wander around but it didn't. Any advice on what is needed to change to make the wander behaviour happens?

Also, does anyone know what should Location returns? Isn't Vector2 position already has the location?

  • Is the show() method called every frame? – Alexandre Vaillancourt Mar 24 '16 at 10:21
  • well, i guess. the show() method of screen class should be called every frame. If you're asking the SteeringCircle class, I created a render method to draw in the Screen render class and added the update method before it. – tipsywacky Mar 24 '16 at 12:09
  • Ah, and I forgot to say: You could use a tool like GifCam to take a live screenshot (an animated gif) of your issue. This would add a lot to the description of your issue! – Alexandre Vaillancourt Mar 24 '16 at 12:11
  • Ok, I'm not familiar with the framework, but it looks like you are recreating the 'arrive' behavriour each frame, thus setting the value with the initial parameters each frame (new Arrive<Vector2>(sCircle, target).setTimeToTarget(0.1f).setArrivalTolerance(10f).setDecelerationRadius(25f)). I think if you could manage to create your objects in a separate function that is called once, you'll probably achieve what you want. – Alexandre Vaillancourt Mar 24 '16 at 13:11
  • oh, my bad. Show() method is only called once, The render() method is called every frame. I was mistaken about what you were asking. – tipsywacky Mar 24 '16 at 15:04

I think that experimenting with different values for your parameters should fix the issue. Specifically the zero threshhold and deceleration radius. If your deceleration radius is too short the dynamic body won't have enough time to slow down to a speed within the zero threshhold and will overshoot the target. Try playing with the demo that's provided with the test code.

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.