Jump to content

[general approach request] Ho to draw two bitmaps with two different blend modes?


piotr
 Share

Recommended Posts

Hi,

 

I'd like to understand what's the best approach to draw two gradients with two different blending modes in the same scene. One should be set to screen and act as a light source, the second be set to multiply and hide most of the scene, except the area around the player (see image). Both bitmaps should follow the player.

 

Should I have two bitmapData one for each blend mode or one bitmapData added to the game and then somehow change the blending modes of each gradient? 

 

I've been trying to use Phaser.blendModes.SCREEN and Phaser.blendModes.MULTIPLY on the same bitmapData but they cancel each other. 

 

Also setting the bitmaps to fixedToCamera = true; or setting their position to the player coordinates seems to bring mixed results.

 

Thanks

p.

 

post-15566-0-00668600-1441477082.png

Link to comment
Share on other sites

Thanks for your reply.

 

How do you mean? In my understanding bitmapData is a sort of canvas to which you add bitmaps. I've managed to add a blend mode to the parent bitmapData object, but this applies to all children bitmaps. Applying different modes to the child bitmaps does nothing.

 

Here's some code:

/in createcreateLighAndShadow: function() {	// Create a bitmap texture to draw all the light effects    this.bitmap = this.game.add.bitmapData(game.global.gameWidth, game.global.gameHeight);    //fill the bitmap with white    this.bitmap.context.fillStyle = 'rgb(255, 255, 255)';    //add the bitmap to the game    var lightBitmap = this.game.add.image(0, 0, this.bitmap);    //lightBitmap.fixedToCamera = true;    //set the bitmap mode to multiply (Blend modes are only supported in WebGL)    lightBitmap.blendMode = Phaser.blendModes.MULTIPLY;    //this.bitmap.fixedToCamera = true;},//in updatedrawLightAndShadow: function() {	//Fill the bitmap with a dark shadow color    this.bitmap.context.fillStyle = 'rgb(50, 50, 50)';    this.bitmap.context.fillRect(0, 0, game.global.gameWidth, game.global.gameHeight);  	//Create a gradient for the halo around the player    var lightGradient = this.bitmap.context.createRadialGradient(this.player.x,this.player.y,0,this.player.x,this.player.y,200);    lightGradient.addColorStop(0, 'rgba(255, 255, 220, 1)');    lightGradient.addColorStop(0.15, 'rgba(255, 255, 220, 1)');    lightGradient.addColorStop(1, 'rgba(0, 0, 0, 0)');    this.bitmap.context.fillStyle = lightGradient;    // Connect the dots and fill in the shape with cones of light    this.bitmap.context.beginPath();        this.bitmap.context.moveTo(this.points[0].x, this.points[0].y);    for(var i = 0; i < this.points.length; i++) {       var xxx  = this.bitmap.context.lineTo(this.points[i].x, this.points[i].y);    }    this.bitmap.context.closePath();    this.bitmap.context.fill();    //SHADOW CIRCLE    //Add a second circle to the bitmap to obscure the rest of the game map	this.bitmap.context.beginPath();	var shadowGradient = this.bitmap.context.createRadialGradient(this.player.x,this.player.y,0,this.player.x,this.player.y,350);    	shadowGradient.addColorStop(0, 'rgba(255, 255, 255, 0.4)');	shadowGradient.addColorStop(1, 'rgba(0, 0, 0, 0)');	}    this.bitmap.context.fillStyle = shadowGradient;        //x, x, radius, starting angle, ending angle    this.bitmap.context.arc(this.player.x, this.player.y, 350, 0, Math.PI*2);    this.bitmap.context.fill();    this.bitmap.context.closePath();     //-------    //Tell the engine it should update the texture cache    this.bitmap.dirty = true;},
Link to comment
Share on other sites

Thank you, it worked. The only issues is that once the player moves beyond gameWidth and gameHeight the textures doesn't follow him. 

 

Using fixedToCamera or resetting the sprite's position to player's position it doesn't work. Any suggestions?

createLighAndShadow: function() {//create two canvas objects, one for every blend mode. Bitmaps are used as textures for objects    this.lightTexture = this.game.add.bitmapData(game.global.gameWidth, game.global.gameHeight);    this.shadowTexture = this.game.add.bitmapData(game.global.gameWidth, game.global.gameHeight);    //create sprites objects that will use the bitmaps as a texture    this.lightSprite = this.game.add.image(0, 0, this.lightTexture);    this.shadowSprite = this.game.add.image(0, 0, this.shadowTexture);    //set the blend modes for sprites    this.lightSprite.blendMode = Phaser.blendModes.SCREEN;    this.shadowSprite.blendMode = Phaser.blendModes.MULTIPLY;},drawLightAndShadow: function() {	//LIGHT 	//fill the entire texture with black, multiply will make it completely transparent, avoid alpha cause it to draw trails    this.lightTexture.context.fillStyle = 'rgb(0, 0, 0)';    //create a rect of the size of the game 	this.lightTexture.context.fillRect(0, 0, game.global.gameWidth, game.global.gameHeight);	//start the path	this.lightTexture.context.beginPath();    	//create the gradient	var lightGradient = this.lightTexture.context.createRadialGradient(this.player.x,this.player.y,0,this.player.x,this.player.y,100);    	lightGradient.addColorStop(0, 'rgba(255, 255, 220, 0.8 )');    	lightGradient.addColorStop(0.15, 'rgba(255, 255, 220, 0.8)');    	lightGradient.addColorStop(1, 'rgba(0, 0, 0, 0)');    //set the "color" of the fill to the gradient	    this.lightTexture.context.fillStyle = lightGradient;    //draw the circle    this.lightTexture.context.arc(this.player.x, this.player.y, 100, 0, Math.PI*2); //x, x, radius, starting angle, ending angle    //fill the circle    this.lightTexture.context.fill();    this.lightTexture.context.closePath();    //SHADOW    //fill the entire texture with a dark gray, avoid alpha cause it draw trails	this.shadowTexture.context.fillStyle = 'rgb(30, 30, 30)';	//create a rect of the size of the game 	this.shadowTexture.context.fillRect(0, 0, game.global.gameWidth, game.global.gameHeight);    //create a white circle inside the dark texture, multiply    this.shadowTexture.context.beginPath();    //create shadow gradiente   	var shadowGradient = this.shadowTexture.context.createRadialGradient(this.player.x,this.player.y,0,this.player.x,this.player.y,200);    	shadowGradient.addColorStop(0, 'rgb(255, 255, 255)');    	shadowGradient.addColorStop(0.5, 'rgb(255, 255, 255)');		shadowGradient.addColorStop(1, 'rgb(30, 30, 30)');	//set the "color" of the fill to the gradient	    this.shadowTexture.context.fillStyle = shadowGradient;    //draw the circle    this.shadowTexture.context.arc(this.player.x, this.player.y, 200, 0, Math.PI*2); //x, x, radius, starting angle, ending angle    //fill the circle    this.shadowTexture.context.fill();    this.shadowTexture.context.closePath();    //update the cache   	this.lightTexture.dirty = true;   	this.shadowTexture.dirty = true;},
Link to comment
Share on other sites

Final, working code is here:

- draws to two gradients, one set to screen the other to multiply

- follow the player

createLighAndShadow: function() {	//create two canvas objects, one for every blend mode. Bitmaps are used as textures for objects    this.lightTexture = this.game.add.bitmapData(this.game.width, this.game.height);    this.shadowTexture = this.game.add.bitmapData(this.game.width, this.game.height);    //create sprites objects that will use the bitmaps as a texture    this.lightSprite = this.game.add.image(this.game.camera.x, this.game.camera.y, this.lightTexture);    this.shadowSprite = this.game.add.image(this.game.camera.x, this.game.camera.y, this.shadowTexture); 	 //set the blend modes for sprites    this.lightSprite.blendMode = Phaser.blendModes.SCREEN;    this.shadowSprite.blendMode = Phaser.blendModes.MULTIPLY;},drawLightAndShadow: function() {	//calculate player's position relative's to camera	 var playerX = this.player.x - this.game.camera.x;     var playerY = this.player.y - this.game.camera.y;	//LIGHT 	//fill the entire texture with black, multiply will make it completely transparent, avoid alpha cause it to draw trails    this.lightTexture.context.fillStyle = 'rgb(0, 0, 0)';    //create a rect of the size of the game 	this.lightTexture.context.fillRect(0, 0, this.game.width, this.game.height); 	//reposition the SPRITE to match camera's position 	this.lightSprite.reset(this.game.camera.x, this.game.camera.y);	//start the path	this.lightTexture.context.beginPath();    	//create the gradient	var lightGradient = this.lightTexture.context.createRadialGradient(playerX,playerY,0,playerX,playerY,100);    	lightGradient.addColorStop(0, 'rgba(255, 255, 220, 0.8 )');    	lightGradient.addColorStop(0.15, 'rgba(255, 255, 220, 0.8)');    	lightGradient.addColorStop(1, 'rgba(0, 0, 0, 0)');    //set the "color" of the fill to the gradient	    this.lightTexture.context.fillStyle = lightGradient;    //draw the circle    this.lightTexture.context.arc(playerX,playerY, 100, 0, Math.PI*2); //x, x, radius, starting angle, ending angle    //fill the circle    this.lightTexture.context.fill();    this.lightTexture.context.closePath();    //SHADOW    //fill the entire texture with a dark gray, avoid alpha cause it draw trails	this.shadowTexture.context.fillStyle = 'rgb(30, 30, 30)';	//create a rect of the size of the game 	this.shadowTexture.context.fillRect(0, 0, this.game.width, this.game.height); 	//reposition the SPRITE to match camera's position 	this.shadowSprite.reset(this.game.camera.x, this.game.camera.y);    //create a white circle inside the dark texture, multiply    this.shadowTexture.context.beginPath();    //create shadow gradiente   	var shadowGradient = this.shadowTexture.context.createRadialGradient(playerX,playerY,0,playerX,playerY,200);    	shadowGradient.addColorStop(0, 'rgb(255, 255, 255)');    	shadowGradient.addColorStop(0.5, 'rgb(255, 255, 255)');		shadowGradient.addColorStop(1, 'rgb(30, 30, 30)');	//set the "color" of the fill to the gradient	    this.shadowTexture.context.fillStyle = shadowGradient;    //draw the circle    this.shadowTexture.context.arc(playerX,playerY, 200, 0, Math.PI*2); //x, x, radius, starting angle, ending angle    //fill the circle    this.shadowTexture.context.fill();    this.shadowTexture.context.closePath();    //update the cache   	this.lightTexture.dirty = true;   	this.shadowTexture.dirty = true;},
Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

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