[SOLVED] Creating Cutscene in middle of Look-At function

Started by tobulos1, Sat 04/04/2015 13:30:19

Previous topic - Next topic

tobulos1

I'm trying to create a cutscene for my game. If I'm not mistaken, you create cutscenes with the help of additional rooms? Well, suppose I want to change to a cutscene in the middle of a "Look-At" command, like this:

Code: ags
//Original room
    if(UsedAction(eGA_LookAt)) {
    player.Say("Text, text, text");
    cCharacter.ChangeRoom(61, -100, -100);
    player.Say("More text!");
  }


The cutscene's purpose: to create a sort of "Five minutes later" screen after the player has used "Look-At" on an object. After the scene is finished however, the character will continue speaking. Like this, for instance:


  • Character: Wow, look at that sky, I wonder if...
  • *Switch to cutscene room*
  • Text displayed in the center of the screen: Five minutes later
  • *Switch back to original room*
  • Character: But after some thought, that wouldn't work.
However, when I execute and run the command in my game, my character will speak his lines all through and then at the end of it, it'll change the room. As if I had written the function like this (which I don't want):

Code: ags
//Original room
    if(UsedAction(eGA_LookAt)) {
    player.Say("Text, text, text");
    player.Say("More text!");
    cCharacter.ChangeRoom(61, -100, -100);
  }


The code inside the cutscene room looks like this:

Code: ags
// Cutscene room
function room_AfterFadeIn()
{
  Overlay *textOverlay;
  textOverlay = Overlay.CreateTextual(160, 160, 100, Game.NormalFont, 7, "Five minutes later...");
  Wait(50);
  cCharacter.ChangeRoom(1);
}


So, my question is: How can I make a cutscene in the middle of a "Look-At" function and after it's done playing, resume the character's actions/dialogue?

P.S. How can I make the text "Five minutes later..." centered on the screen? Is there a fast way to do it without calculating the X and Y co-ordinates?

Thanks!

Haggis

Someone might word this better than me but first let's deal with your problem:

My assumption is that you want the player to do this - player.Say("More text!"); - after the cutscene has happened. All code within a function, even after a 'changeroom' event, will be completed before the room changes - which is why you're seeing all the dialog in one chunk before the cutscene. To do what you want to do you need to catch the player returning to the Original room (most likely in the room after fade in function) after the cutscene has been shown. You can use 'if (cPlayer.previousRoom == x)' to perform the check.

In terms of cutscenes:

A cutscene doesn't necessarily need to make use of other rooms (it could take place in one room or across many) - it just represents a section of the game where the player has limited control, usually they sit and watch rather than play. They can also usually be skipped by pressing a certain key. You use the startCutscene / EndCutscene commands for this.


Gurok

What Haggis said, but let me lay it out with examples for you:

Code: ags
// Original Room
function oSomeObject_Interact()
{
    if(UsedAction(eGA_LookAt))
    {
        player.Say("Text, text, text");
        cCharacter.ChangeRoom(61, -100, -100);
    }
}

function room_AfterFadeIn()
{
    if(player.PreviousRoom == rCutsceneRoom) // Fill in your own cutscene room number here
        player.Say("More text!");
}


Code: ags
// Cutscene Room

function room_AfterFadeIn()
{
    Overlay *textOverlay;
    textOverlay = Overlay.CreateTextual(160, 160, 100, Game.NormalFont, 7, "Five minutes later...");
    Wait(50);
    cCharacter.ChangeRoom(1);
}


Regarding centring the overlay, you can use GetTextWidth() to create your own centred overlay function:

Code: ags
Overlay *CreateCentredTextualOverlay(FontType font, int colour, String caption)
{
    int textHeight;
    int textWidth;

    textWidth = GetTextWidth(caption, font);
    if(textWidth > System.ViewportWidth)
        textWidth = System.ViewportWidth;
    textHeight = GetTextHeight(caption, font, textWidth + 1); // There's a known quirk with getting the height of text

    return(Overlay.CreateTextual((System.ViewportWidth - textWidth) / 2, (System.ViewportHeight - textHeight) / 2, textWidth, font, colour, caption));
}
[img]http://7d4iqnx.gif;rWRLUuw.gi

tobulos1

#3
Hi, thanks for the replies!

Unfortunately, I've come no closer to the solution yet...

I tried with the "StartCutscene"/"EndCutscene", but I'm not sure there to place them? Are they supposed to be placed inside the Original room or the Cutscene room?

Also, I tried with the "room_AfterFadeIn()", but it didn't work too well. I tried this:

Code: ags
////HOTSPOT SKY////
function hSky_AnyClick()
{
  player.FaceDirection(eDir_Up);
  // PICK UP
  if(UsedAction(eGA_PickUp)) {
    player.Say("Hm. It should be possible to build a... hm...");
    cHector.ChangeRoom(61, -100, -100);
  }
  else Unhandled();
}

