Java 类com.badlogic.gdx.ai.GdxAI 实例源码

项目:Inspiration    文件:MessageDispatcher.java   
/** Dispatches any delayed telegrams with a timestamp that has expired. Dispatched telegrams are removed from the queue.
 * <p>
 * This method must be called regularly from inside the main game loop to facilitate the correct and timely dispatch of any
 * delayed messages. Notice that the message dispatcher internally calls {@link Timepiece#getTime()
 * GdxAI.getTimepiece().getTime()} to get the current AI time and properly dispatch delayed messages. This means that
 * <ul>
 * <li>if you forget to {@link Timepiece#update(float) update the timepiece} the delayed messages won't be dispatched.</li>
 * <li>ideally the timepiece should be updated before the message dispatcher.</li>
 * </ul> */
public void update () {
    float currentTime = GdxAI.getTimepiece().getTime();

    // Peek at the queue to see if any telegrams need dispatching.
    // Remove all telegrams from the front of the queue that have gone
    // past their time stamp.
    Telegram telegram;
    while ((telegram = queue.peek()) != null) {

        // Exit loop if the telegram is in the future
        if (telegram.getTimestamp() > currentTime) break;

        if (debugEnabled) {
            GdxAI.getLogger().info(LOG_TAG,
                "Queued telegram ready for dispatch: Sent to " + telegram.receiver + ". Message code is " + telegram.message);
        }

        // Send the telegram to the recipient
        discharge(telegram);

        // Remove it from the queue
        queue.poll();
    }

}
项目:Inspiration    文件:Jump.java   
/** Returns the airborne time and sets the {@code outVelocity} vector to the airborne planar velocity required to achieve the
 * jump. If the jump is not achievable -1 is returned and the {@code outVelocity} vector remains unchanged.
 * <p>
 * Be aware that you should avoid using unlimited or very high max velocity, because this might produce a time of flight close
 * to 0. Actually, the motion equation for T has 2 solutions and Jump always try to use the fastest time.
 * @param outVelocity the output vector where the airborne planar velocity is calculated
 * @param jumpDescriptor the jump descriptor
 * @param maxLinearSpeed the maximum linear speed that can be used to achieve the jump
 * @return the time of flight or -1 if the jump is not achievable using the given max linear speed. */
