Jump to content

Is it possible to use this sprite?


Aristy
 Share

Recommended Posts

Hey,

 

Today is my third day of learning Phaser and here I am with one more question. I found a sprite like this, but I am not sure if Phaser supports it.

 

qo61wbN.png

 

This sprite has no standard dimensions (and I've tried everything I could, splitted frames, got them to the same size, used atlas to load them etc.) but none of them worked. Frame where she swings the sword is too big. It messes up the character collision. (since first and last images should be small in height, but others should be a bit bigger)

 

Width also causes problems, since character is located in different places on each frame (frame 1: right side, frame 2: middle, frame 5: left side) it looks weird during gameplay.

 

Is it possible to make use of this sprite somehow? I thought about taking sword from all frames and keeping it in a secondary atlas. Make the girl's size and position same on each frame, and attach the sword layer on top of her somehow. And if I can find a way to run a callback where player.animations.frame.5 is being executed, I can damage all monsters between player.x to player.x + 50.

 

Would that work like that? I'm not even sure if that is a good plan.

Link to comment
Share on other sites

this is ptobably a texture ATLAS.. split them up and recreate the atlas with spritesheetpacker or texture packer or any other suitsble tool so you get the fitting json file too

 

I did it. The problem is, since widths are not equal and character position is different, character does slides to right effect while attacking.

 

Here is a similar issue with another character I used tonight. It is an atlas. Took the frames with ASU, merged them with TexturePackager as Atlas.

 

qNZZ0Ot.gif

 

This is how it looks in the TexturePackager:

 

HRkaEjK.png

Link to comment
Share on other sites

Are you sure, that your separate images 0.png ... 7.png has same dimensions? It must have the same dimensions - it means there will be lot of free space in some of them. Do not worry, TP will trim this space and keep information on inner position in exported JSON.

 

For example this is JSON for image that fully fills frame it is drawn in:

{    "filename": "TileCeiling",    "frame": {"x":806,"y":1,"w":160,"h":160},    "rotated": false,    "trimmed": true,    "spriteSourceSize": {"x":0,"y":0,"w":160,"h":160},    "sourceSize": {"w":160,"h":160}},

and this is JSON for image that only partialy fills frame it is draw in:

{    "filename": "LaserVertical",    "frame": {"x":942,"y":163,"w":56,"h":160},    "rotated": false,    "trimmed": true,    "spriteSourceSize": {"x":52,"y":0,"w":56,"h":160},    "sourceSize": {"w":160,"h":160}},

See last line "sourceSize". It is info on original frame size, while "spriteSourceSize" is rectangle within this original frame.

Link to comment
Share on other sites

The problem with sprite sheets like this is that they're just ripped from the games and usually not aligned for actual playback.

 

You will need to manually adjust every single frame by hand in an art package to ensure they align correctly before converting to a texture atlas. This will need doing before this sheet will be of any use in a game.

Link to comment
Share on other sites

Hi,

 

Thanks, that solved my issue. Had to do alot of test/trial until I fixed the animation. There are two issues, though.

 

1. When I move all images to TexturePacker, it aligns images to top. (like in the image you can see on my previous message) Is there any way to line them in the bottom so dealing with Y axis would be as easy as possible?

2. When I generate an Atlas out of Textture packer, I get a JSON file along with the Atlas image. Then I manually modify .json file to get the pixel perfect look. The problem is, how can I add more animations to this Atlas in the future? It will override the json file (which is no biggie, I can only copy paste the updated json to previous one) but it sometimes reorders images things get messy.

 

Can I tell texture packer to keep contents of the folder in the same line? For example, images in 'idle' folder should be on y:0 to y:110, moveleft should be on 110 to 220, so when I add a third folder in the future, it automatically starts loading images in the y:220?

 

3. Can I attach animations dynamically? Instead of having one playerAtlas, I believe it would be better to have more atlases that can be bound on the player. Something like:
 

game.load.atlasHash('player.idle');game.load.atlasHash('player.left');game.load.atlasHash('player.right');var animIdle = new Animation('player.idle', Phaser.Animation.generateFrameNames('i', 1, 9, '.png'), 15, true);var animLeft = new Animation('player.idle', Phaser.Animation.generateFrameNames('l', 1, 9, '.png'), 15, true);var animRighht = new Animation('player.idle', Phaser.Animation.generateFrameNames('r', 1, 9, '.png'), 15, true);var player = game.sprite.add('player');player.animations.add('idle', [...], 20, animIdle);player.animations.add('left', [...], 20, animLeft);player.animations.add('right', [...], 20, animRight);

it would be much more maintainable for me. Also, I can then use apps like Piskerapp to generate sprites and align them easily.

 

Thank you!

Link to comment
Share on other sites

1) sprite.anchor.y = 1 will make the texture align on the bottom with whatever y axis you give the sprite.

 

