idontknow Posted June 13, 2017 Share Posted June 13, 2017 I'm currently trying to animate a composite sprite and I currently have a working version, but it seems quite inefficient and I'm wondering if there's a built-in method that accomplishes what I'm trying to do. I've searched the documentation but to be quite honest, it's not that great and it's not particularly helpful. My composite sprite is composed of several parts: a head, body, arms, and a face. To create the composite sprite, each of the pieces are attached onto another piece using a common joint point, e.g. neck/shoulders/nose. Each piece can have its own independent animation frames, so for example the body could have 3 frames (e.g. chest puffing) while the face has 2 (e.g. blinking) and the rest of the parts aren't animated. The reason for splitting into different parts is to allow a high degree of customization of the player's sprite. The way I'm currently animating and rendering this composite sprite is by creating every possible permutation of the composite sprite and then adding/removing the frames as needed. For example: function createFrame1() { let head = new PIXI.Sprite(resources["assets/stand10.head.png"].texture); let body = new PIXI.Sprite(resources["assets/stand10.body.png"].texture); let arm = new PIXI.Sprite(resources["assets/stand10.arm.png"].texture); let face = new PIXI.Sprite(resources["assets/default.face.png"].texture); let sprite = new PIXI.Container(); sprite.addChild(head); sprite.addChild(body); // ... body.x = 4; body.y = 40; // ... return sprite; } function createFrame2() { let head = new PIXI.Sprite(resources["assets/stand10.head.png"].texture); let body = new PIXI.Sprite(resources["assets/stand11.body.png"].texture); let arm = new PIXI.Sprite(resources["assets/stand10.arm.png"].texture); let face = new PIXI.Sprite(resources["assets/default.face.png"].texture); let sprite = new PIXI.Container(); sprite.addChild(head); sprite.addChild(body); // ... body.x = 5; body.y = 39; // ... return sprite; } // ... let playerIdle = [ createFrame1(), createFrame2(), ..., createFrameN() ]; function animate() { requestAnimationFrame(animate); stage.removeChild(sprite); frame += 1/30; if (frame >= N) { frame = 0; } sprite = playerIdle[Math.floor(frame)]; stage.addChild(sprite); render(stage) } The issue I have with this is that if any container's properties need to be updated, there is no way to apply these changes to all the different animation frames easily - you'd need to iterate over the array and apply the settings to each container. Switching to another animation, i.e. walking, proves to be annoying as well. Is there any built-in class that can handle my use-case? Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted June 13, 2017 Share Posted June 13, 2017 One container for whole character, multiple sprites acting as "slots", and there you can change their textures. Every frame is just a set of textures, so it'll be like mySprite.frames = []; mySprite.changeFrame = function(index) { for (var i=0;i<sprite.children.length;i++) { sprite[i].texture = frames[index][i]; } } I wont paste here the full code, i think you can do it just fine. There are many shortcuts: you can fill loader with "for" , and use names for resources. I also recommend to create your own Sprite class that accepts frames, or character name as a parameter, like our AnimatedSprite but for your case. I assure you that you can do it all only with a 20-30 lines of code if you try. I would like to add it as pixi-example later, because that usecase appears often. Quote Link to comment Share on other sites More sharing options...
idontknow Posted June 13, 2017 Author Share Posted June 13, 2017 1 minute ago, ivan.popelyshev said: One container for whole character, multiple sprites acting as "slots", and there you can change their textures. Every frame is just a set of textures, so it'll be like mySprite.frames = []; mySprite.changeFrame = function(index) { for (var i=0;i<sprite.children.length;i++) { sprite[i].texture = frames[index][i]; } } I wont paste here the full code, i think you can do it just fine. There are many shortcuts: you can fill loader with "for" , and use names for resources. I also recommend to create your own Sprite class that accepts frames, or character name as a parameter, like our AnimatedSprite but for your case. I assure you that you can do it all only with a 20-30 lines of code if you try. I would like to add it as pixi-example later, because that usecase appears often. That's ultimately what I started to do, I was just hoping that someone else already did it for me and called it something weird . Are there any plans to add a slotted sprite class into a new version? Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted June 13, 2017 Share Posted June 13, 2017 There are many other usecases that need to be added too I dont know about that one yet. Quote Link to comment Share on other sites More sharing options...
Exca Posted June 14, 2017 Share Posted June 14, 2017 I have made one composite sprite. Basically did it by having one container with custom animationcontroller (based on animatedsprite, just added the possibility to have multiple sets of textures). You give it a bunch of animationnames + textures corresponding for those and the first animationcontroller acts as a master controller. Each other are then synced to that animationcontroller each frame and when animation changes (for example from walk to jump) then you just go through each of the children and change their animation also. If some of the child controllers are missing some frames, then they are hidden for those frames/animations. Requires some planning on how to do the actual spritesheets and how naming is done, but worked pretty good for my usecase where the slotting was done to preserve image loading time. Haven't got a generic version of that code available, but I'll see if I can make one later. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.