Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

TexturePacker, spritsheets and @2x images...
Started by clalvial Aug 28 2012 04:25 AM

29 replies to this topic
[TOPIC CONTROLS]
Page 1 of 2 1 2
This topic has been archived. This means that you cannot reply to this topic.
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

clalvial

[GLOBAL: userInfoPane.html]
clalvial
  • Enthusiast

  • 31 posts
  • Corona SDK

Hello.

To build all my spritesheets, I use TexturePacker. My plan is to support 320x480 and 640x960 resolutions on the iPhone.

My config is pretty simple and looks like this:
application = {	content = {		width = 320,		height = 480, 		scale = "letterBox",		fps = 30,	        imageSuffix = {		    ["@2x"] = 2,		}	},}


what I do is build the 640x960 sprites first, saving the png with the suffix @2x and then use TP to scale it to half size and save it with the normal file name.
But when testing on simulator, it always uses the normal images and not the @2x spritesheets.

My code to loading and using the sheets is like this:
--get all sprite data    --script generated by texturepacker    local heroSheetData = require("scripts.herosheet");     local heroData = heroSheetData.getSpriteSheetData();    --sheet created by texturepacker    local heroSheet = sprite.newSpriteSheetFromData( "images/herosheet.png", heroSheetData.getSpriteSheetData() );    local heroSet = sprite.newSpriteSet(heroSheet, 1, 16);    --prepare animations    sprite.add(heroSet, "death", 1, 3, 800, 1);    sprite.add(heroSet, "falling", 4, 1, 1, 1);    sprite.add(heroSet, "jumping", 5, 1, 1, 1);    sprite.add(heroSet, "sliding", 6, 1, 1, 1);    sprite.add(heroSet, "rolling", 7, 3, 200, 0);    sprite.add(heroSet, "running", 10, 7, 400, 0);


(Seems I missed the existence of the 3rd Party Tools and Services sub-forum. It doesn't seem to be updated often though, if a moderator decides to move it then I guess it's ok...)
uid: 136402 topic_id: 30336 reply_id: 330336


[TOPIC: post.html]
#2

JoshuaNovak919

[GLOBAL: userInfoPane.html]
JoshuaNovak919
  • Enthusiast

  • 55 posts
  • Enterprise

Your code looks good. I would just make sure when you bring in your 640x960 images into texturepacker and export them make sure you select auto sd. You then need to make sure the png and the lua datasheet both end in @2x and then it will do the sd ones for you. If you did all that and are still having issues, i would test the paths and make sure they are all good.
uid: 26491 topic_id: 30336 reply_id: 121604


[TOPIC: post.html]
#3

clalvial

[GLOBAL: userInfoPane.html]
clalvial
  • Enthusiast

  • 31 posts
  • Corona SDK

I "discovered" the AutoSD feature and it's a real time saver, it's great!

My problem is still unsolved though, changing devices in the simulator still loads the low-res sprites. I don't have a real device to test with yet.

I guess I could probably just check display.contentWidth or something similar and then load the appropriate files, but that kinda defeats the purpose of making a config.lua ;p
uid: 136402 topic_id: 30336 reply_id: 121693


[TOPIC: post.html]
#4

JoshuaNovak919

[GLOBAL: userInfoPane.html]
JoshuaNovak919
  • Enthusiast

  • 55 posts
  • Enterprise

I'm still new to this, but your code looks good to me from what i can see. I'm not sure what you are doing after the sprite.add line, but here is the code that i am using and that i know works. May be of some help.

local enemyData = require("resources.sprite_sheets.guy")
local enemySpriteSheet = sprite.newSpriteSheetFromData( "resources/sprite_sheets/guy.png", enemyData.getSpriteSheetData() )
local enemySpriteSet = sprite.newSpriteSet(enemySpriteSheet, 1, 24)
sprite.add(enemySpriteSet,"run", 1, 10, 1000, 0)
sprite.add(enemySpriteSet,"walk", 11, 14, 1000, 0)
local enemy = sprite.newSprite(enemySpriteSet)
enemy:prepare("walk")
enemy:play()
uid: 26491 topic_id: 30336 reply_id: 121699


