Ask here your questions to get help using GDevelop.
User avatar
By TristanBacon
#64277 I have a City object, and each one has a text object below with the City Name.
I've got ~20 of these pairs on the map in my game.

When the City is 'captured', (a variable is changed) I'd like to change the City Name text object colour, but I can't figure out how to 'target' the nearby text object to change it.
I've looked into linking objects, but the neither the City objects or City Name text objects are unique, so it affects all of them in the scene.
I also considered the following:
  • Collisions, but text objects don't have collision masks!
  • Pick the Nearest Object - in order to 'capture' a city, a player unit has to be in contact with the city collision mask (about 10 pixels out) and for design reasons, the text object is about 20-30 pixels away from the city object depending on the zoom level


Is it possible to somehow target the closest text object? Or is there an expression that I can use in the Link Two Objects action that I've not found?
User avatar
By TristanBacon
#64278
TristanBacon wrote:Collisions, but text objects don't have collision masks!


Ok, so it turns out that text objects do have collision boxes after all... :lol:

That solves the main problem, but then creates a new problem with the text objects being too close to/overlapping the city object icon, and I can't expand the collision box because that'd mess with my city capture mechanic.

I'll have another play around - perhaps I could make use of multiple collision boxes? I read somewhere that you can create then specify collision boxes in events - is that correct?
By MattLB
#64279
I've looked into linking objects, but the neither the City objects or City Name text objects are unique, so it affects all of them in the scene.


That doesn't matter for linking, but linking would normally be done in events, so you would have a loop in which you create the city object, then create the name text object, then link them. Then create the next city, next text object and so on. That way GDevelop always knows which city instance goes with which text object instance.

If you are manually creating and placing cities and names then GDevelop won't know which to link, so the standard solution here would be to use object variables to link them with a unique ID number i.e. manually give both the city object and the name text object the same value for an object variable called ID.

Then you can use a condition something like
Code: Select allcity.Variable(captured)=1
city.Variable(ID) = name.Variable(ID)
Trigger once

with the action to change the colour of name. This should mean GDevelop knows which instance of name to change the colour of.
User avatar
By TristanBacon
#64281
MattLB wrote:so you would have a loop in which you create the city object, then create the name text object, then link them. Then create the next city, next text object and so on. That way GDevelop always knows which city instance goes with which text object instance.


You know what, it hadn't even crossed my mind to create the cities + names programmatically. However, I don't like the idea of having a global variable structure with ~40 child structures each containing X + Y coordinates, names, and the 11 variables associated with each city.

It's times like these where I'd love to just use a SQLite DB and handle it there in a calm and collected fashion, but that's not possible or practical in this ecosystem, AFAIK (right?). I saw the docs about using JSON, but I'm planning an Android app so can't use it.

the standard solution here would be to use object variables to link them with a unique ID number

I'll give this a whirl and let you know how it goes :D
User avatar
By ddabrahim
#64285 Maybe you don't need to create the cities programmatically but the text objects only.
If the cities on the map are single objects only, It can be an instance of the same object displaying a different animation.
Then, using the for each event you can loop through all the city instances , create the text for each, link the text to each and update the text.

Code: Select allFor each city:
-create text in position city.X(), city.Y() + 20 or something
-link text to city
-do = city.VariableString(name) to text of text


After, to change text color of captured cities just do:
Code: Select allFor each city:
-if city.Variable(captured) = 1 then take in to account text linked to city and change colour of text.
User avatar
By TristanBacon
#64286 [quote="ddabrahim"]
Code: Select allFor each city:
-create text in position city.X(), city.Y() + 20 or something
-link text to city
-do = city.VariableString(name) to text of text


So I implemented your idea, but I don't think I'm using the Linked Objects actions properly:
citylabelissue.png
citylabelissue.png (67 KiB) Viewed 139 times


The Wiki documentation on linking objects is pretty minimal, so I'll take what I learn here and see if I can improve the Wiki page for it

EDIT: In case it wasn't clear, the text object isn't being displayed with that event
Last edited by TristanBacon on Wed 6 Dec 2017, 21:44, edited 1 time in total.
User avatar
By ddabrahim
#64287 For one thing, you are using the Always and At he beginning condition in the same event. I don't know what effect it has as I never tried it but it is two opposite condition. Always means, run it every frame, At the beginning means, run it only the first frame. Both can't be true. It might be the problem.

Also you don't need to take in to account the text object right after you have linked the text. At that point, you should be able to set the name without taking in to account.

Next, make sure you spelling the object names right.

Finally, to change the colour of the text should be checked every time the owner of the city can change. If the owner can change anytime during the game then you must check the owner every frame for each city but ideally whenever the owner change, you need to perform this check.
So it needs to be a separated event and this is where you need to take in to account the text as I have explained before.

EVENT1:
Code: Select allAt the beginning:
   For each city:
     -create text in position city.X(), city.Y() + 20 or something
      -link text to city
      -do = city.VariableString(name) to text of text


EVENT2:
Code: Select allFor each city:
-if city.Variable(captured) = 1 then take in to account all text linked to city and then change colour of text.
User avatar
By Lizard-13
#64288 I made it yesterday but I forgot to share it :roll: , here are some examples to "link" an object and a text label through simple conditions, and an example for the link extension:
(14.45 KiB) Downloaded 2 times
User avatar
By TristanBacon
#64289 Thank you all for your help!

So in the end, I experimented with the different solutions and decided to use @Lizard-13's solution with the linking of the City object and cityMapLabel text object using the City Name as the unique identifier (it'll make adding new cities easier, as using a a unique number ID would've definitely resulted in me losing track and duplicating IDs down the line).

Here's what it looks like in Events:
objectandtextlinking.png
objectandtextlinking.png (41.54 KiB) Viewed 120 times


and here's how it looks in my in-game WIP:
object-text-linking-examples.png
object-text-linking-examples.png (112.22 KiB) Viewed 120 times


Thanks again guys!