Sprite Animation Scaling on Multiple screen factors

I have created two sprite sheets using Texture Packer, one with regular resolution with this file name:

healthbar.png and healthbar@2x.png

When I publish the sheets Texture Packer generates a data format file in my case I get:

healthbar.lua and healthbar@2x.lua

When I run on an iPhone 5 all animations work fine, when I run on iPhone 7, 8 or X the graphics are not right.

When I renamed the healthbar@2x.png, the problem disappeared.

I know Lua will load the @2x on a higher resolution, my issue looks like Lua still reading the parameters from the

healthbar.png and loading the image from healthbar@2x.png.

I am handling the sprite data files correctly? How can LUA switch the data file based on the resolution? Or how can I solve this issue?

local healthbar

local healthsequenceData = { 

        { name = “health1”, start = 1, count = 1, time = 250 }, { name = “health1blink”, frames = { 1,9}, time = 250, loopCount = 3 },

        { name = “health2”, start = 2, count = 1, time = 250 }, { name = “health2blink”, frames = { 2,9}, time = 250, loopCount = 3 },

        { name = “health3”, start = 3, count = 1, time = 250 }, { name = “health3blink”, frames = { 3,9}, time = 250, loopCount = 3 },

        { name = “health4”, start = 4, count = 1, time = 250 }, { name = “health4blink”, frames = { 4,9}, time = 250, loopCount = 3 },

        { name = “health5”, start = 5, count = 1, time = 250 }, { name = “health5blink”, frames = { 5,9}, time = 250, loopCount = 3 },

        { name = “health6”, start = 6, count = 1, time = 250 }, { name = “health6blink”, frames = { 6,9}, time = 150, loopCount = 3 },

        { name = “health7”, start = 7, count = 1, time = 250 }, { name = “health7blink”, frames = { 7,9}, time = 150, loopCount = 3 },

        { name = “health8”, start = 8, count = 1, time = 250 }, { name = “health8blink”, frames = { 8,9}, time = 150, loopCount = 3 },

        { name = “health9”, start = 9, count = 1, time = 250 }

      }

local healthSheetInfo = require(“images.healthbar”) local healthImageSheet = graphics.newImageSheet( “images/healthbar.png”, healthSheetInfo:getSheet() ) healthbar = display.newSprite(healthImageSheet, healthsequenceData)

the “normal” way this works is the @2x sprite sheet is an exact duplicate of the @1x image, just 2x bigger.  then, as long as sheetContentWidth/Height are specified, the single sheet specification works for both images automagically.

if your @2x image is NOT an exact duplicate of the @1x, ie if different layout or sequence or etc, and does in fact require a separate specification file, then YOU (not Corona) will have to be responsible for loading the appropriate specification at runtime, fe (just pseudocode, will need to handle nil):

local healthSheetInfo = require("images.healthbar"..display.imageSuffix)

They are the same, number of images but the x and y coordinates on the sheet and the dimensions width and height are different.

I don’t understand how it will work, even if I make the sheetContentWidth/Height the same, the other coordinates will not be the same.

See the data files for both image factors:

healthcare.lua

local SheetInfo = {} SheetInfo.sheet = { frames = { { -- hbar1 x=1, y=1, width=150, height=47, }, { -- hbar2 x=153, y=1, width=150, height=47, }, { -- hbar3 x=305, y=1, width=150, height=47, }, { -- hbar4 x=1, y=50, width=150, height=47, }, { -- hbar5 x=153, y=50, width=150, height=47, }, { -- hbar6 x=305, y=50, width=150, height=47, }, { -- hbar7 x=1, y=99, width=150, height=47, }, { -- hbar8 x=153, y=99, width=150, height=47, }, { -- hbar9 x=305, y=99, width=150, height=47, }, }, sheetContentWidth = 456, sheetContentHeight = 147 } SheetInfo.frameIndex = { ["hbar1"] = 1, ["hbar2"] = 2, ["hbar3"] = 3, ["hbar4"] = 4, ["hbar5"] = 5, ["hbar6"] = 6, ["hbar7"] = 7, ["hbar8"] = 8, ["hbar9"] = 9, } function SheetInfo:getSheet() return self.sheet; end function SheetInfo:getFrameIndex(name) return self.frameIndex[name]; end return SheetInfo

healthbar@2x

local SheetInfo = {}

SheetInfo.sheet =