[TOPIC: post.html]
#5

Screaming Leaf

[GLOBAL: userInfoPane.html]
Screaming Leaf
  • Contributor

  • 144 posts
  • Corona SDK

Try changing the ["@2x"] = 2, to a lower value like ["@2x"] = 1.8.

uid: 94868 topic_id: 30336 reply_id: 121710


[TOPIC: post.html]
#6

clalvial

[GLOBAL: userInfoPane.html]
clalvial
  • Enthusiast

  • 31 posts
  • Corona SDK

Sadly, no change.

I used print to see the values of display.contentWidth display.contentHeight display.viewableContentWidth and display.viewableContentHeight during gameplay. Their values are always 480x320 no matter what system I'm running the simulator on.

I'm using the latest daily build and director to manage my screens if that's of any help.
uid: 136402 topic_id: 30336 reply_id: 121750


[TOPIC: post.html]
#7

Screaming Leaf

[GLOBAL: userInfoPane.html]
Screaming Leaf
  • Contributor

  • 144 posts
  • Corona SDK

okay looking at it again, how about changing "letterBox" to "letterbox".

The display.contentWidth and display.contentHeight will always display the height/width you define in the config.lua.
uid: 94868 topic_id: 30336 reply_id: 121753


[TOPIC: post.html]
#8

clalvial

[GLOBAL: userInfoPane.html]
clalvial
  • Enthusiast

  • 31 posts
  • Corona SDK

nope, still nothing, I also tested it on my windows machine.

"The display.contentWidth and display.contentHeight will always display the height/width you define in the config.lua."

I use that data to help me locate other elements in the game screen. Does that mean that when/if I get this working, even if I am using the higer res graphics Corona will still think that I'm on a lower screen resolution?
uid: 136402 topic_id: 30336 reply_id: 121809


[TOPIC: post.html]
#9

Screaming Leaf

[GLOBAL: userInfoPane.html]
Screaming Leaf
  • Contributor

  • 144 posts
  • Corona SDK

Oh wait. You are using the older sprite api. That doesn't do the dynamic scaling. Use the newer sprite api, it is a lot easier.

http://docs.coronalabs.com/api/library/display/newSprite.html

Well it knows you're on a higher resolution screen, but it bases all of its values according to the height/width you defined in the config. So it scales all of the values to match the screen. And it swaps in the higher resolution images when the scale goes above the values you declared in the config.

uid: 94868 topic_id: 30336 reply_id: 121838


[TOPIC: post.html]
#10

clalvial

[GLOBAL: userInfoPane.html]
clalvial
  • Enthusiast

  • 31 posts
  • Corona SDK

Whoa, one would think Ansca would have updated their articles to account for this. I finally managed to load the high res textures... But it's not working right...

2 problems arose: 1. It seems that it's not using the @2x script, because animations are out of place. And 2. The higher res graphics are bigger than they should be (meaning, the hd images are being scaled up).

code for loading the spritesheet now looks like
    --get all sprite data
    local oldStyleData = require("scripts.catsheet");
    local oldSpriteSheetData = oldStyleData.getSpriteSheetData();
    local options = { spriteSheetFrames = oldSpriteSheetData.frames };
    local heroSheet = graphics.newImageSheet( "images/catsheet.png", options );
    --prepare animations
    local sequenceData = {
        { name="death",   start=1,  count=3, time=800, loopCount=1 },
        { name="falling", start=4,  count=1, time=1,   loopCount=1 },
        { name="jumping", start=5,  count=1, time=1,   loopCount=1 },
        { name="sliding", start=6,  count=1, time=1,   loopCount=1 },
        { name="rolling", start=7,  count=3, time=200, loopCount=0 },
        { name="running", start=10, count=7, time=400, loopCount=0 }
    };
    --start everything
    local hero = display.newSprite( heroSheet, sequenceData );
    hero:setSequence("running");
    hero:play();
