There is a ball dropping by increasing its 'y' value.
There is a wall at y = 100.
Ball should collide with wall and both should stop.
Also, i need a viewport with a focus on ball. I try moving the wall in the opposite direction of the ball.
function update() {
ballupdate();
// opposite direction
var viewportY = - gety('#ball');
wallupdate(viewportY);
collision();
requestAnimationFrame(update);
}
function ballupdate() {
var top = gety('#ball');
top+= 3;
top = Math.min(top, 300);
sety('#ball', top);
}
function wallupdate(viewportY) {
sety('#wall', 100 + viewportY);
}
if there is a collision, ball is moved above the wall.
function collision() {
var balltop = gety('#ball');
var walltop = gety('#wall');
if (balltop + getheight('#ball') >= walltop) {
//console.log(balltop);
ballhit(walltop - getheight('#ball'));
}
}
function ballhit(y) {
sety('#ball', y);
}
This results in both ball and wall shaking up and down. Here is a JSFIDDLE.
http://jsbin.com/Stop-Elements-Move-After-Collision/2/edit
You're getting on every requestAnimationFrame
the Element selector (instead of caching it),
the elements heights,
positions and lot of other stuff,
that are unnecessary overkills for the poor browser.
Your issue was that you were updating the elements positions and than resetting that position all over again -> therefore all you could see was a funny sexy show!
Instead use Object Literals {}
to store everything about your elements, the position, the width... everything. Even the jQuery element reference $('#ball')
.
Fun right? all in one place!
Now having that Objects, introduce a property speed
,
Update the Object.y
property using i.e: += Object.speed
,
on collision, set both Objects speed
to 0 and you're done!
Look how nice, simpler and manageable is now your code (and terribly faster) :
$(function() {
var ball = { $:$("#ball"), w:10, h:10, y:0, x:0, speed:3 };
var wall = { $:$("#wall"), w:100, h:10, y:100, x:0, speed:3 };
function ballupdate() {
ball.$.css({top: ball.y += ball.speed });
}
function wallupdate() {
wall.$.css({top: wall.y -= wall.speed });
}
function collision() {
if (ball.y+ball.h >= wall.y) {
wall.speed = 0;
ball.speed = 0;
}
}
(function update() {
ballupdate();
wallupdate();
collision();
requestAnimationFrame(update);
}());
});
To add more info on the last comment of OP (@user3552579)
I supposed you needed something like that, that's why I was asking what you were actually up to, and that's why my answer to you is now: you're doing it the wrong way cause you move your player instead of moving the map and it's obstacles toward the player.
The principle of games like that is:
have a map that travels and a static player that moves X (in your case) and that eventually can move Y (for example on an exit animation when the player walks out on map end).
You can create bricks (opponents) on random positions but than you need a more Object Oriented way of making your game. Every brick should be an Object (Object function) with properties, at object creation (i.e: new Obstacle()
) you put that new brick on map but also into an Array that will hold all your bricks, so that once they're off-screen/viewport you can leverage your calculations by removing that brick from array.
Inside the game engine you just check for:
1 - Loop your Array of bricks that are in the hit area (the player Y area), and get every brick X position and Width, check for collision with your player and if hit = Game Over (Stop the map move.)
2 - The MAP movement I'm talking about is the entire (random generated) world moving underneath your player. It's up to you what to do on player X movements, here's my suggestion. The map and obstacles move up, and here's how you should handle the (red) viewport and player position: