I'm making an isometric Sim City-Styled game and I've ran into a couple of problems, both regarding the way objects are overlapping each other in the frame.
First of all, I have two different buildings. When you click on them they become 'selected' (flag is switched on, animation is changed). When you click somewhere else they become 'deselected' and return to their original state.
The problem is when these buildings are overlapping slightly and both buildings are clicked at the point they overlap. They both will become 'selected and everything gets screwed up. I'd like it if it only selected the building on top but I can't seem to come up with a method to do this.
Second problem isn't really a problem... yet, but I need to make it that objects to the back of the isometric grid are layered behind the objects at the front of the isometric grid. Any simple way of doing this?
There is an extension I believe that will help very much, I think it's called Select Object, Sort Object or something.
It can sort actives based on values, X/Y and stuff.
What I would do for the layering issue is run a loop for the amount of buildings, then start with the building at the topleft-most X/Y-pos, bring it to front, and repeat the process working in rows toward the rightbottom-most object. You need to do this loop each time a building is added or otherwise layer-interacted.
For the pick frontmost object problem I'd use the Sort/Select Object and make it pick the object whose bottomY is the greatest, that should pick the object in front.
It shouldn't be,it's perfectly doable without extensions.
A rough example on how to do it; (mind you this is not the most efficient way)
For layering correctly:
I assume there is a grid and for this example I assume that each building's hotspot is in the middle x max y coordinate(down-center). Make an active 1x1 pixels. Each time buildings have interacted in a way that would change the layering order run a loop for the amount of tiles your grid has. Now, have the 1x1 object start at the tile whose Y is the lowest(positioned down-center in the tile so it would overlap a buildings hotspot), make a comparison if a building's hotspot is equal to the 1x1 object's, if so move it to front.
In the next loopstep move the 1x1 object half a tilewidth to the right and half a tileheight down i.e position it at the next tile in the row, do comparison etc.
When the 1x1 object is done with the first row, move it half a tilewidth to the left times the amount of tiles in a row plus one to position it's X for the next row. The object shall also be moved up half a tileheight times the amount of tiles in a row minus one, et voíla, it's ready for the next row.
Rinse and repeat.
For the overlapping issue when clicking:
Use a 1x1 object again, for this example I assume only two buildings can overlap at any given time(you can make it for more though). Have the object positioned at the mouse cursor. Make an event that says something along the lines of "if building is overlapping object + building flag 0 + user clicks = Set flag 0 on, set value A to building Y".
Now, the bruteforce magic of it all, make an exact same event below the previous.
Now you have two buildings with flag 0 on (we'll use flag 0 as "active"), and two Value A holding the buildings' Y values. The building in front will automatically have the higher Y value, so now it's simply a matter of deactivating the building with the lower Y value.
A blunt way of doing it would be to subtract 1 from value A, setting flag 0 off when value A is 0, until only one building has flag 0 on.
These aren't in any way the best ways of doing it, you should use an array and use that to loop through each tile for the layering issue. You could also save height data in each cell and use that to determine if a building is in front of the one above.
Anyways, it's very doable. There was a way before extensions.
Thanks for that, Eternal Man! It's very much appreciated. I think I understand except for one part.
You said to "subtract 1 from value A, setting flag 0 off when value A is 0, until only one building has flag 0 on."
How do I detect when only just 1 of the building's flag is on and prevent the last building's flag from turning off?
It can be done in several ways, but an easy way to fix would be to make another counter named "Flag 0's on" or something
Above the two identical events, make an "always = Set "Flag 0's on" to 0" event.
In the two identical events, stick a "add 1 to "Flag 0's on"" action.
Now, make the subtraction loop repeat only if "Flag 0's on" is greater than 1, and to the "Value A is 0 = Set Flag 0 off" event add a "subtract 1 from "Flag 0's on"" action. That should have the loop subtract until only one building's flag 0 is on.
By the by, everything I've written is from the top of my head, so I can't guarantee that it'll work, but I believe it should. If you encounter any problems with getting the loops right don't hesitate to ask!
Isometric games inherently tend to be a little more complex in getting the basics done right. What is your main concern at the moment?
The main issue is to not give up because of complexity, but rather get an understanding of it bit by bit, that's a good way of progressing your creative skills in this matter.
If you want to though, I could probably whip up an example of what I've said in my replys.
I just did not expect to run into all these problems with layering. I am determined to finish this game! I have been around for a long time but have not really been able to produce anything worth sharing because I always get discouraged when I run into problems I can't seem to fix, like these.
I'm pretty sure it's the fast loop parts I'm messing up. I'm fairly inexperienced when it comes to using these.
If you made me an example file, I would be eternally greatful! That would be awesome. I'd like to get a better understanding of fastloops, they are proving to be quite useful.
MMF processes your events one at a time from top to bottom. After the last event, the screen is updated and the process repeated. If your game is set at 50 frames per second, MMF will loop through your code 50 times each second.
When you call a fast loop, MMF will stop processing your main code and run the fast loop as many times as you told it to. Once the fast loop is complete, MMF will resume your code from the next action after the fast loop was called.
Each iteration of a fast loop can be referenced via the loop index and all loop indexes begin at 0.
I suggest running some experiment fast loops to see for yourself. Good luck comrade!
The "loopindex" is simply a variable that tells you how many times a loop has been run already that frame.
For example, if you want to instantly load a 10x10 tile-based map from an array (with 32x32 size tiles).
+ Start of frame
-> Start fastloop "Load" 100 times -10 rows x 10 columns = 100 tiles
-> Tile: Destroy -This event doesn't run until after the "Load" events have all repeated 100 times
+ On loop "Load" -This event will only run when triggered by a "start fastloop" action
-> Set GridX to LoopIndex("Load") mod 10 -This calculates a column from the loop index
-> Set GridY to LoopIndex("Load") / 10 -This calculates a row from the loop index
-> Tile: Set X position to GridX * 32
-> Tile: Set Y position to GridY * 32
+ On loop "Load"
-> Tile: Set animation frame to ValueAtXY("Array", GridX, GridY)
-> Tile: Add to backdrop
note: If you have several conditions, the "on loop" condition always has to go at the top (it will be highlighted in red).
You've been quite active on both forums this last week compared to usual. It may possibly be all in my head, but it seems you are replying to threads you usually wouldn't, giving more detailed responses and as much as a person can tell from reading short pieces of writing about computer programming from a person they otherwise know nothing about, seeming happier than usual.
Thanks Chris, I think I have a much better understanding of fast loops although I am still struggling to get this to work. I've uploaded my little practice file regardless of how embarrassing as my attempt is... Perhaps you guys can take a look at it