config.lua remains unchanged.
uid: 136402 topic_id: 30336 reply_id: 121881


[TOPIC: post.html]
#11

Screaming Leaf

[GLOBAL: userInfoPane.html]
Screaming Leaf
  • Contributor

  • 144 posts
  • Corona SDK

I am not exactly sure what you mean by the @2x script, but I believe Corona will always use the data from the initial lua file; In other words if you have a 1x and a 2x file (with the 1x file not actually having the 1x suffix), Corona will base all of the coordinates off of the data in the 1x lua file that TexturePacker produced. So when it uses the images from the @2x sprite sheet, it is basing the height,width,x and y position off of the data in the 1x file. So if the two sprite sheets are not scaled correctly, your @2x images will be off.

So if your maximum resolution images are @2x, you images' dimensions should be divisible by 2. Otherwise, when it produces the 1x sprite sheet, it will have 1/2 a pixel and it will either round up or down and then your spacing will be off between the two sprite sheets. Also make sure your border padding and shape padding are changed also.

I think I read somewhere that Texture Packer might be addressing the issue or has some additional code (or maybe that is what you were referring to?) Or maybe it is in the beta. No idea and haven't looked into it.

And not sure about your second problem of the items being scaled up.

uid: 94868 topic_id: 30336 reply_id: 122140


[TOPIC: post.html]
#12

clalvial

[GLOBAL: userInfoPane.html]
clalvial
  • Enthusiast

  • 31 posts
  • Corona SDK

When I say "the @2x script" I talk about the script generated by Texture Packer. For example, if I create a spritesheet called heroanimations, and I use the AutoSD, then i get 4 files.

heroanimations.png
heroanimations.lua
heroanimations@2x.png
heroanimations@2x.lua

What I suspect is that even if Corona loads the higher res sprites, it still uses the original lua script. Causing the coordinates to be wrong and causing the messy animations. I upgraded to Texture Packer beta (that has a reworked AutoSD feature) but the issue is still the same.

I really don't know what could be wrong here...
uid: 136402 topic_id: 30336 reply_id: 122355


[TOPIC: post.html]
#13

krystian6

[GLOBAL: userInfoPane.html]
krystian6
  • Contributor

  • 560 posts
  • Corona SDK

Your expectation is correct.
Corona does load all resolutions using the 'base' one.
Unfortunately, because Texture Packer is redoing it's algorithms for each of them, they may look different. Well they actually do. Up until week ago, you could use one of the betas, where there was an option to solve it by using base sorting by name, without trimming and NOT using auto-sd but scale.
Unfortunately, this beta has expired and all of the new betas will generate different layouts.

Although Andreas responds to issues pretty quick, this one seems to be either tough nut to crack or he is focused on something else. Either way I'm screwed ;)
I'm looking into different ways of solving the problem.

I've got around 30 imagesheets which I generate using ant script, so It's quite automated.
I will try to generate the sheet and lua file for HD files and then convert it to SD file on my own [imagemagick/automator here we come :) ].
I think that by modifying the exporter to multiply all of the values by 0.5 I will be able to get the SD coordinates. Hopefully it will work.
If I get something working I will share. I've ran few queries here and there but couldn't find a working solution.
uid: 109453 topic_id: 30336 reply_id: 122507


[TOPIC: post.html]
#14

Screaming Leaf

[GLOBAL: userInfoPane.html]
Screaming Leaf
  • Contributor

  • 144 posts
  • Corona SDK

Well this is my process:

My hi-res images are @4x resolution (for the new ipad). And I make sure each image's dimensions are evenly divisible by 4.
In Texture Packer, I import the @4x images and change the border padding and shape padding to 8.
Save it with the @4x suffix.
Then I change the filenames to the @2x suffix, the scale to .5, the border and shape padding to 4.
Save it.
Then I change the filenames to no suffix, the scale to .25, the border and shape padding to 2.
Save it.

