Jump to content

Animating Composite Sprites


idontknow
 Share

Recommended Posts

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?

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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 :P. Are there any plans to add a slotted sprite class into a new version?

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

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