2) What are you changing in the atlas to get a 'pixel perfect look' ? I don't get this part. If you've prepared the sprite sheet correctly then you shouldn't need to change anything in there. And no to the question about telling it not to change things around - the whole point is that it will automatically try to find the best possible fit for the contents, so if you add a new image to the atlas then it'll recalculate everything in order to do this.

 

3) A Sprite can only have 1 texture bound to it. That one texture needs to contain all frames of all animations for the Sprite. Otherwise you'll need to Sprite.loadTexture whenever you change animation, which isn't a great solution typically.

Link to comment
Share on other sites

2) What are you changing in the atlas to get a 'pixel perfect look' ? I don't get this part.

 

Okay let me explain the issue with images.

 

I found a ripped sprite here: http://www.spriters-resource.com/fullview/26464/, used ASU to get extract images from that sprite. Since dimensions are different, when I play it as a Sprite I get the following:

 

QfF4iKx.gif

 

So, I changed the images to an Atlas with Texture Packer. Got my json output. Then I modified the values:

..."i3.png":{	"frame": {"x":300,"y":2,"w":115,"h":85},	"rotated": true,	"trimmed": true,	"spriteSourceSize": {"x":-11,"y":2,"w":115,"h":85}, //x and y is modified here	"sourceSize": {"w":115,"h":85}},...

And got the following result:

 

cuww63Z.gif

 

It is much better. (although a alot of footwork for me) Anyway, the problem starts here.

 

I want to add the following animation to my character when I hold space.

 

rmpRNP4.gif

 

I have two choices here:

 

1. Combine images of the "Attack" animation with "Player" via Texture Packer. Problem: I need to do it each time I want to add a new animation. Also, all of my previous pixel settings (changes in the JSON) will be overridden. I can backup it before and copy paste values again, but Texture Packer changes the location of images. So let's say "idle5.png" will be on a different spot each time. It makes adding new skills extremely painful.

 

2. Keep each animation in different atlasses. Inject them to player object dynamically. Something like:

player.animations.add('idle', loadFromAtlas('player/idle.png', 'player/idle.json'));player.animations.add('attack', loadFromAtlas('player/attack1.png', 'player/attack1.json'));

People say it would cause performance issues, and sounds like it is not well supported in Phaser, but it would improve maintainability of my player drastically. I could simply create a new Atlas for "Attack2", do the fine touches (changes in json), save and forget it. There is no way it would break since I do it only once.

 

In the final form, I want my game to be played like this. I am not very experienced with Phaser but this is what looks like a good practice to me:

create ->         player.animations.add('idle', loadFromAtlas('idle'));     player.animations.add('move_right', loadFromAtlas('move_right'));     player.animations.add('attack1', loadFromAtlas('attack1'));     player.animations.add('move_left', loadFromAtlas('move_left'));update ->     // When my character decides to attack a monster:            // Tween into (monster.x - 50, monster.y) over (400 miliseconds) with 'move_right' animation.            // When tween is complete, play 'attack' animation and deal random damage to monster.            // When animation is complete, tween into (player.location.x) over (400 miliseconds) with 'move_left' animation.            // Start the 'idle' animation when tween completes

Which looks something like this:

 

amberthronegif1.gif

 

The problem is, once again, my sprites being crappy. I must make them seperated and combine them during runtime somehow so I can easily fix issues like in the first gif without touching the rest of my atlas. It would also give me ability to maintain my project a bit easier, so I could add 'attack2', 'attack3' etc. with ease and inject them to my player.

 

Sorry if I can't explain myself well.

 

Ps. Let me also explain the problem with atlas generation. I currently have this Atlas:

 

jNKvzKM.png

 

When I add the attack animation into this, Texture Packer adds it to the top, so the locations of previous textures differ from the old version and I lose all the json changes I make.

Link to comment
Share on other sites

Manually editing the sprites positions in the file created by TexturePacker does not make much sense - you are right.

 

What you have to do is to align the sprites *before* you add them.

 

That means:

1) Split the sprite sheet you found on the internet into separate images.

