Script not quite right (on_key_press function) (SOLVED)

Started by Vera, Tue 09/06/2009 09:53:19

Previous topic - Next topic

Vera

I'm having trouble getting one part of my script to run.

This first room is just my title screen room. It scrolls and such like I want it, that part works fine. However, after the initial cutscene ends, I want the player to have to press ENTER in order to continue to the next room where gameplay actually begins and they can control the character and such.

So I believe I need to use the on_key_press function within this room. Unfortunately, since I'm new to this, I seem to be messing up bracket placements and such.  When I try to test the room, I get an error around line 21, which is where the on_key_press function is.

Here's my full script for this room:

Code: ags
// room script file

  
function room_AfterFadeIn()
{
StartCutscene(eSkipESCOnly);
  int ypos = 0;
while (ypos < 120) {
  SetViewport(0, ypos);
  Wait(4);
  ypos = ypos +1;
}
{
EndCutscene();
oTitle.Visible = true;
oPressEnter.Visible = true;
object[1].SetView(3);
object[1].Animate(0,  3, eRepeat);
}

function on_key_press(eKeyCode keycode)
{
  if (keycode == eKeyReturn)
  {
    player.ChangeRoom (2, 130, 120);
    ClaimEvent();
  }
}
}


As I said, the first part of the script works fine; the issue I'm having is with the on_key_press function not running. If anyone can spot my error, it would be a great help.

Thank you.

GuyAwesome

#1
Is the error 'nested functions not supported', or something like that? It looks like you've got a { you don't need, before EndCutscene(), and an extra } at the end - meaning you've put on_key_press inside room_AfterFadeIn, casing the error. Try using Ctrl-B on all the braces to check where they match up, to see what I mean.

Edit, after KhrisMUC:
Ah yes, indentation is another good way to make sure braces match.
But I'd argue the point, and say there's no arguement. That IS the best indentation style. The fact that it's the one I generally use has nothing to do with it, obviously...

Khris

It should look like this:

Code: ags
// room script file

function room_AfterFadeIn() {
  StartCutscene(eSkipESCOnly);
  int ypos = 0;
  while (ypos < 120) {
    SetViewport(0, ypos);
    Wait(4);
    ypos = ypos +1;
  }
  EndCutscene();
  oTitle.Visible = true;
  oPressEnter.Visible = true;
  object[1].SetView(3);
  object[1].Animate(0,  3, eRepeat);
}

function on_key_press(eKeyCode keycode) {
  if (keycode == eKeyReturn) {
    player.ChangeRoom (2, 130, 120);
    ClaimEvent();
  }
}


At least when one uses my indentation style, which is arguably the best :=

Vera

Ah, thank you both. That is much easier to read! The script will run now without errors, however, when I press ENTER to make it take me to the next room, nothing happens. I know I have the right room number (2) because, well... I only have the two rooms!

Is there something else I'm missing...?

Khris

if you add this line:

Code: ags
function on_key_press(eKeyCode keycode) {
  Display("%d", keycode);
  if (keycode == eKeyReturn) {
    player.ChangeRoom (2, 130, 120);
    ClaimEvent();
  }
}

what happens when you press enter?

GuyAwesome

#5
Hmm, it works OK for me... Does it work with any other key than return, and does anything else work in on_key_press? (KhrisMUC's line should help answer this.) If it's a complete no-go, could be that something else (e.g. a GUI Textbox) is intercepting the keystroke.

Trent R

I think the cutscene is intercepting the keystroke, since you have it set to EscOnly.

~Trent
To give back to the AGS community, I can get you free, full versions of commercial software. Recently, Paint Shop Pro X, and eXPert PDF Pro 6. Please PM me for details.


Current Project: The Wanderer
On Hold: Hero of the Rune

GuyAwesome

Oh, yeah. It won't work during the cutscene because - as mentioned recently - cutscenes 'block' on_key_press handling. I didn't think of the two bits of code as related, for some reason  ::) If it's not working outside the cutscene, it may be a problem, though.

Vera

Ok I tested everyone's suggestions, and here are my results:

Putting in Display("%d", keycode); didn't change anything or display anything new. You are all right, it was because of the cutscene interfering. So as a test, I cut out the cutscene, changing my code to this:

Code: ags
// room script file

  
function room_AfterFadeIn() {
  int ypos = 0;
  }

function on_key_press(eKeyCode keycode) {
  if (keycode == eKeyReturn) {
    player.ChangeRoom (2, 130, 120);
    ClaimEvent();
  }
}


That worked. Pressing ENTER took me to room 2. But I wanted all that other stuff that I had inside my cutscene to occur. So I tried putting it all back minus just the startcutscene/endcutscene/esconly bits:

Code: ags
// room script file

  
function room_AfterFadeIn() {
  int ypos = 0;
  while (ypos < 120) {
    SetViewport(0, ypos);
    Wait(4);
    ypos = ypos +1;
  }
  oTitle.Visible = true;
  oPressEnter.Visible = true;
  object[1].SetView(3);
  object[1].Animate(0,  3, eRepeat);
}

function on_key_press(eKeyCode keycode) {
  if (keycode == eKeyReturn) {
    player.ChangeRoom (2, 130, 120);
    ClaimEvent();
  }
}


This did not work. It made the first part work (it scrolls and everything) but pressing ENTER again did nothing.

So do I need to just research Global Variables like in the link GuyAwesome provided, or am I missing something else as well?

Thank you everyone for your responses! It's so close to working!  :)

GuyAwesome

OK slightly off topic, but if you want to show the pan down the room to ypos == 120 why do you also want to be able to change rooms in the middle of it? Might not be important, but might help us come up with some better suggestions. Such as:

It's a bit hacky, but what about
Code: ags

function room_AfterFadeIn()
{
  ypos = 0;
  while (ypos < 60) {
    SetViewport(0, ypos);
    Wait(4);
    if (IsKeyPressed(eKeyReturn)) {
      ypos = 120; // Ends the loop, otherwise the room change is queued until after the pan down
      player.ChangeRoom (2, 130, 120);
    }
    ypos = ypos +1;
  }
  oTitle.Visible = true;
  oPressEnter.Visible = true;
  object[1].SetView(3);
  object[1].Animate(0,  3, eRepeat);
}


It works, but it doesn't really address why the other way didn't work - which might not matter but it WILL bug me...

BTW, I just linked to that topic because it's a generally similar problem, I don't think JpSoft's solution is what you need.

Vera

GuyAwesome: Ah ok, allow me to explain myself a little better.

This will be my Intro/Title room. I have a tall image so that it will scroll. Here is a shot of what it looks like at the very beginning after the room fades in:



Right away, it should begin to scroll downward slowly, as the big red arrow shows, until it reaches a certain point around the treetops below (the bottom of the image).

