General

Migrating to Phaser from AS3 - single onMouseDown Event listener

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?

 

Share this post


Link to post
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;}

Share this post


Link to post
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?

Share this post


Link to post
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.

Share this post


Link to post
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.

Share this post


Link to post
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);

Share this post


Link to post
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?

Share this post


Link to post
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...

  • Recently Browsing   0 members

    No registered users viewing this page.