Script dependant on game's FPS...is this a good solution?

Started by Knox, Thu 24/05/2012 17:55:29

Previous topic - Next topic

Knox

Hi,

I have a script that seems to be dependant on the game's framerate, but not too sure if my solution to overcome this is a good idea. I placed this question in the "Advanced" section since Im guessing what you guys might suggest could be complicated, but Im not sure.

Basically what Im doing is if the user presses the left arrow key down for a certain amount of time, it calls a script that will turn the car in 30º increments. The values I use for the timer that tells when to stop the rotation has been set by me manually so that the car turns left perfectly at an intersection on an isometric map. The only thing is, I tested this script on two computers where the FPS is about 98, and everything works as it should...but on a laptop where the FPS is 35, the turning "mechanism" timers no longer seem to be "in sync" and the car rotates too much (therefore missing the intersection turn)...the various values for the timer (iTurnTimer) are no longer valid when the game runs at a lower FPS:

Code: ags

//in the driving map room.asc:
function on_key_press(int keycode)
{
     if (IsKeyPressed(375)) //LEFT TURN   
    {
      setTurnTimerValue(0);
      if (bLeftKeyHOLD == false) carDrive_LEFT(eManual, 0);
    }
}
// in my driving module:
void setTurnTimerValue(int iMode)
{
  if (iMode == 0) //Left
  {
    if (fDrive_Angle == 210.0 || fDrive_Angle == 30.0) iTurnTimer = 17; //NW or SE                 
    else if (fDrive_Angle == 330.0 || fDrive_Angle == 150.0) iTurnTimer = 20; //NE or SW                      
    else
    {
      iTurnTimer = 0;
      return;
    }  
  }                                       
}

function repeatedly_execute()
{
      if (!bAutomatic) //Manual
      {
        //TURN MANUAL
        if (IsKeyPressed(375)) processQuickTurn_Left(1);
        else 
        {
          iHoldKeyPressLeft = 0;
          if (bLeftKeyHOLD) bLeftKeyHOLD = false;
        }
}

#define KEYHOLD 15 //in the .ash 

void processQuickTurn_Left(int iMode)
{
  if (iMode == 1) //Manual
  {    
    if (iHoldKeyPressLeft >= KEYHOLD) 
    {
      if (!bLeftKeyHOLD) bLeftKeyHOLD = true;
      //value of iTurnTimer is set in the room, at "on_key_press"
      if (iHoldKeyPressLeft < iTurnTimer) 
      {
        rotateCar_TAP(-30.0);      //script that rotates the car by 30 degree increments
        iHoldKeyPressLeft++;
      }
    }
    iHoldKeyPressLeft++;
  }
}


As a solution I was thinking of using scorpiorus' script http://www.adventuregamestudio.co.uk/yabb/index.php?topic=42836.0 to detect the game's FPS, and if during the driving sequences the FPS drops to a certain amount, have the iTurnTimer values changed on the fly so that everything works as it should on slower computers.

Is that a good idea, or is there a better way?
--All that is necessary for evil to triumph is for good men to do nothing.

Khris

Where are you getting 98 from? Did you use SetGameSpeed(100) or something like that?
Because unless you change the speed to something higher than the default 40, even a very fast computer shouldn't run the game faster than 40 fps but cap them at that value.

And regarding the way you're turning the car; is the player supposed to be able to screw up turning properly? For a driving sequence à la Police Quest, shouldn't they just push left/right once at the proper time and the car turn automatically?

Knox

I think the reason I  get 98 is because I have photoshop opened...I believe  the same happens if AfterEffects or QuickTime is opened too, the fps goes up to like 98-100...I tested having various programs like that opened at the same time as AGS, and the FPS is increased majorly.

Well I could send a clip via youtube to show what Im doing if you wish (?)...let me know!

The player can "tap" the direction keys to rotate the car in 30º increments "a la police quest 1 EGA" (so to turn at an intersection you would have to tap the left or right keys multiple times depending on your direction...the faster you go though, the harder it is to tap the perfect amount to get a nice turn without hitting the borders)...to make it easier, I implemented a system that if you hold down the left or right keys for x amount of time, it will make "the perfect turn" for you, using the iTurnTimer (automatically turning the car in the right amount of degrees so the intersection is cleared perfectly)...so you can turn using both "tap" and "hold".
--All that is necessary for evil to triumph is for good men to do nothing.

Knox

--All that is necessary for evil to triumph is for good men to do nothing.

Jakey

Maybe I don't fully understand what is happening in the script but it doesn't seem correct to have "iHoldKeyPressLeft++;" possibly incrementing twice during a single call of "processQuickTurn_Left". Probably should add a return or else statement somewhere, so only one of the two executes each call.

But of course, this is very likely not the cause of your problem :P

Knox

Yeah, thats not really the problem. Everything works fine on my faster computer, but on my laptop the timing of the turning is "off". Ill try to see if I can find a different way of doing the turn. I still dont know why fps is messing with the timing script (shouldnt the turn just be donw slower on a slower maching?)
--All that is necessary for evil to triumph is for good men to do nothing.

Andail

What you say about the fps is rather puzzling.
Have you used the debug function to get your fps displayed on your screen while playing? If not, please do so and report back what you see.
As Khris said, the game shouldn't run faster than 40 fps even if you played it on Deep Thought, unless you manually set it to do so.

Knox

Hmm...well could it have something to do with the keyboard press sensitivity? The script calculates how long the key is pressed down, maybe different keyboards have different sensitivities and that's what's causing the turn-timing issuea on different computers?

Ill get a clip on youtube to show what's happening.
--All that is necessary for evil to triumph is for good men to do nothing.

EchosofNezhyt

Quote from: General_Knox on Sun 10/06/2012 16:07:02
Hmm...well could it have something to do with the keyboard press sensitivity? The script calculates how long the key is pressed down, maybe different keyboards have different sensitivities and that's what's causing the turn-timing issuea on different computers?

Ill get a clip on youtube to show what's happening.

I don't think should affect it, I can run it on my computer and slow lap old lappy if you want to see if I have that problem.
Either way thats wierd.

Monsieur OUXX

#9
Why are there two "iHoldKeyPressLeft++;", the first one ebing conditional, and the second one occurring all the time?
at the moment I'm searching for a flaw in your timing design, but I can't put my finger on it: You seem to make both angle increments and timer increment rely on the frame being rendered, so it should be correct.
I do believe that when the framerate drops, AGS skips not only the rendering of the slow frame, but also the execution of the associated script. I hope I'm right.


EDIT: I think I might have an explanation :
- Consider that when the framerate drops to 35, a timer of 15 to 20 frames is equivalent to almost one half second (500ms).
- A half second is a rather huge time gap, and is more than enough to confuse the player (if he sees the car at a certain angle, and stops pressing the key, but the script still locks down the key for 500ms, and makes the car turn further).

You have 2 solutions :
- Either you reduce the timer's interval to check the car's state more often (but still update the sprite only once in a while, when needed)
- Or you should redesign the script in order to make it check that the car has reached the target angle rather than checking that the timer has expired. The timer expiration should be used only to match the current angle to the time elapsed, and THEN the sprite should be based on the actual angle. That second solution needs more thinking.
 

Knox

Man, I see! Ok I'll try both solutions and post what happens...it makes sense, very clever!
Thanks :)
--All that is necessary for evil to triumph is for good men to do nothing.

SMF spam blocked by CleanTalk