Scaling image and collision

Hi All,

Been learning solar for a bit and find it fun. I’ve been trying to scale an image, which scales fine, but the collision box doesn’t seem to scale. My understanding is that if I scale the image first and then add it, the collision box should match. Here is an excerpt of my code. “enemy” is just an image that gets created

    enemy =
    if enemyData.scale then
      enemy:scale( enemyData.scale, enemyData.scale )
    physics.addBody(enemy, "dynamic", {isSensor=true, density=0, friction=0, bounce=0, filter=collisionRules.enemyFilter})

…am I doing something wrong? or do I just misunderstand how it works?


You should add physics an object at its natural size. If you want a larger object the place to add the scaling is when you make the display object.

local box = display.newRect( 0, 0, 20, 20 )

double the box’s size during its creation and then add physics

local box = display.newRect( 0, 0, 40, 40 )
physics.addBody(box, "dynamic")

This kind of doesn’t work for me as the way I’ve designed so far is to have a lua file of level data that allows me to specify enemy attributes off of a sprite sheet and have the system randomly generate the enemy out of possible list of choices. Ideally I would be able to simply scale the sprite sheet image after it got pulled in and create a collision box around it based on the scale.

Simply manually changing the height and width does work for my needs, so right now I have the code below and that works fine. My question still remains, is the object:scale() function not designed to work like this? or is this a bug?

enemy =
if enemyData.scale then
  enemy.width = enemy.width * enemyData.scale
  enemy.height = enemy.height * enemyData.scale
  --enemy:scale( enemyData.scale, enemyData.scale )
physics.addBody(enemy, "dynamic", {isSensor=true, density=0, friction=0, bounce=0, filter=collisionRules.enemyFilter})

It’s not a bug. The best way to think about it as two separate engines. The display engine and the physics engine. Once you hand off a display object to the physics engine it becomes a physics object and you should no longer use any position, scale or rotational display methods on that objects. The physics engine then controls the display object’s position and rotation. Trying to change the physics objects properties via the display engine will result in the decoupling of the physics bodies to what you see on the screen.

You can scale the physics object visually by scaling the display group that it belongs to. *Note - you would also need to proportionately scale any other group with physics bodies to keep everything working together.

So essentially, once you pass the display object to the physics engine you can use the display engine to change things like color and alpha but NOT position, rotation or scale.

Thank your for the detailed explanation. Since in my example I’m calling :scale() before adding my object to the physics engine I had assumed it would utilize the scaled object dimensions. But based on your explanation it sounds as though the :scale() function part of the display engine would be something that is applied on the individual object and everything in it upon presentation. i.e. the actual dimensions, which are leveraged by the physics portion, remain unedited.

I’m going to go do some more digging to satisfy my curiosity now…

Thank you,