Tilemap segment endless generation [FULLY SOLVED]

Hello every body,

I am trying to implement an endless runner with tilemap segments as suggested by @vigridzki and @britzl in this other thread: Endless Runner - segment generation

I have followed the same setup suggested in the post:

The segment1.collection contains the tilemap from @britzl examples


That tilemap has a tilesource with tiles 64x64 pixels in size (thanks again @sicher for the name of the collection :ok_hand:)

The content of segment.script file

function init(self)
    -- Register segment with the controller
    msg.post("game:/game", "register_segment", { url = msg.url("#collectionfactory"), id = go.get_id() })
end

And in the game.script file I have something like this (simplified version):

function on_message(self, message_id, message, sender)
    if message_id == hash("register_segment") then
        table.insert(self.segments_url, message.url)
        if #self.segments_url == MAX_SEGMENTS then
            self.all_segments_registered = true
            spawn_segment(self)
            spawn_segment(self)
            spawn_segment(self)
        end -- if max segments
    end
end

function spawn_segment(self)
    local xpos = (845 * #self.segments)   -- <--------- POSITION IN PIXELS HERE
    local seg_num = 1
    if math.random() > 0.5 then
        seg_num = 2
    end
    -- spawn tilemap
    local segment = collectionfactory.create(self.segments_url[seg_num], vmath.vector3(xpos, 0, 0), nil, { }, 0.6)
    table.insert(self.segments, segment)
end

But I can not make the segments spawn together seamlessly, first my logical thought made me get the bounds of the tilemap and multiply them by the size of the tilesource tile

local x, y, w, h = tilemap.get_bounds(segment_url)
xpos = (x + w) * 64
print("BOUNDS", x, y, w, h, w * 64, xpos)
-- RESULT:
DEBUG:SCRIPT: BOUNDS	-1	1	22	23	1408	1344

But the result was a big gap between the tilemaps, then I tried to fine tune it by hand and I arrived to the value 845 shown in the code above, but it only works for the first spawn, after that there is always a small gap of varying dimensions:

I think I might missing some property or some configuration some place but I don’t know where.

Any help, observations or suggestions will be greatly appreciated and welcome.

Thanks!

UPDATE:

Ok, so if I remove the code that moves the segment I get rid of the gap:

The position to spawn is tuned by hand,value: 845

So it seems that the gap is produced by the motion of the segment… :thinking:

EDIT:

I added the speed of the segment to the spawning position and the gap is gone!

function spawn_segment(self)
    local last_seg_pos = getLastSegmentPosition()
    xpos = last_seg_pos.x + 845 --<--- SEGMENT SIZE IN PIXELS, TUNED BY HAND
    xpos = xpos - 9 --<--- SEGMENT DISPLACEMENT SPEED
    -- spawn tilemap
    local segment = collectionfactory.create(randomSegmentUrl(), vmath.vector3(xpos, 0, 0), nil, { }, 0.6)
    table.insert(self.segments, segment)
end

No need for Tilemap size in pixels. I guess I’ll have to edit the title of this post.

EDIT 2:
I solved my problem, for now, but what happens if I have segments of different sizes? Why didn’t the tilemap.getbounds.w * tilesource.tile.width returned the displacement in pixels?
(note: ‘tilemap.getbounds.w’ and ‘tilesource.tile.width’ are a simplification, you can’t get the values just like that)

EDIT 3:
Thanks to @Mathias_Westerdahl that pointed me out that the last parameter of the collection factory creation function is scale, which in this case is 0.6.
See Collection factory API documentation
(see @Mathias_Westerdahl full answer below)

The width * tile_size == 1408 is correct.
The reason that you use another number is because you spawn the object with smaller scale, 0.6:

local segment = collectionfactory.create(self.segments_url[seg_num], vmath.vector3(xpos, 0, 0), nil, { }, 0.6)
>>> (22 * 64) * 0.6
844.8

Which is pretty close to 845 :slight_smile:

3 Likes

Ooooooooooooooh… that is why! :upside_down:

Thank you very, very, very much @Mathias_Westerdahl!

Me so dumb :see_no_evil:

1 Like

Nicely caught @Mathias_Westerdahl! The scale could have easily been overlooked.