Some AI Code, Who wants to help me? :D


(Nate ) #1

Hey guys! As part of my small side project game I would like to have soldiers spawn and wander around and then fire at the player. This is what I have so far, and it SEEMS to be working for the most part.

Some issues I am having currently is, bullets sometimes don’t move from the soldiers gun. If the soldier shoots to the left, then the player runs the right and the soldier shoots to the right, the previously left traveling bullet changes its course of direction to the right… lol I am sure this is because I am not instancing correctly. Here is the soldier update code:

override public function update():void
{
    
  hFriction = 0.9;
  vFriction = 0.9;
  
  stopped = false;
  
  if (stopped == false)
  {
  //  ammo = 2;
  }
    
  b += FP.elapsed;
  
  if ( b >= 5)
  {
    a = FP.rand(4);
    b -= 5;
  }
    
  //soldier will pick up down left or right
  
  if (a == 1)//up
  {
    direction = 1;
  }
  if (a == 2)//down
  {
    direction = 2;
  }
  if (a == 0)//left
  {
    direction = 3;
  }
  if (a == 3)//right
  {
    direction = 4;
  }
  
  trace("the value of a: " + a);
  trace("the value of b: " + b);
  
  //checks if the zombie is located within range
  
  for (var i:int = 0; i < 250; i ++)
  {
    if (collide("zombie", x + i, y))//zombie is to the right of the soldier
    {
      b = 0;
      direction = 4;
    }
  }
  for (var j:int = 0; j < 250; j ++)
  {
    if (collide("zombie", x - j, y))//zombie is to the left of the soldier
    {
      b = 0;
      direction = 3;
    }
  }
  for (var k:int = 0; k < 250; k ++)
  {
    if (collide("zombie", x , y + k))//zombie is beneath the soldier
    {
      b = 0;
      direction = 2;
    }
  }
  for (var l:int = 0; l < 250; l ++)
  {
    if (collide("zombie", x , y - l))//zombie is beneath the soldier
    {
      b = 0;
      direction = 1;
    }
  }
  
  if (direction == 1)
  {
    ySpeed -= power;
    playerSprite.play("up");
  }
  if (direction == 2)
  {
    ySpeed += power;
    playerSprite.play("down");
  }
  if (direction == 3)
  {
    xSpeed -= power;
    playerSprite.play("left");
  }
  if (direction == 4)
  {
    xSpeed += power;
    playerSprite.play("right");
  }
  
  
  if (collide("zombie", x - 50, y))
  {
    stopped = true;
  }
  
  if (collide("zombie", x + 50, y))
  {
    stopped = true;
  }
  
  if (collide("zombie", x , y + 50))
  {
    stopped = true;
  }
  
  if (collide("zombie", x , y - 50))
  {
    stopped = true;
  }
  
  
   if (stopped == true)
  {
    xSpeed = 0;
    ySpeed = 0;
  }
  
  
  //shoot code 
  if (direction == 1 && stopped == true && ammo > 1)
  {
    playerSprite.play("stop_up");
    shootDirection = 3;
    ammo --;
    world.add(new bullet(x, y));
  }
  
  if (direction == 2 && stopped == true && ammo > 1)
  {
    playerSprite.play("stop_down");
    shootDirection = 4;
    ammo --;
    world.add(new bullet(x, y));
  }
  
  if (direction == 3 && stopped == true && ammo > 1)
  {
    playerSprite.play("stop_left");
    shootDirection = 1;
    ammo --;
    world.add(new bullet(x, y));
  }
  
  if (direction == 4 && stopped == true && ammo > 1)
  {
    playerSprite.play("stop_right");
    shootDirection = 2;
    ammo --;
    world.add(new bullet(x, y));
  }
  //end of shoot code

  
  trace("ammo: " + ammo);
  
  
  //  if (Math.abs(xSpeed) < 1)
  //  {
  //    xSpeed=0;
  //  }
  
  xSpeed *= hFriction;
  ySpeed *= vFriction;
  
  moveBy(xSpeed, ySpeed, ["level","zombie","soldier"]);//

  //end of the update function
}

This is my bullet update method:

override public function update():void
{
  //shoot left
  if (theSoldier.shootDirection == 1)
  {
    xSpeed -= power;
  }
  //shoot right
  if (theSoldier.shootDirection == 2)
  {
    xSpeed += power;
  }
  //shoot up
  if (theSoldier.shootDirection == 3)
  {
    ySpeed -= power;
  }
  //shoot down
  if (theSoldier.shootDirection == 4)
  {
    ySpeed += power;
  }
  
  trace("direction: " + theSoldier.shootDirection);
  
  if (collide("level", x, y - 1) || collide("level", x + 1, y) || collide("level", x -1, y) || collide("level", x, y + 1))
  {
    FP.world.recycle(this);
  }
  
  xSpeed *= hFriction;
  ySpeed *= vFriction;
  
  moveBy(xSpeed, ySpeed, ["level", "zombie", "soldier"]);
}

Thanks guys! I have never coded any type of AI before so this is probably pretty nooby looking! I am interested in any and all feedback!

Thanks again! :grin:


(JP Mortiboys) #2

There’s clearly lots of things to be optimised there! Anyway, in order to get the bullets working the way you want, without changing anything else, add this to the bullet class:

public class Bullet extends Entity {
  public var shootDirection:int;

  public static function shoot(theSoldier:Soldier):Bullet {
    var b = world.create(Bullet);
    b.x = theSoldier.x;
    b.y = theSoldier.y;
    b.shootDirection = theSoldier.shootDirection;
  }
}

The alter the update function to remove references to theSoldier.shootDirection and replace them with references to the Bullet's own shootDirection member variable.

This done, in the soldier’s update function replace the shoot code with this:

if (stopped && ammo > 1) {
  playerSprite.play(['stop_up','stop_down','stop_left','stop_right'][direction-1]);
  shootDirection = direction;
  ammo--;
  Bullet.shoot(this);
}

(You were using world.recycle but not world.create so bullets weren’t being recycled; with this method they are).

One other thing to look at : when the soldier is looking for zombies, you’re doing four 250 iteration loops with collide - that’s excessive - I’d recommend doing something like world.collideRect(right, top, 250, height) (to check right - you can work out the other directions.) instead. Also this doesn’t take into account distance at all - if there is a zombie 20 pixels below the soldier and one 200 pixels to his right, he will go for the one on the right every time.