Thunder and Lightning Effect

NB: This code is only relevant to those using a black or dark background in their game. In this example the background is set to #111111 (one shade up from black)

You will need: A thunder clap mp3 file.

For this tutorial we will use the room name cellar but of course you will need to substitute the room name for your own.


Step 1: Create a room and call it thunderlightning
Step 2: In the room, switch to Run script and insert the following script

HideCommandBar
SetBackgroundColour ("White")
SetTimeout (2) {
  play sound ("thunder.mp3", false, false)
  SetTimeout (2) {
    SetBackgroundColour ("#111111")
    ShowCommandBar
    MoveObject (player, cellar)
  }
}

(The HideCommandBar / ShowCommandBar rule only applies to those who hide it for their game)

Step 3: In the room where you want the thunder and lightning, use the following script:

msg ("You're in the cellar bla bla bla bla bla")
SetTimeout (3) {
  MoveObject (player, thunderlightning)
}

Of course the first script could be included within the room itself, but this just feel cleaner and less fussy.

This is my first tutorial. If anyone more experienced can see any potential dangers or better ways to do this, please feel free to amend.


awesome, nicely done OurJud, another library for quest users, and media one for weather/thunder/lightning effect!


Thanks :)


Know of a way to create a flickering effect (to simulate lightning)?


Probably JavaScript because it can handle milliseconds. Quest's wait can only handle full seconds, so even though you could flick between the two background colours the quickest you can go is one second, so it wouldn't really be a flicker.

The Pixie could do a much better lightning effect - although I'm not volunteering her/him.


Thanks


Flicker code with JavaScript. Add this attribute to your game object in full code view (f9) (so only with the off-line editor unfortunately):

    <js><![CDATA[
    <script>
      events = [0];
      onColour = 'white';
      offColour = 'black';
      state = false;
      startTime = 0;
      active = null;
      
      function setTimer(col, s) {
        if (active) return;
        
        offColour = $('body').css('background-color');
        events = [0];
        onColour = col;
        d = new Date();
        startTime = d.getTime();
        active = setInterval(myTimer, 10);
        ary = s.split(';');
        count = 0;
        for (i = 0; i < ary.length; i++) {
          count += parseInt(ary[i]);
          events.push(count);
        }
        counter = events.length;
      }

      function myTimer() {
        timeNow = new Date();
        lapsed = timeNow.getTime() - startTime;
        for (var i = 0; i < events.length; i++) { 
          if (events[i] < lapsed) {
            if (state) {
              $('body').css('background-color', offColour);
            } else {
              $('body').css('background-color', onColour);
            }
            state = !state;
            events[i] = 9999999999;
            counter--;
          }
        }
        if (counter < 1) {
          clearInterval(active);
          active = null;
        }
      }      
    </script>
]]></js>

In the game start script, add this:

      JS.addText (game.js)

Now you can have flick effects, by doing something like this:

JS.eval ("setTimer('white', '50;20;50');")

Obviously "white" is the colour you want it to change to. The other three numbers are the time intervals in milliseconds; you can have as many as you like, but best to have an odd number.

It changes the body element, by the way. If you try to start a sequence when one is already running, it will get ignored.


Can't get this to work, TP. I know that must come as a massive shock to everyone, but there you go.

I've got my test game background set to #111 (almost black.

I then opened my game code and pasted your main block of JS just before the </start> and </game> tags.

Then I went to game in the UI >> script >> Start script, and added the call script.

Finally I created a room with the command test and have it run a script, into which I added your JS.eval line.

When I run the game and type test nothing happens.


It needs to go after and before tags.


So I put the code in twice?

After and before what tags?