2) Use e.g. Photoshop, Gimp or whatever to align the animations. Make sure that each frame has exactly the same size and that the character is positioned so that the animations can run without jittering.

3) Save all images.

4) Add them to TexturePacker and re-create the sheet. 

 

With this you don't have to shift the position of the sprite - everything works in place.

Link to comment
Share on other sites

Yes I agree 100% with Andreas - you need to fix the animation BEFORE you make an atlas from it, just like I suggested. Open every single frame into an art package, edit them ALL until they align and animate perfectly and THEN make an atlas from it.

 

There is no other way to do this properly. Changing pixel values by hand in the atlas file is insane as it means you could never edit that atlas again. Honestly - don't do it - fix the animation first. The atlas should be the final step of the process.

Link to comment
Share on other sites

 

 

Manually editing the sprites positions in the file created by TexturePacker does not make much sense - you are right.

 

What you have to do is to align the sprites *before* you add them.

 

That means:

1) Split the sprite sheet you found on the internet into separate images.

2) Use e.g. Photoshop, Gimp or whatever to align the animations. Make sure that each frame has exactly the same size and that the character is positioned so that the animations can run without jittering.

3) Save all images.

4) Add them to TexturePacker and re-create the sheet. 

 

With this you don't have to shift the position of the sprite - everything works in place.

 
 

Yes I agree 100% with Andreas - you need to fix the animation BEFORE you make an atlas from it, just like I suggested. Open every single frame into an art package, edit them ALL until they align and animate perfectly and THEN make an atlas from it.

 

There is no other way to do this properly. Changing pixel values by hand in the atlas file is insane as it means you could never edit that atlas again. Honestly - don't do it - fix the animation first. The atlas should be the final step of the process.

 

Thanks for the replies once again. Actually, I've tried doing that... with no luck.

 

This is what I did: I opened ASU, converted all the images in the sprite into seperate images. Then I created 10x 200x200 pixel transparent frames on piskelapp.com. Dragged each image to each frame and clicked play. Aligned them at the middle (with feet touching bottom) until I got the perfect look. Clicked on the ZIP file to get my 200x200 (x10) images seperatedly.

 

When I dragged each image into Texturepacker, it automatically removed all the transparent background and converted images back to the original state. (e.g 200x200 image became 110x90 because that is where the corners of the image is)

 

Am I supposed to combine images, and move that combined image to Atlas?

 

There is literally no way to make each image to have same height and width without having transparency on sides. The wing is really problematic. It increases the height or width of the image depending on the position as you can see in the images. (same goes for sword animation)

 

However, I think this theory may work. Let's say I made each image 200x200, then combined them to get 2000x200 sprite, then dragged that sprite to generate atlas, and finally, update the collision pointers of my character to match the body. ImpactJS had a feature where I could define collision points for my sprite, so I could target my sprite's body to be collision detected. Can we do that here? I think that should work... but that's just the theory.

 

If this would work, I would like to ask a few things:

 

1. Would that cause performance on GPU? Since there will be alot of transparent area that is going to be rendered unnecessarily.

 

2. What am I supposed to do if I get an image that is 300px wide? (let's say my character swings a huge 2 handed axe, and positioned on the left side) I need to convert every image to 300x300 again? What should do about the collision points in this case? Since this time body will be on all the way to left, while in other frames it will be at the center.

 

3. What if I keep the body in the sprites (images can be in the same size then), and move the wing animation into seperate sprite, then position sprite.wing on the sprite.player.x - 20 sprite.player.y - 40? Would that work? Maybe then I can enable collision detection on the wing sprite, and each time the wing collides something (e.g takes damage), I can do player.receiveDamage();

 

Sorry for bugging you for the past few days. I don't have much problem programming wise, but I just can't make my mind around animations. Hoping to learn the best practice doing this. :)

 

@rich; I just realized you're the core developer of Phaser. Great work!

