HTML5 - Collisions [closed] - javascript

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I'm working on a top down game, and this game is going to contain a lot of collisions simple and complex.
After doing some research, I understand that I have to always compare my character with 'object' within my code - and then check for collision calculations.
EG:
CheckCollisions(Player, Object);
Which means I have to add in every single collide-able object within my scene, into my code:
CheckCollisions(Player, Building1);
CheckCollisions(Player, Building2);
CheckCollisions(Player, Trash);
CheckCollisions(Player, Bench1);
CheckCollisions(Player, Bench2);
CheckCollisions(Player, Office1);
CheckCollisions(Player, Office2);
First off, my objects might not even be simple rects, they might be complex shapes. Secondly, some of them might have their own rotation. And thirdly, what happens if I have over tens of thousands of collie-able objects in my scene?
Ins't there an easier way to check for collisions within a HTML5/JS game?
Is this even possible? I'm really just looking for some advice and pointers.
Thanks

It's very uncommon to have a named variable for every single object in your game. Usually you store all objects in one data structure (like an array) and when you need to do something with all objects, you do a for-loop over this array.
Some important objects, like the player character, could have an own variable, but they should also be in the "all objects" array, so you don't need to program a special handling to include the player character.
Regarding performance: When you check everything against everything, the amount of collision checks which need to be performed increases quadratically. But you can reduce the effort when you only check collisions of those objects which are already close to each other. Before you check collisions, you:
divide the playing field into rectangular zones (the zones must be at least as large as the largest object).
Then you assign each object to the zone its upper-left corner is in.
Then you take each zone, and check collisions of each object in it with the other objects in the zone and with all objects the three zones right, down and rightdown from it (for objects which overlap zone borders).
When you have very complex shapes, you could also speed up collision-detection by calculating a bounding-rectangle for each shape (the smallest possible rectangle it fits into). Before you check the collision between two objects, you first check if their bounding rectangles intersect. When they don't, there is no chance for the complex shapes to intersect, and you can skip all the complex calculations.

As everyone so far has indicated, an array of objects is much better than naming all your objects individually.
A much easier method of collision detection that might work for you is to have a central object that tracks all occupied spaces. For instance, let's call it LocationTracker for now.
Assuming you're only using x and y axes, you can have a Point object that stores an X and a Y location, (and if you want to get fancy, a timestamp). Each object as it moves would send an array of all the Points that it is occupying. For example, you can call locationTracker.occupySpace(player[i], array(point(3,4), point(4,4), point(5,4)), etc.
If your call to occupySpace returns false, none of the Points match and you're safe, if it returns true, then you have a collision.
The nice thing about doing it this way is if you have x amount of objects, instead of checking x*x times per move, you check x times max.
You wouldn't need to pass in all points of the objects, just the outer most ones.

1 - you don't need to write a line of code for every object in your game. Put them into an array and loop over the array:
var collidableObjects = [Building1, Building2, Trash, Bench1, Bench2,Office1, Office2];
var CheckAllCollisions = function() {
for (var i=0; i<collidableObjects.length; i++) {
CheckCollisions(Player, collidableObjects[i]);
}
}
2 - if you have complicated collision check (ie rotated shape, polygon, etc) you can first check a simple rectangle check (or radius check) and do the more accurate check if the first one returns true.
3 - if you plan to have tens of thousands of objects you should have smarter data collections, for example objects sorted by X coordinate so you can quickly avoid checking everything larger than Player.X+100 and smaller than Player.X-100 (using binary search), or split the objects into a grid and just check the objects in the 3x3 grid cells around the player.

A much better way is to put all your scene objects into an array or a tree structure and then
for( var i=0; i<scene.length; i++ ) {
scene[i].checkCollision( player );
}
if you add a function .checkCollision() to every object, you can handle any special case in there.
It's a good idea to make the player a rectangle so the checking code doesn't become too complex.
Make the collision-checking-rectangle of the player object slightly smaller than the actual sprite; that makes the life easier for your players.

First of all, you should always have your objects in arrays. This includes things like enemies, bullets and other such things. That way your game can create and destroy them at will.
You seem to be talking about the actual frequency of the collision checks, and not the collision check method. To that my advice would be to only run collision checks on a finite number of the objects. Try using a grid, and only checking for collisions with objects in the same grid block as the player.
Another thing that helps is to have plenty of "short cuts" inside the method itself. These are things that can be checked quickly and easily before any complex math is done. For example, you could check the distances between the two objects. If the objects are farther away than their farthest corner, you don't have to check for a collision.
There are plenty of these methods that you can utilize in your own unique combination.

Related

Instancing Multiple Objects Lowers Framerate of WEBGL Application

