Windfield and Tiled. Dynamically change tiles

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Post Reply
DannyMcWopper
Prole
Posts: 8
Joined: Tue Nov 14, 2023 4:01 pm

Windfield and Tiled. Dynamically change tiles

Post by DannyMcWopper »

I am working on a copy of Hotline Miami and can't solve the problem with breakable windows tiles.

So, idea is simple: draw usual windows on load of level and change them to broken ones once bullet destroys them.
I have solved the collisions part of the problem and it works as expected: player can't go through the collider unless bullet passes it and destroys the collider.

But here is a problem: drawing windows in Tiled on tilemap (tileMap.lua) makes them permanent so windows must be drawn dynamically taking obj.x and obj.y from their colliders. tileMap has windowsObjects layer with drawn objects to make colliders with windfield help.

Simply drawing windows on locations of windowsObjects (game_map.layers["windowsObjects"].objects) does not work, because I cant remove those later. (screenshot1)
for j, obj in ipairs(game_map.layers["windowsObjects"].objects) do
love.graphics.draw(windowV, obj.x, obj.y)
end


So I want to draw windows on positions of objects in the world, however I can't access specific objects with specific CollisionClass ('window'). The class gets assigned properly and logic of interactions with other objects works as expected, but drawing...

So I am trying to do something like this. If I remove 'obj.collision_classes == 'window' and' condition then I get (screenshot2). And if it is back, then (screenshot3)
local colliders = world:getBodies()
for i, obj in ipairs(colliders) do
if obj.collision_classes == 'window' and not obj.destroyed then
love.graphics.draw(windowV, obj:getX(), obj:getY())
end
end


If you need the rest of the code then let me know and I will provide it.
Also, if there is a better way than the one I am trying to describe then I would be really happy to learn it.

Thank you in advance!
Attachments
screenshot3
screenshot3
three.png (365.52 KiB) Viewed 3404 times
screenshot2
screenshot2
two.png (403.3 KiB) Viewed 3404 times
screenshot1
screenshot1
one.png (386.31 KiB) Viewed 3404 times
User avatar
dusoft
Party member
Posts: 510
Joined: Fri Nov 08, 2013 12:07 am
Location: Europe usually
Contact:

Re: Windfield and Tiled. Dynamically change tiles

Post by dusoft »

Windfield is archived at Github and as such outdated. You might consider using something else.
DannyMcWopper
Prole
Posts: 8
Joined: Tue Nov 14, 2023 4:01 pm

Re: Windfield and Tiled. Dynamically change tiles

Post by DannyMcWopper »

pgimeno wrote: Wed Nov 15, 2023 7:25 am Would this help?

viewtopic.php?p=231293#p231293
viewtopic.php?p=232236#p232236
pgimeno wrote: Wed Nov 15, 2023 7:25 am Would this help?

viewtopic.php?p=231293#p231293
viewtopic.php?p=232236#p232236
Could not get this method to work but I found a stupid solution. ('V' stands for vertical, horizontal windows will be handled according to the same logic but separately)

So first I created a list for window colliders in love.load()
windowCollidersV = {}

On the loading of our map once we encounter the windows object we not only give it collision class but also insert it into the list of windows.
local static_layers = {"walls", "furniture", "boundaries", "low_furniture", "passage", "windows_v"}
for i, layer_name in ipairs(static_layers) do
for j, obj in ipairs(game_map.layers[layer_name].objects) do
local collider = world:newRectangleCollider(obj.x, obj.y, obj.width, obj.height)
collider:setType('static')
if layer_name == "windows_v" then
collider:setCollisionClass('window')
table.insert(windowCollidersV, collider)
— [[rest of conditions]]
else
collider:setCollisionClass('static')
end
end
end


In bullet class I described the behaviour for the case of entering a collider of 'window' collider class which finds the same collider bullet has entered right now and the same collider that was put in the list before. Once the collider is found, we change its class to 'destroyed_window' and remove it from the list. Destroying the collider for some reason caused unpredictable behaviour so it stays like this:
-- bullet.lua
function Bullet:update(dt)
if self.collider:enter('window') then
local collision_data = self.collider:getEnterCollisionData('window')
for i, collider in ipairs(windowCollidersV) do
if collider == collision_data.collider then
table.remove(windowCollidersV, i)
collision_data.collider:setCollisionClass('destroyed_window')
break
end
end
end
end


Finally in main.lua we simply draw window images on the coordinates of remaining objects in windows list:
— main.lua
function love.draw()
for i, collider in ipairs(windowCollidersV) do
local x = collider:getX() - windowV:getWidth() / 2
local y = collider:getY() - windowV:getHeight() / 2
love.graphics.draw(windowV, x, y)
end
end
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 54 guests