Resize sprite dynamically

Hi, guys!

I wanna sprites in my application be flexible. They have to depend on display.contentWidth and display.contentHeight. It works fine with display.newImageRect. For example:

local a = display.newImageRect( “logo.png”, display.contentWidth * .5, display.contentHeight * .5)

How can I do that with sprites?

Thx!

I don’t think this is possible in Corona. With sprites, the sizes already need to come pre-determined, so that when you split up the frames the sprite looks good. 

sprite:scale(1.2, 1.2)

I guess it is.  :stuck_out_tongue:

Just to make sure that this advice doesn’t get taken in the wrong direction, I want to mention the physics-related matter here (if the OP is using physics):

https://docs.coronalabs.com/guide/physics/limitations/index.html#object-scaling

Take care,

Brent

@Brent… how do you scale if using physics - just for the benefit of other users that stumble upon this post?

@SGS,

There are ways, but it’s not a “one size fits all” topic and it would depend on the scenario… so if anybody encounters this, better that they give specifics or start a new thread on the matter. :slight_smile:

Brent

@Sphere Game Studios, I found a thread response by @Brent that could solve this:

@Brent: "Hi @atrizhong,

In this case, Box2D is still considering the pre-scaled size, but you can work around this by using a custom “shape” body instead of relying on auto-trace (in this case it’s still a basic square, just defined as a shape with the four corners). So, it might look like this:

 

  1. local crate = display.newImage(“crate.png”);
  2. crate.x = display.contentCenterX + math.random(-200,200);
  3. crate.y = -50;
  4. crate.rotation = math.random(1,360);
  5. local scaleX,scaleY = 1.5,1.5;
  6. crate:scale(scaleX,scaleY);
  7.  
  8. local nw, nh = crate.width*scaleX*0.5, crate.height*scaleY*0.5;
  9. physics.addBody(crate, { density = 2.5, friction = .2, bounce = .1, shape={-nw,-nh,nw,-nh,nw,nh,-nw,nh} });
  10. print(“generating crate”);

 

If you’re not already familiar with Box2D rules in Corona, remember that all shapes  must  have their points declared in clockwise order, and concave bends are not allowed. Just a piece of advice as you move forward with your projects.  :slight_smile:

 

Happy New Year,

Brent"

 

Perhaps this is the solution we were looking for.

Just to add that if you changed your sprite’s scale mid-game, say like Mario changing from mini size to large size, I believe you have to remove the physics body, and re-add it with the recalculated points.

I’ve also done this with a sonic-clone I was playing around with, changing him to a circle shape when he jumps or rolls, but otherwise he has a custom shape.

Just FYI, a slightly better way (than removing the physics body and adding a larger one) is to use a multi-element body where you have different sizes of the same basic body shape. If your body was just a perfect circle, imagine it like a series of circles aligned at their center, each one slightly larger than the previous one (a similar concept could be done with polygonal body shapes of course). Then, depending on the “state” of your player… meaning, whatever size it’s supposed to be at that time in the game… you “ignore” the body elements which don’t match the player’s current size by using PhysicsContact and pre-collision handling.

This entire concept is outlined in the old (but battle-tested) tutorial here, specifically in the part about the “nebula”:

https://coronalabs.com/blog/2013/01/08/working-with-multi-element-physics-bodies/

Hope this helps,

Brent

just be cautious that while this can solve the collision aspect, it can potentially introduce undesirable changes to the overall simulation (because those extra fixtures will contribute mass to the body, even if their collisions are ignored - presuming that the body had non-zero mass to begin with of course)

depending on the relative positions of those fixtures, you may be able to just “rebalance” the individual fixture densities to counter their cumulative effect.  otoh, would be quite a bit more difficult to completely remedy if the fixtures don’t share a common center of mass (fe arbitrary polygon shapes).

I think we have properly confused the OP now…

What’s an OP? (Not trying to hack)

OP = “Original Poster” (of this forum thread). :slight_smile:

Yea,a little bit confused :slight_smile:

Let’s imagine - no physics, ok?

So, I have a few devices with different resolutions: iphone 5, 6, 7 and Nexus One for example.

To be sure that my image will be always in correct place on screen and with correct proportions I set it’s width and height depending on contentWidth and contentHeight.

Let me show exmaple code:

local _W, _H = display.contentWidth, display.contentHeight

local logo = display.newImageRect( sceneGroup, “logo.png”, _W * .5, _H * .5 )

logo.x, logo.y = _W * .25, _H * .25

This code will make proportional image (1/4 of screen size) on any device in left up corner. And it does not matter what the size of logo.png

With sprites it is impossible to change width and height. If my designer will make me a set of sprites 500x300 each I would have to work with that size on any device.

The idea with scale is nice but I have not checked it yet. 

the rest of us are probably make it too complicated by bringing physics into it…

you’re maybe making it too complicated by focusing just on the sprite object…

first, re content sizes (there are like a dozen recent threads on the topic):  just pick one, how about 320x480?  and make your sprite “look right” on that content size.  yes, you’ll get some letterbox bars added, or zoomEven cropping at runtime on various devices, but typically you’re close enough.  at least now you know what your “@1x” resolution ought to be.

if you REALLY need to fine-tune it further than that, here are some ideas:

* scale the sprite directly (already covered above, want a 500px wide sprite to be 200px wide?  sprite.xScale = 200/500, etc)

* put your sprite in a group, scale the group (same math as above)

* put your entire game in a group, scale THAT group (same math as above)

  (suggestion:  don’t mess with the scene.view’s scale, make another group just for this)

* are all your sprite frames on a sheet?  if so, mess with sheetContentWidth/Height at runtime before loading (same math as above)

  (say you have a 512x512 sheet - if you tell it sheetContentWidth/Height = 256, then your sprite will be half-size, get it?  this is typically used for “retina” image support, but you scale it arbitrarily if you wish)

I don’t think this is possible in Corona. With sprites, the sizes already need to come pre-determined, so that when you split up the frames the sprite looks good. 

sprite:scale(1.2, 1.2)

I guess it is.  :stuck_out_tongue:

Just to make sure that this advice doesn’t get taken in the wrong direction, I want to mention the physics-related matter here (if the OP is using physics):

https://docs.coronalabs.com/guide/physics/limitations/index.html#object-scaling

Take care,

Brent