I am developing a THREE.JS WebGL application where I need to render multiple objects with the same geometry and I've stumbled upon a bottleneck. It seems that my instancing of objects has some issue, that I can't really understand/realize, maybe someone can help me with that. For context, I have a PointCloud with normals, that gives me information about where to position my instanced objects, and also the orientation of the object through the normal quaternion. Then, I loop through this array, and place each instanced object accordingly. After looking at various posts about instancing, merging, etc, I can't figure out what I'm doing wrong.
I attach the code snippet of the method in question :
bitbucket.org/snippets/electricganesha/Mdddz
After reviewing it multiple times, I'm really wondering what is wrong here, and why does this particular method slow down my application from 60fps to 20fps.
You might be overcompensating with the optimization.
In your loop where you merge all these geometries try to add something like this
var maxVerts = 1 << 16;
//if merging a new object causes the vert number to go over 2^16 push the merged geometry somewhere, and make a new one for the next batch
if( singleGeometry.vertices.length + newObject.geometry.vertices.length > maxVerts ){
scene.add(singleGeometry);
singleGeometry = new Geometry();
}
singleGeometry.merge(newObject.geometry, newObject.matrix);

How to detect collision between two objects in JavaScript with Three.js?

There a lot of nice things for collision detection like threex.colliders or code snippets here on questions, but acutally the most stuff is old (some functions like multiplyVector3 are changed and other are removed. I have a Object3D (Character Model) and a World (3D Models: cars, trees, buildings etc.). I can move the Character with the arrow keys (moving it via translateX/Y in a render loop.
What I want is a collision detection between the character model and everything else (except ground and some else). So I need a collision detection between Object3D (Character) and WorldObjects[] (all Objects).
So, now there are a few ways to get the wanted result maybe, which is the best (fast & readable) way to perform this? And now the problem (maybe) if it works: When the Character collides with anything else, how can I stop that he can move in this direction but he can go back, right or left?
You can detect collisions by using bounding boxes of objects. Bounding boxes are of type THREE.Box3 and have useful methods as isIntersectionBox, containsBox or containsPoint which will suit all your needs when you want to detect collisions.
Using them is as simple as this:
var firstObject = ...your first object...
var secondObject = ...your second object...
firstBB = new THREE.Box3().setFromObject(firstObject);
secondBB = new THREE.Box3().setFromObject(secondObject);
var collision = firstBB.intersectsBox(secondBB);
collision will be true if the boxes are colliding/hitting each-other.
This gives you an impression on how you can use bounding boxes.
You can also check this example out. I think it will be very useful for you.
EDIT:
You should maybe also checkout the Physijs library which is a plugin to three.js.
There is someone with a similar question on Stackoverflow that you might want to keep track of.

solving a trig equation numerically with in-browser JS [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
Given values for the variables s, v, and h, and given a library such as numeric.js how can I numerically solve the following equation for a within a given degree of accuracy?
I'm wanting a JS algorithm for use in-browser.
Separating variables and parameters
You could start by substituting b = a/h. That would turn your equation into
2b*sinh(1/(2b)) = sqrt(s²-v²)/h
That way you have all the inputs on the right hand side, and the variable on the left hand side, but unfortunately still occuring in several places in a transcendental form. The benefit is that we can now treat the right-hand side as a single number in order to gain some understanding of this function.
First look at a plot
The function seems reasonably well-behaved:
So you can do standard numerical root-finding methods, e.g. Newton's method, to find the position where this function takes a given value (i.e. the one you computed from the right-hand side). If you interpret root-finding as finding locations where a function is zero, then the function for which you want to find zeros is the difference, i.e.
2a*sinh(h/(2a)) - sqrt(s²-v²)
Using optimization from numeric.js
If you want to make use of numeric.js, numeric.uncmin would likely be your best bet. At least it's the best I could find in the docs so far. (Perhaps there is some bare root-finding implementation in there, but if so, I couldn't find it yet.) You'd try to find the minimum of the function
(2a*sinh(h/(2a)) - sqrt(s²-v²))²
interpreted as a function of a, and hope that that minimum is actually (close to) zero. You might get better results (i.e. faster convergence and/or lower error) by also providing the gradient (derivative) of that function as a separate argument. You can use Wolfram Alpha to find that derivative.
Further rewriting of the function
Let's define f as f(b) = 2b*sinh(1/(2b)). You are trying to find out at what position f assumes a given value. In order to make convergence faster, you can try to turn this f into a different function which will be close to linear. Toying around with plots, I've come up with this:
g(b) = (f(b) - 1)^(-1/2)
You can apply the same conversion to the right hand side to see the desired value for this function. For b > 0.06 this looks fairly linear, so it should converge really fast. Provided your parameters are expected to be in that range where it is almost linear, but even for smaller b it should be no worse than the original formulation. You could use the linear form to compute the starting position of your Newton's method, but I wouldn't bother: as long as you start with a reasonably big value, the first step of Newton's method will do just that.
this is transcendent equation
I assume real domain in that case you can not separate the unknown from it (in general) instead you still can solve it numerically (as you intended)
I am too lazy to do proper analysis of 2a.sinh(h/2a)=sqrt(s.s-v.v)
but if I see it right then 2a.sinh(h/2a) is monotone so let c=sqrt(s.s-v.v) for simplicity and speed up. As I see it c >= 0 so if h >= 0 then a = <0,+inf)
find value crossing
double a0,a1,da=initial accuracy step;
for (a1=0.0;2a.sinh(h/2a)<=sqrt(s.s-v.v);a1+=da);
now a1 holds approximate top bound solution
for (a0=a1;2a.sinh(h/2a)>sqrt(s.s-v.v);a0-=da);
now a0 holds approximate low bound solution
find solution in desired accuracy
if a0==a1 then you have found exact solution so stop
if fabs(a1-a0)<=accuracy you are inside your accuracy so stop and lower the da for example da*=0.01; this will boost accuracy 100 times. Now search for solution again but only on interval <a0,a1> and repeat this until solution is found
[notes]
Another example of solution of transcendent equation is here: solving Kepler`s equation. When nothing else works you still can try this:
How approximation search works

Conway's Game of Life - How to fake an "infinite" 2d plane

I'm using a 2d array to represent the grid of cells. When a cell on an edge or in a corner checks it's neighbors that would be out of bounds, it treats them as permanently dead.
function getCell(row, column) {
if(row === -1 || row === cellMatrix.length || column === -1 || column === cellMatrix[0].length)
{
return 0;
}
else return cellMatrixCopy[row][column];
}
I'd just like to get rid of behavior like gliders halting and turning into blocks when they reach the edge of the grid. How would you "get rid" of the edges of the array?
You can checkout the full implementation here. Thanks in advance.
How to fake an “infinite” 2d plane?
To create an infinite dimension game board use a sparse matrix representation where the row and column indicies are arbitrary-precision integers. Roughly as follows:
map<pair<BigInt,BigInt>, Cell> matrix;
Cell& get_cell(BigInt x, BigInt y)
{
return matrix[make_pair[x,y]];
}
The game of life is impossible to fake being infinite. Say the structure you create tries to expand past the current bounds, what is to stop it from expanding infinitely. Like MitchWheat said you could wrap the edges which is your best bet (for the more natural looking behavior), but since it's turing complete you can't fake it being infinite in every situation without having infinite memory.
Since the game of life is turing complete that means if a something "goes off the edge" it is impossible to tell if it will come back for a general case (related to the halting problem), meaning any heuristic you use to decide when something goes off the edge will have a degree of inaccuracy, if this is acceptable then you should consider that approach to, though IMO simulating the game of life incorrectly kinda defeats the purpose.
Another way to go would be to purposely simulate a larger area than you show so objects appear to go off the edge
This question is also here with some good answers.
The simplest modification to your simulation (and not mentioned on the other question) would be to triple the area's length and width, but only show what you currently show. The only catch would be if something went off-screen, hit the wall, and then came back. You could try playing around with the game rules at the boundary to make it more likely for a cell to die (so that a glider could get a little further in before becoming a block that could mess things up). Maybe that a live cell with three neighbors would die if it were within two steps of the side.
One of the other answers (and our answer) can be summarized as keeping track of the live nodes, not the entire screen. Then you would be able to do cool stuff like zoom and pan as if it were Google Maps.

Detecting collisions between two moving objects

I've got a basic Space Invaders type game going, and I can't get it to recognise when the shot from the player hits the alien. (I'm only checking Alien2 atm, the one second from the left). Since they're both moving, I've decided the only way to check for collisions is with either a range-based if statement (with 2 top coordinates and one left coordinate), or directly comparing the positions along the Y axis with Jquery.
I'm using the range-based solution at the moment, but so far it hasn't worked (not sure why).
My code so far:
if (key == "87"/*&& document.getElementById('BarrelOne').id=='BarrelOne'*/){
var Invader2 = document.getElementById('Alien2');
var Shot1 = document.getElementById('ShortShot');
Shot1.style.webkitAnimationPlayState="running";
setTimeout(function(){
Shot1.style.webkitAnimationPlayState="paused";
}, 1200);
if(document.elementFromPoint(625.5, 265.5) == Shot1){
Invader2.style.visibility="hidden";
}
};
Jsfiddle:
http://jsfiddle.net/ZJxgT/2/
I did something similar, and i found that it was much easier to achieve using gameQuery.
to test for collisions:
var collided = $("#div1").collision("#div2");
you can see full working example here
EDIT
If you're having trouble check out the API. For example, to find out how to use collisions check this part of the API.
the collision works in the following way:
This method returns the list of elements collisioning with the selected one but only those that match with the filter given as parameter. It takes two optional arguments (their order is not important). The filter is a string filtering element used to detect collision, it should contain all the elements the function should search collision into. For example if you look for collision with element of the class ‘foo’ that may be contained in a group you will use the filter ".group,.foo".
So, write something like this:
$("#ShortShot").collision("#Alien2").hide();
// will return the alien if it collides with ShortShot
or, to hide them both:
if (($("#ShortShot").collision("#Alien2")).length) {
$("#ShortShot").remove();
$("#Alien2").remove();
}
Instead of losing hours reinventing the wheel, I would suggest to switch (if still possible, depending on your time deadline) to a real 2D game engine for Javascript, with easy collision detection.
Check as well: 2D Engines for Javascript

Categories