Displaying text while on region?

Started by SeamanNaranja, Sat 07/06/2014 13:40:20

Previous topic - Next topic

SeamanNaranja

Tried to find an answer for this in the manual and on the forum, but I'm not sure what the best way to do it is. :-\

I'm trying to get text to display while my character is standing on different regions.

  • I am using keyboard only for my game
  • Regions are used as interaction points (example: while standing on a region beside a lamp the player can hit space and interact with it)
I want to display non-blocking text at the bottom of the screen while standing on the region. Something like this:

"SPACE: Interact, 1: Use screw driver, 2: Use gun etc"

Should I use a text window gui? Or something completely different? And how would I integrate it?
Developer of Hjarta, Providence and Skumring.

Khris

In general, the way I found to do this is to
a) draw hotspots on the floor in front of what would conventionally be the hotspot, acting as region
b) use regions for objects, making sure their ID matches; region #1 for object #1, etc.

If you do that, you can use this code:
http://www.adventuregamestudio.co.uk/forums/index.php?topic=44602.msg595707#msg595707
to interact with hotspots and objects.
(Some modifications are necessary to include using inv items, the code reacts to pressing the up arrow key)

As for displaying the message, does it change for the hotspots? Or is always "space: interact"  plus a list of inventory items?

SeamanNaranja

Quote from: Khris on Sat 07/06/2014 14:13:27
In general, the way I found to do this is to
a) draw hotspots on the floor in front of what would conventionally be the hotspot, acting as region
b) use regions for objects, making sure their ID matches; region #1 for object #1, etc.
Since my character moves only along the x-axis (platform style), I just figured I'd use regions for everything. So I set up my regions like this:

Code: ags
function region3_Standing()
{
  if (IsKeyPressed(eKeySpace) == 1){
    if (oDoor1.Transparency == 0){
      cEgo.LockView(26);
      cEgo.Animate(cEgo.Loop, 1, eOnce, eBlock, eForwards);
      oDoor1.TweenTransparency(1.0, 100, eEaseOutTween, eBlockTween);
      cEgo.Animate(cEgo.Loop, 1, eOnce, eBlock, eBackwards);
      cEgo.UnlockView();
    }
    else if (oDoor1.Transparency == 100){
      cEgo.LockView(26);
      cEgo.Animate(cEgo.Loop, 1, eOnce, eBlock, eForwards);
      oDoor1.TweenTransparency(1.0, 0, eEaseOutTween, eBlockTween);
      cEgo.Animate(cEgo.Loop, 1, eOnce, eBlock, eBackwards);
      cEgo.UnlockView();
   }
  }
}


Is this a bad way to solve it?  ???

Quote from: Khris on Sat 07/06/2014 14:13:27
As for displaying the message, does it change for the hotspots? Or is always "space: interact"  plus a list of inventory items?
I'm thinking space for interact always. Currently I'm using down and up for going down or up stairs, but I'm thinking about just using space, since you really can't interact with the stairs, other than walking up or down on them.
So yeah, space: interact, and a list of inventory items!
Developer of Hjarta, Providence and Skumring.

SeamanNaranja

Never mind, I just found out why that is a bad solution:

Quote from: Khris on Mon 10/10/2011 15:31:25
(There is another way; you could use IsKeyPressed() and handle the interaction directly, the only problem is that holding the button even for a short time will trigger the event multiple times.)
I'll change it. :smiley:
So then there's only the problem of text left.
Developer of Hjarta, Providence and Skumring.

Khris

The basic idea is to detect a change in "player is on a region".

Code: ags
bool was_on_region;

function repeatedly_execute() {

  Region *r = Region.GetAtRoomXY(player.x, player.y);
  bool is_on_region = r.ID > 0;
  if (is_on_region && !was_on_region) gText.Visible = true;
  if (!is_on_region && was_on_region) gText.Visible = false;
  was_on_region = is_on_region;
  
  // .. other rep exe code
}

gText is a GUI with blank background and a single label, showing the text.

A comment on the game design, if I may: how about displaying the name of the object instead? The fact that space is used to interact with hotspots is an integral part of the controls; and it won't change during the game. There's really no need to constantly remind the player about the functionality of the game's most used button, imo.

