Making a more efficient "world map"

Started by Ghost, Thu 18/07/2013 19:25:49

Previous topic - Next topic

Ghost

I have recently finished a rather elaborate "world map" for a GiP, and while it works the way I want it to work, it includes two designer sins- code being distributed over several scripts, and quite a bit of repetitive code. Maybe someone has a better idea, or some general pointers- I can script alright but sometimes I have a hard time finding an efficient (but more obscure) solution  :)

First things first, the player aquires a map that can be used to fast-travel between locations. The map is initially almost empty but fills up during the game when new locations are pointed out by other characters.

Locations are represented by graphics that overlay the world map's "city grid". I am using objects placed within the worldmap room. Since these graphics are of irregular shape and often overlap, I am not using them for mouse click detection.
Instead I have a separate GUI with small "marker" buttons, small enough to never overlap. There is one button corresponding to one map "spot" object. I even created them in the same order, so that button[1] is the marker for object[1].

To unlock map locations, I wrote a function in GlobalScript and imported it so that its accessible from anywhere in the game. There is also a matching "lock" function. I included an enum with entries for all map locations which I pass as a parameter to make the code more readable:

Code: AGS

function UnlockMapSpot(MapSpots ms)
{
  if (ms == eMsLemonadeFactory) 		
  { 
    gvMapSpot01Unlocked = true; 
  }
  ...
}


And here is where I am sure that things could be done more efficiently. Since you can only acess objects by name while in their room script file, I use global variables to keep track of everything, and that means I have the map room process a lot of stuff each time it is entered.

The "unlock function" only sets the global variable.
The worldmap room script checks the global variables, and makes objects and buttons visible according to that global variable's state.

This all works. It's not even too complicated, and the constant updates are necessary, too, because map spots can also vanish from the map. Still, I think there should be an easier way.
Any ideas?

Crimson Wizard

Well, I would use same general method, actually: set the room "config" in global script and update room state at room load.

However, I suggest use an array(s) instead of separate variables. Since you already have locations enumerated, you can use their enum constants as array indices:

Code: ags

function UnlockMapSpot(MapSpots ms)
{
   MapSpotsUnlocked[ms] = true;
}


Go in this direction, and this would greatly simplify things.

Ghost

#2
See, that's what I mean. Array, of course! Cleaned up things a lot already, thanks!

Still three places where map-related code is stored, though. Is there no workaround to getting an object reference from a script outside the room script?

Scarab

If you use

Code: AGS
object[ID].SetPosition(x ,y); // or any other object function

//or

if(Object.GetAtScreenXY(mouse.x, mouse.y) == object[ID])


It uses the object of that ID number in whatever room you're currently in, no matter what script it's put in.

Crimson Wizard

Quote from: Scarab on Fri 19/07/2013 10:03:26
Code: ags

object[ID].SetPosition(x ,y); // or any other object function


It uses the object of that ID number in whatever room you're currently in, no matter what script it's put in.
Right... just make sure this function never called from different room.
Just saying :)

Ghost

Quote from: Scarab on Fri 19/07/2013 10:03:26
Code: AGS
object[ID].SetPosition(x ,y); // or any other object function
It uses the object of that ID number in whatever room you're currently in, no matter what script it's put in.
[/quote]

I'd like to avoid that. As CW said there is a lot of potential for errors there. Object names would be preferred. Still, with the array in place the whole thing is a good deal tidier. If that's all that can be done I won't complain!

SMF spam blocked by CleanTalk