Addwallsprites do not follow the sprites location

Mac latest SDK

I have added wallsprites to my tilemap and I can see the collision boxes appear but if I move to my sprite the collision box doesn’t follow (it’s also always wider - the full width)

If I manually update the x, y for wall sprites this moves it but as more floor position is dynamic that doesn’t help long term.

I assumed the wall sprites would be couple to the shape and location of the tilesprite.


    -- setup floor map 
    floorTable = gfx.imagetable.new("images/floor")    
    floorMap = gfx.tilemap.new()
    floorMap:setImageTable(floorTable)
    floorMap:setSize(20,1)
    
    for x = 1,20 do
        floorMap:setTileAtPosition(x,1,1)
    end
      
    -- add floor to sprite
    
    floorSprite = gfx.sprite.new(floorMap)
   -- dont want to and no idea why I need manually moving wallsprite to match floorsprite but also no idea about width ?
    gfx.sprite.addWallSprites(floorMap, {}, 0,150)
    -- need tp update wallSprites position
    
    floorSprite:moveTo(0,150)
    floorSprite:add()

Oh I have just thought as I want this to be the ground and a tile map would generally cover the whole screen the Addwallsprites would be the whole tile map from 0,0 so I need to set a lot of IDs as passable - … so probably the short cut addWallSprites is the wrong thing to use With making this type of floor/ map ?

Although I do want to use a tile map to be able to draw the floor and caves - I still think hmmm

hmm I thought maybe its because I am not using map:draw - as the single file example doesnt put the map into a sprite but previously the map doesnt render if I dont put it into a sprite but this made no difference

    
    floorTable = gfx.imagetable.new("images/floor")    
    floorMap = gfx.tilemap.new()
    floorMap:setImageTable(floorTable)
    floorMap:setSize(20,1)
    floorMap:draw(0,150)
   
    for x = 1,20 do
        floorMap:setTileAtPosition(x,1,1)
        
    end
    floorSprite = gfx.sprite.new(floorMap)
    floorSprite:moveTo(0,150)
    gfx.sprite.addWallSprites(floorMap, {})  

    floorSprite:add()

Just popping link to whole code as FYI

chnged this line

gfx.sprite.addWallSprites(floorMap, {})

to this

floorSprite:setCollideRect( 0, 0, floorSprite:getSize() )

works as expected now - no idea why addWallSprites was considered wrong the docs seems to suggest it would short cut stuff...hmm

video

1 Like

You definitely reached the right conclusion, adding a collision rect to your floor sprite makes more sense here than trying to use gfx.sprite.addWallSprites(). The wall sprites convenience function is generally useful if you have a large tilemap with areas that you want to be consolidated into “walls” to save on the number of sprites and collision rects you must create. In the Level 1-1 example, for instance, this allows us to create sprites representing large unbreakable brick areas rather than adding a collision rect to each brick.

The function returns an array of the new sprites it has created, so in this case since you already have a floor sprite you’d be creating an additional sprite for no reason.

The reason you needed to set the offset is because addWallSprites() by default assumes the tilemap it’s being passed should start at (0, 0) - it doesn’t know anything about the floor sprite you have already created.

As a reminder, you can view the source for the CoreLibs functions such as addWallSprites, (which lives in CoreLibs/sprites.lua) just to dispel the notion that there is anything magic going on behind the scenes :slight_smile:

function spritelib.addWallSprites(tilemap, emptyIDs, xOffset, yOffset)

	xOffset = xOffset or 0
	yOffset = yOffset or 0

	local tileWidth, tileHeight = tilemap:getSize()
	local pixelsWide, pixelsHigh = tilemap:getPixelSize()
	local tileWidthInPixels = pixelsWide / tileWidth
	local tileHeightInPixels = pixelsHigh / tileHeight

	local collisionRects = tilemap:getCollisionRects((emptyIDs or {}))
	local wallSprites = {}

	for i = 1, #collisionRects do
		
		local r = collisionRects[i]
		
		-- Create an invisible sprite (no image or update()) to be used by the collision system
	
		local x = r.x * tileWidthInPixels
		local y = r.y * tileHeightInPixels		
		local w = r.width * tileWidthInPixels
		local h = r.height * tileHeightInPixels
	
		local sprite = spritelib.new()
		sprite:setBounds(x+xOffset, y+yOffset, w, h)
		sprite:setCollideRect(0, 0, w, h)
		sprite:setUpdatesEnabled(false)
		sprite:setVisible(false)
		sprite:add()
	
		wallSprites[i] = sprite
	end

	return wallSprites
end
2 Likes