function room_AfterFadeIn()
    {
    if(player.PreviousRoom == 61)
        player.Say("And I could call it a sky rocket!");
        Wait(30);
        player.Say("Naah, who am I kidding? That would never work.");
    }


This didn't do anything besides saying the first line (using Pick-Up), switching to the cutscene room and then switching back again without my character saying the rest of his lines.
Also, my character seems to appear standing somewhere else when he's switching back to the original room. For instance, he's standing to the right of the screen when he uses "Pick-Up Sky", then when the cutscene is over, he's standing to the very far left. How do I make him appear on the exact same spot as before the cutscene?

Oh, and this didn't seem to work:
Code: ags
Overlay *CreateCentredTextualOverlay(FontType font, int colour, String caption)
{
    int textHeight;
    int textWidth;
 
    textWidth = GetTextWidth(caption, font);
    if(textWidth > System.ViewportWidth)
        textWidth = System.ViewportWidth;
    textHeight = GetTextHeight(caption, font, textWidth + 1); // There's a known quirk with getting the height of text
 
    return(Overlay.CreateTextual((System.ViewportWidth - textWidth) / 2, (System.ViewportHeight - textHeight) / 2, textWidth, font, colour, caption));
}

I'm not sure if I did it wrong... Do I just copy the whole thing just as it is?

Haggis

#4
Ok - first up, not to be disrespectful but this probably belongs in the other technical forum so someone should probably move it at some point.

I'll try to help with the ChangeRoom stuff (I'm not a proper programmer):

Quotemy character seems to appear standing somewhere else when he's switching back to the original room

This is because the characters position in the room is not remembered - the player has one x,y attribute and they apply to all rooms. When you change to room 61 you are changing the x,y to -100 and -100 so when you change the player back to the original room he will be placed at the coordinates you pass in the next ChangeRoom function. To resolve this you could create temporary x/y values in the original room, store them before the player changes room so they = the location you want him to be when he comes back, then use them in the 'beforeFadeIn' to position the character back where he was. You may also have to select the correct loop depending on whether the character does anything in the cutscene room.

e.g.

Code: ags

//ORIGINAL ROOM

int returnX;
int returnY;

////HOTSPOT SKY////
function hSky_AnyClick()
{
  player.FaceDirection(eDir_Up);
  // PICK UP
  if(UsedAction(eGA_PickUp)) {
    player.Say("Hm. It should be possible to build a... hm...");
  returnX = cPlayer.x; //or cHector
  returnY = cPlayer.y; //or cHector
    cHector.ChangeRoom(61, -100, -100);
  }
  else Unhandled();
}

//ROOM LOAD
function room_Load()
{
  cPlayer.x = returnX; //or cHector
  cPlayer.y = returnY; //or cHector
}


Alternatively you work out what the players x/y coordinates are before they changeRoom and then use them when using changeRoom to return to the original room.

QuoteAlso, I tried with the "room_AfterFadeIn()", but it didn't work too well. I tried this:

OK, is cHector the player? Try:
Code: ags
if(cHector.PreviousRoom == 61)



EDIT - oh and with regards:
QuoteI tried with the "StartCutscene"/"EndCutscene", but I'm not sure there to place them? Are they supposed to be placed inside the Original room or the Cutscene room?

It's up to you but you usually have them at the start of the cutscene and then at the very end (before the player takes control again / has to answer dialog / or is about to say something that shouldn't be skippable). Example below:
Code: ags
////HOTSPOT SKY////
function hSky_AnyClick()
{
  player.FaceDirection(eDir_Up);
  // PICK UP
  if(UsedAction(eGA_PickUp)) {
    StartCutscene(eSkipESCOnly);
    player.Say("Hm. It should be possible to build a... hm...");
    cHector.ChangeRoom(61, -100, -100);
  }
  else Unhandled();
}
 
function room_AfterFadeIn()
    {
    if(player.PreviousRoom == 61)
        player.Say("And I could call it a sky rocket!");
        Wait(30);
        player.Say("Naah, who am I kidding? That would never work.");
        EndCutscene();
    }



EDIT 2 - I note the player is interacting with the Sky - is this game about Jimi Hendrix?

tobulos1

#5
Okay, so after a lot of trial and error, I've fixed:

  • The positioning problem with the text (by some guessing).
  • The character positioning.
  • The "Start/EndCutscene". I had to put it inside the Cutscene room (look below) for it to work properly...
This is how the script looks in the Cutscene room at the moment, and everything works fine in there:

Code: ags
// Cutscene room 
function room_AfterFadeIn()
{
  StartCutscene(eSkipESCOrRightButton);
  Overlay* myOverlay = Overlay.CreateTextual(190,120,350, Game.SpeechFont, 15,"Five minutes later...");
  Game.TextReadingSpeed = 3;
  player.Say("Bla bla bla");
  cHector.ChangeRoom(1, 113, 289);
  gMaingui.Visible = true;
  gAction.Visible = true;
  EndCutscene();
}


So the only problem that persists now is that the character should continue speaking after the room switches back. I have tried every possible solution I can think of, and the ones you've posted here as well, but no dice.

This is the script:

Code: ags
//Original room script file
////HOTSPOT SKY////
function hSky_AnyClick()
{
  // PICK UP
   if(UsedAction(eGA_PickUp)) {
    player.Walk(113, 289, eBlock, eWalkableAreas);
    player.FaceDirection(eDir_Up);
    player.Say("Hm. It should be possible to build a... hm...");
    gAction.Visible = false;
    gMaingui.Visible = false;
    cHector.ChangeRoom(61, 113, 289);
  }
  else Unhandled();
}

// Room after fade in
function room_AfterFadeIn()
    {
    if(player.PreviousRoom == 61)
        player.Say("And I could call it a sky rocket!");
        Wait(30);
        player.Say("Naah, who am I kidding? That would never work.");
    }


I've tried with function room_FirstLoad() and also removing the if(player.PreviousRoom == 61), thinking it caused some sort of problem, but to no avail yet...
And no, the game is not about Jimi Hendrix, haha.

Haggis

Good to see we're making some progress.

QuoteSo the only problem that persists now is that the character should continue speaking after the room switches back. I have tried every possible solution I can think of, and the ones you've posted here as well, but no dice.

Just to confirm, did you try this instead?
Code: ags
if(cHector.PreviousRoom == 61)


Also maybe add
Code: ags
Display("Player was in room 61");

to this so we can see if this statement is coming back as true and being run.

tobulos1

Hi!
I've tried with both if(cHector.PreviousRoom == 61) and if(player.PreviousRoom == 61), but none have worked thus far.
Also, it doesn't even display the message, so the statement doesn't come back as true.

Haggis

ok, in the room_afterfadein add an else statement to display another message e.g. Player was not in room 61 and see if that displays.

Also - just to make sure, the cutscene room number is 61 (i.e. hector is the player character)?

Once the cutscene has finished, missing dialog aside, does the game play on as normal without issue e.g player can walk, talk, interact as normal?

tobulos1

#9
Tried this:
Code: ags
function room_AfterFadeIn()
{
  if(player.PreviousRoom == 61)
  {
    Display("Player was in room 61");
    player.Say("And I could call it a sky rocket!");
    Wait(30);
    player.Say("Naah, who am I kidding? That would never work.");
  }    
  else
  {
    Display("Player was not in room 61");
  }
}


But didn't work either. The cutscene room is 61 because I wanted to leave some space to the "real" rooms, so to speak. The playable character's name is Hector, so everything seems to be fine on that end. And yes, everything else works fine. After the cutscene, I can still walk, talk, and even do the cutscene again.

Gurok

tobulos1, try displaying the value of previous room:

Code: ags
    function room_AfterFadeIn()
    {
      Display("Player's previous room was %d", player.PreviousRoom);
      if(player.PreviousRoom == 61)
      {
        player.Say("And I could call it a sky rocket!");
        Wait(30);
        player.Say("Naah, who am I kidding? That would never work.");
      }    
    }


Also, if you want to use CreateCentredTextualOverlay, paste the code for it somewhere near the top of your global script and change

Code: ags
Overlay.CreateTextual(190,120,350, Game.SpeechFont, 15,"Five minutes later...");


to

Code: ags
CreateCentredTextualOverlay(Game.SpeechFont, 15, "Five minutes later...");


If you're happy with the manually positioned overlay, then just ignore this.
[img]http://7d4iqnx.gif;rWRLUuw.gi

Haggis

Second everything that Gurok suggested.

It sounds like the room_afterfadein function in room 1 isn't actually being run.

Apologies if this sounds basic but best to check every avenue - in room 1, did you create 'room_afterfadein' by copying and pasting the script from another room or did you create it through the 'edit room > events pane'?

tobulos1

Oh my gosh... it just is the simplest of things, isn't it?

Quote from: Haggis on Sun 05/04/2015 15:47:00best to check every avenue - in room 1, did you create 'room_afterfadein' by copying and pasting the script from another room or did you create it through the 'edit room > events pane'?

Everything works perfectly fine now, thank you guys. I guess spending too much time in front of this editor makes you miss the most obvious things :-\

Haggis

I'm sure everyone must have done this at least once when starting out - I know I spent a good amount of time investigating it myself before I realised the simplicity of the fix.

SMF spam blocked by CleanTalk