{

    frames = {

    

        {

            – hbar1@2x

            x=1,

            y=1,

            width=196,

            height=62,

        },

        {

            – hbar2@2x

            x=1,

            y=65,

            width=196,

            height=61,

        },

        {

            – hbar3@2x

            x=1,

            y=128,

            width=196,

            height=61,

        },

        {

            – hbar4@2x

            x=1,

            y=191,

            width=196,

            height=61,

        },

        {

            – hbar5@2x

            x=1,

            y=254,

            width=196,

            height=61,

        },

        {

            – hbar6@2x

            x=1,

            y=317,

            width=196,

            height=61,

        },

        {

            – hbar7@2x

            x=1,

            y=380,

            width=196,

            height=62,

        },

        {

            – hbar8@2x

            x=1,

            y=444,

            width=196,

            height=62,

        },

        {

            – hbar9@2x

            x=1,

            y=508,

            width=196,

            height=61,

        },

    },

    sheetContentWidth = 198,

    sheetContentHeight = 570

}

SheetInfo.frameIndex =

{

    [“hbar1@2x”] = 1,

    [“hbar2@2x”] = 2,

    [“hbar3@2x”] = 3,

    [“hbar4@2x”] = 4,

    [“hbar5@2x”] = 5,

    [“hbar6@2x”] = 6,

    [“hbar7@2x”] = 7,

    [“hbar8@2x”] = 8,

    [“hbar9@2x”] = 9,

}

function SheetInfo:getSheet()

    return self.sheet;

end

function SheetInfo:getFrameIndex(name)

    return self.frameIndex[name];

end

return SheetInfo

you can’t mix and match “solutions” - either your sprite sheets are *identical* (except for scaling) and you use a single sheet specification with sheetContentWidth/Height to auto-adjust for the scaling, OR you use separate sheet specifications.

but you’re probably making this too hard - there’s a setting in TP like force same layout (or some such, it’s been a while) that let’s you do it the “simple” way with a single sheet specification for all scaling factors, suggest you look into that.  (maybe someone else can chime in here with fresher TP how-to knowledge, or just google around for it)

It’s exactly as Dave said.

Your healthcare.lua has sheetContentWidth = 456 and sheetContentHeight = 147 whereas your healthcare@2x.lua has sheetContentWidth = 198 and sheetContentHeight = 570. This simply means that the sheets are not identical in terms of layout, so you’d have to personally load those different lua files and their specifications by following Dave’s advice.

It is also curious that you have given the other sheet a @2x variant suffix, when in reality the images are nowhere close to being that large. Seeing that your @2x sheet includes the @2x suffix at the end of each frame makes me think that you haven’t actually used TexturePacker to output the sheets at the same time, but instead you’ve manually created the @2x images and then you’ve made an individual sheet out of those assets. You should  not  include the @2x suffix to the frames inside the sheet, i.e. you don’t want or need @2x after these.

SheetInfo.frameIndex =

{

 

    [“hbar1@2x”] = 1,

    [“hbar2@2x”] = 2,

    [“hbar3@2x”] = 3,

    [“hbar4@2x”] = 4,

    [“hbar5@2x”] = 5,

    [“hbar6@2x”] = 6,

    [“hbar7@2x”] = 7,

    [“hbar8@2x”] = 8,

    [“hbar9@2x”] = 9,

}

You can export both sheets at the same time from TexturePacker and they will have identical layout by default. You can access the scaling variant export options under the layout tab. If you export the sheets like this, then they should be identical and the frames will be named the same.

davebollinger and Xedur @Spyric,

Thank you so much for your reply, I was able to find a Texture Packer Tutorial that covers Dynamic Content Scaling for Corona.

I added a link below just in case other people in this forum has the same issue.

Dynamic Content Scaling for Corona SDK

the “normal” way this works is the @2x sprite sheet is an exact duplicate of the @1x image, just 2x bigger.  then, as long as sheetContentWidth/Height are specified, the single sheet specification works for both images automagically.

if your @2x image is NOT an exact duplicate of the @1x, ie if different layout or sequence or etc, and does in fact require a separate specification file, then YOU (not Corona) will have to be responsible for loading the appropriate specification at runtime, fe (just pseudocode, will need to handle nil):

local healthSheetInfo = require("images.healthbar"..display.imageSuffix)

They are the same, number of images but the x and y coordinates on the sheet and the dimensions width and height are different.

I don’t understand how it will work, even if I make the sheetContentWidth/Height the same, the other coordinates will not be the same.

See the data files for both image factors:

healthcare.lua

