Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: Amayirot Akago on Thu 02/03/2017 12:51:03

Title: How to use the Random function?
Post by: Amayirot Akago on Thu 02/03/2017 12:51:03
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) Select

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) Select

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?
Title: Re: How to use the Random function?
Post by: Khris on Thu 02/03/2017 13:11:56
I guess the problem is you used the command outside a function, and that will only work for literal values, likeint a = 5;
If you want a room variable with a random value, you need to declare it outside, then set it inside a function:int a;

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


As for panning the screen around:
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();
    }
  }
}

Title: Re: How to use the Random function?
Post by: Amayirot Akago on Fri 03/03/2017 12:37:07
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.
Title: Re: How to use the Random function?
Post by: Crimson Wizard on Fri 03/03/2017 13:09:10
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
Title: Re: How to use the Random function?
Post by: Snarky on Fri 03/03/2017 13:13:50
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).
Title: Re: How to use the Random function?
Post by: NicolaGs on Sat 04/03/2017 11:57:37
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 ?
Title: Re: How to use the Random function?
Post by: dayowlron on Sat 04/03/2017 15:36:31
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.
Title: Re: How to use the Random function?
Post by: NicolaGs on Sat 04/03/2017 16:41:21
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...