Map Screen question (Solved)

Started by Hobbes, Sat 29/05/2021 06:56:06

Previous topic - Next topic

Hobbes

So... I'm guessing this is a Beginner question, but it might be more advanced to solve it. I'm working on a map screen for my game and would like to do this as a GUI. The main reason being:

1. I have multiple player characters. So a Character.ChangeRoom & Character.ChangeView won't work, since the map screen is in the menubar GUI and might be used by different Characters at any time.
2. With the map screen being in the menubar, it's accessible from any room at any time. So if you're on the map, pressing "Exit"... there's no Character.ChangeRoom(PreviousRoom, previousX,previousY) function that I can see.

Let's say my map looks something like this (it doesn't, but it's not finished yet):



The finished map will have many things on it that, on hovering over them, I'd like its name displayed. It doesn't have to do anything with clicking on it, just hover over, show name.

If the map was in a room, I could easily add hotspots to it. With the gActionBar (I'm using the BASS template) it would then display the names of these hotspots. However, hotspots don't exist in the GUI toolkit that I can see. I've changed the Z order, so the gActionBar is on top of the gMapScreen GUI... so is there an easy way to make things appear on hovering over them? Like, invisible buttons that would trigger gActionBar?

The reason I would like to use invisible buttons (or something similar) is that this map screen will have many, many things. I don't want to use sprites on top of the map, I would like the map to stay as one big fat 320 x 200 sprite. Makes it easy for me to add/change things as the game grows.

Any help/thoughts about this would be greatly, greatly appreciated. Thank you!

(For those of you who played Betrayal at Krondor back in the day, that's exactly the vibe I'm going for. You hover over stuff and the name of the city/forest/river/ocean appears)

Snarky

I've done something like this by placing a button and assigning a sprite to it (so that it doesn't show up with the default gray box), either just transparent or with the graphic that you want to show, e.g. the icon for a town.

You then put the description you want to appear on hover as the Button.Text, and assign an invisible font to Button.Font. There is a TTF one for download here, or you can create a sprite-based font with blanks for each character. (I learned this trick from some module.)

You then just need to add a small bit of logic to the BASS template to ensure that if the map is visible and you're over a map button, gActionBar should show the Button.Text

This is essentially how the tooltips over the buttons in the AGS Awards Ceremony work.

Snarky

Quote from: Hobbes on Sat 29/05/2021 06:56:06there's no Character.ChangeRoom(PreviousRoom, previousX,previousY) function that I can see.

By the way, there is a Character.PreviousRoom property, and since the character would be hidden on this screen anyway, you could just preserve their X and Y position, so it would be possible to do this as a room and have them return to where they were without too much trouble.

Matti

Quote from: Hobbes on Sat 29/05/2021 06:56:06
1. I have multiple player characters. So a Character.ChangeRoom & Character.ChangeView won't work, since the map screen is in the menubar GUI and might be used by different Characters at any time.
2. With the map screen being in the menubar, it's accessible from any room at any time. So if you're on the map, pressing "Exit"... there's no Character.ChangeRoom(PreviousRoom, previousX,previousY) function that I can see.

1. If you use player.ChangeRoom instead of Character.ChangeRoom (which is recommended anyway) it doesn't matter which character is the current player character, same with ChangeView or anything else.

2. There is a Character.PreviousRoom property you can use. And you can easily store the player's coordinates before entering the map, so that shouldn't be a problem. Edit: Also, what Snarky said. If the player is invisible on the map you don't even need to store the coordinates.

I'd say go for using a room as a map.

Hobbes

Quote from: Matti on Sat 29/05/2021 09:48:28
Quote from: Hobbes on Sat 29/05/2021 06:56:06
1. I have multiple player characters. So a Character.ChangeRoom & Character.ChangeView won't work, since the map screen is in the menubar GUI and might be used by different Characters at any time.
2. With the map screen being in the menubar, it's accessible from any room at any time. So if you're on the map, pressing "Exit"... there's no Character.ChangeRoom(PreviousRoom, previousX,previousY) function that I can see.

