Need help with Bump.lua Filters

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.
dpkgluci
Prole
Posts: 8
Joined: Wed Jul 31, 2024 10:05 pm

Need help with Bump.lua Filters

Post by dpkgluci »

Ok I pretty much understand bump.lua completely, except filters. I'm trying to use the libraries STI and Bump.lua to work together and they do! but I want to add spikes to my tilemaps and I thought I add a custom property to the spike tiles like "isSpike" or something and if the player collides with it it would trigger another function

How do the <filter> in world:move

Code: Select all

local actualX, actualY, cols, len = world:move(item, goalX, goalY, <filter>)
and world:check

Code: Select all

local actualX, actualY, cols, len = world:check(item, goalX, goalY, <filter>)
works?

I tried putting "slide" and "cross" there but it gives me an error
dpkgluci
Prole
Posts: 8
Joined: Wed Jul 31, 2024 10:05 pm

Re: Need help with Bump.lua Filters

Post by dpkgluci »

update: I don't know how to set up the Type attribute of objects, and in the bump.lua docs it seems to need it for filters
do someone understand how to set up type? is it the same as Class in tiled?
cip
Prole
Posts: 15
Joined: Wed Jun 07, 2023 5:44 pm

Re: Need help with Bump.lua Filters

Post by cip »

I've been recently using bump (which, like lots of LÖVE libraries, is very good!) and I think I can help you with this question:

From my understanding, in place of <filter> you can put a function there directly, as <filter> is already a function which returns one of the collision responses (from the tutorial, these are: cross, slide, touch, bounce).

If you set the spikes with a isSpike property to true (so self.isSpike = true when you initially create the spikes), you can iterate over the collisions like so,

Code: Select all

local actualX, actualY, cols, len = world:move(player, goalX, goalY, function(item, other) 
if other.isSpike == true then	
     return 'bounce'
  end	
end)
In this case, "other" is the sprite you are acting upon.

Also, you can iterate over the collisions,

Code: Select all

for i=1,len do
   local other = cols[i].other
   if other.isCoin then
      takeCoin(other)
   elseif other.isExit then
      changeLevel()
   elseif other.isSpring then
      highJump()
  end
