Jump to content

Adding visibility flashlight affect to a mask


cococohen
 Share

Recommended Posts

I have a Phaser game created and I am able to create an updated visibility graphic object while my sprite moves.

However, like in this example, and every other I have found online: http://www.emanueleferonato.com/2014/10/21/phaser-tutorial-how-to-create-an-html5-survival-horror-game-in-6-easy-steps/,

they are using an image of the thing you want to see as the 'background', and simply .mask against the visibility graphic.

In my case, I do not have an image of the map as it is created through a tilemap generator, so my current code basically shows the opposite of what I am looking for:

agW2wfa.png

 

For this example, I created a test box in the bottom right of the screen that has nothing to do with the real map (I'll add the correct walls later to the visibility algorithm).

I want the part that is not white to be blacked out, and the whited part to be crystal clear.

 

I have tried creating a sprite of just black, and a sprite of just transparent, and had them .mask = visibility graphic. But this just overwrites everything else.

 

I have taken out the most important part of the code for reference:

  preload () {
    //load assets that are specific for this level
    this.game.load.image('blackness', '../../assets/images/blackness.jpg');
    this.game.load.image('transparent', '../../assets/images/transparent.png');
    //this.game.load.image('yellowish', '../../assets/images/yellowish.png')

  }

create () {
 this.blackness = this.game.add.sprite(0,0,'blackness');
    //this.blackness.alpha = 0.8;
    //this.transparent = this.game.add.sprite(0,0,'transparent');

 this.lightCanvas = this.game.add.graphics(0,0);
}

update() {

	  let visibility = this.createLightPolygon(this.currentPlayerSprite.x,       this.currentPlayerSprite.y);
	  this.lightCanvas.clear();

      this.lightCanvas.beginFill(0xffffff,0.5);
      console.log('visibility',visibility)
      this.lightCanvas.moveTo(visibility[0][0],visibility[0][1]);
      for(let i=1;i<=visibility.length;i++){
          this.lightCanvas.lineTo(visibility[i%visibility.length][0],visibility[i%visibility.length][1]);
      }
      //this.transparent.mask = this.lightCanvas;
      this.lightCanvas.endFill();

}

 

 

Link to comment
Share on other sites

Ended up creating a different visibility polygon called maskGraphics, adding a 'blackness' sprite over the whole game, adding another sprite object that had the entire picture of the map itself over the whole thing, then made the visibility polygon the mask of the map sprite.

 

It works!

 

create() {

    //Create game set up through tiled state by calling super
    super.create.call(this);



    this.lightAngle = Math.PI/2;
    this.numberOfRays = 600;
    this.rayLength = 300;
    this.wallsBitmap =  this.game.make.bitmapData(3200,3200);
    this.wallsBitmap.draw('mapbitmap');
    this.wallsBitmap.update();
    this.game.add.sprite(0,0,this.wallsBitmap);
    this.maskGraphics = this.game.add.graphics(0,0);
    this.blackness = this.game.add.sprite(0,0,'blackness');
    this.blackness.alpha = 0.7;
    this.mapSprite = this.game.add.sprite(0,0,'map');

...
}


update () {
...

    let mouseAngle = Math.atan2(this.currentPlayerSprite.y-this.game.input.activePointer.worldY,this.currentPlayerSprite.x-this.game.input.activePointer.worldX);
    this.maskGraphics.clear();
    this.maskGraphics.lineStyle(2, 0xffffff, 1);
    this.maskGraphics.beginFill(0xffff00, 0.5);
    this.maskGraphics.moveTo(this.currentPlayerSprite.x, this.currentPlayerSprite.y);
    for(var i = 0; i<this.numberOfRays; i++){
      //this.maskGraphics.moveTo(this.currentPlayerSprite.x,this.currentPlayerSprite.y);
      let rayAngle = mouseAngle-(this.lightAngle/2)+(this.lightAngle/this.numberOfRays)*i
      let lastX = this.currentPlayerSprite.x;
      let lastY = this.currentPlayerSprite.y;
      for(let j= 1; j<=this.rayLength;j+=1){
        var landingX = Math.ceil(this.currentPlayerSprite.x-(2*j)*Math.cos(rayAngle));
        var landingY = Math.ceil(this.currentPlayerSprite.y-(2*j)*Math.sin(rayAngle));
        if(this.wallsBitmap.getPixel32(landingX,landingY)===0){
          lastX = landingX;
          lastY = landingY;
        }
        else{
          this.maskGraphics.lineTo(lastX,lastY);
          break;
        }
      }
      this.maskGraphics.lineTo(lastX,lastY);
    }
    this.maskGraphics.lineTo(this.currentPlayerSprite.x,this.currentPlayerSprite.y);
    this.maskGraphics.endFill();
    this.mapSprite.mask = this.maskGraphics;


}

However, I still haven't been able to find a way to hide other entities (other players/sprites) when they are not in the visibility polygon.

 

Thanks for your help! 

Link to comment
Share on other sites

  • 8 months later...

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