Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
There is a stackoverflow post by a guy called Gustavo Carvalho that shows how camera/viewport works in a HTML5 game.
All's good except that setInterval is used instead of requestAnimationFrame.
I tried converting to requestAnimationFrame without success :-(
Can somebody pls help? Here's the post:
Simple HTML5 game camera/viewport
Thanks very much!
EDIT: After reviewing the answers below, I came up with this solution:
REPLACE THE FOLLOWING CODE...
// Game Loop
var gameLoop = function(){
update();
draw();
}
// <-- configure play/pause capabilities:
var runningId = -1;
Game.play = function(){
if(runningId == -1){
//Use setInterval instead of requestAnimationFrame for compatibility reason
runningId = setInterval(function(){
gameLoop();
}, INTERVAL);
console.log("play");
}
}
Game.togglePause = function(){
if(runningId == -1){
Game.play();
}
else
{
clearInterval(runningId);
runningId = -1;
console.log("paused");
}
}
// -->
REPLACE WITH THIS ONE...
// Game Loop
var gameLoop = function(){
if(gameStatus == 'play'){
update();
draw();
}
window.requestAnimationFrame(gameLoop);
}
var gameStatus = 'play';
Game.play = function() {
gameLoop();
}
Game.togglePause = function() {
if(gameStatus == 'play'){
gameStatus = 'pause';
console.log(gameStatus);
}
else if(gameStatus == 'pause'){
gameStatus = 'play';
console.log(gameStatus);
}
}
You can modify the following parts of the code to:
/// add a flag as condition for loop
var isPlaying = true;
// Game Loop
function gameLoop(){
update();
draw();
/// incorporate loop here
if (isPlaying)
requstAnimationFrame(gameLoop);
}
And then:
Game.play = function(){
if (!isPlaying){
isPlaying = true; /// enable looping
gameLoop(); /// start loop
console.log("play");
}
}
Game.togglePause = function(){
if(!isPlaying){
Game.play();
}
else
{
isPlaying = false; /// this will terminate loop
console.log("paused");
}
}
Note that for latest versions of Firefox and Chrome the requestAnimationFrame is now unprefixed. For older and other browsers you might need to use a polyfill.
The call to requestAnimationFrame function has to actually provide loop in its first argument, that happens to be a function.
So roughly speaking, do something like this:
function draw() {
// some drawing on a canvas happens here
}
function game_loop() {
var callback = function(t) {
draw();
// loop the whole thing:)
game_loop();
};
window.requestAnimationFrame(callback);
}
Related
This is an small snipped of a game developed in javascript.
It has a main function that loops infinitely.
PROBLEM
I want a single alert to show up when the character dies, otherwise it appears thousands of alerts due to the loop
characterDead = false;
function colision(){
//if colision > true
charactedDead = true;
alert("the character died")
}
function main(){
//...other functions
colision();
requestAnimationFrame(main);
}
window.onload = function() {main();};
You need a characterDead check in colision().
Also, you have a typo - "charactedDead" should be "characterDead" in the same function :)
var characterDead = false;
function colision() {
if (!characterDead) { // check if the character is dead already
characterDead = true; // kill it
console.log("the character died"); // alert or log this
}
}
function main() {
//...other functions
colision();
requestAnimationFrame(main);
}
window.onload = function() {
main();
};
This question already has answers here:
Repeat code every x seconds but not if [insert check here]
(3 answers)
Do something every 5 seconds and the code to stop it. (JQuery)
(4 answers)
Call a Javascript function every x seconds and stop after y seconds?
(1 answer)
Closed 4 years ago.
Thanks for the attention, and sorry form my very bad english.
I have a nice function using jQuery:
function(){
//do something
if(certain conditions){
return true;
}else{
return false;
}
}
The function work nice... But I need to execute it every X seconds, while the function returns false. If the function returns true, the loop must be stopped.
I have not idea how to do that... Can you help me? Thanks in advance...
you could use an setInterval combined with clearInterval.
var interval = setInterval(function(){
if(certain conditions)
{
// this will prevent the function from running again
clearInterval(interval);
return true;
}
return false;
},1000); // 1000 ms or, 1 sec
You can always use the good old window.setInterval():
var interval = 500;
function callback(){
//your function call here
var result = yourFunction();
//check if we need to clear the timeout
if(result == true){
clearTimeout(handle);
}
}
var handle = setInterval(callback, interval)
Here's a snippet.
var interval = 500;
function callback(){
//your function call here
var result = yourFunction();
//check if we need to clear the timeout
if(result == true){
clearTimeout(handle);
}
}
var handle = setInterval(callback, interval)
function yourFunction(){
document.write(new Date().toLocaleTimeString())
if(Math.random() > 0.2){return false}
else return true;
}
You are looking for the window.setTimeout function.
function yourFunction(){
// do your task
if(1 == 1 /* the condition to make the loop continue*/){
return true;
}else{
return false;
}
}
function loop(){
if(yourFunction()){
window.setTimeout(loop, 1000);
}
}
loop();
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
My question is related to the play function. How can I call this Player.play() method recursively call?
Using this.player.play() is not working.
function Player(playlist){
open:function(){
//doing some stuff here
}
play:function(){
if(picture){
//document.getElementById("img").src =playlist[n]
}
}
}
var player = new Player([link1, link2, link3]);
document.getElementById("play-btn").addEventListener("click", player.play())
At first, your syntax is a comvination of a function and a class, you may use a class like:
class Player {
constructor(links,element){
this.images = links;
this.position = 0;
this.element = element;
}
//...
}
Then you can set an Interval that shows one image after another:
next(){
this.element.src = this.images[
this.position = (this.position + 1) % this.images.length
];
}
play(){
if(!this.interval) this.interval = setInterval(_=>this.next(),1000);
}
stop(){
clearInterval(this.interval);
this.interval = null;
}
Now you can do:
var player = new Player(
["1.jpg","2.jpg","3.jpg"],
document.getElementById("img")
);
document
.getElementById("play-btn")
.addEventListener("click", _=>player.play());
If you want to do recursive there should be a stop condition.
this.player.play() is not correct.Should be this.play()
This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 6 years ago.
I am writing a Javascript class to cycle through a number of ticks and call a function at specified ticks. However, I am having a problem with my prototyping of the Javascript Class. The main count variable appears as undefined or Nan and one of the functions (methods) is apparently "not a function". Am just perplexed. Any pointers would be great.
Here is a JSFiddle: https://jsfiddle.net/hp5dj665/ but here is the code in question:
<script>
function tickStep(tickInMilliSeconds){
this.tickCount = 0; //just used as a counter
this.tickMax = 48; //highest number of ticks before it ends
this.monitorTextInputId = "";
this.paused = false;
this.tickMilliSeconds = tickInMilliSeconds;
this.tickRepeat = true; //when reaching the end start again at the beginning
this.eventArray = new Array();
this.setint; //the set time out variable
}
tickStep.prototype = {
constructor: tickStep,
monitorTick:function(){
console.log(this.tickCount);
/* if(this.monitorTextInputId.length>0){
document.getElementById(this.monitorTextInputId).value = this.tickCount;
}*/
},
tick:function(){
if(!this.paused){
console.log("HERE: "+this.tickCount); // WHY IS THIS NaN ??? <---------------
this.tickCount++;
if(this.tickCount>this.tickMax && this.tickRepeat){
this.tickCount = 0;
}
console.log("tick: "+this.tickCount);
if(this.tickCount>this.tickMax && !this.tickRepeat){
this.stop();
return false;
}
this.monitorTick(); // <!----------------- WHY DOES THIS SAY IT IS NOT A FUNCTION?
if(typeof this.eventArray[this.tickCount] !== "undefined"){
if(this.isAFunction(this.eventArray[this.tickCount])){
eval(this.eventArray[this.tickCount]);
}
}
}else{
console.log("Paused...");
}
},
isAFunction:function(functionalCall){
if(functionName.indexOf("(")){ //remove the brackety stuff
functionName = functionName.substring( 0,functionName.indexOf("(") );
}
console.log("Testing for function: "+functionName);
return typeof(functionName) === typeOf(Function);
},
start:function(){
console.log("STARTING");
if(!this.tickMilliSeconds>0){
this.tickMilliSeconds = 1000; //default to 1 second
console.log("defaulting to 1 tick = 1000ms")
}
console.log("Tick duration: "+this.tickMilliSeconds);
this.setint = window.setInterval(this.tick,this.tickMilliSeconds);
},
stop:function(){
console.log("STOPPING");
clearInterval(this.setint);
},
restart:function(){
console.log("RESTARTING");
this.stop();
this.tickCount =0;
this.start();
},
pause:function(){
this.paused = !this.paused;
},
addEvent:function(tickValue,funcCall,params){
this.eventArray[this.tickValue] = funcCall+"("+params+")";
},
removeEvent:function(tickValue){
this.eventArray[this.tickValue] = null;
}
} //end of tickStep prototype
var seq = new tickStep();
seq.monitorTextInputId = "tb";
var myFunction = function(){
console.log("myFunctionCalled");
}
seq.addEvent(2,myFunction,"");
seq.start();
</script>
So
1. Why does the "this.tickCount" == Nan or undefined inside the Tick function
2. Why is this.monitorTick() apparently not a function when this.tick() is a function?
Stuff may break after that as I can't get past that stage - but I would like those two queries sorted out so I can progress. Thanks
UPDATE
Just for completeness sake, following a couple of the comments I thought I would post that the addEvent function is now:
addEvent:function(tickValue,funcCall,params){
this.eventArray[tickValue] = Array(funcCall,params);
},
and tick is now:
tick:function(){
if(!this.paused){
this.tickCount++;
if(this.tickCount>this.tickMax && this.tickRepeat){
this.tickCount = 0;
}
if(this.tickCount>this.tickMax && !this.tickRepeat){
this.stop();
return false;
}
this.monitorTick();
if(typeof this.eventArray[this.tickCount] != "undefined"){
this.eventArray[this.tickCount][0](this.eventArray[this.tickCount][1]);
}
}else{
console.log("Paused...");
}
},
Binding "this" on the setInterval call solved the initial problem. Thanks everyone.
I would guess because the tick function is called by setInterval and is therefore not bound to the object. Try
this.setint = window.setInterval(this.tick.bind(this),this.tickMilliSeconds);
Read more about the meaning of this in JavaScript here
This question already has answers here:
Implementing a pause and resume mechanism for javascript loop execution
(2 answers)
Closed 7 years ago.
I have a start button that when clicked runs a function that loops. How do I get a stopBTN.onClick to stop the running loop?
https://jsfiddle.net/vduxbnkj/
startBTN.onClick = function(){ runLoop(); }
function runLoop(){
while(condition true){
getFolderContentsLoop();
}
}
function getFolderContentsLoop(){
//loop through folders & files looking for .txt file and if "finished"
delete files and folders
}
If you're running a simple for (..) loop, this cannot be stopped via external influence. Everything is happening on the same thread in Javascript, unless your code "ends" at some point and returns control to the browser for a while no UI interaction can happen. The easiest way to have a "loop" is via a setTimeout or setInterval:
interval = null;
startBTN.onclick = function () {
var i = 0;
interval = setInterval(function () {
console.log(i++); // this is inside your loop
}, 1);
};
stopBTN.onclick = function () {
clearInterval(interval);
};
Javascript is single threaded and as long it is in a loop, it can't give control to other code to stop it. But if you have a special kind of loop that is implemented with setTimeout:
function loopStep() {
...
}
function loop() {
loopStep();
setTimeout(loop, 0);
}
then you can add a flag to be able to stop loop's execution:
var flag = true;
function loop() {
if (!flag) return;
loopStep();
setTimeout(loop, 0);
}
and then you can define your stop function:
function stop() {
flag = false;
}
I usually work around this by making my own boolean test as the while condition, like so:
var keepLooping = false;
while(!keepLooping){
document.getElementById("loopButton").onclick = function(){
keepLooping = true;
}
}
while(keepLooping){
//do something here
document.getElementById("loopButton").onclick = function(){
keepLooping = false;
}
}
The only method I can think of is to create a boolean at the very beginning, and set stopBTN.onclick as a function that switches the variable. Then put an if condition that uses break if the boolean is switched.
var r = false;
startBTN.onClick = function(){ runLoop(); }
stopBTN.onClick = function(){r = true; }
function runLoop(){
while(condition true){
getFolderContentsLoop();
if(r){
break;
}
}
}
function getFolderContentsLoop(){
/*loop through folders & files looking for .txt file and if "finished"
delete files and folders*/
}
It's crude, but it should work.