[SOLVED] One script works and the copy/paste of that script doesn't

Started by Rik_Vargard, Tue 15/04/2025 20:27:30

Previous topic - Next topic

Rik_Vargard

Yeah, sorry, but I couldn't find a better title for this one.

Here's my problem: It's a minigame. An "attack object image" appears on the left and moves to the right.
To stop it, player has to click on an object-image that will make the left laser appear.
When the Attack object X == the Laser X they both disappear.
And this one is working.

I copy/Pasted the code for the RIGHT attack object, which means the same happens from the right but the attack object appears on the right and moves to the left and if it hits the right laser, they both disappear, too.
And this one is NOT working for some reason. (When the Right Laser X hits the Right Object X)

So:

Attack from left > if (oAttackLEFT.X == oLaserLEFT.X-75 && oLaserLEFT.Visible == true) is working
Attack from right> if (oAttackRIGHT.X == oLaserRIGHT.X+75 && oLaserRIGHT.Visible == true) is NOT working, the "collision" doesn't happen


I might be missing something really stupid here; here's the code:

In Room Load:
Code: ags
oAttackLEFT.X = 209;
oAttackRIGHT.X = 892;

int L = Random (2); // AttackLEFT
if (L == 0) SetTimer (3, 40);
else if (L == 1) SetTimer (3, 80);
else if (L == 2) SetTimer (3, 120);
  
int R = Random (2); // AttackRIGHT
if (R == 0) SetTimer (5, 40);
else if (R == 1) SetTimer (5, 80);
else if (R == 2) SetTimer (5, 120);

In Room Rep_Exec:

Code: ags
//////////////////////////////////////////// Attack LEFT
  if (IsTimerExpired (3))
  {
    oAttackLEFT.Visible = true;
    SetTimer (4, 3);
  }
  if (IsTimerExpired (4))
  {
    oAttackLEFT.X += 1;
    SetTimer (4, 3);
  }
  if (oAttackLEFT.X == oLaserLEFT.X-75 && oLaserLEFT.Visible == true)
  {
    oAttackLEFT.Visible = false;
    oLaserLEFT.Visible = false;
    oAttackLEFT.X = 209;
    SetTimer (4, 0);
    int L = Random (2);
    if (L == 0) SetTimer (3, 40);
    else if (L == 1) SetTimer (3, 80);
    else if (L == 2) SetTimer (3, 120);
  }
 //////////////////////////////////////////// Attack RIGHT
  if (IsTimerExpired (5))
  {
    oAttackRIGHT.Visible = true;
    SetTimer (6, 3);
  }
  if (IsTimerExpired (6))
  {
    oAttackRIGHT.X -= 1;
    SetTimer (6, 3);
  }
  if (oAttackRIGHT.X == oLaserRIGHT.X+75 && oLaserRIGHT.Visible == true) //// [b][u]THIS IS THE PART THAT'S NOT WORKING[/u][/b]
  {
    oAttackRIGHT.Visible = false;
    oLaserRIGHT.Visible = false;
    oAttackRIGHT.X = 892;
    SetTimer (6, 0);
    int R = Random (2);
    if (R == 0) SetTimer (5, 40);
    else if (R == 1) SetTimer (5, 80);
    else if (R == 2) SetTimer (5, 120);

And here's the "buttons/objects" code:

Code: ags
function oLeft_Interact(Object *theObject, CursorMode mode) // AttackLEFT
{
  if (oAttackLEFT.Visible == true)
  {
    oLaserLEFT.Visible = true;
  }
}

function oRight_Interact(Object *theObject, CursorMode mode) // AttackRIGHT
{
  if (oAttackRIGHT.Visible == true)
  {
    oLaserRIGHT.Visible = true;
  }
}

I did try to use IsCollidingWithObject, which I used before, but in this case they're PNG images with some "empty room" around them so that's no use in this case.

But the LEFT attack script works so I don't know why the RIGHT attack doesn't.

And again, I might have missed something stupid but I just don't see it.

Any ideas?



heltenjon

I feel silly just by suggesting this, but is there any event on the right side that should have been enabled by the lightning icon in the editor? I guess that's the most common thing to miss if copy-pasting code, at least if I'm doing it.

Khris

Use debugging: add a GUI that is always visible, put a label on it, then put a suitable line in repeatedly_execute.

Like
Code: ags
function repeatedly_execute_always() {
  lblDebug.Text = String.Format("X difference is: %d", oAttackRIGHT.X - (oLaserRIGHT.X + 75));
}

This should read "X difference is 0" at some point.

Some unrelated tips regarding your code:
Spoiler
1.
oLaserLEFT.Visible == true
is an expression that is evaluated to the exact same value as
oLaserLEFT.Visible

That's because "false == true" is false, and "true == true" is true. So you can just get rid of the "== true" part.

2. Instead of assigning a random value to L, then using three if lines for the delays of 1, 2 or 3 seconds, you can simply do:
  SetTimer(3, (Random(2) + 1) * GetGameSpeed());

First add one to the random value to shift the range from 0-2 to 1-3. Then multiply by 40 / the game's FPS value to get to actual seconds. Any literal number in your code can be replaced with a mathematical expression, and those in turn can contain function calls that return numbers.

3. The code where you position the attack objects and start their times repeats verbatim in your code. You should move it to a custom function and call the function instead. This drastically reduces the possibility of typos and makes your code easier to adjust/fix because you only have to do it in one place.
[close]

Rik_Vargard

@heltenjon  Yeah, I learned that one pretty soon, but you're right, we're never safe from making silly mistakes, especially me, as you will read here  (laugh)

@Khris Oh boy, I knew it was something stupid: Since the attack comes from the right and moves to the left, the X value goes down !! and it's starting point is +32 so it could never hit +75!  :shocked: Damn it (laugh).
That's one copy/paste lesson.

Thanks for that debug line that made this clear, I didn't know I could check stuff like that inside the room page.

And thanks a lot for taking the time for those tips! My script will be neater and I will feel smarter!  (laugh)

Cheers!  :)

SMF spam blocked by CleanTalk