Simple Javascript loop that repeats each second - javascript

I'm writing a code to move a character in a browser game. I managed to get the pixels it must move per second both horizontally and vertically.
pxsecx is the number of pixels it must move horizontally per second
pxsecy is the same but vertically
Basically it should += them to the current horizontal and vertical position.
I need the loop to keep repeating itself every second until the element position meets the new position (newx).
This is as far as I have gone:
<body onmousedown="showCoords(event)">
<script type="text/javascript">
function showCoords(evt){
oldx = parseInt(document.getElementById("character").style.left);
oldy = parseInt(document.getElementById("character").style.top);
width = parseInt(document.getElementById("character").style.width);
height = parseInt(document.getElementById("character").style.height);
newx = evt.pageX - width/2;
newy = evt.pageY - height/2;
disx = newx - oldx;
disy = newy - oldy;
diag = parseInt(Math.sqrt(disx*disx + disy*disy));
speed = 50;
secs = diag/speed;
pxsecx = disx/secs;
pxsecy = disy/secs;
while(document.getElementById("character").style.left<newx)
{
document.getElementById("character").style.left += pxsecx;
document.getElementById("character").style.top += pxsecy;
}
}
</script>
Everything works until the while where I have no idea how to do make it work every second. I'm testing it here: http://chusmix.com/game/movechar.php
How do I make it repeat that once a second so it works?
thanks

JavaScript is primarily asynchronous, so you'll need to rewrite this a little. setTimeout executes a function after a certain amount of time. Therefore, you can do this:
(function move() {
var character=document.getElementById("character");
if(character.style.left<newx) {
character.style.left += pxsecx;
character.style.top += pxsecy;
setTimeout(move, 1000);
}
})();

You can use the function setInterval(function, interval)
// To start the loop
var mainLoopId = setInterval(function(){
// Do your update stuff...
move();
}, 40);
// To stop the loop
clearInterval(mainLoopId);`

You want the JavaScript setTimeout() function. It calls a function every n milliseconds.

I made a coffescript class to handle time loops, maybe it will be helpful for someone.
# Classe TimeLoop, execute a function every x miliseconds
#
# #example How o create a loop
# myLoop = new TimeLoop((-> alert("loop"),1000)
# myLoop.start()
#
class window.TimeLoop
constructor: (#function,#miliseconds) ->
# Start loop.
#
start: -> #loop = setInterval #function, #miliseconds
# Stop loop.
#
stop: -> clearInterval(#loop)
link to gist: https://gist.github.com/germanotm/6ee68f804860e2e77df0

to loop something every second you'll have to use a set interval:
let before = new Date();
setInterval(() => {
console.log(Math.round((new Date() - before) / 1000));
}, 1000);
this code gets the date of the run and is subtracted to the date of every second. (by the way it starts at one not at zero, so you will have to do it manually if you want)

Related

How to create number suffixes such as "100K" without having to be repetitive?

I've been having a problem that when my auto clicker in my clicker game goes fast enough to get to 200 thousand, it starts to lag, and then it doesn't function properly, or as fast.
Is there a way to make 100 thousand turn into 100K, and 101 thousand turn into 101K without being repetitive?
I tried this with my original code, and realized putting up to 1000 suffixes into each function would be a little too hard:
if (number >= 100000) {
document.getElementById(ID).innerHTML = "100K"
}
if (number >= 101000) {
document.getElementById(ID).innerHTML = "101K"
}
and on and on.
I don't want multiple if statements!
This would work, but it would take up way too much space, and I know there is an easier way to it, but I just couldn't find it. Can anyone provide a way to do this?
Try separating the job of formatting your number into a different function.
SUFFIXES = 'KMBTqQsSOND' // or whatever you'd like them to be
function getSuffixedNumber(num) {
var power = Math.floor(Math.log10(num));
var index = Math.floor(power / 3);
num = Math.round(num / Math.pow(10, (index * 3))); // first 3 digits of the number
return num + (SUFFIXES[index - 1] || ''); // default to no suffix if we get an out of bounds index
}
You can call the function like this: var x = getSuffixedNumber(101000), the value of x will be "101K".

How to reset stop watch for multiple stop watch time?

I am trying to use multiple stop watch timer by using anchor tag.I have successfully done but I am not able to add a functionality like if I clicked first timer,It will start timer from zero,when I clicked second one,first timer's value will be zero and second one will start timer from zero.I am giving my working code below :
JS:
var digit=0;
var hrs = 0;
var min=0;
var time;
var timer_is_on=0;
var id;
function timer(id){
//[Old] - this should be placed after you increment digit
// document.getElementById("secs").innerHTML = digit
//alert("I am testing value"+id);
//[New]
// get the numerical value for seconds,minutes,hours
digit = parseInt(document.getElementById("secs"+id).innerHTML);
min = parseInt(document.getElementById("mins"+id).innerHTML);
hrs = parseInt(document.getElementById("hrs"+id).innerHTML);
// increment;
digit=digit+1;
if(digit>"59"){
min = parseInt(min)+1;
// why is this code here
var count = min.toString().length;
digit=0;
}
// [old] checking if second is greater than 59 and incrementing hours
// if(digit>"59"){
// [new] check if minute is greater than 59
if(min > "59"){
hrs=parseInt(hrs)+1;
digit=0;
min=0; // minute should be reset as well
}
// set the values after all processing is done
document.getElementById("secs"+id).innerHTML = format(digit);
document.getElementById("mins"+id).innerHTML= format(min);
document.getElementById("hrs"+id).innerHTML=format(hrs);
}
function activate(id){
if(!timer_is_on){
timer_is_on=1;
// time = setTimeout("timer()",1000) will only call it once , use setInterval instead
time=setInterval("timer("+id+")",1000);
}
else {
timer_is_on=0;
clearInterval(time); // clear the timer when the user presses the button again and reset timer_is_on
}
return id;
}
// left pad zero if it is less than 9
function format(time){
if(time > 9)
return time;
else return "0"+time;
}
And The HTML code I have used are :
Click here to start the timer
<span id="hrs1" >00</span>:<span id="mins1" >00</span>:<span id="secs1">00</span></strong>
<br/>
Click here to start the timer
<span id="hrs2" >00</span>:<span id="mins2" >00</span>:<span id="secs2">00</span>
Here is my working js fiddle demo : http://jsfiddle.net/EPtFW/1/
as you are using same method activate() to start second timer, it will make first timer as zero if timer already running.
Solution is "you have to maintain multiple unique timer ids for multiple timers"
For Example, let's say you have T1 and T2 timers to start time;
var timerMap={};
timerMap[createUniqueId for T1] = setInterval();
timerMap[createUniqueId for T2] = setInterval();
to clear timers
clearInterval(timerMap[createUniqueId for T1]);
clearInterval(timerMap[createUniqueId for T2]);
In your case, you have to have createUniqueId and adding to timerMap should be in activate() method. they will work independently.

Trouble Displaying Words in Sequence In JQuery and JavaScript

I have been trying to make a simple word sequence display program in jQuery. I want to achieve a simple program that can take sentence as input and its output can be displayed in sequence of words.
Now how can I make this program show these words in sequence like below
<div class="bar">One Two </div> //(hide it after few seconds and show next line)
<div class="bar">Three Four </div> //(hide it after few seconds and show next line)
<div class="bar">Five Six </div> //(hide it after few seconds and show next line)
<div class="bar">Seven </div> //(hide it after few seconds)
The number of words displayed at a time in sequence can be configured using wordCount var in my program
My Program at JSFiddle
I have tried a lot of options on this and its always displaying the last word "Seven" in the div. The animation seems to work right amount of time, that makes me think it has to do with the way JS handles delay in animations.
I guess this goes back to the clear understanding of few things Not sure how JavaScript is handing the delay here.
I have tried following but did not work
- setTimeout - calling the function with a delay
- jQuery.delay() call
When I put the console.log messages it does show me all the words in sequence however the div always contains the last word.
I guess JavaScript is not waiting for the animations to complete and the last word reaches too soon and animation continues later.
I guess the main line of code to look at would be
$('.bar').fadeIn(1000).text(displayWords).fadeOut(1000);
Any help and insight on this would be greatly appreciated.
Try below version using setInterval,
var words = $('.foo').text().split(' ');
var index = 0;
var wordCount = 3;
var showHide = setInterval(function () {
var displayWords = "";
var mx = index + wordCount;
if (mx > words.length) mx = words.length;
for (var i = index; i < mx; i++) {
displayWords += words[i] + " ";
}
$('.bar').fadeIn(1000).text(displayWords).fadeOut(1000);
index = mx;
if (index > words.length) clearInterval(showHide);
}, 2000);
DEMO: http://jsfiddle.net/9T4HE/15/
Have a look at jQuery.queue()...
http://api.jquery.com/queue/
here is the code from the above url:
var div = $("div");
function runIt() {
div.show("slow");
div.animate({left:'+=200'},2000);
div.slideToggle(1000);
div.slideToggle("fast");
div.animate({left:'-=200'},1500);
div.hide("slow");
div.show(1200);
div.slideUp("normal", runIt);
}
function showIt() {
var n = div.queue("fx");
$("span").text( n.length );
setTimeout(showIt, 100);
}
runIt();
showIt();
The runIt() method adds the animations to the queue and the showIt method invokes the queue with a timeout.
The URL above also shows a demo of various animations running in succession.
HTH

JavaScript - Reposition a DIV incrementally onClick

Very simple code, very simple problem. When a link is pressed, it moves a div either up or down. However, I cannot get it to move incrementally. I know this is a simple syntax error, but google isn't revealing the error of my ways. Anyone willing to enlighten me?
<a class="galsel" onclick="document.getElementById('innerscroll').style.bottom -='167px';">«</a>
<a class="galsel" onclick="document.getElementById('innerscroll').style.bottom +='167px';">»</a>
I already have it so that the div tiles itself vertically, so I'm not worried about it going "too high" or "too low"
Here's what it looks like right now: drainteractive.com/FBD/projects.php
You have to parse the value from the string containing px
// Increase by 167
document.getElementById('innerscroll').style.bottom = (parseInt(document.getElementById('innerscroll').style.bottom, 10) + 167) + ' px'
// Decrease by 167
document.getElementById('innerscroll').style.bottom = (parseInt(document.getElementById('innerscroll').style.bottom, 10) - 167) + ' px'
// Abstracted
function addToBottom(el, amount) {
// You probably add lower and upper bound check conditions
el.style.bottom = (parseInt(el.style.bottom) + amount) + ' px';
}
var el = document.getElementById('innerscroll');
addToBottom(el, 167);
addToBottom(el, -167);
Also be sure to make it work for cases where bottom wasn't set initially
var currentBottom = parseInt(document.getElementById('innerscroll').style.bottom) || 0;
+='167px' will concatinate it an it will become '167px167px167px167px167px'. Not sure what will result -='167px', but probably will result an error.
You need to rip the 'px' off the string, convert(?) it to an int, then subtract from that.
onclick="var mElem = document.getElementById('innerScroll'); mCur = parseInt(mElem.style.bottom.replace('px', 0)); mElem.style.bottom = (mCur-167)+'px'"
Naturally, this should all be put into a separate function, who is then called in the onclick, rather than the monstrosity above.
function moveUp()
{
var mElem = document.getElementById('innerScroll');
var mCur = parseInt(mElem.style.bottom.replace('px', 0));
mElem.style.bottom = (mCur-167)+'px';
}
...
<strike>onlick="moveUp()"</strike>
onclick="moveUp()"
My mind must have been somewhere else..

Adding leading zeros to a Javascript timer

I'm attempted to add leading zeros to the seconds value and I keep running into errors. I've tried a number of selected solutions posted here and can't seem to make it work.
I'm pulling values from the spans because those values are coming from the database.
var timer = $('.timer');
$('.prev-button,.next-button').hide();
setInterval(function () {
var m = $('.min', timer),
s = $('.sec', timer);
if (m.length == 0 && parseInt(s.html()) <= 0) {
timer.html('Proceed to the Next Slide');
$('.prev-button,.next-button').fadeIn();
}
if (parseInt(s.html()) <= 0) {
m.html(parseInt(m.html() - 1));
s.html(60);
}
if (parseInt(s.html()) < 10) {
$('.sec').prepend(0)
}
if (parseInt(m.html()) <= 0) {
timer.html('Time remaining for this slide - <span class="sec">59</span> seconds')
}
s.html(parseInt(s.html() -1));
}, 1000);
http://jsfiddle.net/certainstrings/a2uJ2/1/
I've modified your Fiddle to make it work. http://jsfiddle.net/a2uJ2/3/
You should store the time in javascript int vars instead of reading it from the html elements every time. This causes maintainability problem as you are attaching logic to the layout of your html document.
I haven't fixed all your code but i've created two variables that are used to perform the calculations instead.
Couple of things: You'd be better off registering a start time, and comparing against that inside the interval function. Timers are not guaranteed to be precise, but will instead trigger on or after the interval you specify. If the computer's busy, the timer might be late.
Also, if you're using parseInt, always, always specify a radix argument (the number base). If you don't, the string "08" will will be parsed to "0" because a leading zero is intepreted as an octal (base-8). So use parseInt(string, 10) to parse to a normal base-10 number.
As for adding the leading zero, I'd say you should keep a couple variable for total amount of seconds, rather than reading/writing to the elements all the time.
Updated you jsfiddle
var duration, startTime, interval;
duration = parseInt($(".min").text(), 10) * 60 + parseInt($(".sec").text(), 10);
startTime = (new Date()).getTime();
function countDown() {
var elapsed, remaining, m, s;
elapsed = ((new Date()).getTime() - startTime) / 1000;
remaining = duration - elapsed;
if(remaining <= 0) {
clearInterval(interval);
$(".timer").text('Proceed to the Next Slide');
$('.prev-button,.next-button').fadeIn();
} else {
m = String(Math.round(remaining / 60));
s = String(Math.round(remaining % 60));
if( s < 10 ) {
s = "0" + s;
}
$(".min").text(m);
$(".sec").text(s);
}
}
interval = setInterval(countDown, 500);
This is just a minimal change from you code. I'd probably do something fundamentally different to keep the markup and JS as separate as possible, and so on and so forth, but this works too.
try it like this:
if (parseInt(s.html()) < 10) {
$('.sec').val('0' + $('.sec').val());
}
You're going to need to treat the value as a string rather than as an int. JavaScript is pretty aggressive about converting things that look like numbers into numbers, and that's what's happening here.

Categories

Resources