local SheetInfo = {} SheetInfo.sheet = { frames = { { -- hbar1 x=1, y=1, width=150, height=47, }, { -- hbar2 x=153, y=1, width=150, height=47, }, { -- hbar3 x=305, y=1, width=150, height=47, }, { -- hbar4 x=1, y=50, width=150, height=47, }, { -- hbar5 x=153, y=50, width=150, height=47, }, { -- hbar6 x=305, y=50, width=150, height=47, }, { -- hbar7 x=1, y=99, width=150, height=47, }, { -- hbar8 x=153, y=99, width=150, height=47, }, { -- hbar9 x=305, y=99, width=150, height=47, }, }, sheetContentWidth = 456, sheetContentHeight = 147 } SheetInfo.frameIndex = { ["hbar1"] = 1, ["hbar2"] = 2, ["hbar3"] = 3, ["hbar4"] = 4, ["hbar5"] = 5, ["hbar6"] = 6, ["hbar7"] = 7, ["hbar8"] = 8, ["hbar9"] = 9, } function SheetInfo:getSheet() return self.sheet; end function SheetInfo:getFrameIndex(name) return self.frameIndex[name]; end return SheetInfo

healthbar@2x

local SheetInfo = {}

SheetInfo.sheet =

{

    frames = {

    

        {

            – hbar1@2x

            x=1,

            y=1,

            width=196,

            height=62,

        },

        {

            – hbar2@2x

            x=1,

            y=65,

            width=196,

            height=61,

        },

        {

            – hbar3@2x

            x=1,

            y=128,

            width=196,

            height=61,

        },

        {

            – hbar4@2x

            x=1,

            y=191,

            width=196,

            height=61,

        },

        {

            – hbar5@2x

            x=1,

            y=254,

            width=196,

            height=61,

        },

        {

            – hbar6@2x

            x=1,

            y=317,

            width=196,

            height=61,

        },

        {

            – hbar7@2x

            x=1,

            y=380,

            width=196,

            height=62,

        },

        {

            – hbar8@2x

            x=1,

            y=444,

            width=196,

            height=62,

        },

        {

            – hbar9@2x

            x=1,

            y=508,

            width=196,

            height=61,

        },

    },

    sheetContentWidth = 198,

    sheetContentHeight = 570

}

SheetInfo.frameIndex =

{

    [“hbar1@2x”] = 1,

    [“hbar2@2x”] = 2,

    [“hbar3@2x”] = 3,

    [“hbar4@2x”] = 4,

    [“hbar5@2x”] = 5,

    [“hbar6@2x”] = 6,

    [“hbar7@2x”] = 7,

    [“hbar8@2x”] = 8,

    [“hbar9@2x”] = 9,

}

function SheetInfo:getSheet()

    return self.sheet;

end

function SheetInfo:getFrameIndex(name)

    return self.frameIndex[name];

end

return SheetInfo

you can’t mix and match “solutions” - either your sprite sheets are *identical* (except for scaling) and you use a single sheet specification with sheetContentWidth/Height to auto-adjust for the scaling, OR you use separate sheet specifications.

but you’re probably making this too hard - there’s a setting in TP like force same layout (or some such, it’s been a while) that let’s you do it the “simple” way with a single sheet specification for all scaling factors, suggest you look into that.  (maybe someone else can chime in here with fresher TP how-to knowledge, or just google around for it)

It’s exactly as Dave said.

Your healthcare.lua has sheetContentWidth = 456 and sheetContentHeight = 147 whereas your healthcare@2x.lua has sheetContentWidth = 198 and sheetContentHeight = 570. This simply means that the sheets are not identical in terms of layout, so you’d have to personally load those different lua files and their specifications by following Dave’s advice.

It is also curious that you have given the other sheet a @2x variant suffix, when in reality the images are nowhere close to being that large. Seeing that your @2x sheet includes the @2x suffix at the end of each frame makes me think that you haven’t actually used TexturePacker to output the sheets at the same time, but instead you’ve manually created the @2x images and then you’ve made an individual sheet out of those assets. You should  not  include the @2x suffix to the frames inside the sheet, i.e. you don’t want or need @2x after these.

SheetInfo.frameIndex =

{

 

    [“hbar1@2x”] = 1,

    [“hbar2@2x”] = 2,

    [“hbar3@2x”] = 3,

    [“hbar4@2x”] = 4,

    [“hbar5@2x”] = 5,

    [“hbar6@2x”] = 6,

    [“hbar7@2x”] = 7,

    [“hbar8@2x”] = 8,

    [“hbar9@2x”] = 9,

}

You can export both sheets at the same time from TexturePacker and they will have identical layout by default. You can access the scaling variant export options under the layout tab. If you export the sheets like this, then they should be identical and the frames will be named the same.

davebollinger and Xedur @Spyric,

Thank you so much for your reply, I was able to find a Texture Packer Tutorial that covers Dynamic Content Scaling for Corona.

I added a link below just in case other people in this forum has the same issue.

Dynamic Content Scaling for Corona SDK