Jump to content

Phaser Update/Render Race Condition


amadeus
 Share

Recommended Posts

I have been banging my head against a wall with this for a while, so I am posting here to hopefully get some more insight.

 

The premise is simple, based on what I learned from this thread I posted earlier (in which I got a super helpful answer, thanks george!), I have created a reflection sprite that creates this effect on a group of sprites.

 

I did this by subclassing Sprite like so:

 



var Reflection = function(game, x, y, width, height, group){
this._texture = game.make.renderTexture(width, height);
Phaser.Sprite.call(this, game, x, y, this._texture);
this._group = group;
this.scale.y = -1;
this.alpha = 0.4;
};

Reflection.prototype = Object.create(Phaser.Sprite.prototype);
Reflection.prototype.constructor = Reflection;

Reflection.prototype.updateMirror = function(){
this._texture.renderXY(this._group, 0, 0, true);
};


 

Basically I created a new type of sprite that stores a couple other required references and added an .updateMirror function that is supposed to update the texture from the current group.

 

Next I am attempting to use a tween to move one of the sprites across screen. Here's a JSFiddle of the effect:

 


 

It seems to work, however if you look closely, there is a subtle issue where it appears that the mirror is about a frame behind.

 

In this second example, I extended Phaser.Game to utilize PIXI's resolution paramater to blow up the canvas better and make it more clear what is happening:

 


 

I've tried calling the .updateMirror function in the state's render method, but still to no avail.

 

I must be missing something stupidly obvious here, but I am not quite sure.

 

Link to comment
Share on other sites

state.render is called AFTER everything has been drawn for the frame. preRender is called right BEFORE, so any changes you make there will be reflected in the frame, while anything you do in render will only apply in the next.

 

Right, I gathered that. I've tested the following methods - update/render/preRender, all the same results. I think where it gets complicated is I have to call updateMirror AFTER the group was rendered, but BEFORE the mirror is rendered. Which I am not quite sure how to pull off exactly.

Link to comment
Share on other sites

I think you can solve this by using preRender but also by doing an updateTransform at the start of preRender, on any object you need mirrored. So if you only have say 10 sprites being mirrored then update their transforms at the start of preRender, then mirror them. If you've got hundreds of them then do updateTransform on the whole stage.

Link to comment
Share on other sites

I think you can solve this by using preRender but also by doing an updateTransform at the start of preRender, on any object you need mirrored. So if you only have say 10 sprites being mirrored then update their transforms at the start of preRender, then mirror them. If you've got hundreds of them then do updateTransform on the whole stage.

Thanks so much for the response! I updated the fiddle as per your feedback, however it doesn't seem to solve it:

 

http://jsfiddle.net/amadeus/zrd2mbd4/3/

 

Also, a side note, for some reason, I HAVE to have the if (this.mirror) check in preRender, but not in the render or update methods, not sure why.

Link to comment
Share on other sites

Ok, through some more testing, I think I have finally solved this issue (well, it's not fully solved, it's partly my ignorance of Phaser and partly a PixiJS bug).

 

@wayfinder and @rich - you where both correct in your assertions that I use preRender. What I didn't notice at first, was that when I put updateMirror in preRender, I actually exposed an issue that looked very similar to the initial issue I was having. In my first jsFiddle, I updated it to use the preRender method, and everything works as expected:

 

http://jsfiddle.net/amadeus/zrd2mbd4/4/

 

However, if I do this same thing on my second example above, where I abused the PixiJS resolution option, everything starts to break down. You can see the example here:

 

http://jsfiddle.net/amadeus/zrd2mbd4/5/

 

What's actually happening now, is the mirror effect is sometimes ahead, and sometimes behind the actual scene moving above. This is because I believe the resolution of the canvas is at 4x, however the RenderTexture is still 1. This essentially applies a sort of rounding algo to the mirror effect, making it sometimes ahead and sometimes behind.

 

RenderTexture accepts a resolution parameter, however, the moment I updated it to match, I exposed a bug in PixiJS, which I have since reported here:

 

https://github.com/GoodBoyDigital/pixi.js/issues/1322

 

To see it more simply, just check out this fiddle I created that exposes the PixiJS bug pretty quickly (I left a comment where a line can be changed to see before/after effects of using the resolution argument in RenderTexture):

 

http://jsfiddle.net/amadeus/s87s1c3w/

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

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