Reputation: 951
I am creating an addition and subtraction game where a sum is randomly generated and displayed at the top of the container. Numbers then animate from bottom to top and the idea is to click on the correct one.
Numbers are given a random "x" position at the start and then animate to the top at the same speed.
The problem I am having is that when the program is running the elements can sometimes overlap because they are given a similar "x" position at the start.
I need to tell the program not to give the same "x" position until the element using it is far enough up the screen for them to not overlap.
The problem is at it's worst when the game first starts.
Here is the relevant code...
var currentMoving = [];
function moveRandom(id) {
// Mark this one as animating
currentMoving.push(id);
var cPos = $('#container').offset();
var cHeight = $('#container').height();
var cWidth = $('#container').width();
var bWidth = $('#' + id).width();
var bHeight = $('#' + id).css('top', '395px').fadeIn(100).animate({
'top': '-55px'
}, AnimationSpeed,'linear').fadeOut();
maxWidth = cPos.left + cWidth - bWidth;
minWidth = cPos.left;
newWidth = randomFromTo(minWidth, maxWidth);
$('#' + id).css({
left: newWidth
}).fadeIn(100, function () {
setTimeout(function () {
$('#' + id).fadeOut(10);
// Mark this as no longer animating
var ix = $.inArray(id, currentMoving);
if (ix !== -1) {
currentMoving.splice(ix, 1);
}
window.cont++;
}, 100);
});
}
Here is a fiddle - http://jsfiddle.net/pUwKb/68/
Upvotes: 11
Views: 1370
Reputation: 1244
Extending on @DhruvPathak's solution, my suggestion would be to have another array to keep track of objects in your starting zone and when choosing a random position check against all objects in that zone for collisions.
When animating the objects you would need to chain two animations together. The first would take the object all the way out of the starting zone and then clear itself from the array and then animate all the way to the top.
When checking for collisions, if a collision is detected the simplest solution would be to calculate the difference in height between the new object and the one it collided with in order to place the new object a bit further down.
All you would need to do then is to adjust the animation speed accordingly to make it move at a constant rate compared to the other objects as you would be covering arbitrary distances to get out the starting zone compared to the constant distance you have now.
Upvotes: 0
Reputation: 43235
Here is a simple solution, not most optimal though.
1/ Instead of random x, mark your canvas with grids, and only chose x offset as multiple of 50px( your box width), so a box can be launched from any of 12 grids in your 600px canvas .
|1|2|3|4|5|6|7|8|9|10|11|12
2/ When a box is launched in any grid, lock that grid for 1 second or 2 seconds, so that your random position generator for the new boxes, does not generate this grid till it is locked.
3/ After sometime,clear the lock for the grid.
Code snippet to generate grid based x position,instead of random x :[lines 230-238]
function randomFromToPosition(from, to) {
/* align boxes in grids instead of random positions */
do {
var pos = Math.floor(Math.random() * (to - from + 1) + from);
var roundedPos = Math.floor(pos/50)*50;
} while(lockedGrid[roundedPos] == true);
return roundedPos;
}
Locking and Unlocking the grid : [ lines 289-300 ]
maxWidth = cPos.left + cWidth - bWidth;
minWidth = cPos.left;
newWidth = randomFromToPosition(minWidth, maxWidth);
lockedGrid[newWidth] = true; // Lock the grid position
setTimeout(function(){
delete lockedGrid[newWidth];
},2000); // free the lock after 2 seconds.
Upvotes: 5