Jump to content
This forum will be closing down. Please move to the respective dedicated project forums.

shake effect


Recommended Posts

I try to shake the camera on a timer but it does not move, what could be wrong?


cameraShake: function() {
        var min = -20;
        var max = 20;
        this.game.camera.x+= Math.floor(Math.random() * (max - min + 1)) + min;
        this.game.camera.y+= Math.floor(Math.random() * (max - min + 1)) + min;

Link to comment
Share on other sites

  • 2 months later...

Sorry if it's inappropriate to bump this thread. Can someone give me a little example of how this could be applied?


This is what I tried: (yeah, yeah laugh at the idiot ;_; )

Function shakerino() {for(var i=0;i<6;i++){			var rand1 = game.rnd.integerInRange(-20,20);		var rand2 = game.rnd.integerInRange(-20,20);		var rand3 = game.rnd.integerInRange(-20,20);		var rand4 = game.rnd.integerInRange(-20,20);		game.world.setBounds(rand1, rand2, game.width + rand3, game.height + rand4);	}		game.world.setBounds(0, 0, game.width,game.height); // normalize after shake?} // Nothing at all seems to happen when I call this funct
Link to comment
Share on other sites

I guess you placed this code in your update function.


The problem is you have to think of what a phaser game does for every frame that is displayed on screen:

- calls your updated functions

- does physic-engine stuff

- paints the sprites on screen


This happens over and over again.


If you change the world-bounds in the update function, and then put them right back where they were, then by the time we reach the painting code, nothing has moved at all.


So the solution is to get rid of the loop, and only reset the world bounds after you have shaken the world enough.

(To check if we have shaken enough we should check a counter or the time.)


Quick example:



put a variable somewhere (for example global):

var shakeWorld = 0;

in the update function put:

if (shakeWorld > 0) {   var rand1 = game.rnd.integerInRange(-20,20);   var rand2 = game.rnd.integerInRange(-20,20);    game.world.setBounds(rand1, rand2, game.width + rand1, game.height + rand2);    shakeWorld--;    if (shakeWorld == 0) {        game.world.setBounds(0, 0, game.width,game.height); // normalize after shake?    }}

when ever you want to shake the world you do this:

shakeWorld = 80;


Now the world will shake for the next 80 frames.


If you want the shake effekt to have a duration that is not framerate dependend you have to switch from a simple counter to a timestamp and a little calculation.

Link to comment
Share on other sites

In addition to jpdev's post you can also control the magnitude of the shake based on how long it has been shaking. For example, if you wanted an immediate blast to shake the camera at a rand of -20/+20, and then have that amount trickle down over 40 frames of the game, you could do something like the following. This would separate the duration from the magnitude.


// global vars, or attach them to the current statevar shakeWorld = 0;var shakeWorldMax = 20;var shakeWorldTime = 0;var shakeWorldTimeMax = 40;// on updateif (shakeWorldTime > 0) {   var magnitude = ( shakeWorldTime / shakeWorldTimeMax ) * shakeWorldMax;   var rand1 = game.rnd.integerInRange(-magnitude,magnitude);   var rand2 = game.rnd.integerInRange(-magnitude,magnitude);    game.world.setBounds(rand1, rand2, game.width + rand1, game.height + rand2);    shakeWorldTime--;    if (shakeWorldTime == 0) {        game.world.setBounds(0, 0, game.width,game.height); // normalize after shake?    }}// then, whenever you want the shake to be triggered (bullet fired, land on ground, boss appearance, etc.)shakeWorldTime = shakeWorldTimeMax;

This allows for short violent shakes or long subtle shakes, without a sharp cut off of non-shake once you settle back to zero.

Link to comment
Share on other sites

This was something I was looking for too and works perfectly.


I am however having one very small issue, when it normalises after shake, I sometimes get a 1 or 2px gap to the right or bottom of my game screen.


Is anyone else seeing this or know why it would be doing this?



After testing a little more it seems to be something to do with setting the first two params in the setBounds function, when removing rand1 and rand2 and keeping them as 0 it doesn't seem to happen and you still get a good shake effect for anyone coming across this issue.


Would still be good to understand why this is happening though as these values are getting reset to 0 afterwards anyway.

Link to comment
Share on other sites

It looks like the issue is that the normalize code might not be getting run. Try changing it to less than or equal to zero:

if (shakeWorldTime <= 0) {    console.log('normalized'); // test if this is ever getting run, watch your console    game.world.setBounds(0, 0, game.width,game.height); // normalize after shake?}

Glad it is working for the most part!

Link to comment
Share on other sites

  • 2 months later...


I used the code from jackrugile for my game to shake the screen every time the player dies. But after the shaking of the world the camera stops following the player.

Apparently I am doing something wrong, can someone help me and tell me what.

Link to comment
Share on other sites

Heya! I just transitioned from flixel to phaser and loving it so far! TONS OF ♥♥♥ for Richard!


I've got the shaking to work fine too thanks jackrugile for sharing. That gave me a bit of insight. I just have one problem now, so I had to bump this.


This seems to also reset my camera to 0.0 for x and y ...  I tried entering the old current offsets as variables to get that back to where it was... BUT Since my bullets are set to die when off screen, after a shake they get killed earlier (by the camera offset I entered into the game.world.setBounds(96, 0, game.width,game.height)... and re-setting the camera.x doesn't seem to have an effect after setting the bounds?!


Do I need to recalculate any other bounds? Thanks for any advice

Link to comment
Share on other sites

  • 2 months later...
  • 1 month later...



Cool link, I wonder if this could be rolled into a function and submitted as a PR. I have hacked it into my group just for quickness (not shaking camera, shaking a display object) so I do not think it is limited to the camera.  Also I am not sure where this belongs in the code. (Utils etc?)

Link to comment
Share on other sites

  • 10 months later...

  • Recently Browsing   0 members

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