Jump to content

Pixi Sprite not drawing


rlangton
 Share

Recommended Posts

I'm having an issue where the first time I try to draw a sprite, it works fine.  I call the loader.load and within the 'complete' callback I load the sprite and render the stage.  All is good.  I then load a second page and it draws the canvas (black background so I see it) but does not render the sprite.  I can see the textures loaded if I console.log them, I can create the sprite with new Sprite(texture) and the sprite object looks the same in console.log.  But only the stage renders!  Black background, No Sprite.  

Here is a stackoverflow question with the code I am using: http://stackoverflow.com/questions/41865191/pixijs-add-sprite-works-first-time-not-second

Please help, thanks. 

Link to comment
Share on other sites

Alright, this API is making no sense to me.  If I call loader.reset() at the start, everything works.  But since these are small components on the screen and there may be many, there is no way I want to reset between drawing all of them.  This code below works the first time, then never hits the callback for loader.load the second time.  Wish I could find some straightforward code on how to do this seemingly simple thing (DRAW A SPRITE).  BTW the ngOnInit function is what is executed when the page loads.

 

    renderer: PIXI.WebGLRenderer | PIXI.CanvasRenderer;
    spriteSheet: string = 'assets/images/tiles/sprites.json';

    constructor(private el: ElementRef) {
        this.renderer = PIXI.autoDetectRenderer(64, 64);
        el.nativeElement.style.width = '64px';
        el.nativeElement.style.height = '64px';
        el.nativeElement.appendChild(this.renderer.view);
    }

    // let renderer = PIXI.autoDetectRenderer(64, 64, {antialias: false, transparent: true, resolution: 1});
    ngOnInit() {
        debugger;
        const resources = PIXI.loader.resources[this.spriteSheet];
        if (!resources) {
            PIXI.loader.add(this.spriteSheet).once('complete', (loader) => {
                this.load();
            });
        } else {
            this.load();
        }

    }

    load() {
        PIXI.loader.load((ldr, r) => {
            this.loadAvatar(r);  // this code only executed the first time!  
        });
    }

    loadAvatar(resources) {
        const stage = new PIXI.Container();
        const sprite = new PIXI.Sprite(resources[this.spriteSheet].textures[this.logo]);  // exception the second time around
        stage.addChild(sprite);
        this.renderer.render(stage);
    }

Link to comment
Share on other sites

PIXI.loader is just a default convenience instance of PIXI.loaders.Loader, it's intended to be single use, one callback and it's done. Maybe you could instantiate a new one each time to do what you're trying to do? I can't exactly tell what you're doing, but it looks like a pretty unusual setup.

Link to comment
Share on other sites

I have components on my page, they are Angular components but could as well be Web Components or React Components.  I'm drawing in each of these components from art I have stored on a tileset.  I'm not sure why this is ususual?  The code might look unusual just because I'm fumbling around it trying to get it to work :)  I've tried using a new Loader every time too.. I think that's probably the route I'm going to have to go is use a different loader for each component.  They will each have the same tileset loaded though so it seems rather inefficient.

Also all this code does is draw a single sprite in a 64x64 element on the screen, that's it.  

The problem only happens when I navigate from one page to another (it's a SPA so there is not a page reload).  New elements are rendered and those are the elements that fail to load the sprite, though I can tell the loader still exists it just doesn't work.

Link to comment
Share on other sites

This is in a web browser? Are you creating multiple rendering contexts and multiple canvases on one page? That's the part I don't understand.

If each object is using the same sprite sheet, could you load the texture once, in a global scope or as a static member of your class, and then each object could create a sprite referencing that one texture?

In any case, yes, each Loader instance will only callback once without being reset.

Link to comment
Share on other sites

Yes it's in a web browser and yes each component will need their own canvas.  The code I have posted is for a single component.  If there are other components they will execute the same code.  What you're describing is what I'm trying to do.  I'm using the PIXI loader that is in the global scope.

Link to comment
Share on other sites

So I was able to get it working and this is how.  This is global code that is executed on every page load, so on a page load I reset the loader and reload the textures:

        this.texture$ = new BehaviorSubject<PIXI.loaders.ITextureDictionary>(null);
        const loader = PIXI.loader;
        loader.reset();
        loader.add(this.spriteSheet);
        loader.load((l, resources) => {
            this.loader = l;
            this.texture$.next(resources[this.spriteSheet].textures);  // this pushes textures out to any components that want it
        });

Then the components all have access to the PIXI.loaders.ITextureDictionary so textures are shared between them and only loaded once per page load.

Link to comment
Share on other sites

After working on this awhile it is apparent a separate instance of a loader is necessary for each canvas that will be drawn.  This seems rather inefficient, and I'm curious why it is this way?  Since at times I will have 10+ canvases on the page, I'm worried about performance problems.

Link to comment
Share on other sites

4 hours ago, rlangton said:

I'm worried about performance problems.

I'd give it a go and see if there's actually a problem, and then worry about it if there is.

Is it an option to simply separate your texture atlas into individual textures and load them only on the components where they are needed?

Link to comment
Share on other sites

7 hours ago, Sambrosia said:

I'd give it a go and see if there's actually a problem, and then worry about it if there is.

Is it an option to simply separate your texture atlas into individual textures and load them only on the components where they are needed?

Thanks, that's what I plan on doing.  So just an fyi why I need multiple canvases, this is a web app that has a main "play" area (hex grid with players and npcs).  On the side there are lists of the players and npcs, which also need to draw the avatar + the hex graphic (not currently shown).  So the web layout controls where the components go on the page, it's not just one big canvas.  Also each canvas could need access to any of the same textures.  If I have other textures that could only appear in one place, I'll split those out into their own tilesets.

https://www.evernote.com/shard/s214/sh/ef7392b7-c079-4995-bfff-041d76ee84f3/b0e5e6cb15be45cebbde70159908df56

Can't wait to start getting into what pixijs can do when I begin moving around sprites and adding effects.

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...