Using keys in dialog doesn't work

Started by geork, Tue 06/10/2009 21:19:01

Previous topic - Next topic

geork

 Sorry if this is a little noobie...
Somehow, when a dialog is going (even when no-one is speaking), the key functions cease to work untill the dialog finishes with a stop command. Is there anyway to be able to switch on key usage in dialogs? (after someone has spoken would probabely be easiest)
   Thanks

discordance

You'd have to move all the key-related functions into repeatedly_execute_always(). In which case they would always work, no matter what else was going on.

monkey0506

Although it might be a bit overboard for just the arrow keys, you may also want to take a look at my KeyPressAlways module. That supports every keycode I could find including Ctrl- and Alt- codes. ;)

geork

 Umm...I've looked up repeatedly_execute_always(), but I have not found it anywhere in the global scripts, and AGS doesn't seem to recognize it as a predefined global script function (well, AGS doesn't recognize it as anything), even though it is in the index.
  where should I look?
    thanks

Wonkyth

That's odd.
I'd suggest that you've made a spelling error in the function name, so that it treats it as a new(non-predefined) function.
Make sure that you've put it as "function repeatedly_execute_always() ", with no CAPS.
That's all I can think of, so I hope that helps.
"But with a ninja on your face, you live longer!"

monkey0506

Quote from: geork on Thu 08/10/2009 20:28:47I have not found it anywhere in the global scripts, and AGS doesn't seem to recognize it as a predefined global script function

Do you mean that you're not finding the function in any of your existing scripts or it isn't being called?

Unless you're already using it, you will have to manually define the rep_ex_always function, such as:

Code: ags
// global script

function repeatedly_execute_always() {
  // do some stuff here
}


You would most likely have to actually type the function yourself. Although it's a built-in function, it's not automatically included in every script (though it will be called when properly declared in any *.asc file, including room script files). ;)

geork

Sorry about the reply time
  Thanks!
  It took me 2 weeks to say it  ;)

monkey0506

Hey, "better late than never", right? :D

So presumably this is now resolved?

geork

 Unfortunately, not quite...
  I got the repeatedly_execute_always function working in the GlobalScript.asc, which is the same as the on_key_press. However, I am confused as to why on_key_press is an undefined token in that global script. here's the code:
Code: ags

function repeatedly_execute_always() {
  on_key_press(eKeyCode eKeyF10){
    if(RoomIsFinis == true){
      RoomIsFinis = false;
    }
    else{
      RoomIsFinis = true;
    }
  }
  on_key_press(eKeyCode eKeyF8){
    if(SoundOn == true){
      SoundOn = false;
      SetVoiceMode(eSpeechTextOnly);
    }
    else{
      SetVoiceMode(eSpeechVoiceAndText);
      SoundOn = true;
    }
  }
}


   I have an incling that this is not the way to do it, but not really on how to go about it
  thanks

Lufia

To define a function, you do it like that:
Code: ags
function myFunction() {
  // code
}


You can then call it from inside another function:
Code: ags
function OtherFunction() {
  myFunction();
  // Something else
}


writing on_key_press(KeyCode eKeyF5) {} has no meaning. To call the on_key_press function from inside another function, you'd do it like that:
Code: ags
function myFunction() {
  on_key_press(eKeyEscape);
}