I added the code before the </game> and </start> tags, and also after </start> but before </game> (won't let me put it after </game>) but it still doesn't work.

Sorry, I must sound like a troll at times.


No, it just goes in once. Look for the </game>and insert it just before that.


Yes, that's what I did the first time. Just checked it all again and everything is per your instructions, but it still doesn't trigger.


Have you tested this, TP, or are you just relying on your coding knowledge?


I did test it, but I now realise there was an error (offColor needs to be set inside the function). I have updated the code.

Here is a complete game; typer RED, YELLOW or WHITE to see the flash.

<!--Saved by Quest 5.6.6108.15891-->
<asl version="550">
  <include ref="English.aslx" />
  <include ref="Core.aslx" />
  <game name="flash-effect">
    <gameid>0b330506-44ce-4b60-9e4a-6c9c0b46a180</gameid>
    <version>1.0</version>
    <firstpublished>2016</firstpublished>
    <js><![CDATA[
    <script>
      events = [0];
      onColour = 'black';
      offColour = 'white';
      state = false;
      startTime = 0;
      active = null;
      
      function setTimer(col, s) {
        if (active) return;
        
        offColour = $('body').css('background-color');
        events = [0];
        onColour = col;
        d = new Date();
        startTime = d.getTime();
        active = setInterval(myTimer, 10);
        ary = s.split(';');
        count = 0;
        for (i = 0; i < ary.length; i++) {
          count += parseInt(ary[i]);
          events.push(count);
        }
        counter = events.length;
      }

      function myTimer() {
        timeNow = new Date();
        lapsed = timeNow.getTime() - startTime;
        for (var i = 0; i < events.length; i++) { 
          if (events[i] < lapsed) {
            if (state) {
              $('body').css('background-color', offColour);
            } else {
              $('body').css('background-color', onColour);
            }
            state = !state;
            events[i] = 9999999999;
            counter--;
          }
        }
        if (counter < 1) {
          clearInterval(active);
          active = null;
        }
      }
    </script>
    ]]></js>
    <start type="script">
      JS.addText (game.js)
      JS.eval ("$('body').css('background-color', 'black');")
      JS.eval ("$('#gamePanesRunning').css('background-color', 'transparent');")
      JS.eval ("$('#gamePanes').css('background-color', 'transparent');")
    </start>
    <defaultbackground>Black</defaultbackground>
    <defaultforeground>LightGray</defaultforeground>
  </game>
  <object name="room">
    <inherit name="editor_room" />
    <object name="player">
      <inherit name="editor_object" />
      <inherit name="editor_player" />
    </object>
  </object>
  <command>
    <script>
      JS.eval ("setTimer('red', '50;20;50');")
    </script>
    <pattern>red</pattern>
  </command>
  <command>
    <script>
      JS.eval ("setTimer('yellow', '150;80;150');")
    </script>
    <pattern>yellow</pattern>
  </command>
  <command>
    <pattern>white</pattern>
    <script>
      JS.eval ("setTimer('white', '100;100;100;100;100;100;100');")
    </script>
  </command>
</asl>

Man that's good! I so wish I'd asked for this before releasing my game, instead of trying to do it myself.

I love how you can not only vary the speed of the flashes, but increase the overall duration by just adding more figures to the command script.

I take it when I use this in my next game (and I will) I just need the JS code from your demo?

I still couldn't get your original to work.


I tried adding this to an existing game and couldn't trigger it, so assumed it was something I'd done with the settings. For that reason I created a brand new test game and STILL couldn't get it to work.

Then I realised it's because I'm using a custom width, which results in the affected background being pushed off either side of the screen. And therein lies the problem. Your demo only affects the background BEHIND the pane / window in which the game is set.

Is it not possible to add the flash to the actual gameplay area of the screen as well?


Can't quite believe I worked this out myself, but...

Set your game with a custom width of 1300* (this ensure the 'game window' takes up the whole width of the browser window)

And then in TP's JS code, change the three instances of body to #gameBorder (the forth instance of body can be ignored or even removed completely, as it's setting the background which is no longer visible)

*add left and right margins of about 250 while setting the custom width, otherwise the words will stretch off screen too.


You have it set up a little odd so the gameBorder div hides the body element. Replace "body" with "#gameBorder" three times and it should work (and have an odd number of intervals).


o0 I think you missed my last post, above yours, and my revised thread with my findings, but thanks all the same.

I did try to target both the body and #gameBorder elements so that the custom width wasn't necessary, but couldn't figure out how to do it.

I tried:

offColour = $('body', '#gameBorder').css('background-color');

But it didn't work.


I have to admit, having looked at your code, I do not get why it is not working. I will look some more, but it is late on Christmas Eve and I have had a bit to drink, so may not be soon...


:D I'd say you've had TOO much to drink. I got it working four posts ago, at around 6:30 this evening.

Or are you now specifically referring to why this isn't working?

offColour = $('body', '#gameBorder').css('background-color');

Hi..i am a new user here. In my case i have the switch, which will obviously turn on the lights. If you create object switch and tick the switchable option under features, you will have an option to run a script when object is turned on. In this script, I add a message to tell the player the light switch is flipped and I also make each object in the room visible. Then, in the turn off script I just do the opposite.


This thread concerns a lightning effect, Ricalii, as in thunder and lightning, not lighting in general.


This is just genius! Hope it's okay if i "steal" this code for use in my own game. It's perfect for when my wizard appears in the room :)


Go ahead, that's what TP created it for. Combine it with a clap of thunder sound file and it looks incredible (remember to have a slight delay before the thunder clap, though - light traveling faster than sound etc) :)


This topic is now closed. Topics are closed after 60 days of inactivity.

Support

Forums