I'm trying to put together a simple game in javascript, and I cant get the jumping to work:
function jump()
{
isJumping=true;
var jumpint= setInterval(function() {
ypos=ypos-5;
}, 10);
if(ypos==150)
{
isJumping == false;
clearInterval(jumpint);
jumpint = 0;
alert("it works");
return;
}
}
Whenever I call this function it provides the animation, and the character moves in the right direction, but it doesn't stop. Once the ypos would equal 150 it keeps moving and doesn't execute the if statement and I cant figure out why. Obviously, I'll some equation in there, but I want to get this jumping to execute right before I move on.
Put the if-statement inside the setInterval, otherwise it will only be executed once.
var jumpint = setInterval(function() {
ypos=ypos-5;
if(ypos==150)
{
isJumping == false;
clearInterval(jumpint);
alert("it works");
}
}, 10);
Also, you might want to change the condition to ypos <= 150. Say the ypos is 157. If you keep decreasing by 5, it will go 157 -> 152 -> 147 and jump right past the condition. To fix it, simply change the if-statement's condition to ypos <= 150.
Related
I am making a game where when the user presses the space bar, the player jumps so its y coordinate decreases by 1. However calling my movePlayer() function multiple times will increase the jump height for some reason (The first time pressing space will result in the y coordinate decreasing much less than the 10th time). Can someone help me out with this problem? Thanks!
this.interval = setInterval(movePlayer, 25);
...
function movePlayer() {
if (player.y + player.radius < display.canvas.height) {
player.y++;
}
document.addEventListener('keypress', function(event) {
if(event.keyCode == 32) {
player.y -= 1;
}
});
}
You have stated that calling my movePlayer() function multiple times will increase the jump height.
This is the root cause of your problem. Consider movePlayer:
function movePlayer() {
if (player.y + player.radius < display.canvas.height) {
player.y++;
}
document.addEventListener('keypress', function(event) {
...
The problem here is that every single time you call movePlayer, you create a new event listener on the keypress event.
The first time you call it, pushing space will run player.y -= 1; once.
By the fifth time, you are running player.y -= 1; 5 times over!
You only need to add the handler once for the keypress event (unless you want it to run n times).
I have 2 static (html position: fixed;) images at the edges of the screen (right and left). When users scrolls more than 100 pixels from top, these edges retract 50 pixels.
I want to them to reappear (normal again, as they were at the beginning) when users scrolls back to top. I tried adding boolean value which is true when they retract and added it to condition when they need to reappear again. But it isn't working. Why?
userHasScrolled = false;
$(document).ready(function(){
$(window).scroll(function(){
if ($(window).scrollTop() > 100) {
$(".rightstatic").animate({marginRight:'-50px'}, 900);
$(".leftstatic").animate({marginLeft:'-50px'}, 900);
userHasScrolled = true;
}
});
});
if($(window).scrollTop() <= 0 && userHasScrolled) {
$(".rightstatic").animate({marginRight: '+50px'}, 400);
$(".leftstatic").animate({marginLeft:'+50px'}, 400);
userHasScrolled = false;
}
Edit:
$(document).ready(function(){
$(window).scroll(function(){
if ($(window).scrollTop() > 100) {
$(".rightstatic").animate({marginRight:'-20px'}, 900);
$(".leftstatic").animate({marginLeft:'-20px'}, 900);
} else if($(window).scrollTop() <= 0) {
$(".rightstatic").animate({marginRight: '+0px'}, 400);
$(".leftstatic").animate({marginLeft:'+0px'}, 400);
}
});
});
It kinda works, but has a HUGE delay. Like more than a minute after reaching top it retracts back.
Edit 2: After throttling it finally works. Thanks #TomaszBubaĆa.
It isn't working because the bottom part of your code is called only once and userHasScrolled is false by that time. You need to combine both inside $(window).scroll(). I think you can get rid of userHasScrolled variable and second condition could be just else instead of else if.
var scrollTimeout;
var throttle = 250;
$(document).ready(function(){
$(window).scroll(function(){
if(scrollTimeout) return;
scrollTimeout = setTimeout(function() {
scrollTimeout = null;
const scrolled = $(this).scrollTop();
if (scrolled > 100) {
console.log("1");
$(".rightstatic").animate({marginRight:'-20px'}, 900);
$(".leftstatic").animate({marginLeft:'-20px'}, 900);
} else {
console.log("2");
$(".rightstatic").animate({marginRight: '+0px'}, 400);
$(".leftstatic").animate({marginLeft:'+0px'}, 400);
}
}, throttle);
});
});
Fiddle: https://jsfiddle.net/wctxbynt/41/
EDIT:
It wasn't working as intended since scroll event is fired multiple times (tens of times) with a single mousewheel interaction, causing jQuery animate to be called far too many times than it needs to be. A common way to fix this problem is to "throttle" a function not to be called unless a certain amount of time has passed. In edited code above we define timeout as 250ms, which means that our scroll handler code will get called up to 4 times a second - not more (a big difference as opposed to ex. 30 times in 100ms which is huge improvement in performance). Above is just an easy implementation of throttle function - read more about throttling here.
I am trying to create an ajax request when the div is scrolled to the bottom, and have come up with this code. When i'm not subtracting 100 from the elem.outerHeight() inside the if statement it all works fine, but i want to load the extra images before it hits the end, so i am trying to subtract 100, so it will load 100 pixels before the bottom, but it just won't work. Here is the code with the subtraction:
$('#thubnails').scroll(chk_scroll);
function chk_scroll(e) {
var elem = $(e.currentTarget);
if (elem[0].scrollHeight - elem.scrollTop() == elem.outerHeight()-100) {
loadmoreimg();
console.log(elem.outerHeight());
}
}
Anyone have an answer?
It's hard to catch exactly 100 px from bottom, but you could use greater or equal:
if (elem[0].scrollHeight - elem.scrollTop() >= elem.outerHeight() - 100) {
// do stuff
}
I have a drawButtons function that takes an argument of "nonhover", "hover1" or "hover2" and draws up a new button set to the canvas, and depending on the argument it takes, will draw the buttons different colors. It does work when i call it from setUpGame() but not when I call it from draw(). I want to call it from draw() because draw() is called 80 times a second in setInterval(). That way it can keep checking if the mouse is hovering over the button and draw the appropriate button set.
setUpGame() is called outside of any object or function. draw() is called by setInterval() which is outside of any function or object. setInterval calls draw 80 times a second.
getMouseOver() another function that is the one that should actually be called by draw(), because it says "if mouse is over button one: drawButtons("hover1") and so on. It just doesn't draw the buttons when I call it.
There are no errors in the browser Javascript console. I am using Chrome which works best with my game.
From this we can deduce that there is no problem with drawButtons() as it worked when called from setUpGame().
There is possibly a problem with draw() as drawButtons() doesn't work when I call it from there (but to perplex us more, displayNumbers does display the numbers when I call it from there) and it worked fine when playing the game (here we are not playing the game, we are on a start screen).
There is probably a problem with getMouseOver() because that doesn't work anywhere.
I will show you getMouseOver() for now. My program is getting big and it is overwhelming to show too much right from the start. I intend for this function to be called 80 times a second.
getMouseOver: function() {
window.onload = (function(){
window.onmouseover = function(e) {
// IE doesn't always have e here
e = e || window.event;
// get event location
// change the code so that it gives the relative location
var location = {
x: e.pageX - offset.x,
y: e.pageY - offset.y
};
if (location.x > 103.5 && location.x < 265.5) {
if (location.y > 240 && location.y < 291) {
nonGameContent.drawButtons("hover1");
}
}
if (location.x > 103.5 && location.x < 265.5) {
if (location.y > 160 && location.y < 212) {
nonGameContent.drawButtons("hover2");
}
}
else{
nonGameContent.drawButtons("nonHover");
}
}
})},
In this fiddle you have click() and onmousemove() that are working.
I didn't understand well if you want to display button at the beginning or just when the mouse hovers somewhere on the future place of the button but it's a beginning :
http://jsfiddle.net/Akinaru/3a7g2/57/
Main modification :
canvas.onmousedown = nonGameContent.getMouseClick;
canvas.onmousemove = nonGameContent.getMouseOver;
to change the canvas rectangle color when you mouse over it use onmousemove to find if you are over it, then redraw the canvas with a different color rectangle
getMouseClick: function() {
window.onmousemove = function(e) {
I had an idea for like a bus window as a fixed frame, about 800px wide, with a parallax city with the content on billboards spaced out so when you scroll between them it allows the parallax to look like bus is moving. The content will be much bigger than the window like a sprite and I'll put forward and back buttons that will scrollBy (x amount, 0). I have a working parallax script and a rough cityscape of 3 layers that all work fine.
I have hit a wall. I am trying to clear a scrollBy animation after it scrolls 1000px. Then you click it again and it goes another 1000px. This is my function.
function scrollForward() {
window.scrollBy(5,0);
scrollLoop = setInterval('scrollForward()',10);
}
So far I can only clear it when it gets to 1000. I tried doing 1000 || 2000 ect but after the first one it goes really fast and won't clear.
Excelsior https://stackoverflow.com/users/66580/majid-fouladpour wrote a great piece of code for someone else with a different question. It wasn't quite right for what the other guy wanted but it is perfect for me.
function scrollForward() {
var scrolledSoFar = 0;
var scrollStep = 75;
var scrollEnd = 1000;
var timerID = setInterval(function() {
window.scrollBy(scrollStep, 0);
scrolledSoFar += scrollStep;
if( scrolledSoFar >= scrollEnd ) clearInterval(timerID);
}, 10);
}
function scrollBack() {
var scrolledSoFar = 0;
var scrollStep = -75;
var scrollEnd = -1000;
var timerID = setInterval(function() {
window.scrollBy(scrollStep, 0);
scrolledSoFar += scrollStep;
if( scrolledSoFar <= scrollEnd ) clearInterval(timerID);
}, 10);
}
Now for step two figuring out how to put this content animation behind a frame.
Not quite sure what your asking here. Perhaps you could provide more relevant code?
I do see a potential issue with your code. You call setInterval('scrollForward()', 10) which will cause scrollForward to be called every 10ms. However, each of those calls to scrollForward will create more intervals to scrollForward creating a sort of explosion of recursion. You probably want to use setTimeout or create your interval outside of this function.
Also, as an aside you can change your code to simply: setInterval(scrollForward, 10). Removing the quotes and the parens makes it a littler easier to read and manager. You can even put complex, lambda functions like:
setInterval(function() {
scrollForward();
// do something else
}, 10);
edit:
So if you know that scrollForward moves the item 10px, and you want it to stop after it moves the item 1000px, then you simply need to stop it has moved that much. I still don't know how your code is actually structured, but it might look something like the following:
(function() {
var moved_by = 0;
var interval = null;
var scrollForward = function() {
// move by 10px
moved_by += 10;
if (moved_by === 1000 && interval !== null) {
clearInterval(interval);
}
};
var interval = setInterval(scrollForward, 10);
})();
If you want to clear it after 1000 or 2000, you simply adjust the if statement accordingly. I hope that helps.