1. If you use player.ChangeRoom instead of Character.ChangeRoom (which is recommended anyway) it doesn't matter which character is the current player character, same with ChangeView or anything else.

2. There is a Character.PreviousRoom property you can use. And you can easily store the player's coordinates before entering the map, so that shouldn't be a problem. Edit: Also, what Snarky said. If the player is invisible on the map you don't even need to store the coordinates.

I'd say go for using a room as a map.

That's great news, thanks both Snarky and Matti! There's a player.Changeroom, that's great. I tried looking in the ags-help.chm file for that, but couldn't find it... fool on me. :) Is there also a player.PreviousRoom property?

In that case, if they both exist and work (and you're right, leaving the x and y alone), then I just need to make sure I change views... which might be a bit tricky, since the character I'm controlling needs to change to an empty view. However I've got 2 possible characters, so I could change both their views, I suppose...

I could even have the whole room as a walk-behind, then I don't need to bother with changing their views, I imagine?

The option to do it within the GUI as described by Snarky might work as well... I think I'll have a play with both options - thanks again!

Matti

You don't need to change the view to make the character invisible. There's a ShowPlayerCharacter property in the room's properties panel in the editor that you can set to false. Another way would be to set the character's transparency to 100.

Snarky

#6
player is just shorthand for "the Character that is currently the player character" (in technical terms, it's a Character*â€"a Character pointerâ€"that gets reset to point to the new player character whenever you change that via Character.SetAsPlayer()). You can think of it like a company where everybody has a personal email address, but there's also a ceo@company.com email that gets forwarded to whoever holds the position at the moment.

In other words, just like cBob (or whatever you name your character) is a Character, so is player. All Character functions and properties work on player, and if cBob is currently the player character, cBob.Whatever and player.Whatever mean exactly the same thing.

Hobbes

Thank you all for this, it's been a great help. I've been playing around with this and I've got a fully functional map (accessible from the inventory bar). The map is a separate room. I set the player character to be invisible and can now use "hover over" on the hotspots to highlight cities, rivers, mountain ranges, etc.

The only thing I did was modify the GlobalScript to prevent interactions & looking at things:

Code: ags

if (type == 1) // look
    {
      if (player.Room == 14) {
        Wait(0);
      }
      else {
      player.Say("It looks as expected.");
      }


This way, when the player's in Room 14, the Unhandled Event for looking doesn't run. Yet it runs in every other room. I've also done this with the Interact unhandled event. That way, the gActionBar works as expected. I've set the gInventoryBar to 100 transparancy (since it's insistent on popping up and I don't want it on the map screen.

Since the character's set to invisible, can't move, doesn't trigger interactions, I use player.ChangeRoom(player.PreviousRoom); to go back when I press Exit. And the x and y coordinates work. I've tested with both my main characters and it works a treat.

Not sure if this is the "cleanest" way, but hey... it works!  :)

Thank you all!!!

Matti

You can shorten the bit you changed in the GlobalScript:

Code: ags

if (type == 1) // look
{
  if (player.Room != 14) {
    player.Say("It looks as expected.");
  }
}

Crimson Wizard

Note that calling "Wait(0)" does not make much sense and will throw an error.

Khris

Add this to your map room's script (doesn't need to be linked):

Code: ags
function on_mouse_click(MouseButton button) {
  if (mouse.Mode == eModeLookat) {
    ClaimEvent(); // prevent global script's on_mouse_click from running
  }
}


That's the "cleaner" way :)

Hobbes

Again, I just wanted to say: Thank you all! I moved Khris' suggestion into the room script (the less I touch the GlobalScript the better I feel, since then the map-exclusive behaviour is only loaded for the map, which makes sense) and it works a treat. And here's me thinking that Wait(0) was clever.  ;)

Khris

I just noticed that depending on your interface you might want to also make sure that  button == eMouseLeft

SMF spam blocked by CleanTalk