public float calculateAirborneTimeAndVelocity (T outVelocity, JumpDescriptor<T> jumpDescriptor, float maxLinearSpeed) {
    float g = gravityComponentHandler.getComponent(gravity);

    // Calculate the first jump time, see time of flight at http://hyperphysics.phy-astr.gsu.edu/hbase/traj.html
    // Notice that the equation has 2 solutions. We'd ideally like to achieve the jump in the fastest time
    // possible, so we want to use the smaller of the two values. However, this time value might give us
    // an impossible launch velocity (required speed greater than the max), so we need to check and
    // use the higher value if necessary.
    float sqrtTerm = (float)Math.sqrt(2f * g * gravityComponentHandler.getComponent(jumpDescriptor.delta)
        + maxVerticalVelocity * maxVerticalVelocity);
    float time = (-maxVerticalVelocity + sqrtTerm) / g;
    if (DEBUG_ENABLED) GdxAI.getLogger().info("Jump", "1st jump time = " + time);

    // Check if we can use it
    if (!checkAirborneTimeAndCalculateVelocity(outVelocity, time, jumpDescriptor, maxLinearSpeed)) {
        // Otherwise try the other time
        time = (-maxVerticalVelocity - sqrtTerm) / g;
        if (DEBUG_ENABLED) GdxAI.getLogger().info("Jump", "2nd jump time = " + time);
        if (!checkAirborneTimeAndCalculateVelocity(outVelocity, time, jumpDescriptor, maxLinearSpeed)) {
            return -1f; // Unachievable jump
        }
    }
    return time; // Achievable jump
}
项目:Inspiration    文件:Jump.java   
private boolean checkAirborneTimeAndCalculateVelocity (T outVelocity, float time, JumpDescriptor<T> jumpDescriptor,
    float maxLinearSpeed) {
    // Calculate the planar velocity
    planarVelocity.set(jumpDescriptor.delta).scl(1f / time);
    gravityComponentHandler.setComponent(planarVelocity, 0f);

    // Check the planar linear speed
    if (planarVelocity.len2() < maxLinearSpeed * maxLinearSpeed) {
        // We have a valid solution, so store it by merging vertical and non-vertical axes
        float verticalValue = gravityComponentHandler.getComponent(outVelocity);
        gravityComponentHandler.setComponent(outVelocity.set(planarVelocity), verticalValue);
        if (DEBUG_ENABLED)
            GdxAI.getLogger().info("Jump", "targetLinearVelocity = " + outVelocity + "; targetLinearSpeed = " + outVelocity.len());
        return true;
    }
    return false;
}
项目:GdxDemo3D    文件:GameEngine.java   
public void update(float deltaTime) {
    // Update AI time
    GdxAI.getTimepiece().update(deltaTime);

    // Dispatch delayed messages
    MessageManager.getInstance().update();

    // Update Bullet simulation
    // On default fixedTimeStep = 1/60, small objects (the stick) will fall through 
    // the ground (the ground has relatively big triangles).
    dynamicsWorld.stepSimulation(deltaTime, 10, 1f / 240f);

    for (GameObject object : objectsById.values()) {
        if (object != null) {
            object.update(deltaTime);
        }
    }
}
项目:GdxDemo3D    文件:LoopedAnimationTaskBase.java   
protected void monitorAnimationTransition(DogCharacter dog, TaskAnimation ta) {
    if (dog.monitoredTaskAnimation != ta) {
        if (dog.currentTaskAnimation != null) {
            dog.monitoredTaskAnimation = ta;
            dog.switchAnimationTime = GdxAI.getTimepiece().getTime() + 0.2f;
            return;
        }
    }
    else if (dog.switchAnimationTime < GdxAI.getTimepiece().getTime()) {
        return;
    }

    // Start the new animation since the dog has maintained appropriate speed for long enough
    dog.currentTaskAnimation = ta;
    dog.monitoredTaskAnimation = null;
    dog.switchAnimationTime = -1;
    startAnimation(dog);
}
项目:gdx-ai    文件:SteeringBehaviorsTest.java   
@Override
public void render () {
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    // Render current steering behavior test
    if (currentTest != null) {
        if (!pauseButton.isChecked()) {
            // Update AI time
            GdxAI.getTimepiece().update(Gdx.graphics.getDeltaTime());

            // Update test
            currentTest.update();
        }
        // Draw test
        currentTest.draw();
    }

    stage.act();
    stage.draw();
}
项目:gdx-ai    文件:StateMachineTest.java   
@Override
public void render () {
    float delta = Gdx.graphics.getDeltaTime();
    elapsedTime += delta;

    // Update time
    GdxAI.getTimepiece().update(delta);

    if (elapsedTime > 0.8f) {
        // Update Bob and his wife
        bob.update(elapsedTime);
        elsa.update(elapsedTime);

        // Dispatch any delayed messages
        MessageManager.getInstance().update();

        elapsedTime = 0;
    }
}
项目:gdx-ai    文件:MessageTestBase.java   
public void create () {
    lastUpdateTime = 0;
    testStack = new Stack();
    container.stage.getRoot().addActorAt(0, testStack);
    testStack.setSize(container.stageWidth, container.stageHeight);
    testStack.add(testTable = new Table() {
        @Override
        public void act (float delta) {
            float time = GdxAI.getTimepiece().getTime();
            if (lastUpdateTime != time) {
                lastUpdateTime = time;
                super.act(GdxAI.getTimepiece().getDeltaTime());
            }
        }
    });
    testStack.layout();
}
项目:gdx-ai    文件:MessageTests.java   
@Override
public void render () {
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    // Render current steering behavior test
    if (currentTest != null) {
        if (!pauseButton.isChecked()) {
            // Update AI time
            GdxAI.getTimepiece().update(Gdx.graphics.getDeltaTime());

            // Update test
            currentTest.update();
        }
        // Draw test
        currentTest.draw();
    }

    stage.act();
    stage.draw();
}
项目:gdx-ai    文件:Box2dJumpTest.java   
@Override
    public void update () {
        super.update();

        // Should the character switch to Jump behavior?
        if (character.getSteeringBehavior() == seekSB) {
            if (character.getPosition().x >= jumpDescriptor.takeoffPosition.x - runUpLength
                && character.getPosition().x <= jumpDescriptor.landingPosition.x) {
                System.out.println("Switched to Jump behavior. Taking a run up...");
//              System.out.println("run up length = " + distFromTakeoffPoint);
//              character.body.setDamping(0, 0);
//              System.out.println("friction: " + character.body.getFriction());
//              character.body.setFriction(0);
                System.out.println("owner.linearVelocity = " + character.getLinearVelocity() + "; owner.linearSpeed = "
                    + character.getLinearVelocity().len());
                character.setSteeringBehavior(jumpSB);
            }
        }

        // Update the character
        character.update(GdxAI.getTimepiece().getDeltaTime());
    }
