I'm having issues resuming my game after pausing. It seems like the code never reads my else statement but I'm not sure how to fix it.
I've tried to use different keys and even clicking to pause/resume. I've also tried to add a function in both the create function and the update loop but I get the same issue from both.
this.input.keyboard.once('keydown_ESC', function () {
if (game.scene.isActive('default')){
game.scene.pause('default');
} else {
game.scene.resume('default');
}
});
I expect the game to resume after pressing the esc key a second time.
The reason is that the scene becomes inactive altogether, thus no function in it will run. In other words this scene's code dead stops from running. So you need some other part of the game, which will remain active (e.g running) to take over the 'resume' functionality. Without me being an expert in phaser 3. This is a workaround to achieve this by putting this inside your scripts but outside of any scene's class or code. Let's say you define your
var game = new Phaser.Game(config);
inside the script called game.html. So in there and still inside the javascript tag put this:
var global_scene_paused = false;
var global_time_paused = Date.now() - 10000;
function global_pause(scene){
if(Date.now() - global_time_paused > 2000 && game.scene.isActive(scene)){
game.scene.pause(scene);
console.log('--------- global_pause called');
global_time_paused = Date.now();
global_scene_paused = scene;
}
}
// keyCode 80 : P. Will resume by pressing 'P'
document.addEventListener('keydown', function(event) {
if(event.keyCode == 80 && Date.now() - global_time_paused > 2000 && global_scene_paused) {
game.scene.resume(global_scene_paused);
console.log('+++++++++++ RESUME');
global_scene_paused = false;
global_time_paused = Date.now();
}
});
Inside your scene add this call instead of pause:
this.input.keyboard.once('keydown_ESC', function () {
global_pause('default'); //will be unpaused in game.html
});
I am trying to implement kind of player on my website.
If press 'Play' button, the music starts and the page smoothly scrolls down.
But when you press 'Mute' button (function(){music.volume=0}) I am not sure why the page appears at the top again. window.scroll() doesn't do anything without delay. So i am using setTimeout function to scroll the page on the current place. The problem is that in Opera and IE setTimeout takes about 10 ms, so when i click 'Mute' button i see like ticks to top and back. In chrome it takes only 2 ms and there is no problems.
Now when i decide to create my own timeout function the window.scroll() does not work again.
Here is my code:
var isMuted = false;
muteButton.onclick = function() { ////This function works with big delay.
if (!isMuted) {
mainAudio.volume = 0;
isMuted = true;
} else {
mainAudio.volume = bgAudioTrackVolume;
isMuted = false;
}
setTimeout(function() {
window.scroll(0, offset); /// Works
}, 0)
};
Change setTimeout with:
i = 9542155.873; /// I have tried delay time from 1ms - 250ms by changing this value.
while (i > 0.00001) {
i = i / 1.0001234567;
if (i < 0.00001) {
window.scroll(0, offset); /// Does not do anything. Strange! Have tried to change variable with a number.
}
}
Every time i check offset value, it is always available before calling scroll function.
I know that my problem is not usual and i am realy need your help.
The reason that the page scrolls to the top is that you are using a link with the empty bookmark #, which represents the top of the page. The reason that the scroll method doesn't work without a timeout is that jumping to the bookmark happens after the event handler.
Instead of trying to scroll the page back to where it was, just stop the default action of the link by returning false from the event handler:
var isMuted = false;
muteButton.onclick = function() {
if (!isMuted) {
mainAudio.volume = 0;
isMuted = true;
} else {
mainAudio.volume = bgAudioTrackVolume;
isMuted = false;
}
return false;
};
Alternatively, use some other element than a link.
This is the slideshow script, I want it to stop when mouse move over. But i dont know what to add on it. I've tried to look for it online, but all of them doesn't work:(
<SCRIPT LANGUAGE="JavaScript">
<!--
var dimages=new Array();
var numImages=2;
for (i=0; i<numImages; i++)
{
dimages[i]=new Image();
dimages[i].src="/v/vspfiles/assets/images/image"+(i+1)+".jpg";
}
var curImage=-1;
function swapPicture()
{
if (document.images)
{
var nextImage=curImage+1;
if (nextImage>=numImages)
nextImage=0;
if (dimages[nextImage] && dimages[nextImage].complete)
{
var target=0;
if (document.images.myImage)
target=document.images.myImage;
if (document.all && document.getElementById("myImage"))
target=document.getElementById("myImage");
if (target)
{
target.src=dimages[nextImage].src;
curImage=nextImage;
}
setTimeout("swapPicture()", 4000);
}
else
{
setTimeout("swapPicture()", 1000);
}
setTimeout("swapPicture()", 4000);
//-->
Based on the info provided ( only the javascript at this point ). The slideshow script is dependent on
setTimeout();
The code responsible for stopping setTimeout(); is
clearTimeout();
Add the mouse event(s) to the slideshow and call clearTimeout(). As for the mouse events and best practices check SO for more instructions.
Here is one reference about setTimeout().
http://www.w3schools.com/js/js_timing.asp
Please post HTML for better and more accurate code on the mouse events.
I'm using Three.js with the WebGL renderer to make a game which fullscreens when a play link is clicked. For animation, I use requestAnimationFrame.
I initiate it like this:
self.animate = function()
{
self.camera.lookAt(self.scene.position);
self.renderer.render(self.scene, self.camera);
if (self.willAnimate)
window.requestAnimationFrame(self.animate, self.renderer.domElement);
}
self.startAnimating = function()
{
self.willAnimate = true;
self.animate();
}
self.stopAnimating = function()
{
self.willAnimate = false;
}
When I want to, I call the startAnimating method, and yes, it does work as intended. But, when I call the stopAnimating function, things break! There are no reported errors, though...
The setup is basically like this:
There is a play link on the page
Once the user clicks the link, a renderer's domElement should fullscreen, and it does
The startAnimating method is called and the renderer starts rendering stuff
Once escape is clicked, I register an fullscreenchange event and execute the stopAnimating method
The page tries to exit fullscreen, it does, but the entire document is completely blank
I'm pretty sure my other code is OK, and that I'm somehow stopping requestAnimationFrame in a wrong way. My explanation probably sucked, so I uploaded the code to my website, you can see it happening here: http://banehq.com/Placeholdername/main.html.
Here is the version where I don't try to call the animation methods, and fullscreening in and out works: http://banehq.com/Correct/Placeholdername/main.html.
Once play is clicked the first time, the game initializes and it's start method is executed. Once the fullscreen exits, the game's stop method is executed. Every other time that play has been clicked, the game only executes it's start method, because there is no need for it to be initialized again.
Here's how it looks:
var playLinkHasBeenClicked = function()
{
if (!started)
{
started = true;
game = new Game(container); //"container" is an empty div
}
game.start();
}
And here's how the start and stop methods look like:
self.start = function()
{
self.container.appendChild(game.renderer.domElement); //Add the renderer's domElement to an empty div
THREEx.FullScreen.request(self.container); //Request fullscreen on the div
self.renderer.setSize(screen.width, screen.height); //Adjust screensize
self.startAnimating();
}
self.stop = function()
{
self.container.removeChild(game.renderer.domElement); //Remove the renderer from the div
self.renderer.setSize(0, 0); //I guess this isn't needed, but welp
self.stopAnimating();
}
The only difference between this and the working version is that startAnimating and stopAnimating method calls in start and stop methods are commented out.
One way to start/stop is like this
var requestId;
function loop(time) {
requestId = undefined;
...
// do stuff
...
start();
}
function start() {
if (!requestId) {
requestId = window.requestAnimationFrame(loop);
}
}
function stop() {
if (requestId) {
window.cancelAnimationFrame(requestId);
requestId = undefined;
}
}
Working example:
const timeElem = document.querySelector("#time");
var requestId;
function loop(time) {
requestId = undefined;
doStuff(time)
start();
}
function start() {
if (!requestId) {
requestId = window.requestAnimationFrame(loop);
}
}
function stop() {
if (requestId) {
window.cancelAnimationFrame(requestId);
requestId = undefined;
}
}
function doStuff(time) {
timeElem.textContent = (time * 0.001).toFixed(2);
}
document.querySelector("#start").addEventListener('click', function() {
start();
});
document.querySelector("#stop").addEventListener('click', function() {
stop();
});
<button id="start">start</button>
<button id="stop">stop</button>
<div id="time"></div>
Stopping is as simple as not calling requestAnimationFrame anymore, and restarting is to call it it again.
ex)
var pause = false;
function loop(){
//... your stuff;
if(pause) return;
window.requestionAnimationFrame(loop);
}
loop(); //to start it off
pause = true; //to stop it
loop(); //to restart it
var myAnim //your requestId
function anim()
{
//bla bla bla
//it's important to update the requestId each time you're calling reuestAnimationFrame
myAnim=requestAnimationFrame(anim)
}
Let's start it
myAnim=requestAnimationFrame(anim)
Let's stop it
//the cancelation uses the last requestId
cancelAnimationFrame(myAnim)
Reference
I played around with the tutorial of a 2D Breakout Game where they also used requestAnimationFrame and I stopped it with a simple return. The return statement ends function execution if the value of return is omitted.
if(!lives) {
alert("GAME OVER");
return;
}
// looping the draw()
requestAnimationFrame(draw);
I would suggest having a look at the requestAnimationFrame polyfill gibhub page. There are discussions about how this is implemented.
So, after doing some more testing, I've found out that it was, indeed, my other code that posed a problem, not the animation stopping (it was a simple recursion after all). The problem was in dynamically adding and removing the renderer's domElement from the page. After I've stopped doing that, for there was really no reason to do so, and included it once where the initialization was happening, everything started working fine.
I have that Javascript counter:
var x=100;
function timerCountdown()
{
document.getElementById('timer1').value=x;
x--;
t=setTimeout("timerCountdown()",1000);
if (x<-1)
{
document.getElementById('timer1').value='Done!';
clearTimeout(t);
}
}
function stopCounter(){
clearTimeout(t);
x=x+1;
}
Then I use:
<body onFocus='timerCountdown()' onBlur='stopCounter()'>
But the problem is, the countdown doesn't start when the page loads. It waits for me to click on another window and to reFocus on the window again.
So I tried this:
<body onLoad='timerCountdown()' onFocus='timerCountdown()' onBlur='stopCounter()'>
But this time, the countdown goes pretty fast. Probably because timerCOuntdown is called twice every second.
Alternatively, I could just use the onFocus and onBlur in the body tag, but I need a function to trigger the Focus upon body load. Is that possible?
Does anyone have a suggestion to solve this problem?
thanks a lot!
The simple answer is because setTimeout is invoked twice, running timerCountdown() once for two times separately, and continually setting two setTimeout IDs.
This would be what you want:
var x = 100;
var t = 0;
function timerCountdown()
{
if (t == 0) t = setInterval(timerCountdown, 1000);
document.getElementById('timer1').value=x;
x--;
if (x < 0)
{
document.getElementById('timer1').value='Done!';
clearTimeout(t);
ticker = 0;
}
}
function stopCounter()
{
clearTimeout(t);
t = 0;
x++;
}
setInterval is much more suited for countdown timers, and things you need to run continually since setTimeout only runs once and you need to keep on calling it.
Edit: This fixes the initial rapid triggering of the timer on Firefox.
Remove the handler from <body onload= and add this to the end of the script block above:
t = setInterval(timerCountdown, 1000);