[−][src]Trait tokyo::behavior::Behavior
Behavior
trait abstracts an action or a series of actions that a Player
can take. It may be useful if you want to model a complex behavior, that
spans multiple ticks, or whose interpretation changes dynamically. You can
use Sequence::with_slice()
to combine multiple behaviors.
Some Behavior
s take Target
as an argument to dynamically specify which
player to act against. See its documentation for details (later in this
file).
Examples
A stateful usage of Behavior
.
impl Handlar for Player { fn tick(...) { self.analyzer.push_state(state, Instant::now()); if let Some(next_command) = self.current_behavior.next_command(&self.analyzer) { return Some(next_command); } // Creates a Behavior and stores it in the Player struct, as we need to // persist the state across ticks and keep track of the number of times it // fired. self.current_behavior = Self::next_behavior(); self.current_behavior.next_command(&analyzer) } fn next_behavior() -> Sequence { // Behavior to keep chasing the target (in this case, the player with // the highest score.) It yields to the next behavior when the distance // to the player is less than 200.0. let chase = Chase { target: Target::HighestScore, distance: 200.0 }; // Behavior to fire at the target player twice. let fire = FireAt::with_times(Target::HighestScore, 2); // A sequence of behaviors: chase and then fire twice. Sequence::with_slice(&[&chase, &fire]) } }
A stateless usage of Behavior
.
impl Handlar for Player { fn tick(...) { self.analyzer.push_state(state, Instant::now()); // Find one of the bullets that are colliding within a second. if let Some(bullet) = self.analyzer.bullets_colliding(Duration::from_secs(1)).next() { let angle = bullet.velocity.tangent(); // Try to dodge from the bullet by moving to a direction roughly // perpendicular to the bullet velocity. let dodge = Sequence::with_slice(&[ &Rotate::with_margin_degrees(angle, 30.0), &Forward::with_steps(1), ]); // This Behavior works without persisting it somewhere for the next tick() as // in the previous example. At the next tick(), Rotate behavior will most likely // return None, proceeding immediately to the Forward behavior. If the situation // changes e.g. the bullet hit someone else, or there are other bullets // colliding, then it may take the Rotate behavior again, but it's likely an // optimal adjustment (assuming your logic of selecting a bullet to dodge is // stable.) return dodge.next_command(&self.analyzer); } None } }