I haven't had any problems after that.
uid: 94868 topic_id: 30336 reply_id: 122513


[TOPIC: post.html]
#15

krystian6

[GLOBAL: userInfoPane.html]
krystian6
  • Contributor

  • 560 posts
  • Corona SDK

@ScreamingLoaf:
but how do you load your fles?
If every one of the sheets created has a different layout, you will end up with 3 lua files, every one of them different. What then?
uid: 109453 topic_id: 30336 reply_id: 122514


[TOPIC: post.html]
#16

Screaming Leaf

[GLOBAL: userInfoPane.html]
Screaming Leaf
  • Contributor

  • 144 posts
  • Corona SDK

Wow. I went back to my code and realized I wrote a bunch of code to figure this stuff out. I did this months ago and completely forgot about it until I just looked! lol.

I use a separate lua module to reference all of my images and I use the code below to figure out the correct data from the Texture Packer file. But again all of the data is based on the dimensions of the images in the 1x image, so all of the larger files need to be scaled correctly.

Hopefully that helps you out (and works).

local function getTPdata(fileName)
--this creates a formatted options table from the Texture Packer data
--Corona uses this for the sprite sheet

	local optionTable = {}
	optionTable.frames = {}
	
	--get all of the data from the Texture Packer file
	local tempTP = require(fileName)
	local gotData = tempTP.getSpriteSheetData()
	local tempData = gotData.frames
	
	--print("TEXTURE PACKER FILE:",fileName)
	
	for j=1,#tempData do
	
		local tempName = tempData[j].name
		--My image files all have the @4x.png ending, so this is here to remove it for searching purposes later

			local atFind = string.find(tempName,"@")
			if atFind then
				tempName = string.sub(tempName,1,atFind-1) .. ".png"
			end
			
		--print("	",tempName,tempData[j].textureRect.x,tempData[j].textureRect.y,tempData[j].textureRect.width,tempData[j].textureRect.height)
		optionTable.frames[#optionTable.frames+1] = {	name=tempName,
														x=tempData[j].textureRect.x,
														y=tempData[j].textureRect.y,
														width=tempData[j].textureRect.width,
														height=tempData[j].textureRect.height
													}
	end
	
	gotData = nil
	tempData = nil
	_G[fileName] = nil
	
	return optionTable
end
--for each sprite sheet you need to setup the options table and define the dimensions of the 1x image file
local options_sprite1 = getTPdata("sprites_all")
options_sprite1.sheetContentWidth = 512
options_sprite1.sheetContentHeight = 512

--create the sprite sheet
local sheet_sprite1 = graphics.newImageSheet("spriteFileName.png",options_sprite1)

