Animation Scaling

Is there any way to scale animations properly? Scaling the initial sprite sheet works, but the second you change frames the animation returns back to it’s normal size (determined by the sheet data). Is there anyway to define the animations width/height in code so I don’t have to create different image sheets?

Actually I should explain a bit further. So the actual image sheets are 256x256. But then I want to scale characters to specific sizes at specific times. So I’m starting them off at 150x150 which works fine. Then I want to scale them up by 1.5x at certain points to make the animation more clear. So now they are at 225. Then when they actually switch frames, it jumps back to 256x256 and keeps the 1.5x scale which just makes them way too big.

Here are some gifs to explain

Correct sizes without switching frames - http://i.imgur.com/3U8YAne.gifv

Weird scaling when switching frames - http://i.imgur.com/8clftBp.gifv

Sorry the gifs are laggy, but I think they get the point across. 

Follow up question. How much more inefficient would it be to remove and redraw a new image. The ‘animations’ are actually only a single frame change, so would creating a new image rect and removing/redrawing that really be that much more inefficient?

Actually I think I may have found a work around. If I just reset their sizes immediately after I play the animation it seems to work fine. 

If anyone would like to suggest a cleaner solution, I’d still be up for it though. 

Hi @Garrettsavo,

Can you post a bit of code on how you’re scaling the animations? I assume you’re scaling the objects themselves?

Brent

The code is a bit of mess right now, but this is the basic idea.

function newBattleGraphic(params) self.graphic = display.newGroup() local charSize = 150 local sheetData = animSheetData["Character\_Anim"] local characterSheet = graphics.newImageSheet(imageName,sheetData) local sequenceData = animSequenceData["Character\_Anim"] self.graphic.character = display.newSprite(characterSheet, sequenceData) self.graphic.character.x = 0 self.graphic.character.y = 0 self.graphic.character.width = charSize self.graphic.character.height = charSize self.graphic:insert(self.graphic.character) params.displayGroup:insert(self.graphic) return self.graphic end

I then scale the display group object, So just.

local attacker = newBattleGraphic(params) attacker:scale(1.5,1.5)

Also while I have you here, is there a way to use setFillColor to make an object completely white. It seems like such a simple thing to do, yet I can’t find a way to do it lol. And I’m talking for a standard image. Obviously (1,1,1) is white on a rect made from code. But on any normal image (1,1,1) is just the image colors. 

Also if you’d like to know. My dirty solution for right now is just.

attacker.character:setSequence("Attack") attacker.character:play() self:resetSize(attacker) function battleOverlay:resetSize(object) object.width = object.charSize object.height = object.charSize end

Set fill color won’t do that, but you may be able to use a filter like brightness (or one of the others) to do it:

https://docs.coronalabs.com/guide/graphics/effects.html#filter.brightness

Alternately, you could write your own filter to set the visible (non-transparent) pixels in your image to pure white with either the same alpha they have or 100% opaque.

Hi @Garrettsavo,

One subtle thing I should mention is the difference between the “scale()” function you’re using, and the “.xScale” and “.yScale” properties. The “scale()” function scales an object by a percentage of its current size, which means if you continue to apply it to an object that has already been scaled, it might be tricky to get it back to its original 100% size using that same API call.

In contrast, setting the “.xScale” and “.yScale” properties are direct values for scale, based around the object’s size at 100%. So, for example, you can scale it up to 150%, then up to 180%, then down to 50%, then back to 100%, and it will always be consistent in that way. This might be the approach you’re looking for… here are the docs on it:

https://docs.coronalabs.com/api/type/DisplayObject/xScale.html

https://docs.coronalabs.com/api/type/DisplayObject/yScale.html

Take care,

Brent

Thanks for the tip :slight_smile:

Follow up question. How much more inefficient would it be to remove and redraw a new image. The ‘animations’ are actually only a single frame change, so would creating a new image rect and removing/redrawing that really be that much more inefficient?

Actually I think I may have found a work around. If I just reset their sizes immediately after I play the animation it seems to work fine. 

If anyone would like to suggest a cleaner solution, I’d still be up for it though. 

Hi @Garrettsavo,

Can you post a bit of code on how you’re scaling the animations? I assume you’re scaling the objects themselves?

Brent

The code is a bit of mess right now, but this is the basic idea.

function newBattleGraphic(params) self.graphic = display.newGroup() local charSize = 150 local sheetData = animSheetData["Character\_Anim"] local characterSheet = graphics.newImageSheet(imageName,sheetData) local sequenceData = animSequenceData["Character\_Anim"] self.graphic.character = display.newSprite(characterSheet, sequenceData) self.graphic.character.x = 0 self.graphic.character.y = 0 self.graphic.character.width = charSize self.graphic.character.height = charSize self.graphic:insert(self.graphic.character) params.displayGroup:insert(self.graphic) return self.graphic end

I then scale the display group object, So just.

local attacker = newBattleGraphic(params) attacker:scale(1.5,1.5)

Also while I have you here, is there a way to use setFillColor to make an object completely white. It seems like such a simple thing to do, yet I can’t find a way to do it lol. And I’m talking for a standard image. Obviously (1,1,1) is white on a rect made from code. But on any normal image (1,1,1) is just the image colors. 

Also if you’d like to know. My dirty solution for right now is just.

attacker.character:setSequence("Attack") attacker.character:play() self:resetSize(attacker) function battleOverlay:resetSize(object) object.width = object.charSize object.height = object.charSize end

Set fill color won’t do that, but you may be able to use a filter like brightness (or one of the others) to do it:

https://docs.coronalabs.com/guide/graphics/effects.html#filter.brightness

Alternately, you could write your own filter to set the visible (non-transparent) pixels in your image to pure white with either the same alpha they have or 100% opaque.

Hi @Garrettsavo,

One subtle thing I should mention is the difference between the “scale()” function you’re using, and the “.xScale” and “.yScale” properties. The “scale()” function scales an object by a percentage of its current size, which means if you continue to apply it to an object that has already been scaled, it might be tricky to get it back to its original 100% size using that same API call.

In contrast, setting the “.xScale” and “.yScale” properties are direct values for scale, based around the object’s size at 100%. So, for example, you can scale it up to 150%, then up to 180%, then down to 50%, then back to 100%, and it will always be consistent in that way. This might be the approach you’re looking for… here are the docs on it:

https://docs.coronalabs.com/api/type/DisplayObject/xScale.html

https://docs.coronalabs.com/api/type/DisplayObject/yScale.html

Take care,

Brent

Thanks for the tip :slight_smile: