Help understanding sprite collision response callback

,

SDK 1.9.3 - Linux

Hi all,

I'm trying to wrap my head around this particular callback on the sprites when working on some game code. It is not an absolute blocker as I can get around it in other ways, but when trying to write test code to understand it, I get unexpected results and wanted a second opinion.

This is the main part of my test code:

seaweed_image = gfx.image.new("seaweed.png")
seaweed = gfx.sprite.new(seaweed_image)
seaweed:moveTo(sea_x, sea_y)
seaweed:setCollideRect(0, 0, seaweed:getSize())
seaweed.type = "seaweed"
seaweed:add()

fish_image = gfx.image.new("fish.png")
fish = gfx.sprite.new(fish_image)
fish:moveTo(x, y)
fish:setCollideRect(0, 0, fish:getSize())
fish.type = "fish"
fish:add()

fish.collisionResponse = function(other)
  print(other.type)
  return gfx.sprite.kCollisionTypeSlide
end

I have issues with collisionResponse. In my update function I have controls over the fish and when I move the fish into the seaweed, i get a printout fish, not seaweed as I would have expected reading the doc on this callback:

A callback that can be defined on a sprite to control the type of collision response that should happen when a collision with other occurs

By this definition, I would have expected an output seaweed as it is the fish that is colliding with the other sprite seaweed, but instead I get other being fish (in this case, self) which to me seems backwards. I am new to Lua so I might have written something incorrectly, but even tutorials like this hint at the sprite other being defined as something you collide with.

Can someone please help me understand this?

I have added the actual code I'm running if anyone is interested. example.zip (13.3 KB)

Thank you in advance.

I'm still fairly new to Lua, but this looks like the same thing I've tripped up on a number of times already. gfx.sprite.colissionResponse is a method on the sprite, not just a function. When methods are called, their first argument is the object they're invoked on, and later arguments are any actual arguments passed to the method.

So, something in the collision system is calling

fish:collisionResponse(seaweed)

... which translates to ...

fish.collisionResponse(fish, seaweed)

Since this is a method, that first argument is always going to be the fish the method was called on. If you change that first line where you define the method, you'll get the behavior described by the documentation.

- fish.collisionResponse = function(other)
+ fish.collisionResponse = function(self, other)
3 Likes

Thanks for the swift reply.

You are absolutely right and looking at it now, it makes sense why it would be written like this. You could in theory write the method elsewhere in the project where you might what to have an instance of self to reference (maybe not a good idea since the docs also state that you should not do any collision resolutions in there, but in moveWithCollisions()).

I presume this is Lua thing and I still haven't gotten used to it. I think Python does something similar in classes.

My fixed example:

function fishCollisionResponse(self, other)
  if other.type == "seaweed" then
    return gfx.sprite.kCollisionTypeFreeze
  else
    return gfx.sprite.kCollisionTypeOverlap
  end
end
  
-- somewhere else in the code
fish.collisionResponse = fishCollisionResponse

Thank you :playdate:

1 Like