If the inventory is displayed all the time, with each item numbered (which is what I'd do), then the rest of the text is also obsolete.

I'd find it much more logical that the text is dynamic and will show whatever action pressing space will execute ("examine note", "open safe", etc.)

SeamanNaranja

#5
Quote from: Khris on Sat 07/06/2014 16:14:59
gText is a GUI with blank background and a single label, showing the text.
It works like! Thank you! :smiley: I tried using @OVERHOTSPOT@ in the text label, but this is for mouse over. What code can I use here?
Quote from: Khris on Sat 07/06/2014 16:14:59
I'd find it much more logical that the text is dynamic and will show whatever action pressing space will execute ("examine note", "open safe", etc.)
Yeah, I do agree with this. I just wanted to keep the screen completely clean (no inventory visible), but I can see that this is a better solution!

However, this leads to another problem. I have a system where the player walks along the same x-axis wether he is inside a building or not. Every location has both a inside and an outside (like an apartment with a balcony). When you stand by the door region SPACE lets you go inside or outside, depending on where you are. The player does not change position, I just use the cEgo.Baseline (a higher number for outside) and fade exteriors away with the Tween Module.

This causes some of the region to have multiple interactions, wether the player is inside or outside:
Code: ags
function region1_Standing()
{
  if (IsKeyPressed(eKeySpace) == 1){
    if (cEgo.Baseline == 720){
      oFront1.TweenTransparency(1.0, 100, eEaseOutTween, eNoBlockTween);
      cEgo.Baseline = 716;
    }
    else {
      oFront1.TweenTransparency(1.0, 0, eEaseOutTween, eNoBlockTween);
      cEgo.Baseline = 720;
    }
  }
}

How can I get the Text-GUI to understand wether the player is inside or outside?
Developer of Hjarta, Providence and Skumring.

Khris

#6
To set the label text, I'd use the room's on_call function.
In line 7 of the code I posted, do this instead:
Code: ags
  if (is_on_region && !was_on_region) CallRoomScript(r.ID);


You can now add this to the room script:
Code: ags
function on_call(int rid) {
  String action = "";
  if (rid == 1) {
    if (player.Baseline == 716) action = "go outside";
    else action = "go inside";
  }
  if (rid == 2) action = "examine note";
  if (rid == 3) {
    // dynamic text depending on room variable
    if (box_opened) action = "search box";
    else action = "open box";
  }
  ...
  lblAction.Text = action;  // lblAction is the label's script name
  gText.Visible = true;
}


If you put this function near the top, you can call it to update the line: on_call(1);
I'd also use the room's on_key_press to handle pressing space:

Code: ags
function on_key_press(eKeyCode k)
{
  if (k != eKeySpace) return;
  ClaimEvent();
  Region *r = Region.GetAtRoomXY(player.x, player.y);
  
  // region 1
  if (r.ID == 1) {
    if (cEgo.Baseline == 720){
      oFront1.TweenTransparency(1.0, 100, eEaseOutTween, eNoBlockTween);
      cEgo.Baseline = 716;
    }
    else {
      oFront1.TweenTransparency(1.0, 0, eEaseOutTween, eNoBlockTween);
      cEgo.Baseline = 720;
    }
  }

  // region 2
  if (r.ID == 2) {
    ...
  }

  on_call(r.ID);  // update text
}


Edit: code (hopefully) fixed

SeamanNaranja

Quote from: Khris on Sun 08/06/2014 21:38:44
You can now add this to the room script:
Code: ags
function on_call(rid) {
  String action = "";
  if (rid == 1) {
    if (player.Baseline == 716) action = "go outside";
    else action = "go inside";
  }
  if (rid == 2) action = "examine note";
  if (rid == 3) {
    // dynamic text depending on room variable
    if (box_opened) action = "search box";
    else action = "open box";
  }
  ...
  lblAction.Text = lbl;  // lblAction is the label's script name
  gText.Visible = true;
}

If you put this function near the top, you can call it to update the line: on_call(1);

I'm getting a Parse error at function on_call(rid):
Error (line 3): PE3: Parse error at 'rid'
Developer of Hjarta, Providence and Skumring.

Ghost

Quote from: SeamanNaranja on Sun 08/06/2014 21:56:58
I'm getting a Parse error at function on_call(rid):
Error (line 3): PE3: Parse error at 'rid'

use r.ID instead

SeamanNaranja

Quote from: Ghost on Sun 08/06/2014 22:01:28
use r.ID instead
Yeah, I did that, but then I got a parse error at 'r' instead! :confused:
Developer of Hjarta, Providence and Skumring.

Gurok

#10
Quote from: SeamanNaranja on Sun 08/06/2014 22:03:12
Quote from: Ghost on Sun 08/06/2014 22:01:28
use r.ID instead
Yeah, I did that, but then I got a parse error at 'r' instead! :confused:

You can keep using rid, but you need to specify a variable type in the function declaration, e.g.:

Code: ags
function on_call(int rid) {


I believe that's what the compiler is complaining about.
[img]http://7d4iqnx.gif;rWRLUuw.gi

SeamanNaranja

Quote from: Gurok on Sun 08/06/2014 22:04:57
I believe that's what the compiler is complaining about.

You are right! The parse error is gone 8-) However I now get a new error: Undefined symbol 'lbl'. I'm not sure how or where for that matter I should define it.
Developer of Hjarta, Providence and Skumring.

Khris

Sorry, I typed it up using "lbl", then changed it later.
Code: ags
  lblAction.Text = action;

SeamanNaranja

The error is gone, but replaced with another one :confused:
This time the error relates to line 5 in the code under:
Code: ags
function on_key_press(eKeyCode k)
{
  if (k != eKeySpace) return;
  ClaimEvent();
  Region *r == Region.GetAtRoomXY(player.x, player.y);
  
  // region 1
  if (r.ID == 1) {
    if (cEgo.Baseline == 720){
      oFront1.TweenTransparency(1.0, 100, eEaseOutTween, eNoBlockTween);
      cEgo.Baseline = 716;
    }
    else {
      oFront1.TweenTransparency(1.0, 0, eEaseOutTween, eNoBlockTween);
      cEgo.Baseline = 720;
    }
  }
 
  // region 2
  if (r.ID == 2) {
    ...
  }
 
  on_call(r.ID);  // update text
}


Error is: Expected ',' or ';', not '=='
Developer of Hjarta, Providence and Skumring.

Khris


SeamanNaranja

Quote from: Khris on Mon 09/06/2014 00:35:54
Replace "==" with "="

I have to go to bed so I'll try it some more in the morning, but... It seems to work just like I wanted it to! Thanks a lot for the help, you're great! :cheesy:
Developer of Hjarta, Providence and Skumring.

SMF spam blocked by CleanTalk