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();
};
Related
How can I call a javascript function (repeatedFunction()) repeatedly but make it so that, let's say an alert("This function is being executed for the first time"), is only activated the first time that repeatedFunction() is, but the //other code is always activated? And also, how can I make the alert() allowed to be activated for one more time, like if the repeatedFunction() was being executed for the first time again?
You can set a flag. Say for example, you have this following code:
var flagAlertExecd = false;
function repeatThis () {
if (!flagAlertExecd) {
alert("Only once...");
flagAlertExecd = true;
}
// Repeating code.
}
And to repeat this code, it is good to use setInterval.
setInterval(repeatThis, 1000);
Functions are objects. You can set (and later clear) a flag on the function if you like:
function repeatedFunction() {
if (!repeatedFunction.suppress) {
alert("This function is being executed for the first time");
repeatedFunction.suppress = true;
}
// ...other code here...
}
When you want to reset that, any code with access to repeatedFunction can clear the repeatedFunction.suppress flag:
repeatedFunction.suppress = false;
The flag doesn't have to be on the function, of course, you could use a separate variable.
That said, I would suggest looking at the larger picture and examining whether the alert in question should really be part of the function at all.
JavaScript closure approach will fit in this task. It has no global variables, and keeps your task in a single function.
var closureFunc = function(){
var numberOfCalls = 0;
return function(){
if(numberOfCalls===0)
{
console.log('first run');
}
numberOfCalls++;
console.log(numberOfCalls);
};
};
var a = closureFunc(); //0
a(); //1
a(); //2
var a = closureFunc(); //drop numberOfCalls to 0
a(); //1
http://jsfiddle.net/hmkuchhn/
You can do it by declaring a variable and incrementing it in your function. Using an if statement, you can check how many times it has been triggered. Code :
var count = 0;
function myfunc(){
if(count==0){
alert("Triggering for the first time");
count++;
}
//Your always triggering code here
}
Demo
This even tracks record of the how many times the function is triggered. It can be useful if you don't want to execute the alert() on nth time.
You can also use boolean values. Like this :
var firstTime = true;
function myfunc(){
if(firstTime){
alert("Triggering for the first time");
firstTime = false;
}
//Your always triggering code here
}
Demo
The second approach will not track the record of how many times the function has been triggered, it will just determine that whether the function is being invoked for the first time or not.
Both the approaches work fine for your purpose.
var firstTime = true;
var myFunction = function() {
if(firstTime) {
alert("This function is being executed for the first time");
firstTime=false;
}else{
//whatever you want to do...
}
}; //firstTime will be true for the first time, after then it will be false
var milliseconds = 1000;
setInterval(myFunction, milliseconds);
//the setInterval means that myFunction is repeated every 1000 milliseconds, ie 1 second.
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.
I have a loop that runs indefinitely until I tell it to stop. I am actually using requestAnimationFrame and a lot more is going on, but the below example is just to simplify my question.
var _stop = false;
var loop = function () {
while (!_stop) {
if (some condition is met) {
stop();
}
/* Do something. */
loop();
}
};
function stop() {
_stop = true;
}
Now this all works great, but it will still run /* Do something */ one more time before it actually stops. I want it to stop immediately and return.
Of course this can be done like so:
if (some condition is met) {
stop();
return;
}
But is there a way to include the return part into stop();? This doesn't do what I want for obvious reasons:
function stop() {
_stop = true;
return;
}
But is there a way to achieve this?
var _stop = false;
try {
var loop = function () {
if(!_stop) {
if (some condition is met) {
stop();
}
/* Do something. */
loop();
}
};
} catch(e) {
}
function stop() {
_stop = true;
throw new Error("USE IT WITH PRECAUTION");
}
The loop above does you job of exiting entire loop, But I will say its horribly wrong way of doing thing as ideally function should be
1) mutating the state variables
2) or should be computing the values.
3) or should be determining error state to stop the execution further
It should never be bothered about how the control flow of function caller is and ways to stop function caller execution flow.
It sounds like you want to check the condition (before) every time the work is done. To do this with a _stop variable (as opposed to simply checking the condition in the while condition itself), you have to:
Set the variable based on the condition before starting the loop
Do your work
Set the variable based on the condition before the next loop iteration
Whether you accomplish this with a while() loop or a do while() loop, the process will be the same. Adding a pre-loop check to your example will prevent the work from being done if the user has already exited:
var _stop = false;
// Call loop() when required
var loop = function () {
// Check condition before first iteration
if (/* some condition is met */) {
stop();
}
while (!_stop) {
/* Do your work */
// Check condition before every subsequent iteration
if (/* some condition is met */) {
stop();
}
loop();
}
};
function stop() {
_stop = true;
}
Is there a reason you are recursively calling loop() instead of calling it once and doing all of your work within the contained loop until the user exits? This more simplified version might work for you:
var _stop = false; // Set it initially, could also use checkStopRequired() here
// Call loop() when required
var loop = function () {
// Check condition before first iteration
_stop = checkStopRequired();
while (!_stop) {
// Do your work, setting _stop to true if work returns early
_stop = !doMyWork();
// Check condition before every subsequent iteration
_stop = checkStopRequired();
}
};
function checkStopRequired() {
// Return true if should stop, false if should continue
}
When doing the work required for each loop iteration, you may want to check the exit condition before any expensive operations to allow the whole thing to halt as soon as an exit condition is met, as opposed to waiting for the work to finish. This obviously depends on what work you're doing and what the exit conditions are.
An example of the function to be called within the loop, which will help you set _stop if the stop condition is met part-way through:
function doMyWork() {
// Get user input here...
if (checkStopRequired()) { return false; }
// Get data here...
if (checkStopRequired()) { return false; }
// Do logic here...
if (checkStopRequired()) { return false; }
// Render objects here...
// Return successful result
return true;
}
it might not be the optimal way to do this, but this can be done like this:
var _stop = false;
var flag=0;
var loop = function () {
if(!_stop) {
if(flag){
return;
}
if (some condition is met) {
stop();
_stop = true;
loop();
}
/* Do something. */
loop();
}
};
function stop() {
//_stop = true;
toReturn();
}
function toReturn(){
flag=1;
}
I have a function which accepts a string and outputs it one character at a time with a delay. The event occurs when the user clicks a link or button. The problem is that if the user clicks a link and then another before the first one is done, they both run at the same time and output to the screen. It becomes jumbled up.
ex:
string1 : "i like pie very much"
string1 : "so does the next guy"
output : i sloi kdeo epse .... and so on.
Anyone know a method to fix this?
I think I need a way to check if the function is being processed already, then wait till it is done before starting the next.
Place both functions inside an object (because globals are bad), add a variable to the object which knows if a function is executing, and check the variable, like this:
var ns = {
isExecuting:false,
func1: function(){
if (this.isExecuting) { return; }
this.isExecuting = true;
//do stuff 1
this.isExecuting = false;
},
func2: function(){
if (this.isExecuting) { return; }
this.isExecuting = true;
//do stuff 2
this.isExecuting = false;
}
}
and for extra elegance:
var ns = {
isExecuting:false,
executeConditionally:function(action){
if (this.isExecuting) { return; }
this.isExecuting = true;
action();
this.isExecuting = false;
}
func1: function(){
this.executeConditionally(function(){
//stuff
})
},
func2: function(){
this.executeConditionally(function(){
//stuff
})
}
}
add a variable globally or in scope outside the method called IsProcessing and set it to true the first time the method is called, on the method you can then just check if (IsProcessing) return false;
All you need to do is set a variable that indicates whether the function is running:
var isRunning = false;
$('a').click(function({
if(isRunning == false){
isRunning = true;
///Do stuff
isRunning = false;
}
else{
return false;
}
});
Don't you want all the clicks to be taken into account, but in order ?
If so, I suggest you separate streams between adding a click to process, and consuming clicks
:
the html :
<a class="example" href="javascript:void(0)" onclick="delayPushLine();">i like pie very much</a><br/>
<a class="example" href="javascript:void(0)" onclick="delayPushLine();">so does the next guy</a>
<div class="writeThere"></div>
and the javascript (using jQuery a bit)
var charDisplayDelay = 50; // the time between each char display
var displayDelay = 2000; // the time before a click is handled
var lines = [];
var lineIdx = 0, pos = 0;
function delayPushLine(e) {
if (!e) {
e = window.event
}
setTimeout(function() { lines.push(e.srcElement.innerText); }, displayDelay);
}
function showLines () {
if (lines.length > lineIdx) {
if (pos < lines[lineIdx].length) {
$(".writeThere").append(lines[lineIdx].substr(pos,1));
pos++;
} else {
pos = 0;
lineIdx++;
$(".writeThere").append("<br/>");
}
}
}
setInterval("showLines()", charDisplayDelay);
http://jsfiddle.net/kD4JL/1/
Only JavaScript, No jquery.
Code goes like:
window.onload = addListeners;
function addListeners(){
for(var i = 0 ; i < document.getElementsByClassName('arrow').length; i++){
if(window.addEventListener){
document.getElementsByClassName('arrow') [i].addEventListener( 'click', func , false);
}else{
document.getElementById('arrow') [i].attachEvent('onclick' , func);
}
}
}
function func(){
//Takes exactly 5 seconds to execute
}
Now, I want to disable the 'click' for 5 seconds when the function 'func()' is running. And, then after the 'func()' is completely executed, the click should again be enabled automatically.
How to do this only using JavaScript?
Rather than disable the click event, check a variable to see if its currently running.
var funcRunning = false;
function func(){
if (funcRunning) return;
funcRunning = true;
//Function logic here
funcRunning = false;
return //whatever
}
This way your not guessing the function will take 5 seconds to run, the function will simply not execute its logic until its completed its current run.
EDIT: As #NULL has suggested, a better method would be to store the boolean variable on the function itself to prevent global pollution:
function func(){
if (func.IsRunning) return;
func.IsRunning = true;
//Function logic here
func.IsRunning = false;
return //whatever
}
To elaborate my comments on Curts answer:
When declaring the function func you can do two things:
function func() {
if ( !func.isRunning ) {
func.isRunning = true;
/* logic goes here */
func.isRunning = false;
}
}
Or you can make a closure and store isRunning inside it:
var func = (function() {
var isRunning = false;
return function() {
if ( !isRunning ) {
isRunning = true;
/* logic goes here */
isRunning = false;
}
};
})();
The second example can makes a private variable only accessible inside the closure.
Its mostly about a design pattern some developers doesn't like to store variables directly on functions like in example one. The only difference is that if someone chooses to set func.isRunning = true the function cannot run again and therefore not reset itself.
If your function is asynchronous (it sends ajax request, as far as I understood), you'd better create a "success" callback for that request and handle funcRunning flag there.
Here is an example:
var funcRunning = false;
function func() {
if (funcRunning) {
return;
}
funcRunning = true;
var xmlhttp = new XmlHttpRequest();
xmlhttp.open('GET', '/xhr/test.html', true);
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4) {
if (xmlhttp.status == 200) {
// do something.
funcRunning = false;
}
}
};
}
P.S. Current example is not the most correct in creating XmlHttpRequest instance (not crossbrowser). It is shown only as an example.