Bullet hit -script, detects hits irregularly

Started by WHAM, Tue 19/04/2011 17:29:15

Previous topic - Next topic

WHAM

The below script SHOULD: move bullets (characters 1-10) that are NOT in reserve (ie. have a Y coordinate that is NOT -1) down by 8 pixels and then processclick on the bottom-mid pixel of the bullet, and then move up, clicking total of 8 pixels. After this, if the same coordinates that were clicked return the target name as "PLAYER" the bullet is sent to reserve.

What happens: The bullets are ALWAYS successfully sent to reserve after impact, but the processclick only seems to hit the player character occasionally, even though they SHOULD to my understanding be processing the same coordinate.

EDIT: forgot to mention, this function is run in global repeatedly execute.

Sorry for the messy code below, I hope someone can make sense out of it.
Code: ags

function enemybullets() { // A general check to see if any enemy bullets have hit the player
  while (MG2whiler <= 9) {
    if (character[MG2whiler+1].y != -1) { // IF the bullet is NOT in reserve
      character[MG2whiler+1].y = character[MG2whiler+1].y + 8; // Move bullet down by 8px
        int taa = 0; // Reset taa
        while (taa < 7) { // This while loop runs for 8 cycles
          // Process a click on the bottom-mid pixel of the bullet character. If click hits player, player takes damage. Bullets are not clickable.
          ProcessClick((character[MG2whiler+1].x + 1 - GetViewportX()), (character[MG2whiler+1].y - GetViewportY() - taa), eModeInteract);
          if (Game.GetLocationName(character[MG2whiler+1].x -GetViewportX(), character[MG2whiler+1].y -GetViewportY() - taa) == "PLAYER") {
            // If the character hit was the player, reset bullet position to reserve
            character[MG2whiler+1].ChangeRoom(player.Room, -1, -1);
          }
          taa++;
        }
  }
    // IF the bullet has left the screen, reset it
    if (character[MG2whiler+1].y >= 410) {
      character[MG2whiler+1].ChangeRoom(player.Room, -1, -1);
    }
    MG2whiler++;
  }
  MG2whiler = 0;
}
Wrongthinker and anticitizen one. Utterly untrustworthy. Pending removal to memory hole.

Khris

ProcessClick isn't processed until the current function has ended. Using it in a while loop inside a function is gonna give really unexpected results, mainly regarding the order of things being processed.

Why do you call it in the first place? Why not directly call player_Interact() inside the if block?

Game.GetLocationName(character[MG2whiler+1].x -GetViewportX(), character[MG2whiler+1].y -GetViewportY() - taa) == "PLAYER"

is a really bad way to do that check; I'd use

Character.GetAtScreenXY(character[MG2whiler+1].x, character[MG2whiler+1].y - taa) == player


Code: ags
function enemybullets() { // A general check to see if any enemy bullets have hit the player

  Character*bullet;
  MG2whiler = 0;

  while (MG2whiler <= 9) {

    bullet = character[MG2whiler+1];

    if (bullet.y != -1) { // IF the bullet is NOT in reserve

      bullet.y += 8; // Move bullet down by 8px

      // IF the bullet has left the screen, reset it
      if (bullet.y >= 410) bullet.ChangeRoom(player.Room, -1, -1);

      bool player_was_hit;    (default value for bools: false)
      int taa; // declare taa (default value for ints: 0)
      while (taa < 8) { // This while loop runs for 8 cycles (0-7)

        // check if player was hit; damage pl & reset bullet if yes
        if (Character.GetAtScreenXY(bullet.x, bullet.y - taa) == player) {

          player_was_hit = true;
          bullet.ChangeRoom(player.Room, -1, -1);
          taa = 7; // exit loop
        }
        taa++;
      }
      if (player_was_hit) damage_player(); // damage player once per frame only!
    }
    MG2whiler++;
  }
}


WHAM

That sounds like it might solve the problem and make the code a bit clearer too.
I'll try that out ASAP, that is, as soon as I can get myself to stay away from Portal 2 for more than 10 minutes.

Gotta go!
Wrongthinker and anticitizen one. Utterly untrustworthy. Pending removal to memory hole.

WHAM

#3
Couldn't fin a player_Interact() function, but after a little rummaging of the manual, found "cEgo.RunInteraction(eModeInteract);" and that worked like a charm! The bullets now detect impacts correctly and seem to kill the player quite nicely.  ;D

Now to do some other hazards!
Wrongthinker and anticitizen one. Utterly untrustworthy. Pending removal to memory hole.

Khris

Yeah, the function you have is probably called cEgo_Interact or similar, it was supposed to be an alternative to ProcessClick.

The thing is that I guess .RunInteraction will also end up in the queue and only get called after the function has finished. That's why I suggested adding a custom function "player_Interact()" to your script because then the hit is handled immediately. It doesn't really make a difference here though.

WHAM

Thanks again for the tips. It seems to work now, which means I will keep my hands off unless something else breaks it again.  ;D

If I can keep this pace up during the coming weekend, the game has hope of making the deadline! *cheers self on*
Wrongthinker and anticitizen one. Utterly untrustworthy. Pending removal to memory hole.

SMF spam blocked by CleanTalk