Results 1 to 8 of 8

Thread: Random based on time and not on frames

  1. #1

    Random based on time and not on frames

    Hello,

    I want to have some Randoms in my sprites move methods.

    So the problem is if you say Random(10)=0 there,
    on fast PCs it is happening more often than on slow PCs, cause higher FPS calls my move method more often.

    I already have my sprites moving in dependency of time_elpased that is the time after the latest timer tick. time_elpased is>0 and <=1

    time_elpase is a single;

    if boolCounter then QueryPerformanceCounter(Current_Time)
    else Current_Time := timeGetTime;
    Time_Elapsed := (Current_Time - Last_Time) * Time_Scale;
    if time_elapsed>1 then time_elapsed:=1;
    So how must my random look like so it happens as often on slow PCs or fast PCs?

    Something like this

    if random(round(1/time_elapsed))=0 then happens each second

    if random(round(2/time_elapsed))=0 then happens each 2 seconds

    if random(round(0.1/time_elapsed))=0 then happens ten times a second

    How is the best way that works for time_elapsed=1 but also for time_elapsed=0.001? Remember when it is 1 it is called 1 time a second, 0.001 would mean 1000 times a second, or am I wrong?

    Thanks,
    Firle

  2. #2
    Legendary Member cairnswm's Avatar
    Join Date
    Nov 2002
    Location
    Randburg, South Africa
    Posts
    1,537

    Random based on time and not on frames

    Within my base sprite class I declare a virtual move function. Part of this function is calculating the time since the last move and moving the sprite based on that value.

    In addition part of the move function holds a bigger counter to manage the frame count of the sprite. (I typically use a value between 150and 180 for Frames).

    As long as your interval of each frame is smaller than the period being checked this is pretty accurate.


    Here is an example:
    [pascal]
    procedure TShip.Move;
    Var
    TC : Single;
    MX,MY : Integer;
    begin
    TC := SDL_GetTicks - LastTick;
    ShootPower := ShootPower - TC;
    // Do Frame Change
    If SDL_GetTicks - FrameTick > 100 then
    Begin
    Frame := Frame + FrameOrder;
    If Frame >= 15 then
    Begin
    Frame := 13;
    FrameOrder := -1;
    End;
    If Frame < 0 then
    Begin
    Frame := 1;
    FrameOrder := +1;
    End;
    FrameTick := SDL_GetTicks;
    End;
    If Keys[SDLK_UP] then
    Y := Y - (TC * VSpeed);
    If Keys[SDLK_Down] then
    Y := Y + (TC * VSpeed);
    If Keys[SDLK_RIGHT] then
    X := X + (TC * (HSpeed*2))
    Else
    If Keys[SDLK_Left] then
    X := X + (TC * (HSpeed / 2))
    Else
    X := X + (TC * HSpeed);
    If Keys[SDLK_SPACE] and (ShootPower <= 0) then
    Begin
    Shoot;
    End;

    // Check Collisions
    MX := (IX + 16) div 16;
    MY := (IY + 16) div 16;
    If Map.CollisionArray[MX,MY].Closed or Map.CollisionArray[MX+2,MY].Closed then
    Begin
    // Collision
    Halt(0);
    End;
    LastTick := SDL_GetTicks;
    end;
    [/pascal]

    To expect something to happen the same on all PCs on a 0.001 second interval is expectign a bit much. I try to not go below a 0.1 second expectation.

    (PS. I develop on a rather poor performing (Graphically) notebook and I make sure even it works at 30FPS - giving me a minumum resolution of 0.03 seconds for events.)
    William Cairns
    My Games: http://www.cairnsgames.co.za (Currently very inactive)
    MyOnline Games: http://TheGameDeveloper.co.za (Currently very inactive)

  3. #3

    Random based on time and not on frames

    Hi cairnswm,

    thanks for the info.

    for movement every sprite has a different xspeed and yspeed and it goes like x:=x+xspeed*time_elapsed, same for y, this works perfect, they are all moving with the same speed on slow or fast FPS.

    But the problem here is every sprite can shoot.
    I want them to shoot manually in random intervals.

    The problem is I want to have a line of code in dependency of time_elapsed that does a thing

    1) one time a second
    2) one time in two seconds
    3) let's say 2 times a second.

    Another problem is then this:
    I already have some values definded for 60 different starships and want to use them without changing each one. ShootH is integer and tells how often it should shoot.
    For ShootH 30 is the fastest, should shoot lets say 4 times a second, 60 should shoot only half of that 2 times a second.
    This problem I have to solve after finding a solution for the above main problem, how to shoot in dependency of time_elapsed and ShootH.

    Thanks,
    Firle



    Firle

  4. #4
    Legendary Member cairnswm's Avatar
    Join Date
    Nov 2002
    Location
    Randburg, South Africa
    Posts
    1,537

    Random based on time and not on frames

    Store a value of last time the ship did shoot.

    Each time move procedure gets called check if the expected delay has happened.

    If it has, make random chance to shoot.

    Set the last shoot value to now (even if the ship didn;t shoot)


    If you need multiple actions store the last action times in an array and check in each cycle.

    I often use an external array to store common intervals. Then what you store per ship is the index into the common array instead of storing the value.

    [pascal]
    Const
    ShootInterval : Array[1..4] of Integer = (100,200,400,600);

    Procedure TShip.CheckShoot;
    Var
    TC : Integer;
    Begin
    TC := SDL_GetTicks - LastShootTick;
    If TC > ShootInterval[ShootType] then
    Begin
    LastShootTick := SDL_GetTicks;
    If Random < ShootChance then
    Shoot;
    End;
    End;
    [/pascal]

    If the ship had multiple weapons I would consider modelling the weapons seperatly and then calling Weapon[I].CheckShoot in each movement step.
    William Cairns
    My Games: http://www.cairnsgames.co.za (Currently very inactive)
    MyOnline Games: http://TheGameDeveloper.co.za (Currently very inactive)

  5. #5

    Random based on time and not on frames

    I hope I'm not missing anything obvious here, but it sounds like you need to keep track of how much time has passed before shooting, so every tick, each enemy will need to accumulate the time to know exactly how much time has passed since the last time they fired. If the accumulated time passes, that's enemy's fire rate, fire off a shot and reset the accumulation. Therefore enemy 1 can have a fire rate of once per second, while enemy 2 can have a fire rate of n per second.

    I hope this helps.
    <br /><br />There are a lot of people who are dead while they are still alive. I want to be alive until the day I die.<br />-= Paulo Coelho =-

  6. #6

    Random based on time and not on frames

    Oops didn't see Williams post.
    <br /><br />There are a lot of people who are dead while they are still alive. I want to be alive until the day I die.<br />-= Paulo Coelho =-

  7. #7

    Random based on time and not on frames

    Hi,

    this sounds like a good solution for my shooting problem, thanks a lot!

    But I also need other random, where I cannot store the time that things last happened, for example particle stuff. Each particle does something randomly different things.

    So how would a solution for the first problem look like, that random in dependency of time_elapsed?

    Firle

  8. #8
    Legendary Member cairnswm's Avatar
    Join Date
    Nov 2002
    Location
    Randburg, South Africa
    Posts
    1,537

    Random based on time and not on frames

    I use a slightly different approach for this. Basically I use a decay option. For example when the ship shoots a bullet, when can they shoot again.

    Whenever an action occurs (eg Shoot) I set a ShootPower variable. Each move this Shoot Power Variable decreases (By TC in the above source example) - In the Move procedure I check if ShootPower is <= 0 and if it is I can then do the next action.

    Each particle can be allocated a DecayValue. When this decay value is <= 0 then do the next random action, and set DecayValue again. To make it even more random - set DecayValue to a random value (DecayValue := Round(Random * 100) + 50).
    William Cairns
    My Games: http://www.cairnsgames.co.za (Currently very inactive)
    MyOnline Games: http://TheGameDeveloper.co.za (Currently very inactive)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •