I'm creating a game with jQuery, and I want my character to move automatically until it hits a boundary. Here is my movement code in right direction:
if (e.keyCode === 39 && (p1_left < 784)) {
$('#p1').rotate(0);
setInterval ( function() {
$('#p1').animate( { left: "+=16px", }, 50); }, 50);
}
This moves my character indefinetely to the right, and I haven't figured out myself how to create a stopper.
EDIT: Updated code snippet, Added jsfiddle http://jsfiddle.net/BjCeq/
You never actually increase pl_left so the loop will just run forever:
while (p1_left <= 784) {
pl_left+=16;
$('#p1').css('left', p1_left);
}
However, this is not going to animate the movement of your character, it will appear to just jump to the end point. For this reason it is kind of pointless to loop. What you probably want is either to use setTimeout to move every second one position or something. Or, you could use animate with a callback function:
function moveLeft(theID){
$(theIE).animate({...},1000, function(){
if(/* keep moving */){
move_left(theID);
}
}
}
What you need is code that's continually called. Your code, as you've written it, is called once, and it performs all of its DOM manipulation at once. What you need is a setInterval or a setTimeout to trigger your code to call itself a certain number of milliseconds in the future, incrementing the css property each time. The easiest way to accomplish this is to simply use jQuery.animate, which runs those methods internally.
var $p1 = $('#p1');
if (e.keyCode === 39 && (p1_left < 784)) {
$p1.rotate(0);
$p1.animate({ 'left' : 784 });
}
Check out the jQuery animate docs for more information, including how to set options and run a callback function with each frame of the animation: http://api.jquery.com/animate/.
Related
I'm using some animation using a function, let say, animateDiv(), and to which I'm assigning in an interval:
setInterval(function(){
stopDiv();//first stop animation
if(something == anotherthing){
doSomething();// it's just about to finish the animation
}
//now using animate
animateDiv();//finish animation from first to last position smoothly
},0);
If I don't use if condition and use doSomething() method directly, it doesn't hamper the animation i.e. smoothly run the animation.
With guess of my eyes there's 100ms gap between stopDiv() and animateDiv() because of checking for something == anotherthing even after this check return false.
So, how should I manage my code? What time does it take to output the result of check between two variables?
I am learning JavaScript and have been developing a simple game that is essentially a balloon that you can move around on the screen. I managed to do keypresses etc with a lot of help and the balloon moved about just perfectly.
I now want to simulate gravity, by having the balloon move one pixel down the screen if the balloon image was above a value, i tried to do this with the following do while statement:
var balloon = document.getElementById("balloon");
var bottom = parseInt (balloon.style.bottom, 10);
do {
balloon.style.bottom = bottom + 50 + 'px';
}
while (bottom = bottom > 600) // Gravity
What I want this to do, is to check the code is working by making the balloon move up the page 1 pixel if the bottom value is less than 600.
I have stripped out all the code I used to make the balloon move.
If I could just see the balloon move slowly up the page I would be very happy, because then at least I know I can just switch the values round when I've added the movement back in.
The other answers address the issue of attempting an animation with an explicit loop. As they have pointed out, you should use timers.
Because it seemed like fun, I made you a simple example of how to use a timer to animate a balloon falling:
http://jsfiddle.net/dmuu9w97/
The key code is the following:
// Make balloon fall 1px every 10ms
setInterval(function() {
var bottom = getBalloonBottom();
if (bottom > 0)
balloon.style.bottom = bottom - 1 + "px";
}, 10);
For your while loop condition should be (bottom>600) . No need for '='
You are loading the variable bottom outside the loop. It will never change. If it is 610 at the start of the loop it will remain 610 because it is assigned only in line 2 of your code
While loop should probably be ....bottom = (bottom - 1) + 'px';
If you write a while loop like this, it will execute 10 times immediately and your baloon will be always stuck in 600
To solve 'stuck at 600' problem, you should use a timer:
Think about "how fast should the balloon fall". Then you can come up with some number like "5 pixels in 100 milliseconds".
Then write a function... call that function on a timer.
Check the setTimeout function here...
setTimeout method
It's not impossible to do with a do loop but I think you ought to abandon this explicit loop in favor of javascript's timer/timeline. Look into how to use window.setTimeout() where the body of your do loop becomes the body of the callback function AND a trailing call to window.setTimeout() passing the callback again with a delay of 1000/your-chosen-framerate milliseconds. Then you can also process keypress events in their own handlers for intentional movement.
If you use an explicit loop, you'll only get gravity because the loop should never end (just as gravity never stops pulling) and therefore the browser will never have a chance to call the keypress event handler.
Your timeout callback runs once, queues itself again, and terminates. That gives control back to the browser's javascript engine to process events or, if nothing else, run the callback function again after the requested delay.
requestAnimationFrame may be more appropriate than setTimeout in modern JS implementations. It usually leads to a smoother result for animations.
I've background image and by using small javascript code, it moves from right to left.
HTML code
<div id="clouds_image"></div>
Javascript code
var g=0;
var speed=30;
function rollClouds() {
document.getElementById('clouds_image').style.backgroundPosition=g+'px 0';
g--;
scroller=setTimeout(function(){rollClouds()},speed);
}
window.addEventListener?
window.addEventListener('load',rollClouds,false):
window.attachEvent('onload',rollClouds);
But i've noticed that, with time my PC CPU memory usage increased ! causing overload on my pc and if i disabled that javascript code, it back to normal.
My question
so i think i need to modify this javascript code that it not keep working forever, i mean, i want to make it to repeat that action only 5 times then stop , maybe i need to define value of g but i'm not good in javascript so any help ~ Thanks.
You need to use a variable to count how many times that function was executed, and use setInterval instead of setTimeout: See example
http://jsfiddle.net/EQDjx/206/ (my counter start from 100 and goes down to 0)
for a more nice effect i recomand you to use jquery. See animate function
http://api.jquery.com/animate/
var g = 1000;
var speed=300;
var counter = 100;
function rollClouds() {
document.getElementById('clouds_image').style.backgroundPosition=g+'px 0';
g--;
if (counter < 1) clearInterval(interval);
}
interval = setInterval(function(){rollClouds()}, speed)
A cleaner solution might be to use jQuery to move the background:
function moveClouds() {
$("#clouds_image").css({left:"-2000px"});
$("#clouds_image").animate({left:"2000px"},10000);
}
Then you might set an interval to trigger it every x milliseconds.
setInterval(moveClouds,10000)
JSFiddle is here: http://jsfiddle.net/qXpVX/
I have several jquery animations running, each of which will need to be somewhat dependent on the success of the others. Is there a way to reliably do so without nesting each animation in another? I've looked into the 'queue' method but I believe queue is true by default? I'm running into an issue where animations start to offset one another if they're lined up like so:
function moduleSwap(){
//animation 1
//animation 2
}
setInterval(moduleSwap, 1000);
I'm using setInterval to repeat the function over and over again. Any recommendations?
setInterval(function(int) {
if(int % 2 == 0)
animation_1();
else
animation_2();
}, 1000);
increase int through int ++ method and pass it on setInterval.Its swap automatically your animations.Tricky but works for me.
I was trying to make a kind of background in which some clouds were moving, but after I got the clouds moving I found that I should either make them stop and return when reaching the browser's max-width, or make them disappear. I was trying to get their position but I can't manage to get all the positions dynamically. Right now (for the sake of simplicity) I'm only using 1 cloud to test and I do this:
$(function () {
var p = $('.clouds').position();
var w = $("#sky").width();
while (p < w);
$('.clouds', this).stop().animate({ left: "+=50000px" }, { queue: false, duration: 90000 });
});
the thing is, that position isn't dynamically refreshed, it sticks with the first one it gets and I have tried to move it inside the while loop but it didn't work...so I'm kinda stuck at the moment...anyone has an idea of how I can achieve this? The image of the cloud is originally set at top:0 left:0
I think this code will be useful to u. Try this out!
$('.clouds').animate({ top: 0 }, { queue: false, duration: 90000 });
setInterval(function () {
if ($(".clouds").position().top == 0) alert("Rain");
}, 5000);
for every 5 seconds, it will check for the position of a "cloud" class if it is zero it will give alert!
for multiple clouds u can use below code
setInterval(function () {
if ($(".clouds").position().top == 0) {
$(".clouds").each(function () {
if ($(this).position().top == 0) $(this).remove();
});
}
}, 1000)
Is the code you've posted a direct copy of what you're using? If so, then the call to animate isn't included in the while loop since it's cut short by the semi-colon. Try to use curly braces; it makes it much easier to maintain and look at. :)
while(p < w) {
$('.clouds',this).stop().animate({left:"+=50000px"},{queue:false, duration:90000});
}
Also, I don't think that loop will ever complete. Neither of those variable's values are changing during iteration so it's never-ending. In order for it to work you'll need to modify (update) the 'p' variable within the loop, on every iteration.
EDIT: Actually, scratch that, the loop won't even begin because elem.position() returns an object, not a number (NaN). To make it work you'll need elem.position().left.
why not use a looping background image and modify the background-position css property?
edit: I don't know if there's a jquery plugin to do this automatically, but it should be easy enough in old fashioned javascript with setInterval and modulus.
for example, your background image is 400 pixels wide,
the css would be:
body {
background: transparent url(yourbackground.png) repeat-x scroll 0 0;
}
and javascript would be:
var BGPosition = 0;
var resetSize=400;
function scrollBodyBG() {
BGPosition = ++BGPosition % resetSize;
$('body').css("background-position", (-1 * BGPosition) + "px 0px");
}
var si = setInterval(scrollBodyBG,100)
Edit: Tested and working (without jquery) as
var BGPosition = 0;
var resetSize=400;
function scrollBodyBG() {
BGPosition = ++BGPosition % resetSize;
document.body.style.backgroundPosition = (-1 * BGPosition) + "px 0px";
}
document.addEventListener("DOMContentLoaded",function() { setInterval(scrollBodyBG,100);},false);
obviously this would need to change for IE event listener support
How about:
while($('.clouds').position().left < $("#sky").width())
{
// do stuff
}
The only way to do this reliably is to listen property changes on DOM elements, using mutation events DOMAttrModified (for ex.) and the proprietary "onpropertychange" on IE.
Someone ported this to Jquery, here's the article.
http://www.west-wind.com/Weblog/posts/453942.aspx
Put it all in a function, let's say moveCloud()
Then use the callback of the animate position and call that function.
At the beginning of the function check the position of the cloud:
-If it is 0 move it to the right until it reaches maxwidth
-If it is the maxwidth, move it to the left until it reaches 0
Once the animation is done, the callback executes and calls again the function, which will move the cloud to the other side of the screen.