项目:gdx-ai    文件:Scene2dSteeringTest.java   
@Override
public void create () {
    lastUpdateTime = 0;
    testStack = new Stack();
    container.stage.getRoot().addActorAt(0, testStack);
    testStack.setSize(container.stageWidth, container.stageHeight);
    testStack.add(testTable = new Table() {
        @Override
        public void act (float delta) {
            float time = GdxAI.getTimepiece().getTime();
            if (lastUpdateTime != time) {
                lastUpdateTime = time;
                super.act(GdxAI.getTimepiece().getDeltaTime());
            }
        }
    });
    testStack.layout();
}
项目:gdx-ai    文件:MessageDispatcher.java   
/** Dispatches any delayed telegrams with a timestamp that has expired. Dispatched telegrams are removed from the queue.
 * <p>
 * This method must be called regularly from inside the main game loop to facilitate the correct and timely dispatch of any
 * delayed messages. Notice that the message dispatcher internally calls {@link Timepiece#getTime()
 * GdxAI.getTimepiece().getTime()} to get the current AI time and properly dispatch delayed messages. This means that
 * <ul>
 * <li>if you forget to {@link Timepiece#update(float) update the timepiece} the delayed messages won't be dispatched.</li>
 * <li>ideally the timepiece should be updated before the message dispatcher.</li>
 * </ul> */
public void update () {
    float currentTime = GdxAI.getTimepiece().getTime();

    // Peek at the queue to see if any telegrams need dispatching.
    // Remove all telegrams from the front of the queue that have gone
    // past their time stamp.
    Telegram telegram;
    while ((telegram = queue.peek()) != null) {

        // Exit loop if the telegram is in the future
        if (telegram.getTimestamp() > currentTime) break;

        if (debugEnabled) {
            GdxAI.getLogger().info(LOG_TAG,
                "Queued telegram ready for dispatch: Sent to " + telegram.receiver + ". Message code is " + telegram.message);
        }

        // Send the telegram to the recipient
        discharge(telegram);

        // Remove it from the queue
        queue.poll();
    }

}
项目:gdx-ai    文件:Jump.java   
/** Returns the airborne time and sets the {@code outVelocity} vector to the airborne planar velocity required to achieve the
 * jump. If the jump is not achievable -1 is returned and the {@code outVelocity} vector remains unchanged.
 * <p>
 * Be aware that you should avoid using unlimited or very high max velocity, because this might produce a time of flight close
 * to 0. Actually, the motion equation for T has 2 solutions and Jump always try to use the fastest time.
 * @param outVelocity the output vector where the airborne planar velocity is calculated
 * @param jumpDescriptor the jump descriptor
 * @param maxLinearSpeed the maximum linear speed that can be used to achieve the jump
 * @return the time of flight or -1 if the jump is not achievable using the given max linear speed. */
public float calculateAirborneTimeAndVelocity (T outVelocity, JumpDescriptor<T> jumpDescriptor, float maxLinearSpeed) {
    float g = gravityComponentHandler.getComponent(gravity);

    // Calculate the first jump time, see time of flight at http://hyperphysics.phy-astr.gsu.edu/hbase/traj.html
    // Notice that the equation has 2 solutions. We'd ideally like to achieve the jump in the fastest time
    // possible, so we want to use the smaller of the two values. However, this time value might give us
    // an impossible launch velocity (required speed greater than the max), so we need to check and
    // use the higher value if necessary.
    float sqrtTerm = (float)Math.sqrt(2f * g * gravityComponentHandler.getComponent(jumpDescriptor.delta)
        + maxVerticalVelocity * maxVerticalVelocity);
    float time = (-maxVerticalVelocity + sqrtTerm) / g;
    if (DEBUG_ENABLED) GdxAI.getLogger().info("Jump", "1st jump time = " + time);

    // Check if we can use it
    if (!checkAirborneTimeAndCalculateVelocity(outVelocity, time, jumpDescriptor, maxLinearSpeed)) {
        // Otherwise try the other time
        time = (-maxVerticalVelocity - sqrtTerm) / g;
        if (DEBUG_ENABLED) GdxAI.getLogger().info("Jump", "2nd jump time = " + time);
        if (!checkAirborneTimeAndCalculateVelocity(outVelocity, time, jumpDescriptor, maxLinearSpeed)) {
            return -1f; // Unachievable jump
        }
    }
    return time; // Achievable jump
}
项目:gdx-ai    文件:Jump.java   
private boolean checkAirborneTimeAndCalculateVelocity (T outVelocity, float time, JumpDescriptor<T> jumpDescriptor,
    float maxLinearSpeed) {
    // Calculate the planar velocity
    planarVelocity.set(jumpDescriptor.delta).scl(1f / time);
    gravityComponentHandler.setComponent(planarVelocity, 0f);

    // Check the planar linear speed
    if (planarVelocity.len2() < maxLinearSpeed * maxLinearSpeed) {
        // We have a valid solution, so store it by merging vertical and non-vertical axes
        float verticalValue = gravityComponentHandler.getComponent(outVelocity);
        gravityComponentHandler.setComponent(outVelocity.set(planarVelocity), verticalValue);
        if (DEBUG_ENABLED)
            GdxAI.getLogger().info("Jump", "targetLinearVelocity = " + outVelocity + "; targetLinearSpeed = " + outVelocity.len());
        return true;
    }
    return false;
}
项目:Inspiration    文件:MessageDispatcher.java   
/** Scans the queue and passes pending messages to the given callback in any particular order.
 * <p>
 * Typically this method is used to save (serialize) pending messages and restore (deserialize and schedule) them back on game
 * loading.
 * @param callback The callback used to report pending messages individually. **/
