/******************************************************************************* * Copyright 2014 See AUTHORS file. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package com.badlogic.gdx.ai.tests.steer.scene2d.tests; import com.badlogic.gdx.ai.steer.Steerable; import com.badlogic.gdx.ai.steer.behaviors.CollisionAvoidance; import com.badlogic.gdx.ai.steer.behaviors.PrioritySteering; import com.badlogic.gdx.ai.steer.behaviors.Wander; import com.badlogic.gdx.ai.steer.limiters.LinearAccelerationLimiter; import com.badlogic.gdx.ai.steer.proximities.RadiusProximity; import com.badlogic.gdx.ai.tests.SteeringBehaviorsTest; import com.badlogic.gdx.ai.tests.steer.scene2d.Scene2dSteeringTest; import com.badlogic.gdx.ai.tests.steer.scene2d.SteeringActor; import com.badlogic.gdx.graphics.glutils.ShapeRenderer; import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType; import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.scenes.scene2d.InputEvent; import com.badlogic.gdx.scenes.scene2d.ui.CheckBox; import com.badlogic.gdx.scenes.scene2d.ui.Label; import com.badlogic.gdx.scenes.scene2d.ui.Slider; import com.badlogic.gdx.scenes.scene2d.ui.Table; import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; import com.badlogic.gdx.utils.Array; /** A class to test and experiment with the {@link CollisionAvoidance} behavior. * * @autor davebaol */ public class Scene2dCollisionAvoidanceTest extends Scene2dSteeringTest { Array<SteeringActor> characters; RadiusProximity<Vector2> char0Proximity; Array<RadiusProximity<Vector2>> proximities; boolean drawDebug; ShapeRenderer shapeRenderer; public Scene2dCollisionAvoidanceTest (SteeringBehaviorsTest container) { super(container, "Collision Avoidance"); } @Override public void create () { super.create(); drawDebug = true; shapeRenderer = new ShapeRenderer(); characters = new Array<SteeringActor>(); proximities = new Array<RadiusProximity<Vector2>>(); for (int i = 0; i < 60; i++) { final SteeringActor character = new SteeringActor(container.greenFish, false); character.setMaxLinearSpeed(50); character.setMaxLinearAcceleration(100); RadiusProximity<Vector2> proximity = new RadiusProximity<Vector2>(character, characters, character.getBoundingRadius() * 4); proximities.add(proximity); if (i == 0) char0Proximity = proximity; CollisionAvoidance<Vector2> collisionAvoidanceSB = new CollisionAvoidance<Vector2>(character, proximity); Wander<Vector2> wanderSB = new Wander<Vector2>(character) // // Don't use Face internally because independent facing is off .setFaceEnabled(false) // // We don't need a limiter supporting angular components because Face is not used // No need to call setAlignTolerance, setDecelerationRadius and setTimeToTarget for the same reason .setLimiter(new LinearAccelerationLimiter(30)) // .setWanderOffset(60) // .setWanderOrientation(0) // .setWanderRadius(40) // .setWanderRate(MathUtils.PI2 * 4); PrioritySteering<Vector2> prioritySteeringSB = new PrioritySteering<Vector2>(character, 0.0001f); prioritySteeringSB.add(collisionAvoidanceSB); prioritySteeringSB.add(wanderSB); character.setSteeringBehavior(prioritySteeringSB); setRandomNonOverlappingPosition(character, characters, 5); setRandomOrientation(character); testTable.addActor(character); characters.add(character); } inputProcessor = null; Table detailTable = new Table(container.skin); detailTable.row(); final Label labelMaxLinAcc = new Label("Max.Linear Acc.[" + characters.get(0).getMaxLinearAcceleration() + "]", container.skin); detailTable.add(labelMaxLinAcc); detailTable.row(); Slider maxLinAcc = new Slider(0, 1500, 1, false, container.skin); maxLinAcc.setValue(characters.get(0).getMaxLinearAcceleration()); maxLinAcc.addListener(new ChangeListener() { @Override public void changed (ChangeEvent event, Actor actor) { Slider slider = (Slider)actor; for (int i = 0; i < characters.size; i++) characters.get(i).setMaxLinearAcceleration(slider.getValue()); labelMaxLinAcc.setText("Max.Linear Acc.[" + slider.getValue() + "]"); } }); detailTable.add(maxLinAcc); detailTable.row(); final Label labelProximityRadius = new Label("Proximity Radius [" + proximities.get(0).getRadius() + "]", container.skin); detailTable.add(labelProximityRadius); detailTable.row(); Slider proximityRadius = new Slider(0, 500, 1, false, container.skin); proximityRadius.setValue(proximities.get(0).getRadius()); proximityRadius.addListener(new ChangeListener() { @Override public void changed (ChangeEvent event, Actor actor) { Slider slider = (Slider)actor; for (int i = 0; i < proximities.size; i++) proximities.get(i).setRadius(slider.getValue()); labelProximityRadius.setText("Proximity Radius [" + slider.getValue() + "]"); } }); detailTable.add(proximityRadius); detailTable.row(); addSeparator(detailTable); detailTable.row(); final Label labelMaxLinSpeed = new Label("Max.Linear Speed.[" + characters.get(0).getMaxLinearSpeed() + "]", container.skin); detailTable.add(labelMaxLinSpeed); detailTable.row(); Slider maxLinSpeed = new Slider(0, 300, 10, false, container.skin); maxLinSpeed.setValue(characters.get(0).getMaxLinearSpeed()); maxLinSpeed.addListener(new ChangeListener() { @Override public void changed (ChangeEvent event, Actor actor) { Slider slider = (Slider)actor; for (int i = 0; i < characters.size; i++) characters.get(i).setMaxLinearSpeed(slider.getValue()); labelMaxLinSpeed.setText("Max.Linear Speed.[" + slider.getValue() + "]"); } }); detailTable.add(maxLinSpeed); detailTable.row(); CheckBox debug = new CheckBox("Draw Proximity", container.skin); debug.setChecked(drawDebug); debug.addListener(new ClickListener() { @Override public void clicked (InputEvent event, float x, float y) { CheckBox checkBox = (CheckBox)event.getListenerActor(); drawDebug = checkBox.isChecked(); } }); detailTable.add(debug); detailWindow = createDetailWindow(detailTable); } @Override public void draw () { if (drawDebug) { Steerable<Vector2> steerable = characters.get(0); shapeRenderer.begin(ShapeType.Line); shapeRenderer.setColor(0, 1, 0, 1); shapeRenderer.circle(steerable.getPosition().x, steerable.getPosition().y, char0Proximity.getRadius()); shapeRenderer.end(); } } @Override public void dispose () { super.dispose(); shapeRenderer.dispose(); } }