Slight issues with patrolling enemy script - SOLVED!

Started by Akril15, Sun 17/03/2024 02:44:20

Previous topic - Next topic

Khris

#20
I was working on a math based solution but it got more complicated quickly. I'll try your original approach again, give me a few hours :)

Edit: got it:

Code: ags
// room script file

enum KiteState {
  eKiteCircling, eKiteSwoopingIn, eKiteSwoopingOut
};

KiteState kite_state = eKiteCircling;
int exposed_timer;

int circling_timer;
int kite_region; // 0 = right, 1 = top right, etc.

function room_Load()
{
  cKite.z = -60;
  kite_region = 0;
}

void caught_by_kite() {
  Display("Caught by kite");
  // QuitGame(0);
}

bool kite_is_outside_screen() {
  ViewFrame* vf = Game.GetViewFrame(cKite.NormalView, cKite.Loop, cKite.Frame);
  int hw = Game.SpriteWidth[vf.Graphic] / 2;
  int h = Game.SpriteHeight[vf.Graphic];
  if (cKite.x < -hw || cKite.x > Game.Camera.Width + hw) return true;
  return cKite.y < 0 || cKite.y > Game.Camera.Height + h;
}

function room_RepExec() {

  // is player in danger
  bool danger_zone = Region.GetAtRoomXY(player.x, player.y) == region[5];
  
  if (danger_zone && cEgo.IsCollidingWithChar(cKite)) caught_by_kite(); //death script

  oDanger.Visible = danger_zone; // obj currently being used for testing
  exposed_timer = (exposed_timer + 1) * danger_zone; // increase / reset timer

  if (kite_state == eKiteCircling) {
       
    // kite swoops for player, continuing straight if player moves
    if (exposed_timer > 100) { 
      exposed_timer = 0;
      kite_state = eKiteSwoopingIn;
      float dx = IntToFloat(player.x - cKite.x);
      float dy = IntToFloat(player.y - cKite.y);
      float f = 2000.0 / Maths.Sqrt(dx * dx + dy * dy);
      cKite.Walk(cKite.x + FloatToInt(f * dx), cKite.y + FloatToInt(f * dy), eNoBlock, eAnywhere);
    }    
    else {
      circling_timer++;
      if (circling_timer >= 50 && !cKite.Moving) {
        kite_region = (kite_region + 1) % 8;
        float a = (IntToFloat(-kite_region)) * (Maths.Pi / 4.0);
        cKite.x = Game.Camera.Width / 2 + FloatToInt(IntToFloat(Game.Camera.Width) * Maths.Cos(a), eRoundNearest); 
        cKite.y = Game.Camera.Height / 2 + FloatToInt(IntToFloat(Game.Camera.Height) * Maths.Sin(a), eRoundNearest) - cKite.z; 
        circling_timer = 0;
        // visible top left
        if (kite_region == 3 && !cKite.Moving) {
          cKite.x = 300;
          cKite.y = -100 - cKite.z;
          cKite.Walk(-300, 200 - cKite.z, eNoBlock, eAnywhere);
        } // visible bottom right
        if (kite_region == 7 && !cKite.Moving) {
          cKite.x = Game.Camera.Width - 300;
          cKite.y = Game.Camera.Height + 100 - cKite.z;
          cKite.Walk(Game.Camera.Width + 300, Game.Camera.Height - 200 - cKite.z, eNoBlock, eAnywhere);
        }
      }
    }
  }
  
  // this makes the kite stop as soon as it has left the screen
  if (kite_state == eKiteSwoopingIn && !kite_is_outside_screen()) kite_state = eKiteSwoopingOut;
  if (kite_state == eKiteSwoopingOut && kite_is_outside_screen()) {
    kite_state = eKiteCircling;
    float a = Maths.ArcTan2(IntToFloat(cKite.y - Game.Camera.Height / 2), IntToFloat(cKite.x - Game.Camera.Width / 2));
    kite_region = (FloatToInt(-a * 4.0 / Maths.Pi, eRoundNearest) + 8) % 8;
  }
}

Akril15

Thank you so much! The kite is now moving just the way I described. I'm sorry this ended up being such a big problem, but I'm really glad that it's finally working. Again, thank you or being so patient with me.

Khris

Great!

Don't worry, and finally solving problems like this is its own reward :)

SMF spam blocked by CleanTalk