How to use the Random function?

Started by Amayirot Akago, Thu 02/03/2017 12:51:03

Previous topic - Next topic

Amayirot Akago

Yep, I'm trying to wrap my caveman brain around scripting again. Hold on to your butts :=

I want to make it so that the room will randomly pan around to each corner of the screen, using the Tween module like so:

Code: ags

function room_AfterFadeIn()
{
  if (ran==0) TweenViewport(7.0, 0, 0);
  else if (ran==1) TweenViewport(7.0, 0, 247);
  else if (ran==2) TweenViewport(7.0, 349, 0);
  else if (ran==3) TweenViewport(7.0, 349, 247);
  }


(never mind the odd coordinates, the background used is slightly larger than the game's resolution of 320x200)

What I'm struggling to understand is how to define a ran variable that gets its value from the Random function. From what I've read in the Help file, I should be able to simply do:
Code: ags

int ran=Random(2);


This, however, makes AGS freak out and tell me "Expected integer value after '='". So, could someone more intelligent than me please explain how to do this right? Furthermore, the plan is to have the screen pan around for several seconds before moving on to something else, how would I tell it to do that?
Quote from: CaptainDMy suspicion is that an accident, probably caused by a lightning storm and a mad professor, resulted in Amayirot's brain becoming inextricably linked to the databases behind MobyGames and LemonAmiga.

Khris

I guess the problem is you used the command outside a function, and that will only work for literal values, like
Code: ags
int a = 5;

If you want a room variable with a random value, you need to declare it outside, then set it inside a function:
Code: ags
int a;

function room_Load() {
  a = Random(2); // a is now 0, 1 or 2
}


As for panning the screen around:
Code: ags
function randomPan() {
  int x = Random(1) * 349, y = Random(1) * 247;
  TweenViewport(7.0, x, y);
}

int frameCount;

function room_RepExec() {
  if (frameCount < GetGameSpeed() * 5) { // for the first 5 seconds, do the following
    frameCount++;
    if (frameCount % GetGameSpeed() * 1 == 0) { // once per second, to the following
      randomPan();
    }
  }
}


Amayirot Akago

Thanks :) Been trying to figure out exactly how the code works, I think I mostly understand it. I did manage to add a line to re-enable the interface after it had been disabled before to prevent the player taking control between pans.

What does the % operator do, exactly? The manual says "remainder" but I don't quite get what it means.
Quote from: CaptainDMy suspicion is that an accident, probably caused by a lightning storm and a mad professor, resulted in Amayirot's brain becoming inextricably linked to the databases behind MobyGames and LemonAmiga.

Crimson Wizard

#3
Quote from: Amayirot Akago on Fri 03/03/2017 12:37:07
What does the % operator do, exactly? The manual says "remainder" but I don't quite get what it means.

This means remainder of division of two integer numbers.

https://en.wikipedia.org/wiki/Modulo_operation

With integer arithmetics -

4 / 4 = 1; 4 % 4 = 0
5 / 4 = 1; 5 % 4 = 1
6 / 4 = 1; 6 % 4 = 2
7 / 4 = 1; 7 % 4 = 3
8 / 4 = 2; 8 % 4 = 0

Snarky

The remainder (also known as modulo) is the "leftover" after a division.

When you do an integer division, the answer has to be a whole number, so it is always rounded down, e.g. 11/4 = 2. The remainder is the bit that can't be divided into a whole number. In this case, if you calculate with fractions you actually have 11/4 = 2 + 3/4, so the remainder is 3. You can calculate it as 11 - 4*2 (though I think the computer uses a more efficient calculation).

The remainder of any (positive) number divided by d is a number between 0 (if the number is a multiple of d) and d-1, which is a useful property, since it allows you to "wrap around" in a cycle. In particular, checking if the remainder of the loop counter is 0 is a common way to have something happen once every d times through the loop. In this case, checking if the remainder of a division by GetGameSpeed() is 0 will be true whenever the frameCount is a multiple of GetGameSpeed(), or in other words once every second (since we're increasing the frameCount once every loop, and GetGameSpeed() tells us how many loops there are in a second).

NicolaGs

Quote from: Snarky on Fri 03/03/2017 13:13:50
In this case, checking if the remainder of a division by GetGameSpeed() is 0 will be true whenever the frameCount is a multiple of GetGameSpeed(), or in other words once every second (since we're increasing the frameCount once every loop, and GetGameSpeed() tells us how many loops there are in a second).

I found this use of remainder quite appealing and wanted to integrate it in a script that calculates the duration of the game.
I already had a working script, but I found your solution more elegant than mine to "beat time" and wanted to test it...

I discovered that the calculated time with this method was going slightly too fast...
By enabling the V-sync option, the calculated time seemed to be running at the correct pace, this time.
I guess it's because without V-sync, the frame rate is not frame-perfect.

So, if someone needed to use a timer accurate to the second, maybe it is a good thing to know ?
My first game : I Want Out!

dayowlron

Don't know for sure, but seems to me enabling V-sync would make it less accurate. Perhaps it works better for you but I wonder if it was run on another system with a different V-sync frequency it would run differently.
Pro is the opposite of Con                       Kids of today are so much different
This fact can clearly be seen,                  Don't you know?
If progress means to move forward         Just ask them where they are from
Then what does congress mean?             And they tell you where you can go.  --Nipsey Russell

NicolaGs

Yes, I was wondering the same thing... maybe the slightly too fast timing would be slightly too slow with another hardware, another video driver, or maybe even a different display setting on the very same system (I can't test since I use a laptop with a fixed refresh rate) ? The same may go for the V-Sync which may be done differently from a system to another...
My conclusion is that this method should not be used to create an accurate timer...
My first game : I Want Out!

SMF spam blocked by CleanTalk