com.badlogic.gdx.ai.steer.proximities.RadiusProximity Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gdx-ai Show documentation
Show all versions of gdx-ai Show documentation
AI algorithms for libGDX
The newest version!
/*******************************************************************************
* 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.steer.proximities;
import com.badlogic.gdx.ai.GdxAI;
import com.badlogic.gdx.ai.Timepiece;
import com.badlogic.gdx.ai.steer.Steerable;
import com.badlogic.gdx.math.Vector;
/** A {@code RadiusProximity} elaborates any agents contained in the specified list that are within the radius of the owner.
*
* Note that this implementation checks the AI time of the current frame through the {@link Timepiece#getTime()
* GdxAI.getTimepiece().getTime()} method in order to calculate neighbors only once per frame (assuming delta time is always
* greater than 0, if time has changed the frame has changed too). This means that
*
* - if you forget to {@link Timepiece#update(float) update the timepiece} on each frame the proximity instance will be
* calculated only the very first time, which is not what you want of course.
* - ideally the timepiece should be updated before the proximity is updated by the {@link #findNeighbors(ProximityCallback)}
* method.
*
*
* @param Type of vector, either 2D or 3D, implementing the {@link Vector} interface
*
* @author davebaol */
public class RadiusProximity> extends ProximityBase {
/** The radius of this proximity. */
protected float radius;
private float lastTime;
/** Creates a {@code RadiusProximity} for the specified owner, agents and radius.
* @param owner the owner of this proximity
* @param agents the agents
* @param radius the radius of the cone area */
public RadiusProximity (Steerable owner, Iterable extends Steerable> agents, float radius) {
super(owner, agents);
this.radius = radius;
this.lastTime = 0;
}
/** Returns the radius of this proximity. */
public float getRadius () {
return radius;
}
/** Sets the radius of this proximity. */
public void setRadius (float radius) {
this.radius = radius;
}
@Override
public int findNeighbors (ProximityCallback callback) {
int neighborCount = 0;
// If the frame is new then avoid repeating calculations
// when this proximity is used by multiple group behaviors.
float currentTime = GdxAI.getTimepiece().getTime();
if (this.lastTime != currentTime) {
// Save the current time
this.lastTime = currentTime;
T ownerPosition = owner.getPosition();
// Scan the agents searching for neighbors
for (Steerable currentAgent : agents) {
// Make sure the agent being examined isn't the owner
if (currentAgent != owner) {
float squareDistance = ownerPosition.dst2(currentAgent.getPosition());
// The bounding radius of the current agent is taken into account
// by adding it to the range
float range = radius + currentAgent.getBoundingRadius();
// If the current agent is within the range, report it to the callback
// and tag it for further consideration.
if (squareDistance < range * range) {
if (callback.reportNeighbor(currentAgent)) {
currentAgent.setTagged(true);
neighborCount++;
continue;
}
}
}
// Clear the tag
currentAgent.setTagged(false);
}
} else {
// Scan the agents searching for tagged neighbors
for (Steerable currentAgent : agents) {
// Make sure the agent being examined isn't the owner and that
// it's tagged.
if (currentAgent != owner && currentAgent.isTagged()) {
if (callback.reportNeighbor(currentAgent)) {
neighborCount++;
}
}
}
}
return neighborCount;
}
}