Animating tiles with STI

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
sawurora
Prole
Posts: 2
Joined: Mon Sep 26, 2022 6:13 am

Animating tiles with STI

Post by sawurora »

Hello! So, I am creating a game, and I've been trying to animate water with STI and Tiled, I tried many ways to do so and the closest I've ever gotten (I guess) is with the setLayerTile function:

Code: Select all

function map:update(dt)
    self.waterTimer = self.waterTimer + dt
    if self.waterTimer >= self.waterDuration then
        self.waterTimer = 0
        -- animate water tiles
        for i, tile in pairs(self.waterTiles) do
            if tile.gid == self.waterLastGID then
                local gid = self.waterFirstGID
            else
                local gid = tile.gid + 1
            end
             
            local x, y = self.currentMap:convertPixelToTile(self:getTilePixelPosition(tile))
            print(x, y)
            self.currentMap:setLayerTile("water", x, y, gid)
        end
    end
end

function map:getTilePixelPosition(tile)
    local x = self.currentMap.tilewidth * (tile.gid)
    local y = self.currentMap.tileheight * math.floor((tile.gid) / self.currentMap.tilesets[5].columns)
    return x, y
end
And the tiles never actually get changed. What am I doing wrong?
Attachments
vivioleta.love
(2.66 MiB) Downloaded 52 times
User avatar
darkfrei
Party member
Posts: 1169
Joined: Sat Feb 08, 2020 11:09 pm

Re: Animating tiles with STI

Post by darkfrei »

The basic animation code:

Code: Select all

function love.load()
	FrameDuration = 0.3
	FrameTimer = 0
	FrameIndex = 1
	Frames = {
		love.graphics.newImage("frame-1.png"),
		love.graphics.newImage("frame-2.png"),
		love.graphics.newImage("frame-3.png"),
		love.graphics.newImage("frame-2.png"),
	}
	FrameEnabled = Frames[FrameIndex]
end

 
function love.update(dt)
	FrameTimer = FrameTimer + dt
	if FrameTimer >= FrameDuration then
		FrameTimer = 0
		FrameIndex = FrameIndex + 1
		if FrameIndex > #Frames then FrameIndex = 1 end
		FrameEnabled = Frames[FrameIndex]
	end
end


function love.draw()
	love.graphics.draw (FrameEnabled)
end
How you want to use the array image / layers in it?
https://love2d.org/wiki/love.graphics.newArrayImage
https://love2d.org/wiki/love.graphics.drawLayer
Attachments
tile-animation-1.love
(7.11 KiB) Downloaded 57 times
:awesome: in Lua we Löve
:awesome: Platformer Guide
:awesome: freebies
User avatar
pgimeno
Party member
Posts: 3544
Joined: Sun Oct 18, 2015 2:58 pm

Re: Animating tiles with STI

Post by pgimeno »

Have you tried Map:swapTile()?

viewtopic.php?f=5&t=76983&p=231293#p231293
sawurora
Prole
Posts: 2
Joined: Mon Sep 26, 2022 6:13 am

Re: Animating tiles with STI

Post by sawurora »

pgimeno wrote: Mon Sep 26, 2022 9:43 am Have you tried Map:swapTile()?

viewtopic.php?f=5&t=76983&p=231293#p231293
I did try, but it wouldn't make it possible to swap between each frame multiple times. I am now trying with instance.batch:set(), because a person said it worked for them.

Code: Select all

function map:update(dt)
    self.waterTimer = self.waterTimer + dt
    if self.waterTimer >= self.waterDuration then
        self.waterTimer = 0
        -- animate water tiles
        for i, tile in pairs(self.waterTiles) do
            local gid = nil
            if tile.gid == self.waterLastGID then
                gid = self.waterFirstGID
            else
                gid = tile.gid + 1
            end
            
            local x, y = self.currentMap:convertPixelToTile(tile.x, tile.y)
            local tileData = self.currentMap.layers["water"].data[y+1][x+1]
            local tileInstance = self:getTileInstance(tileData)

            if tileInstance then
                local newTile = self.currentMap.tiles[gid]
                self.waterTiles[i] = newTile
                tileInstance.batch:set(tileInstance.id, newTile.quad, tileInstance.x, tileInstance.y)
            end
        end
    end
end

function map:getTileInstance(tile)
    local tileInstance = false
    local px = tile.x
    local py = tile.y
    for _, ti in pairs(self.currentMap.tileInstances[tile.gid]) do
        if ti.x == px and ti.y == py then
            tileInstance = ti
            break
        end
    end
    return tileInstance
end
Unfortunately, the water is not changed at all still. I don't know what's wrong.
Post Reply

Who is online

Users browsing this forum: baconhawka7x and 46 guests