--add the sprite sheet data to a table
--purpose of this is so when you do a search for an image, it is all accessible in this table
local optionSheets = {}
optionSheets[#optionSheets+1] = {options=options_sprite1,sheet=sheet_sprite1}
local function findImage(name)
--this searches the big options table for a sprite with NAME
--returns the sheet the image was found in, frame index,width and height 
	for k=1,#optionSheets do
		local imageTable = optionSheets[k].options.frames
		
		for j=1,#imageTable do
			if imageTable[j].name == name then
				return optionSheets[k].sheet,j,imageTable[j].width,imageTable[j].height
			end
		end
	end
end
--create your image
--to make use of image dynamic scaling, you have to use display.newImageRect
local tSheet,tFrame,tWidth,tHeight = findImage(imageName)
local imageObject = display.newImageRect(tSheet,tFrame,tWidth,tHeight)

uid: 94868 topic_id: 30336 reply_id: 122525


[TOPIC: post.html]
#17

krystian6

[GLOBAL: userInfoPane.html]
krystian6
  • Contributor

  • 560 posts
  • Corona SDK

@Screaming Leaf

Thanks for the code! Unfortunately I already have a code to figure out which image file to load. Unfortunately, as you've said. In order for this to work is to have all images with the same layout and use 1x coordinates.
uid: 109453 topic_id: 30336 reply_id: 122583


[TOPIC: post.html]
#18

danedwar

[GLOBAL: userInfoPane.html]
danedwar
  • Enthusiast

  • 47 posts
  • Corona SDK

I think Andreas is working on this very problem - it's the force identical layout option that is disabled in the auto-sd dialog.

For now I just create the highest res imagesheet and lua file then use photoshop to create the other lower res versions and edit the lua file to create the base resolution values (a pain!)
uid: 77943 topic_id: 30336 reply_id: 122631


[TOPIC: post.html]
#19

krystian6

[GLOBAL: userInfoPane.html]
krystian6
  • Contributor

  • 560 posts
  • Corona SDK

@danedwar:
edit your exporter and add "* 0.5" after all of the values [or other multiplier you need].
When not using trimming this worked flawlessly for me. Now I'll test it with trimming, but I think it would be pushing it ;)

Anyway, just edit your exporter, generate the HD imagesheet and use imagemagick/automator/whatever else [even preview] to create an SD copy of your imagesheet.

Don't forget to put the * 0.5 to the width and height of your imagesheet values in your exporter!
uid: 109453 topic_id: 30336 reply_id: 122632


[TOPIC: post.html]
#20

danedwar

[GLOBAL: userInfoPane.html]
danedwar
  • Enthusiast

  • 47 posts
  • Corona SDK

Nice one! I didn't think of that :)
I've been using trimming and it seems to work fine as long as the common divisor is set correctly for the highest res you are using.
uid: 77943 topic_id: 30336 reply_id: 122806


[TOPIC: post.html]
#21

danedwar

[GLOBAL: userInfoPane.html]
danedwar
  • Enthusiast

  • 47 posts
  • Corona SDK

I've just downloaded the latest beta 3.0.0b16 and force identical layout has been added.

Just given it a quick spin and looks like it's all there and working!! Even sorts out the common divisor for you when you setup your scales in auto sd :)

Thanks Andreas!
uid: 77943 topic_id: 30336 reply_id: 122810


[TOPIC: post.html]
#22

krystian6

[GLOBAL: userInfoPane.html]
krystian6
  • Contributor

  • 560 posts
  • Corona SDK

Yeah, I've given it a try few moments ago. Everything works great, unfortunately the 'force identical layout' option was not added as the command line option.
I've got so many different imagesheets created, that creating a tps file for each and every one of them would be just a waste of time. Especially if I wanted to change a single thing in all of them later on.
uid: 109453 topic_id: 30336 reply_id: 122812


[TOPIC: post.html]
#23

clalvial

[GLOBAL: userInfoPane.html]
clalvial
  • Enthusiast

  • 31 posts
  • Corona SDK

Whoa, who would have thought I was going to spark such a discussion! he he...

I'm currently worrying about other stuff, but when I get around to it I'll play around with all things that have been mentioned, see what I can come up with.
uid: 136402 topic_id: 30336 reply_id: 122852


[TOPIC: post.html]
#24

danedwar

[GLOBAL: userInfoPane.html]
danedwar
  • Enthusiast

  • 47 posts
  • Corona SDK

There seems to be a problem with the trimming in Corona, I've checked the imagesheets and they are all fine - only seems to happen when sprites are trimmed.

Seems to be something to do with the scaling of the trimmed area - not 100% yet, but it is affecting the positioning and size of my sprites.
uid: 77943 topic_id: 30336 reply_id: 123238


[TOPIC: post.html]
#25

krystian6

[GLOBAL: userInfoPane.html]
krystian6
  • Contributor

  • 560 posts
  • Corona SDK

Hmm I didn't see this problem in my tests [still tests as I'm waiting for the command line option :/ ].
Make sure you have all of your sprites with even dimensions.
uid: 109453 topic_id: 30336 reply_id: 123239



[topic_controls]
Page 1 of 2 1 2
 
[/topic_controls]