Jump to content

Migrating to Phaser from AS3 - single onMouseDown Event listener


General
 Share

Recommended Posts

Hello!

I'm migrating from AS3 to HTML5 and decided to use Phaser. That's great, many thanks for creating it!

 

I have a question about organizing the MouseDown event listener.

 

Let's say I have 100 sprites on the screen, and if the player click on any of them, the sprite's data should be traced. In AS3 adding event listener to each of the sprites I could do:

stage.addEventListener(MouseEvent.MOUSE_DOWN, onMDown);......private function onMDown(e:MouseEvent):void{ if (e.target is Sprite){   trace("you clicked on: "+(e.target as Sprite).name); }}

Is there such a way in Phaser?

I understand, that when creating these sprites in Phaser I have to do:

for (var i=0; i<100; i++){ var spr = game.add.sprite(Math.random()*600,Math.random()*400,'PIC_SPRITE'); spr.name = 'Sprite'+i; spr.inputEnabled = true; spr.input.start(0, true); spr.events.onInputDown.add(onMDown, this);}...function onMDown(item, pointer){ console.log('you clicked on '+item.name);}

So, I wonder, do I really need to add onInputDown to each sprite? Perhaps, the same effect could be achieved by adding a single function to game.input.onDown, like I did in AS3 adding a single function to stage onMouseDown?

 

Link to comment
Share on other sites

There is a game.input.onDown event you can listen to, but it won't tell you which Sprite the event occurred on - it will literally fire whenever the mouse is pressed down (it doesn't have to happen on a sprite at all, just like in AS3).

 

BTW you don't need to call input.start.

 

You'll probably find it easier to just do this:

    //  Here we create our coins group    coins = game.add.group();    //  Now let's add 50 coins into it    for (var i = 0; i < 50; i++)    {        var coin = coins.create(game.world.randomX, game.world.randomY, 'coin', 0);    }    coins.setAll('inputEnabled', true);    //  Now using the power of callAll we can add the same input event to all coins in the group:    coins.callAll('events.onInputDown.add', 'events.onInputDown', removeCoin);

The function "removeCoin" will be sent the Sprite as the first parameter, so you can then do anything with it:

function removeCoin(item) {    item.alpha = 0.3;}
Link to comment
Share on other sites

Thank you very much!

 

Exploring Phaser I encountered one more question to ask (not sure, whether should I create a separate thread for it, but it's also about AS3->Phaser migration).

 

In AS3 I used to make a fading screen effect in this way:

1. Draw the stage to BitmapData.

2. Add a Bitmap from this BitmapData to the stage and start tweening it to alpha = 0

3. Add new game elements on the stage below the bitmap.

 

I wonder, is there a way to draw a group to BitmapData in phaser? Or, at least, draw a Phaser.Text to Phaser.BitmapData? Or is there any other way to make a "screenshot" of the current game screen in Phaser?

Link to comment
Share on other sites

group.cacheAsBitmap = true will flatten the group to a single texture which can then be manipulated as needed (no need to add this to another object, you can continue changing its position, alpha, scale etc) - this is a pixi level feature, so currently isn't covered in the Phaser docs. You can also draw stuff directly to a BitmapData or RenderTexture instance.

Link to comment
Share on other sites

Thank you. But I tried to call

content = this.game.add.group();//also adding sprites to contentcontent.cacheAsBitmap = true;FadeBMD  =this.game.add.bitmapData(800,600);FadeBMD.draw(content, 100, 100);

and I got this error:

Uncaught TypeError: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': No function was found that matched the signature provided.

Link to comment
Share on other sites

Try it this way:

// the rendertexture to use as the canvasvar fade = this.game.add.renderTexture(800, 600);// draw your content group to the rendertexturefade.renderXY(content, 0, 0, true);// create an image to hold the rendertexturevar fadeImage = this.game.add.image(0, 0, fade);// tween the image opacity to 0 over 1 second, then clean up after ourselvesthis.game.add.tween(fadeImage).to({alpha: 0}, 1000, null, true)  .onComplete.add(function() {    fadeImage.destroy();    fade.destroy();  }, this);
Link to comment
Share on other sites

Thank you very much, this worked well!

While I had troubles with internet connection I compared the performance of different ways to show the graphics.

BitmapData.copyPixels vs BitmapData.draw vs simple sprites vs RenderTexture.renderXY.

 

https://dl.dropboxusercontent.com/u/22620118/PhaserTesting/sandbox.html

 

The game's update function runs one of the functions: useCopyPixels(), useDraw(), useRender() or useSprites().

Here's their code:

                                function useCopyPixels() {					//console.log('useCopyPixels '+num);					bmd.clear(); //that's the bitmapdata used to draw the game's picture					for (var i=0; i<num; i++){						var x =  Math.random()*900;						var y =  Math.random()*700;						bmd.copyPixels(sprBMD, sprRct,x, y);//sprBMD is a BitmapData created once, the sprite is drawn onto it. sprRct is a Rectangle of this bitmapData					}						bmd.dirty = true;				}				function useDraw() {					//console.log('useDraw '+num);					bmd.clear();					for (var i=0; i<num; i++){						var x =  Math.random()*900;						var y =  Math.random()*700;						bmd.draw(spr, x, y); //spr is a Sprite which is created once as the game starts.					}							bmd.dirty = true;				}												function useRender() {					//console.log('useRender '+num);										for (var i=0; i<num; i++){						var x =  Math.random()*900;						var y =  Math.random()*700;						bmd2.renderXY(spr, x, y, i==0);//bmd2 is an RenderTexture created once as the game starts					}										}								function useSprites() {					//console.log('useSprites '+num);										for (var i=0; i<num; i++){						var x =  Math.random()*900;						var y =  Math.random()*700;						sprites[i].x = x;						sprites[i].y = y; //here we have simply sprites in a group on the stage.					}								}

I measure the times between 2 game.render calls, 2 game.update calls and between the beginning and the ending of the game's update call.

 

It appears that on the desktop copyPixels, draw and simply moving the sprites work at almost the same speed, but on mobile devices (Lenovo A850 and iPad2) copyPixes is almost twice faster.

What results will you get, I wonder? And could you, please, also, check, did I miss any possibilities for optimisation in the drawing functions code?

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

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