(During the scroll I would like to eventually add music, but I'll save that for another day.) Here is the image of the point when it stops scrolling:



After a moment, it should display two objects that have so far been hidden. These objects are (1) the image of the game title, and (2) the image of the words "Press Enter" showing the player that they need to hit enter in order to continue to whatever the next room is (eventually the next room will be a newgame/loadgame type thing but I haven't gotten that far yet). Here is that shot:



As you can see in my code posted earlier, I also have the PressEnter object set to animate continuously after it appears.

Now, the actual skippable cutscene should begin after the room fades in, and end at the shot above (screenshot #3). So, if the player skips at anytime after fade-in during the cutscene, it should jump to the shot showing the Title and the Press Enter images (screenshot #3). Then the player can hit enter to continue to this room here:



I wanted it set up this way so it can be like:

ohh pretty landscape view, tra-la-la, and now for the title bum-bum bum, TA-DA!

But if the player has seen all of this before, they can skip it and then hit enter to get on with loading/starting his game (room 2).

-----------------------

I hope this helps to explain my goals a little better; I'm still having trouble getting it to work. Thanks again :)

Trent R

#11
I'm thinking that your Wait(4) for 120 loops may be blocking the keypresses. Try adding this to your room:

Code: ags
function repeatedly_execute_always() {  //the always means that this runs even during blocking events
  if (IsKeyPressed(eKeyReturn)) {
    player.ChangeRoom (2, 130, 120);
  }
}


Not sure, but try it.
[Edit]:Oops, that's what I get from being lazy and copy-pasting.
~Trent
To give back to the AGS community, I can get you free, full versions of commercial software. Recently, Paint Shop Pro X, and eXPert PDF Pro 6. Please PM me for details.


Current Project: The Wanderer
On Hold: Hero of the Rune

GuyAwesome

#12
Trent, you'd have to use IsKeyPressed in repeatedly_execute_always, not keycode. Also, I don't think you can call ChangeRoom from r_e_a - it's classed as a blocking function. I agree that it's the Wait(4)s throwing thing out, though.

Vera:
OK, I think I see now. If the pan is allowed to play out normally the player has to press Enter to continue, but if they skip it you also want to skip that extra step... How about

Code: ags

function room_AfterFadeIn()
{
  StartCutscene(eSkipESCOnly);
  ypos = 0;
  while (ypos < 120) {
    SetViewport(0, ypos);
    Wait(4);
    ypos = ypos +1;
  }
  if (Game.SkippingCutscene) 
    player.ChangeRoom (2, 130, 120);
  EndCutscene();
  oTitle.Visible = true;
  oPressEnter.Visible = true;
  object[1].SetView(3);
  object[1].Animate(0,  3, eRepeat);
}

Vera

Quote from: Trent RI'm thinking that your Wait(4) for 120 loops may be blocking the keypresses. Try adding this to your room:

Code: ags
function repeatedly_execute_always() {  //the always means that this runs even during blocking events
  if (IsKeyPressed(eKeyReturn)) {
    player.ChangeRoom (2, 130, 120);
  }
}



Not sure, but try it.

That gives me the error saying I can't use the change room command within non-blocking events such as the repeatedly_execute_always one.

Quote from: GuyAwesomeVera:
OK, I think I see now. If the pan is allowed to play out normally the player has to press Enter to continue, but if they skip it you also want to skip that extra step...

Sort of. I want the player to have two options:

(A)  To watch the cutscene, waiting until the two objects are shown. THEN press enter once they are shown, moving the player to room 2.

(B)  To skip the cutscene by pressing escape. THEN, since the two objects are now showing, press enter, moving the player to room 2.

Quote from: GuyAwesomeHow about

Code: ags
function room_AfterFadeIn()
{
  StartCutscene(eSkipESCOnly);
  ypos = 0;
  while (ypos < 120) {
    SetViewport(0, ypos);
    Wait(4);
    ypos = ypos +1;
  }
  if (Game.SkippingCutscene) 
    player.ChangeRoom (2, 130, 120);
  EndCutscene();
  oTitle.Visible = true;
  oPressEnter.Visible = true;
  object[1].SetView(3);
  object[1].Animate(0,  3, eRepeat);
}

I tested that, but pressing enter did nothing. It just scrolled down and the objects appeared, as usual, without allowing me to continue to room 2 by pressing enter.

Khris

The original code is perfectly fine, with one exception:
  object[1].Animate(0, 3, eRepeat, eNoBlock);
eBlock is the default, and due to the eRepeat, the game was stuck animating.

GuyAwesome

Quote
I tested that, but pressing enter did nothing. It just scrolled down and the objects appeared, as usual, without allowing me to continue to room 2 by pressing enter.

OK, I'm sure there was more to my post that that... That's what I get for copy/pasting from Notepad when I'm half asleep.
As I MEANT to say :) that code doesn't QUITE do what you're after, but combines 'skipping the cutscene and going to the next room' into one keypress. Let the cutscene play, and you should be able press Enter and move on (see below). Skip the cutscene with Escape, and you go straight to room 2.

Quote
I want the player to have two options:

(A)  To watch the cutscene, waiting until the two objects are shown. THEN press enter once they are shown, moving the player to room 2.

(B)  To skip the cutscene by pressing escape. THEN, since the two objects are now showing, press enter, moving the player to room 2.
This is what it SHOULD do normally - once you've made the change KhrisMUC suggests. Totally spaced on the fact that object animation is blocking by default  :-[ Sorry.

Trent R

Quote from: Vera on Wed 10/06/2009 05:48:22
That gives me the error saying I can't use the change room command within non-blocking events such as the repeatedly_execute_always one.
A-hah. Well, I didn't have the manual in front of me at the time... but Christian has come and save the day.


~Trent
To give back to the AGS community, I can get you free, full versions of commercial software. Recently, Paint Shop Pro X, and eXPert PDF Pro 6. Please PM me for details.


Current Project: The Wanderer
On Hold: Hero of the Rune

Vera

YES! That worked! I put in the eNoBlock and that did it. That you all so much!  ;D

SMF spam blocked by CleanTalk