# Sorting Game Tiles

I have an app the is a tile game. Tiles are placed in layers (1 to 5) as well as rows and columns… giving it a 3D effect. The problem is tiles can be placed on 50% boundarys… like this

Before the board is displayed the tiles are sorted (note the number on each one).
They are sorted first by their column (left to right), then by row (top to bottom)
The idea being that when they are drawn in the proper order, the edges are obscured by the tile to the right and/or below (like the 2nd set in the example)

Obviously there needs to be another/better way to order the tiles before drawing them

I think the first set really should be ordered 0,3,6,2,5,4
but the fact that those rows start offset is the problem

Any ideas?

note : this example is ONE layer only… but each layer would have the same sort rules “within” the layer

If it is one layer then 2,5,4 need to be drawn completely at the top.

At the moment you have an Escher-like effect …

… and different layers could be emphasised with different saturation levels.

if you sort by top, then left
and then draw those with the lowest top (0,3,6), next larger (2,5), then largest (4)
then 2,5 will overlay 0,3,6
and 4 will overlay 2,5

I have code to do this in one sorting pass

basically construct an int64 out of top left then sort those int 64’s
assuming your list of tilesis in an array named tiles

``````dim mb as new memoryblock(8)
dim sortvalues() as int64
for i as integer = 0 to tiles.ubound

mb.Int32Value(0) = tiles.top
mb.int32Value(4) = tiles.left

sortvalues.append mb.Int64Value(0)
next

sortvalues.sortwith tiles
``````

tiles will now be sorted by top, left

you get the idea

As Norm says, they ‘just’ need sorting top, then left with groups of top.

In SQL parlance, order by top asc, left asc
so you get all the row ones, left to right, then all the row twos, left to right, and so on.

So each tile has 3 values, LAYER, XPOS and YPOS
Currenlty sorted by LAYER, YPOS, XPOS
which is exactly what Norman proposed… my code is more brute force, a bubble sort, but speed isn’t an issue… and not XPOS and YPOS are DOUBLE (1.0, 1.5, 2.0, 2.5 etc)

``````var swap : Bool
if currentLayout.tiles.count>2 {
for i in (0...currentLayout.tiles.count-2) {
for j in (i+1...currentLayout.tiles.count-1) {
swap = false
let ci = currentLayout.tiles[i]
let cj = currentLayout.tiles[j]
if cj.layer<ci.layer { swap = true }
if swap==false && ci.layer==cj.layer && ceil(ci.Xpos)>ceil(cj.Xpos) {swap=true }
if swap==false && ci.layer==cj.layer && ci.Xpos==cj.Xpos && ceil(ci.Ypos)>ceil(cj.Ypos) {swap=true }
if swap {
(currentLayout.tiles[i],currentLayout.tiles[j])=(currentLayout.tiles[j],currentLayout.tiles[i])
}
}
}

``````

Looking at your image, I would say that is not correct.

You should first draw the top row (so 0,3,6,7,9,15) then the next one (2,5,8,10,16), etc. That would result in the correct image, and that would actually be what you would get if you sorted by layer, ypos, xpos, but you seem to be sorting by layer, xpos, ypos right now.

Julen

+1
its drawing layer first then everything in xpos order, sub sorted by ypos
If you give everything a string attribute of

||

eg
“1.0|1.5|3.0”

And sort ascending by that attribute, you will get the sequence you need.

LOL… I KNOW the image is not correct… what I am trying to do is come up with a way to draw the tiles in the correct order so it IS correct

We know.
The image is wrong because the sort order you are using is not the one you say you are using.

You are using Layer, XPOS, YPOS instead of LAYER, YPOS, XPOS

I didn’t (mean to) say the image is not correct.

Why do you need to order them before drawing them? Unless there’s a stupid number of them then most current hardware will brute force a back to front, left to right, top to bottom just on xyz checks alone? It’ll only by X x Y x Z iterations to get all tiles shown.

Trust me it is L, Y , X… just look at the index numbers… but it doesn’t matter, no means of simply sorting the tiles will work…period.

FYI… in this example L=1 for all tiles

I am now trying an experiment to just draw the tiles, and then redraw just the faces of the places errors might have occured/

I think one thing that nobody understood is that these tiles are NOT (nor supposed to be) draw “edge to edge”… the overlap
here is just ONE tile image

there is a max of 144 at a time… they all draw on the same z-plane…
and it isn’t worth the effort to tie anything to a GPU… rather defeats x-plat … since this is going to be on macOS, iOS and tvOS by the time I am done…

But thanks for you responses

Thanks, but I don’t have a version of Xojo that can open that…

It only costs bandwidth What version would you liked it saved in?

no worries… I have a solution that works for me…

but trust me… just sorting DOES NOT WORK… it does for some situations but not for all

Norman and I had a long chat on Discord, and I think he agrees after I showed him numerous situaitons

Drew the top 3 left to right
Then the next 2, left to right
Then the last 1

These are
(1,0) (2,0) (3,0)
(1.5,1) (2.5,1)
(2,2)

I havent given them numbers

I drew all those with ypos = 0 first, from left to right
Then the ypos = 1 , left to right
then the ypos = 2

But if there is some situation where that doesn’t work, maybe sorting won’t help.

1 Like

No, or tile 2 would be drawn before 3 (as an example). Tile 2 has a larger Y, so it should be drawn after 3.

That’s what several of us were trying to tell you