Link to comment
Share on other sites

You're honestly over-thinking this :)

 

It doesn't matter that Texture Packer removed all the transparent area, that is exactly what a texture atlas is for. The extra spacing is factored back in automatically by Phaser when the frame is rendered. So if your sprite was 200 x 200 and gets atlased down to 60 x 60 it doesn't matter, as the frame size within Phaser will be 200 x 200 anyway. That is why it's so crucial that the animations align perfectly in their 'raw' original 200 x 200 state, because if they don't align properly there then they'll never do so in-game either.

 

The animation frames should be aligned (in your art package) based on the top-left pixel of every frame. Every frame should have the same dimensions.

 

If you've got multiple animations (flying, walking, etc) then the frame size of every animation should ideally match as well. So if 'flying' is 300x200 then you should make all other animations match that size too, and again align them all perfectly in the art package. If you don't do this then when the player goes from walking to flying you'll have to re-position the sprite in-game through code to account for the now much larger frame size.

 

There are ways around this (using an anchor for example) but I honestly find it easier to just make all anim frames match the same size to start with, then you don't need to worry about it in-game at all, and because you're converting to an atlas anyway all the excess transparent pixels are removed.

 

Alternatively yes you could move just the 'wings' or sword to their own sprites, positioned behind the player sprite - that would be a perfectly valid / sensible option!

Link to comment
Share on other sites

 

You're honestly over-thinking this  :)

 

My developer habit. Trying to figure out all the future possibilities which would limit me in the future, and so far there is always some points that doesn't tick regarding animations.

 

It doesn't matter that Texture Packer removed all the transparent area, that is exactly what a texture atlas is for. The extra spacing is factored back in automatically by Phaser when the frame is rendered. So if your sprite was 200 x 200 and gets atlased down to 60 x 60 it doesn't matter, as the frame size within Phaser will be 200 x 200 anyway. That is why it's so crucial that the animations align perfectly in their 'raw' original 200 x 200 state, because if they don't align properly there then they'll never do so in-game either.

 

Oh, didn't know that! Sounds very logical.

 

The animation frames should be aligned (in your art package) based on the top-left pixel of every frame. Every frame should have the same dimensions.

 

So I should align the tallest image to top, and my broadest image to left, and position the remaining images accordingly? Not all frames will be aligned to top-left, but they will be positioned to match the animation. Is that what you're telling me to do?

 

If you've got multiple animations (flying, walking, etc) then the frame size of every animation should ideally match as well. So if 'flying' is 300x200 then you should make all other animations match that size too, and again align them all perfectly in the art package. If you don't do this then when the player goes from walking to flying you'll have to re-position the sprite in-game through code to account for the now much larger frame size.

 

There are ways around this (using an anchor for example) but I honestly find it easier to just make all anim frames match the same size to start with, then you don't need to worry about it in-game at all, and because you're converting to an atlas anyway all the excess transparent pixels are removed.

 

Alternatively yes you could move just the 'wings' or sword to their own sprites, positioned behind the player sprite - that would be a perfectly valid / sensible option!

 

Understood. What should be done in this case: my player moves right, the wing is on the left side so the character body is on the right. (e.g player.x 0 to player.x 30 is wing, and 30 to 100 is body) When I press left, then player.body will be 0-70, and wing will be 70-100) It will make the animation switch look like my player's body is teleporting. So I suppose having the wing as a seperate image helps alot in this case?

 

I think I'll also extract the sword animation from the sprite. It could allow more functionality to my game. (e.g I can increase the size and slow the animation and call it as "Big Slash", or I could create 3x sprite and call it "Triple Slash" or something)

 

So I assume this would be a proper way:

 

Player.body: Only the body that is same in size in each frame. Contains idle, mvleft, mvright animations.

Player.assets: Things such as wings which will be positioned behind player. Not collision detected by default.

Player.animations.attack1: Only the body movement of the animation. (It would spawn the attacks.attack1 sprite, which is the sword, and give it velocity.x = 200 so it could move all the way to right and damage enemies hit). Would that work?

 

Ps. Out of topic, would you accept a Pull Request for adding following feature.

loader.onTargetLoad(['file1', 'file2', 'file3'), () => {    console.log("Files you specified are loaded.")});

Not sure if you have this functionality already.

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...