piotr Posted September 5, 2015 Share Posted September 5, 2015 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. Thanksp. Link to comment Share on other sites More sharing options...
wayfinder Posted September 5, 2015 Share Posted September 5, 2015 just apply them separately. Link to comment Share on other sites More sharing options...
piotr Posted September 5, 2015 Author Share Posted September 5, 2015 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 More sharing options...
wayfinder Posted September 5, 2015 Share Posted September 5, 2015 make two separate objects, one for the light and one for the shadows. Link to comment Share on other sites More sharing options...
piotr Posted September 7, 2015 Author Share Posted September 7, 2015 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 More sharing options...
piotr Posted September 8, 2015 Author Share Posted September 8, 2015 Final, working code is here:- draws to two gradients, one set to screen the other to multiply- follow the playercreateLighAndShadow: 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;}, jdnichollsc 1 Link to comment Share on other sites More sharing options...
Recommended Posts