Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

imgMap does not work with complex sprites #414

Closed
reececomo opened this issue Feb 8, 2024 · 5 comments
Closed

imgMap does not work with complex sprites #414

reececomo opened this issue Feb 8, 2024 · 5 comments

Comments

@reececomo
Copy link

reececomo commented Feb 8, 2024

Hey there, not sure if we're doing something wrong.

When using a simple texture, or a Sprite.from(TEXTURE), it works great, but if we have a Sprite that contains two sprites, it doesn't render anything for the <key/>:

// For "WASD" layout, returns 'W' on QWERTY/QWERTZ, 'Z' on AZERTY, 'В' on JCUKEN, etc.
//  but could also be bound to another key layout like "ESDF".
const localizedKey = getLocalizedDisplayKey(KeyBind.Jump);

// This is just a plain Sprite with a PIXI.Text inside of it:
const localizedLabelKeySprite = new KeyboardKeySprite( localizedKey );

// In practice the "Press <key/> to jump" would be localized:
const instructionText = new TaggedText('Press <key/> to jump', {
  key: {
    imgSrc: 'keyImg',
    imgDisplay: 'icon',
  }
}, {
  imgMap: {
    keyImg: localizedLabelKeySprite,
  }
});

As a counter-example, showing a plain sprite, a texture or raw asset url works great (but doesn't help with dynamically-configured keys):

  imgMap: {
    keyImg: '/assets/img/ui/input/blank_key.png',
  }

Note: This is not related to #393 (PIXI.BitmapText), this is using plain PIXI.Text / TaggedText.

Would a RenderTexture help? 🤔

@reececomo
Copy link
Author

For context, this is for showing localized labels like "Press <key> to <action>" for different, user-configured layouts:

keys

Would like to avoid creating spritesheets/hundreds of textures for all the different layouts and languages, given that all the keys would be basically identical 😆

@mimshwright
Copy link
Owner

To be honest, I haven't tested this with dynamic sprites. Part of the reason is that I was developing this library based on requests for a specific use case. You have been using it for another use case and it's been showing a bunch of important issues with the library.

When you create a new TaggedText and provide an imgMap, you're actually providing a template for the sprite you want to display. That template is recreated by the library to make as many copies as needed (so you can do like )

The code that clones the sprite is:

// pixiUtils.ts
export const cloneSprite = (sprite: PIXI.Sprite): PIXI.Sprite =>
  new PIXI.Sprite(sprite.texture);

So you can see that I never anticipated the interactive sprites. 😓

I think it should be possible to either rewrite the cloneSprite function or use something like https://pixijs.download/dev/docs/PIXI.Renderer.html#generateTexture . The only real constraint is the sprite would need to have some fixed width and height at the time it's rendered. I presume you'd need to recreate or redraw each time the key label changes too.

@reececomo
Copy link
Author

Nice, all good!

You have been using it for another use case and it's been showing a bunch of important issues with the library.

It's still the best library out there for what it does do.

I think it should be possible to either rewrite the cloneSprite function

Will do - just wanted to check that it definitely wasn't supported out of the box. I think we can make all our input icons (gamepad button, keyboard keys) fit into some fixed-size container. Will report back!

sitenote, I wonder if it could be as easy as:

export const cloneSprite = (sprite: PIXI.Sprite): PIXI.Sprite =>
  sprite.clone();

(or ...come to think of it, do we need to clone? or is that just for multiple occurrences)

@reececomo
Copy link
Author

Ignore me, I think I imagined that sprite.clone() exists 😆

@reececomo
Copy link
Author

Had a quick crack on my lunchbreak and it didn't work first try (boo).

In practice these for us would just be one-liners (no wraparound), so might just glue together raw PIXI.Text.

const TOKEN = "<key>";
const value: string = t("Press <key> to jump"); // translated value

const startMiddleOrEnd = value.startsWith(TOKEN) ? 'start' : value.endsWidth(TOKEN) ? 'end' : 'middle';
const parts = text.split(TOKEN) as [string] | [string, string];

const instruction = new Container();

switch (startMiddleOrEnd) {
  case 'start':
    instruction.addChild(keySprite, makePixiText(parts[0]));
    break;

  case 'end':
    instruction.addChild(makePixiText(parts[0]), keySprite);
    break;

  case 'middle':
    const texts = parts.map(makePixiText);
    instruction.addChild(texts[0], keySprite, texts[1]);
    break;
}

// do layout for instruction.children, etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants