Jump to content

[Solved] Accurate map and sound for piano-like game


kapu
 Share

Recommended Posts

Hi =) I don't know where to find this information, so I'm asking it to you now.

I would like to make a very accurate map/background where there are some areas which plays specific music/sound when we click on it. I guess it would use the same mechanisms as pianos, and I don't know how to do it: a svg map? a tiled map with objects? other options? 

For example, if I want to use the conductor's wand to play a specific instrument when I click on it, how do I say to phaser: "Hey, at this specific area there is something to do => violin.play();".

![](Orquesta_Filarmonica_de_Jalisco.jpg)


GFDL+CC-BY 2.5 Pedro Sanchez  on wikipedia 
 
 
 
Link to comment
Share on other sites

Unsure about Phaser specifically, but a general solution is to use a color map.  E.g. the same orchestra bitmap would have a secondary bitmap with each instrument block colored with a unique color index (gaps between instruments would be blank).  Then, based on pointer click, the color map is pixel sampled at the click position, and the resulting color key used to reference a list of instruments.

Simple by design - but if using this approach be aware that different browsers can interpret color information slightly differently, so "closest value" is often better than "exact value".

An alternative, simple-geometry method is to have predefined center points for each instrument, and then find "which is closest" to the pointer click using sorted Pythagoras.  The result is a field of overlapping circles that often works surprisingly well for bulky objects.

Link to comment
Share on other sites

Thank you.

@b10b I don't really get what you mean, I say to phaser: "if I clik on red then play that sound". Is that it? I didn't even know that we could do that. And for the alternative, it sounds good, I will work with overlaps in the game, it's seem to be adequat, but I searched for 'complex' geometry.

PRhB81bK0qQe.png

 

And i thought that it was possible to draw this kind of pattern on the background/map as an object and says to Phaser: "Hey, the wand and the purple square are overlapping => play the sound". But if not I could use the tips you suggest.

@WiLD11, thank you for the idea. It seems that you can give to the button any shape you want. I will watch your cool video about that =).

Link to comment
Share on other sites

2 hours ago, kapu said:

Thank you.

@b10b I don't really get what you mean, I say to phaser: "if I clik on red then play that sound". Is that it? I didn't even know that we could do that. And for the alternative, it sounds good, I will work with overlaps in the game, it's seem to be adequat, but I searched for 'complex' geometry.

PRhB81bK0qQe.png

 

And i thought that it was possible to draw this kind of pattern on the background/map as an object and says to Phaser: "Hey, the wand and the purple square are overlapping => play the sound". But if not I could use the tips you suggest.

@WiLD11, thank you for the idea. It seems that you can give to the button any shape you want. I will watch your cool video about that =).

5

Hehe, thanks :D If you have any issues get back to me

Link to comment
Share on other sites

@WiLD11 Hey, your tutorial was helpful, but I still have a problem =/
 

I would like to use a non rectangular sprite, and I don't know how to get this.

8D6oviVub6ay.png

 

I tried  to vectorize it with inkscape, but I'm maybe doing it wrong? I have interactions with all the rectangle on Phaser. I don't know how to get the right shape for my sprite =/

 

Link to comment
Share on other sites

7 minutes ago, kapu said:

@WiLD11 Hey, your tutorial was helpful, but I still have a problem =/
 

I would like to use a non rectangular sprite, and I don't know how to get this.

8D6oviVub6ay.png

 

I tried  to vectorize it with inkscape, but I'm maybe doing it wrong? I have interactions with all the rectangle on Phaser. I don't know how to get the right shape for my sprite =/

 

https://phaser.io/examples/v2/input/pixel-perfect-click-detection This should help you

Link to comment
Share on other sites

7 minutes ago, kapu said:

Actually it doesn't work any better =/ It still plays sound in the unwanted area.

Are you using the right callbacks and sprites? it should work.

You need to get rid of buttons and use sprites input instead if you're going to use the pixel perfect method

Link to comment
Share on other sites

  lung = game.add.sprite(game.world.centerX,game.world.centerY, 'lung');;
  lung.inputEnabled = true;
  lung.input.pixelPerfectOver = true;
if (checkOverlap(stetho,lung)){
  vesicular.play();
  console.log("lung");
}

function checkOverlap(spriteA, spriteB) {

    var boundsA = spriteA.getBounds();
    var boundsB = spriteB.getBounds();

    return Phaser.Rectangle.intersects(boundsA, boundsB);

}

Well, I'm wondering if it's not working because of the Phaser.Rectangle.intersects? 

Link to comment
Share on other sites

Maybe try replacing the cursor with an image/sprite and listening for pointer events when the pointer goes over/out or is clicked on the target sprite. The code below is based on the phaser example above.

 

class BallPointer extends Phaser.Image
{
  constructor(game)
  {
    super(game, 0, 0, 'ball');
    this.anchor.setTo(0.5);
  }
  update()
  {
    super.update();
    //Follow the pointer
    this.x = this.game.input.activePointer.x;
    this.y = this.game.input.activePointer.y;
  }
}

class Bunny extends Phaser.Sprite
{
  constructor(game, x, y)
  {
    super(game, x, y, 'bunny');
    this.anchor.setTo(0.5);
    
    //  Listen for input events on this sprite
    this.inputEnabled = true;
    
    //  This will check the pixel every time the mouse moves, which is really expensive!
    //  You can also only do a pixel perfect check on click, which is much cheaper - so
    //  pick the right one accordingly.
    this.input.pixelPerfectOver = true;
    //  For pixel perfect click
    this.input.pixelPerfectClick = true;
  }
}

class MyGame extends Phaser.Game
{
  constructor()
  {
    super(800, 600, Phaser.CANVAS, 'phaser-example',
        { preload: preload, create: create, update: update});
    function preload()
    {
      this.load.image('bunny', 'assets/sprites/bunny.png');
      this.load.image('ball', 'assets/sprites/blue_ball.png');
    }
    function create()
    {
      this.bunny = new Bunny(this, this.world.centerX, this.world.centerY);
      this.world.add(this.bunny);
      this.ball = new BallPointer(this);
      this.world.add(this.ball);
      
      this.bunny.events.onInputOver.add(function()
      {
        console.log("pointer over bunny");
      }, this);
      
      this.bunny.events.onInputOut.add(function()
      {
        console.log("pointer away from bunny");
      }, this);
      
      this.bunny.events.onInputDown.add(function()
      {
        console.log("pointer clicked on bunny");
      }, this);
    }
    function update()
    {
      this.bunny.angle += 0.05;
    }
  }
}
//hide the cursor arrow
document.body.style.cursor = 'none';
var myGame = new MyGame();
  

  

 

Link to comment
Share on other sites

3 hours ago, Gold Finch said:

Maybe try replacing the cursor with an image/sprite and listening for pointer events when the pointer goes over/out or is clicked on the target sprite. The code below is based on the phaser example above.

 


class BallPointer extends Phaser.Image
{
  constructor(game)
  {
    super(game, 0, 0, 'ball');
    this.anchor.setTo(0.5);
  }
  update()
  {
    super.update();
    //Follow the pointer
    this.x = this.game.input.activePointer.x;
    this.y = this.game.input.activePointer.y;
  }
}

class Bunny extends Phaser.Image
{
  constructor(game, x, y)
  {
    super(game, x, y, 'bunny');
    this.anchor.setTo(0.5);
    
    //  Listen for input events on this sprite
    this.inputEnabled = true;
    
    //  This will check the pixel every time the mouse moves, which is really expensive!
    //  You can also only do a pixel perfect check on click, which is much cheaper - so
    //  pick the right one accordingly.
    this.input.pixelPerfectOver = true;
  }
}

class MyGame extends Phaser.Game
{
  constructor()
  {
    super(800, 600, Phaser.CANVAS, 'phaser-example',
        { preload: preload, create: create, update: update});
    function preload()
    {
      this.load.image('bunny', 'assets/sprites/bunny.png');
      this.load.image('ball', 'assets/sprites/blue_ball.png');
    }
    function create()
    {
      this.bunny = new Bunny(this, this.world.centerX, this.world.centerY);
      this.world.add(this.bunny);
      this.ball = new BallPointer(this);
      this.world.add(this.ball);
      
      this.bunny.events.onInputOver.add(function()
      {
        console.log("pointer over bunny");
      }, this);
      
      this.bunny.events.onInputOut.add(function()
      {
        console.log("pointer away from bunny");
      }, this);
      
      this.bunny.events.onInputDown.add(function()
      {
        console.log("pointer clicked on bunny");
      }, this);
    }
    function update()
    {
      this.bunny.angle += 0.05;
    }
  }
}
//hide the cursor arrow
document.body.style.cursor = 'none';
var myGame = new MyGame();
  

  

 

Nice use of classes :D

That should do it, pixel perfect clicking is only for sprite events and not collision/overlap.

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

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