It will run the on_key_press function with eKeyEscape passed as an argument (i.e. as if you'd pressed the Escape key).

To do what you want in the repeatedly_execute_always function, you need to set up some conditions to check whether a key has been pressed.
Code: ags
function myFunction() {
  if (IsKeyPressed(eKeyEscape)==1) { // if Escape key is pressed
    // Code
  }
}

There could be some issues in proceeding like that, though. repeatedly_execute_always loops 40 times per second, you could end up triggereing some conditions multiple times.

Finally, the error message you get means you tried to call the on_key_press function before it was defined.

monkey0506

In addition to what Lufia said which is absolutely correct, you have other issues to consider with your code geork. "repeatedly_execute_always" is called every single game loop period (note that it may not be called during dialogs (not character speech, rather the display of the dialog options) pending a setting in the General Settings pane :P). By default this would mean that you would be calling on_key_press 40 times every second.

You would just be constantly flipping your variables around and making a huge mess of your game, making your variables/settings unreliable and thereby useless.

The appropriate way of doing this would be to implement something such as:

Code: ags
eKeyCode keyHeld = 0; // the key the player was holding during the last loop

function repeatedly_execute_always() {
  if ((keyHeld) && (IsKeyPressed(keyHeld))) return; // the player is still holding the same key as last loop, abort
  if (IsKeyPressed(eKeyF10)) { // player pressed eKeyF10 since the last loop
    if(RoomIsFinis == true){
      RoomIsFinis = false;
    }
    else{
      RoomIsFinis = true;
    }
    keyHeld = eKeyF10; // store the key the player pressed (and may be holding)
  }
  else if (IsKeyPressed(eKeyF8)) {
    if(SoundOn == true){
      SoundOn = false;
      SetVoiceMode(eSpeechTextOnly);
    }
    else{
      SetVoiceMode(eSpeechVoiceAndText);
      SoundOn = true;
    }
    keyHeld = eKeyF8;
  }
  else keyHeld = 0; // otherwise the player hasn't pressed (and isn't holding) any key
}


Also you should remove these keycodes from on_key_press. If you don't then during non-blocking scenarios (such as just normal gameplay) both rep_ex_always and on_key_press would trigger and it would be as if the player pressed the button twice.

Lufia

if (keyHeld) works event though that's not a boolean? I get 0 = false, 1 = true, all the other possible values would stand for "true" as well?

Related question:
given that this is impossible
Code: ags
function repeatedly_execute_always() {
  Display("Plop!");
}


would this work?
Code: ags
funtion myFunc() {
  Display("Plop!");
}
function repeatedly_execute_always() {
  myFunc();
}

(Basically, where is myFunc queued when I call it from rep_exec_always?)

monkey0506

Quote from: Lufia on Tue 20/10/2009 19:40:50if (keyHeld) works event though that's not a boolean? I get 0 = false, 1 = true, all the other possible values would stand for "true" as well?

When the AGS engine evaluates boolean conditions zero = false, non-zero = true. So yes, any non-zero values (note this includes negative values) would be considered as true. Thereby "if (keyHeld)" is syntactically equivalent to "if (keyHeld != 0)" (in AGS).

Quote from: Lufia on Tue 20/10/2009 19:40:50Related question:
given that this is impossible
Code: ags
function repeatedly_execute_always() {
  Display("Plop!");
}


would this work?
Code: ags
funtion myFunc() {
  Display("Plop!");
}
function repeatedly_execute_always() {
  myFunc();
}

(Basically, where is myFunc queued when I call it from rep_exec_always?)

repeatedly_execute_always cannot under any circumstances call a blocking function, even if that function is further in the call stack than just "inside" of rep_ex_always. By calling Display from myFunc, you are inherently making myFunc a blocking function. So in short, no, that wouldn't work either. If you perhaps wanted a non-blocking Display that could be set up via a GUI and then a function set up to display the GUI with the text. Such a function could be called from rep_ex_always, but the entire function of rep_ex_always must be allowed to complete itself (queued function calls and all) without any blocking functions. ;)

geork

 Thanks!
  Yeah, I have, in the past, worked on java a lot, so the functions scene is a little dissimilar, although now I realize what I was doing was something a bit like:
  "call function(int theInteger)". But the Thanks for helping me out on the trickyer parts. ;)
  It works fine, but still, when I am in dialog (even when no-one is speaking), the key's are still ignored (both F10 and F8).
   Will something more be needed?
   Thanks

monkey0506

Quote from: geork on Tue 20/10/2009 21:12:04It works fine, but still, when I am in dialog (even when no-one is speaking), the key's are still ignored (both F10 and F8).
   Will something more be needed?

Is this what you're referring to?

Quote from: monkey_05_06 on Tue 20/10/2009 19:10:53(note that it may not be called during dialogs (not character speech, rather the display of the dialog options) pending a setting in the General Settings pane :P)

In your General Settings pane make sure that "Run game loops while dialog options are displayed" is set to True and see if that provides the behavior you were expecting.

geork

Thanks, that did it  ;)
  And also thankyou for the functions help ;D

monkey0506

You're definitely welcome. Don't hesitate to ask if there's any other issues you have. We're always more than happy to try and help (especially when you're willing to help yourself, i.e. you talked about reading in the manual and such, posted your own code snippets, etc.) however we can. ;)

SMF spam blocked by CleanTalk