public void scanQueue (PendingMessageCallback callback) {
    float currentTime = GdxAI.getTimepiece().getTime();
    int queueSize = queue.size();
    for (int i = 0; i < queueSize; i++) {
        Telegram telegram = queue.get(i);
        callback.report(telegram.getTimestamp() - currentTime, telegram.sender, telegram.receiver, telegram.message,
            telegram.extraInfo, telegram.returnReceiptStatus);
    }
}
项目:Inspiration    文件:MessageDispatcher.java   
/** This method is used by {@link #dispatchMessage(float, Telegraph, Telegraph, int, Object) dispatchMessage} for immediate
 * telegrams and {@link #update(float) update} for delayed telegrams. It first calls the message handling method of the
 * receiving agents with the specified telegram then returns the telegram to the pool.
 * @param telegram the telegram to discharge */
private void discharge (Telegram telegram) {
    if (telegram.receiver != null) {
        // Dispatch the telegram to the receiver specified by the telegram itself
        if (!telegram.receiver.handleMessage(telegram)) {
            // Telegram could not be handled
            if (debugEnabled) GdxAI.getLogger().info(LOG_TAG, "Message " + telegram.message + " not handled");
        }
    } else {
        // Dispatch the telegram to all the registered receivers
        int handledCount = 0;
        Array<Telegraph> listeners = msgListeners.get(telegram.message);
        if (listeners != null) {
            for (int i = 0; i < listeners.size; i++) {
                if (listeners.get(i).handleMessage(telegram)) {
                    handledCount++;
                }
            }
        }
        // Telegram could not be handled
        if (debugEnabled && handledCount == 0) GdxAI.getLogger().info(LOG_TAG, "Message " + telegram.message + " not handled");
    }

    if (telegram.returnReceiptStatus == Telegram.RETURN_RECEIPT_NEEDED) {
        // Use this telegram to send the return receipt
        telegram.receiver = telegram.sender;
        telegram.sender = this;
        telegram.returnReceiptStatus = Telegram.RETURN_RECEIPT_SENT;
        discharge(telegram);
    } else {
        // Release the telegram to the pool
        POOL.free(telegram);
    }
}
项目:Inspiration    文件:Jump.java   
@Override
public SteeringAcceleration<T> calculateRealSteering (SteeringAcceleration<T> steering) {
    // Check if we have a trajectory, and create one if not.
    if (target == null) {
        target = calculateTarget();
        callback.reportAchievability(isJumpAchievable);
    }

    // If the trajectory is zero, return no steering acceleration
    if (!isJumpAchievable) return steering.setZero();

    // Check if the owner has reached target position and velocity with acceptable tolerance
    if (owner.getPosition().epsilonEquals(target.getPosition(), takeoffPositionTolerance)) {
        if (DEBUG_ENABLED) GdxAI.getLogger().info("Jump", "Good position!!!");
        if (owner.getLinearVelocity().epsilonEquals(target.getLinearVelocity(), takeoffVelocityTolerance)) {
            if (DEBUG_ENABLED) GdxAI.getLogger().info("Jump", "Good Velocity!!!");
            isJumpAchievable = false;
            // Perform the jump, and return no steering (the owner is airborne, no need to steer).
            callback.takeoff(maxVerticalVelocity, airborneTime);
            return steering.setZero();
        } else {
            if (DEBUG_ENABLED)
                GdxAI.getLogger().info("Jump",
                    "Bad Velocity: Speed diff. = "
                        + planarVelocity.set(target.getLinearVelocity()).sub(owner.getLinearVelocity()).len() + ", diff = ("
                        + planarVelocity + ")");
        }
    }

    // Delegate to MatchVelocity
    return super.calculateRealSteering(steering);
}
项目:Inspiration    文件:Wander.java   
@Override
protected SteeringAcceleration<T> calculateRealSteering (SteeringAcceleration<T> steering) {
    // Update the wander orientation
    float now = GdxAI.getTimepiece().getTime();
    if (lastTime > 0) {
        float delta = now - lastTime;
        wanderOrientation += MathUtils.randomTriangular(wanderRate * delta);
    }
    lastTime = now;

    // Calculate the combined target orientation
    float targetOrientation = wanderOrientation + owner.getOrientation();

    // Calculate the center of the wander circle
    wanderCenter.set(owner.getPosition()).mulAdd(owner.angleToVector(steering.linear, owner.getOrientation()), wanderOffset);

    // Calculate the target location
    // Notice that we're using steering.linear as temporary vector
    internalTargetPosition.set(wanderCenter).mulAdd(owner.angleToVector(steering.linear, targetOrientation), wanderRadius);

    float maxLinearAcceleration = getActualLimiter().getMaxLinearAcceleration();

    if (faceEnabled) {
        // Delegate to face
        face(steering, internalTargetPosition);

        // Set the linear acceleration to be at full
        // acceleration in the direction of the orientation
        owner.angleToVector(steering.linear, owner.getOrientation()).scl(maxLinearAcceleration);
    } else {
        // Seek the internal target position
        steering.linear.set(internalTargetPosition).sub(owner.getPosition()).nor().scl(maxLinearAcceleration);

        // No angular acceleration
        steering.angular = 0;

    }

    return steering;
}
项目:Inspiration    文件:HierarchicalPathFinder.java   
@Override
public boolean finalizeSearch (long timeToRun) {
    hpfRequest.pathFound = pathFound;
    if (pathFound) {
        // Take the first move of this plan and use it for the next run through
        endNode = resultPath.get(1);
    }
    if (DEBUG) GdxAI.getLogger().debug(TAG, "LevelPathFinder finalizeSearch; status: " + status);
    return true;
}
项目:Inspiration    文件:BehaviorTreeParser.java   
@Override
protected void startStatement (String name, boolean isSubtreeReference, boolean isGuard) {
    if (btParser.debugLevel > BehaviorTreeParser.DEBUG_LOW)
        GdxAI.getLogger().debug(TAG, (isGuard? " guard" : " task") + " name '" + name + "'");

    this.isSubtreeRef = isSubtreeReference;

    this.statement = isSubtreeReference ? Statement.TreeTask : checkStatement(name);
    if (isGuard) {
        if (statement != Statement.TreeTask)
            throw new GdxRuntimeException(name + ": only tree's tasks can be guarded");
    }

    statement.enter(this, name, isGuard);
}
项目:Inspiration    文件:BehaviorTreeParser.java   
@Override
protected void attribute (String name, Object value) {
    if (btParser.debugLevel > BehaviorTreeParser.DEBUG_LOW)
        GdxAI.getLogger().debug(TAG, lineNumber + ": attribute '" + name + " : " + value + "'");

    boolean validAttribute = statement.attribute(this, name, value);
    if (!validAttribute) {
        if (statement == Statement.TreeTask) {
            throw stackedTaskException(getCurrentTask(), "unknown attribute '" + name + "'");
        } else {
            throw new GdxRuntimeException(statement.name + ": unknown attribute '" + name + "'");
        }
    }
}
项目:gdx-ai    文件:BehaviorTreeTests.java   
private void changeTest (int testIndex) {
    // Dispose the previous test (if any)
    if (currentTest != null) currentTest.dispose();

    // Add the new test
    currentTest = tests[testIndex];
    Gdx.app.log("BehaviorTreeTests", "***********************************************");
    Gdx.app.log("BehaviorTreeTests", "Starting test " + currentTest.getName());
    Gdx.app.log("BehaviorTreeTests", "***********************************************");
    String description = currentTest.getDescription();
    if (description != null) {
        Gdx.app.log("BehaviorTreeTests", description);
        Gdx.app.log("BehaviorTreeTests", "***********************************************");
        testDescriptionLabel.setText(description);
    } else {
        testDescriptionLabel.setText("Run the tree, look at the log and see what happens");
    }
    Stack testStack = new Stack() {
        @Override
        public void act (float delta) {
            boolean paused = pauseButton.isChecked();
            getChildren().peek().setVisible(paused);
            if (!paused) {
                // Update AI time
                GdxAI.getTimepiece().update(delta);

                // Call super
                super.act(delta);
            }
        }
    };
    testStack.add(currentTest.createActor(skin));
    testStack.add(new Image(skin, "translucent"));
    splitPane.setSecondWidget(testStack);
}
项目:gdx-ai    文件:TelegramProviderTest.java   
@Override
public void update () {
    elapsedTime += GdxAI.getTimepiece().getDeltaTime();
    if (elapsedTime > 1.5f) {
        MessageManager.getInstance().dispatchMessage(null, MSG_TIME_TO_ACT);
        elapsedTime = 0;
    }
}
项目:gdx-ai    文件:MessageTimerTest.java   
@Override
public boolean handleMessage (Telegram msg) {
    this.msgCounter = (Integer)msg.extraInfo;
    this.msgTimestamp = msg.getTimestamp();
    if (timerEnabledButton.isChecked()) {
        float lag = GdxAI.getTimepiece().getTime() - msg.getTimestamp();
        lag -= (int)lag; // take the decimal part only (in case the lag is > 1)
        float delay = 1f - lag;
        sendMessage(delay, msgCounter + 1);
    }
    return true;
}
项目:gdx-ai    文件:PathFinderTests.java   
@Override
public void render () {
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    // Update time
    GdxAI.getTimepiece().update(Gdx.graphics.getDeltaTime());

    if (currentTest != null) currentTest.render();

    stage.act();
    stage.draw();
}
项目:gdx-ai    文件:Box2dCollisionAvoidanceTest.java   
@Override
public void update () {
    super.update();

    // Update characters
    float deltaTime = GdxAI.getTimepiece().getDeltaTime();
    for (int i = 0; i < characters.size; i++) {
        characters.get(i).update(deltaTime);
    }
}
项目:gdx-ai    文件:Box2dArriveTest.java   
@Override
public void update () {
    super.update();

    // Update the character
    character.update(GdxAI.getTimepiece().getDeltaTime());
}
项目:gdx-ai    文件:Box2dSteeringTest.java   
@Override
public void update () {
    float deltaTime = GdxAI.getTimepiece().getDeltaTime();

    // Update box2d world
    world.step(deltaTime, 8, 3);
}
项目:gdx-ai    文件:BulletJumpTest.java   
@Override
public void update () {
    MessageManager.getInstance().update();
    character.update(GdxAI.getTimepiece().getDeltaTime());

    super.update();
}
项目:gdx-ai    文件:ParallelVsSequenceTest.java   
public void update (float delta) {
    if (!pauseButton.isChecked() && !gameOver) {
        // Update AI time
        GdxAI.getTimepiece().update(delta);

        // Update behavior trees
        sequencePredator.btree.step();
        parallelPredator.btree.step();
    }

    stage.act(delta);
}
项目:gdx-ai    文件:ResumeVsJoinTest.java   
public void update (float delta) {
    if (!pauseButton.isChecked() && !gameOver) {
        // Update AI time
        GdxAI.getTimepiece().update(delta);

        // Update behavior trees
        resumePredator.btree.step();
        joinPredator.btree.step();
    }

    stage.act(delta);
}
项目:gdx-ai    文件:MessageDispatcher.java   
/** Scans the queue and passes pending messages to the given callback in any particular order.
 * <p>
 * Typically this method is used to save (serialize) pending messages and restore (deserialize and schedule) them back on game
 * loading.
 * @param callback The callback used to report pending messages individually. **/