end
If it helps, I am fairly certain that instead of checking against boolean properties of the objects (such as isCoin, isExit, etc) you can also use something like sprite.name == 'coin' or sprite.name == 'exit' (which, when querying for collisions using the code above would turn into other.name == 'coin' or other.name == 'exit'. So the Type attribute you are mentioning is an identifier which helps you and helps bump identify the sprites and their respective collision responses.

Please check out this thread as well,
viewtopic.php?t=87249
MrFariator
Party member
Posts: 543
Joined: Wed Oct 05, 2016 11:53 am

Re: Need help with Bump.lua Filters

Post by MrFariator »

Ninja'd by cip, but posting my reply anyway.

Lets assume you have a player object like the following:

Code: Select all

local player = {
  x = 0,
  y = 0,
  w = 16,
  h = 16,
  isPlayer = true
}
-- insert the object into the world:
world:add (player, player.x, player.y, player.w, player.h)
Just a single table, as an example. As you see, we have "isPlayer" boolean in our player object, and that'll be used by our filters later.
Now, lets assume we create some bullet, perhaps with the following structure:

Code: Select all

local bullet = {
  x = 0,
  y = 0,
  w = 8,
  h = 8,
  isBullet = true,
}
-- insert again like before
world:add (bullet, bullet.x, bullet.y, bullet.w, bullet.h)
Now, when you want to update the bullet, and want to check it colliding against the player, you'd create a filter like the following:

Code: Select all

-- 'item' is the object we're currently updating, 'other' is the object we're colliding with
local function bulletFilter (item, other)
  if other.isPlayer then return 'touch' end
  -- add any other conditions here if desired, like checking for "isWall" or "isBullet"
end
You'd pass this function into world:move (or world:check) when updating your bullet object. If the bullet object collides with the player object, the collision will be returned, otherwise nothing happens.

Code: Select all

local newX, newY, cols, len = world:move (bullet, targetX, targetY, bulletFilter)

for i = 1, len do
  local other = cols[i].other
  if other.isPlayer then
    print("collided with player!")
  end
end
As such, to answer your question simply: the 'types' are just any arbitrary fields you might put into the objects you insert into the bump world. They could be numbers, booleans, strings or even tables. It's up to you what fields the filter functions might check.

Do note, that when using functions like world:queryRect, the filter functions use a simpler form:

Code: Select all

-- here, 'item' is whatever item in the world that the query'd area happened to touch
-- with these query filters, you simply need to return a truthy or falsy value
local function bulletQuery ( item )
  -- add others as desired
  return item.isPlayer
end
cip
Prole
Posts: 15
Joined: Wed Jun 07, 2023 5:44 pm

Re: Need help with Bump.lua Filters

Post by cip »

MrFariator wrote: Thu Aug 01, 2024 5:17 pm Ninja'd by cip, but posting my reply anyway.

Lets assume you have a player object like the following:

Code: Select all

local player = {
  x = 0,
  y = 0,
  w = 16,
  h = 16,
  isPlayer = true
}
-- insert the object into the world:
world:add (player, player.x, player.y, player.w, player.h)
Just a single table, as an example. As you see, we have "isPlayer" boolean in our player object, and that'll be used by our filters later.
Now, lets assume we create some bullet, perhaps with the following structure:

Code: Select all

local bullet = {
  x = 0,
  y = 0,
  w = 8,
  h = 8,
  isBullet = true,
}
-- insert again like before
world:add (bullet, bullet.x, bullet.y, bullet.w, bullet.h)
Now, when you want to update the bullet, and want to check it colliding against the player, you'd create a filter like the following:

Code: Select all

-- 'item' is the object we're currently updating, 'other' is the object we're colliding with
local function bulletFilter (item, other)
  if other.isPlayer then return 'touch' end
  -- add any other conditions here if desired, like checking for "isWall" or "isBullet"
end
You'd pass this function into world:move (or world:check) when updating your bullet object. If the bullet object collides with the player object, the collision will be returned, otherwise nothing happens.

Code: Select all

local newX, newY, cols, len = world:move (bullet, targetX, targetY, bulletFilter)

for i = 1, len do
  local other = cols[i].other
  if other.isPlayer then
    print("collided with player!")
  end
end
As such, to answer your question simply: the 'types' are just any arbitrary fields you might put into the objects you insert into the bump world. They could be numbers, booleans, strings or even tables. It's up to you what fields the filter functions might check.

Do note, that when using functions like world:queryRect, the filter functions use a simpler form:

Code: Select all

-- here, 'item' is whatever item in the world that the query'd area happened to touch
-- with these query filters, you simply need to return a truthy or falsy value
local function bulletQuery ( item )
  -- add others as desired
  return item.isPlayer
end
@MrFariator, your answer is more comprehensive, and more replies is always better :D
dpkgluci
Prole
Posts: 8
Joined: Wed Jul 31, 2024 10:05 pm

Re: Need help with Bump.lua Filters

Post by dpkgluci »

Hi! This seems pretty understandable, But I'm using STI to get the collisions, and I'm trying to make a filter that somehow returns slide on ground (or everything) and "cross" when player touches a spike

Code: Select all

local collidablefilter = function(_, other)
  if other.base == "ground" then
    return "slide"
  elseif other.base == "spike" then
    return "cross"
  else
    return "slide"
  end
end
It always returns slide, and apparently it is not because the last else but the first, it seems like the other.base is strangely defined

I am trying to set a custom property in the spike objects in tiled.
I created a new layer "spike" and inside, there are objects (that have collidable=true) and a "base" property (string) set to "spike" but the filter seems to not read it
MrFariator
Party member
Posts: 543
Joined: Wed Oct 05, 2016 11:53 am

Re: Need help with Bump.lua Filters

Post by MrFariator »

If in doubt, try printing your object's 'base' field before inserting it into the bump world (ie. just print "myObj.base" and see what it prints). If it's undefined (nil) or a non-string value, your filter will return 'slide' in all cases. If it's undefined, you're not importing that information from your tiled maps.

Edit: also, in your case, check if there are any overlapping tiles that have 'base' set to 'ground. If such tiles lie atop/below your spikes, the 'ground' tiles will take priority due to the 'slide' result.
cip
Prole
Posts: 15
Joined: Wed Jun 07, 2023 5:44 pm

Re: Need help with Bump.lua Filters

Post by cip »

Could it be that the spike is over a ground tile (which has a 'slide' response') and the player always collides first with the ground tile? I don't have experience with STI, so I'm not really sure what advice to give.

But I agree with MrFariator, printing the object's base property might get you closer to the answer.

EDIT: had to edit my answer, as I mixed the spike and ground tiles and their collision responses.
dpkgluci
Prole
Posts: 8
Joined: Wed Jul 31, 2024 10:05 pm

Re: Need help with Bump.lua Filters

Post by dpkgluci »

I printed it but got nil, and the ground tile above the spike is impossible since the player is standing on top of a spike, it doesnt touch any ground tiles

But I resolved this! I used the type (class) property! it's not a custom property, but you can put strings on it, so I marked all my spike boxes with spike and all my ground ones with ground and now with this filter

Code: Select all

local collidablefilter = function(_, other)
  if other.type == "spike" then
    return "cross"
  elseif other.type == "ending" then
    return "slide"
  elseif other.type == "coin" then
    return "cross"
  else
    return "slide"
  end
end
MrFariator
Party member
Posts: 543
Joined: Wed Oct 05, 2016 11:53 am

Re: Need help with Bump.lua Filters

Post by MrFariator »

If it printed nil, then perhaps you weren't reading the 'base' property from the tiled map, and setting it to your tile objects accordingly before inserting them to the bump world. I've never used STI, so I wouldn't know how that part should be done, but seems like your solution achieves much of the same result.
Post Reply

Who is online

Users browsing this forum: No registered users and 7 guests