Jump to content
  • Advertisement
DrMeowEyes

Steering Behaviors written for Angelscript?

Recommended Posts

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();
  }

 

 

Share this post


Link to post
Share on other sites
Advertisement

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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;
	}

Share this post


Link to post
Share on other sites

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?

 

Share this post


Link to post
Share on other sites

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;

Share this post


Link to post
Share on other sites

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).

Share this post


Link to post
Share on other sites

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!

Edited by DrMeowEyes

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!