public void scanQueue (PendingMessageCallback callback) {
    float currentTime = GdxAI.getTimepiece().getTime();
    int queueSize = queue.size();
    for (int i = 0; i < queueSize; i++) {
        Telegram telegram = queue.get(i);
        callback.report(telegram.getTimestamp() - currentTime, telegram.sender, telegram.receiver, telegram.message,
            telegram.extraInfo, telegram.returnReceiptStatus);
    }
}
项目:gdx-ai    文件:MessageDispatcher.java   
/** This method is used by {@link #dispatchMessage(float, Telegraph, Telegraph, int, Object) dispatchMessage} for immediate
 * telegrams and {@link #update(float) update} for delayed telegrams. It first calls the message handling method of the
 * receiving agents with the specified telegram then returns the telegram to the pool.
 * @param telegram the telegram to discharge */
private void discharge (Telegram telegram) {
    if (telegram.receiver != null) {
        // Dispatch the telegram to the receiver specified by the telegram itself
        if (!telegram.receiver.handleMessage(telegram)) {
            // Telegram could not be handled
            if (debugEnabled) GdxAI.getLogger().info(LOG_TAG, "Message " + telegram.message + " not handled");
        }
    } else {
        // Dispatch the telegram to all the registered receivers
        int handledCount = 0;
        Array<Telegraph> listeners = msgListeners.get(telegram.message);
        if (listeners != null) {
            for (int i = 0; i < listeners.size; i++) {
                if (listeners.get(i).handleMessage(telegram)) {
                    handledCount++;
                }
            }
        }
        // Telegram could not be handled
        if (debugEnabled && handledCount == 0) GdxAI.getLogger().info(LOG_TAG, "Message " + telegram.message + " not handled");
    }

    if (telegram.returnReceiptStatus == Telegram.RETURN_RECEIPT_NEEDED) {
        // Use this telegram to send the return receipt
        telegram.receiver = telegram.sender;
        telegram.sender = this;
        telegram.returnReceiptStatus = Telegram.RETURN_RECEIPT_SENT;
        discharge(telegram);
    } else {
        // Release the telegram to the pool
        POOL.free(telegram);
    }
}
项目:gdx-ai    文件:Jump.java   
@Override
public SteeringAcceleration<T> calculateRealSteering (SteeringAcceleration<T> steering) {
    // Check if we have a trajectory, and create one if not.
    if (target == null) {
        target = calculateTarget();
        callback.reportAchievability(isJumpAchievable);
    }

    // If the trajectory is zero, return no steering acceleration
    if (!isJumpAchievable) return steering.setZero();

    // Check if the owner has reached target position and velocity with acceptable tolerance
    if (owner.getPosition().epsilonEquals(target.getPosition(), takeoffPositionTolerance)) {
        if (DEBUG_ENABLED) GdxAI.getLogger().info("Jump", "Good position!!!");
        if (owner.getLinearVelocity().epsilonEquals(target.getLinearVelocity(), takeoffVelocityTolerance)) {
            if (DEBUG_ENABLED) GdxAI.getLogger().info("Jump", "Good Velocity!!!");
            isJumpAchievable = false;
            // Perform the jump, and return no steering (the owner is airborne, no need to steer).
            callback.takeoff(maxVerticalVelocity, airborneTime);
            return steering.setZero();
        } else {
            if (DEBUG_ENABLED)
                GdxAI.getLogger().info("Jump",
                    "Bad Velocity: Speed diff. = "
                        + planarVelocity.set(target.getLinearVelocity()).sub(owner.getLinearVelocity()).len() + ", diff = ("
                        + planarVelocity + ")");
        }
    }

    // Delegate to MatchVelocity
    return super.calculateRealSteering(steering);
}
项目:gdx-ai    文件:Wander.java   
@Override
protected SteeringAcceleration<T> calculateRealSteering (SteeringAcceleration<T> steering) {
    // Update the wander orientation
    float now = GdxAI.getTimepiece().getTime();
    if (lastTime > 0) {
        float delta = now - lastTime;
        wanderOrientation += MathUtils.randomTriangular(wanderRate * delta);
    }
    lastTime = now;

    // Calculate the combined target orientation
    float targetOrientation = wanderOrientation + owner.getOrientation();

    // Calculate the center of the wander circle
    wanderCenter.set(owner.getPosition()).mulAdd(owner.angleToVector(steering.linear, owner.getOrientation()), wanderOffset);

    // Calculate the target location
    // Notice that we're using steering.linear as temporary vector
    internalTargetPosition.set(wanderCenter).mulAdd(owner.angleToVector(steering.linear, targetOrientation), wanderRadius);

    float maxLinearAcceleration = getActualLimiter().getMaxLinearAcceleration();

    if (faceEnabled) {
        // Delegate to face
        face(steering, internalTargetPosition);

        // Set the linear acceleration to be at full
        // acceleration in the direction of the orientation
        owner.angleToVector(steering.linear, owner.getOrientation()).scl(maxLinearAcceleration);
    } else {
        // Seek the internal target position
        steering.linear.set(internalTargetPosition).sub(owner.getPosition()).nor().scl(maxLinearAcceleration);

        // No angular acceleration
        steering.angular = 0;

    }

    return steering;
}
项目:gdx-ai    文件:HierarchicalPathFinder.java   
@Override
public boolean finalizeSearch (long timeToRun) {
    hpfRequest.pathFound = pathFound;
    if (pathFound) {
        // Take the first move of this plan and use it for the next run through
        endNode = resultPath.get(1);
    }
    if (DEBUG) GdxAI.getLogger().debug(TAG, "LevelPathFinder finalizeSearch; status: " + status);
    return true;
}
项目:gdx-ai    文件:BehaviorTreeParser.java   
@Override
protected void startStatement (String name, boolean isSubtreeReference, boolean isGuard) {
    if (btParser.debugLevel > BehaviorTreeParser.DEBUG_LOW)
        GdxAI.getLogger().debug(TAG, (isGuard? " guard" : " task") + " name '" + name + "'");

    this.isSubtreeRef = isSubtreeReference;

    this.statement = isSubtreeReference ? Statement.TreeTask : checkStatement(name);
    if (isGuard) {
        if (statement != Statement.TreeTask)
            throw new GdxRuntimeException(name + ": only tree's tasks can be guarded");
    }

    statement.enter(this, name, isGuard);
}
项目:gdx-ai    文件:BehaviorTreeParser.java   
@Override
protected void attribute (String name, Object value) {
    if (btParser.debugLevel > BehaviorTreeParser.DEBUG_LOW)
        GdxAI.getLogger().debug(TAG, lineNumber + ": attribute '" + name + " : " + value + "'");

    boolean validAttribute = statement.attribute(this, name, value);
    if (!validAttribute) {
        if (statement == Statement.TreeTask) {
            throw stackedTaskException(getCurrentTask(), "unknown attribute '" + name + "'");
        } else {
            throw new GdxRuntimeException(statement.name + ": unknown attribute '" + name + "'");
        }
    }
}
项目:Inspiration    文件:HierarchicalPathFinder.java   
@Override
    public boolean search (PathFinderRequest<N> request, long timeToRun) {
        if (DEBUG) GdxAI.getLogger().debug(TAG, "Enter interruptible HPF; request.status = " + request.status);

        // Make sure the level request and its control are instantiated
        if (levelRequest == null) {
            levelRequest = new LevelPathFinderRequest<N>();
            levelRequestControl = new PathFinderRequestControl<N>();
        }

        // We have to initialize the search if the status has just changed
        if (request.statusChanged) {
            if (DEBUG) GdxAI.getLogger().debug(TAG, "-- statusChanged");

            // Check if we have no path to find
            if (request.startNode == request.endNode) return true;

            // Prepare the the level request control
            levelRequestControl.lastTime = TimeUtils.nanoTime(); // Keep track of the current time
            levelRequestControl.timeToRun = timeToRun;
            levelRequestControl.timeTolerance = PathFinderQueue.TIME_TOLERANCE;
            levelRequestControl.server = null;
            levelRequestControl.pathFinder = levelPathFinder;

            // Prepare the level request
            levelRequest.hpf = this;
            levelRequest.hpfRequest = request;
            levelRequest.status = PathFinderRequest.SEARCH_NEW;
            levelRequest.statusChanged = true;
            levelRequest.heuristic = request.heuristic;
            levelRequest.resultPath = request.resultPath;
            levelRequest.startNode = request.startNode;
            levelRequest.endNode = request.endNode;
            levelRequest.levelOfNodes = 0;
            levelRequest.currentLevel = graph.getLevelCount() - 1;
        }

        while (levelRequest.currentLevel >= 0) {
//          if (DEBUG) GdxAI.getLogger().debug(TAG, "currentLevel = "+levelRequest.currentLevel);

            boolean finished = levelRequestControl.execute(levelRequest);
//          if (DEBUG) GdxAI.getLogger().debug(TAG, "finished = "+finished);
//          if (DEBUG) GdxAI.getLogger().debug(TAG, "pathFound = "+levelRequest.pathFound);

//          if (finished && !levelRequest.pathFound) return true;
            if (!finished) {
                return false;
            }
            else {
                levelRequest.executionFrames = 0;
//              levelRequest.pathFound = false;
                levelRequest.status = PathFinderRequest.SEARCH_NEW;
                levelRequest.statusChanged = true;

                if (!levelRequest.pathFound) return true;
            }
        }

        if (DEBUG) GdxAI.getLogger().debug(TAG, "-- before exit");
        // If we're here we have finished
        return true;
    }
