Steering Behaviors written for Angelscript?

Started by
10 comments, last by DekuTree64 5 years, 2 months ago

Hello All,

I am new to Angelscript and I am wanting to create steering behaviors for enemy AI. I haven't found any Angelscript examples on the web for Seek, Flee, Follow, Arrive, Collision avoidance, etc so far. I have successfully written an A* routine, but that's about it.

Does anyone know of any steering behaviors written in Angelscript ? Can you post a link?

Since I wasn't able to find any steering behaviors written in Angelscript, I decided to try to convert a "Flee" behavior written in C. Unfortunately there is a command I can't seem to find in Angelscript that the C code uses. Specifically, the "Limit" command. I think it is equivalent to a "SCALAR" command? I am not sure. Anyone know? Thanks in advance for any help.

This is the code for the "Flee" behavior below:




class Vehicle {
 
  PVector location;
  PVector velocity;
  PVector acceleration;

Additional variable for size

  float r;
  float maxforce;
  float maxspeed;
 
  Vehicle(float x, float y) {
    acceleration = new PVector(0,0);
    velocity = new PVector(0,0);
    location = new PVector(x,y);
    r = 3.0;

Arbitrary values for maxspeed and force; try varying these!

    maxspeed = 4;
    maxforce = 0.1;

  }
 

Our standard “Euler integration” motion model

  void update() {
    velocity.add(acceleration);
    velocity.limit(maxspeed);     <<<------------ THIS LINE USES THE COMMAND "LIMIT"
    location.add(velocity);
    acceleration.mult(0);
  }
 

Newton’s second law; we could divide by mass if we wanted.

  void applyForce(PVector force) {
    acceleration.add(force);
  }
 

Our seek steering force algorithm

  void seek(PVector target) {
    PVector desired = PVector.sub(target,location);
    desired.normalize();
    desired.mult(maxspeed);
    PVector steer = PVector.sub(desired,velocity);
    steer.limit(maxforce);
    applyForce(steer);
  }
 
  void display() {

Vehicle is a triangle pointing in the direction of velocity; since it is drawn pointing up, we rotate it an additional 90 degrees.

    float theta = velocity.heading() + PI/2;
    fill(175);
    stroke(0);
    pushMatrix();
    translate(location.x,location.y);
    rotate(theta);
    beginShape();
    vertex(0, -r*2);
    vertex(-r, r*2);
    vertex(r, r*2);
    endShape(CLOSE);
    popMatrix();
  }

 

 
Advertisement

The language shouldn't matter at all really.  It's just math.

Here are a few sites on steering behavior I found in the past:
https://natureofcode.com/book/chapter-6-autonomous-agents/
http://rocketmandevelopment.com/blog/category/steering/

https://www.gamasutra.com/blogs/JuanBelonPerez/20140724/221421/Introduction_to_Steering_Behaviours.php

https://www.red3d.com/cwr/steer/gdc99/

https://gamedevelopment.tutsplus.com/series/understanding-steering-behaviors--gamedev-12732

Shouldn't take long to translate from C/C++/pseudo code to AngleScript.

"Those who would give up essential liberty to purchase a little temporary safety deserve neither liberty nor safety." --Benjamin Franklin

What is the equivalent of the mathematical commands "SetMag" and "Limit" from C to Angelscript? Those commands are in the examples you posted above. Angelscript doesn't have those commands.

DrMeowEyes

If there aren't built-in functions for it, you can always do it manually.

float speed = sqrt(velocity.x * velocity.x + velocity.y * velocity.y);
	if (speed > maxspeed)
	{
	    velocity.x = velocity.x / speed * maxspeed;
	    velocity.y = velocity.y / speed * maxspeed;
	}

Thanks DekuTree64. I assume the code above is for "Limit"? I am not that familiar with C/++ mathematical commands. Do you know what the equivalent manual code would be for SetMag?

 

Yes, that's for limit. SetMag would be pretty much the same but without the if.


	float oldMag = sqrt(v.x * v.x + v.y * v.y);
	v.x = v.x / oldMag * newMag;
	v.y = v.y / oldMag * newMag;

What engine are you using? AngelScript doesn't have any built-in functions/types for linear algebra (neither does C/C++ for that matter) so you're obviously using some engine that exposes those as part of its interface to AngelScript. Maybe you can ask the author of that engine to add the functions you need (if you don't want to implement them yourself in the script as DekuTree64 suggested).

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Hello WitchLord,

I am using an obscure game engine called, "Ethanon". A 2D game engine that works best with top down and side platform type games. I have been struggling to convert the linear Algebra seen in various steering behaviors using Angelscript and Ethanon. I think I need a crash course in math again. So far, I have gotten A*, Seek, Flee and Arrive to work successfully. However, my attempts at Wander, Pursue and character turning have failed as I cannot seem to supply the correct math those routines are looking for.

For example, here is the pseudo code for Pursuit from a well known site on steering behaviors:

public function pursuit(t :Boid) :Vector3D {
2.  var distance :Vector3D = t.position - position;
3.  var T :int = distance.length / MAX_VELOCITY;
4.  futurePosition :Vector3D = t.position + t.velocity * T;
5.  return seek(futurePosition);
}

I admit, i'm no math wiz. LOL! Can you decipher what this code actually means? I put in line numbers for convenience.

Here is my 2 cents at a conversion of this code. Tell me where I go wrong. :)

Line 2 says...Distance vector = current position - target position. <-- Both are vector2

Line 3 says...Int T = Length of distance vector / max velocity. <-- I have a command "Length" for vector2's, but I'm not sure it is actually calculating right because T ends up being a really large number. I am using pixels for the target and current position.

Line 4 says...FuturePosition = target position + target velocity * T. <--- T ends up being like 500, which makes no sense.

I thought A* was challenging to code till I started working on the steering behaviors. I would be curious about your mathematical interpretation of the above code. Thank you!

I think the idea is to aim ahead of the target so you'll intercept it in the future, rather than heading toward its current position and missing it since it will have moved by the time you get there.

Lines 2 and 3 calculate how many frames it will take to reach the target object if you go straight toward it at full speed. Then line 4 calculates where the object will be after that many frames have passed, and line 5 heads toward that position. It's not a very accurate  prediction, but probably makes for more organic looking behavior, in addition to taking relatively little processor time.

The vector length function should return sqrt(x*x + y*y). If yours is missing the square root, that could explain the unexpectedly large numbers.

Also, what are the units for velocity? Pixels per frame? What is your frame rate? If T is 500 that means it should take 500 frames to reach the target, which would be 8.333 seconds at 60fps.

Hello DekuTree64,

I tested the sqrt(x*x + y*y) against my "length" function and the results are the same. The result is the number of pixels between the enemy position and the target position. Which can be several hundred pixels at any given time. In line 4, T = 200 to 500 pixels and this is multiplied by velocity(1.5) and then added to Target Position to get FuturePosition. The final result doesn't seem to make any sense. I'm supposed to add it to the "steering" variable. I tried adding it to the steering but the velocity goes way too high. There must be something wring with the equation. Not sure what it is.

The units are pixels per frame like you mentioned. Frame rate is around 60FPS.

Thanks,

DrMeowEyes

This topic is closed to new replies.

Advertisement