项目:Inspiration    文件:HierarchicalPathFinder.java   
@Override
public boolean initializeSearch (long timeToRun) {

    // Reset the status
    // We can do it here because we know this method completes during this frame,
    // meaning that it is executed once per request
    this.executionFrames = 0;
    this.pathFound = false;
    this.status = SEARCH_NEW;
    this.statusChanged = false;

    do {
        // Find the start node at current level
        startNode = hpf.graph.convertNodeBetweenLevels(0, hpfRequest.startNode, currentLevel);

        // Find the end node at current level
        // Note that if we're examining level 0 and the current end node, the end node and the
        // start node have the same parent at level 1 then we can use the end node directly.
        endNode = hpf.graph.convertNodeBetweenLevels(levelOfNodes, endNode, currentLevel);
        if (currentLevel == 0) {
            N currentEndNodeParent = hpf.graph.convertNodeBetweenLevels(0, endNode, 1);
            if (currentEndNodeParent == hpf.graph.convertNodeBetweenLevels(0, hpfRequest.endNode, 1)
                && currentEndNodeParent == hpf.graph.convertNodeBetweenLevels(0, hpfRequest.startNode, 1)) {
                endNode = hpfRequest.endNode;
            }
        }

        // Decrease current level and skip it if start and end node are the same
        // FIXME the break below is wrong
        if (DEBUG) GdxAI.getLogger().debug(TAG, "LevelPathFinder initializeSearch");
        levelOfNodes = currentLevel;
        currentLevel--;
        if (startNode != endNode) break;

    } while (currentLevel >= 0);

    // Otherwise we can perform the plan
    hpf.graph.setLevel(levelOfNodes);
    resultPath.clear();
    return true;
}