I think the function will only work with rectangles, just by glimpsing at the code.
This hitTest returns true if the rectangles of the clip1 and clip2 objects overlap:
Line 77 is calculating the distance between the two objects with regards the X axis.
Since I want the distance to be positive, Line78 trough 81 are ensuring thatā¦
Line 83: is comparing that X axis distance against the sum of the halves of both rectangles, if so, that means that they have some pixels in common, but only for the X axis. In order for the function to return ātrueā, we need to do this check with both axis.
Lines 85 to 90 are repeating the same check for the Y axis. If the comparison in line 90 is true, then the function must return ātrueā, else āfalseā.
Lines 83 and 90 will make more sense if you draw 2 rectangles in a piece of paperā¦ one next to the other and visualize them.
You got it right! : )
Dang, that still sounds complicated for a rectangle overlap check.
Usually I would just check if the X of one rectangleās right side is greater than the X of the otherās left side, and if the left of one rectangleās X is less than the right of the X or and uhā¦ Itās mostly like if you were to check if a number is between this number and that number.
Maybe your solution is faster? I dunno, lemme seeā¦
That is the great thing about this, I donāt know the answer to your questionā¦ : )
That is why I posted this custom function hereā¦ If anyone has something better in terms of performance, I will put it in the game code. For instance, if all the clips store somewhere half of their width and height, then I could use those and avoid the 0.5 multiply at lines 83 and 90. Thatās what I was currently doingā¦
Another question that I had was about the Math.abs(x) function, I donāt know how that function is implemented internallyā¦ Maybe it does something better (less expensive) than my lines 80 and 88. If so, I could apply that to lines 77 and 85, and the code would be smaller, but not sure if faster.
Well Iāve been comparing them and the numbers kept fluctating. My program said yours was 10% faster. But when I increase the number of times the function would run it, how faster my solution was to yours would decrease. It decreased to -2% before I changed the code because I realized that making this loop inside a loop would actually be the same thing as just making this one loop. After that it said mines was 50% faster. I increased the number but then it crashed the web cuz it was out of memory. Probably because I made it do it 99999999 times. And every time it would put its result into a list so it could calculate the average. Rip.
Also it didnāt autosave and I wasnāt saving it
Could you put at least pseudo code so I can study how many branches and operations you solution has? By simply comparing them visually, I could tell which is fasterā¦ Iām very good at thatā¦
bounds0 = clip0.bounds
bounds1 = clip1.bounds
return (
bounds0.right > bounds1.left and
bounds0.left < bounds1.right and
bounds0.bottom > bounds1.top and
bounds0.top < bounds1.bottom
)
right and left returns the X coordinates of a bounding boxās right and left side
bottom and top does the same thing but for the Y coordinates
That is a great solutionā¦ Thank you for sharing it. I think they are close. if I define and store properties for the 0.5width and 0.5 height before-hands in each clip to be collide, we should have similar performancesā¦ but you must add to your solution 4 more comparisons ā==ā, mine does not need those extra comparisonsā¦ example:
bounds0.right ā>=ā bounds1.left and
bounds0.left ā<=ā bounds1.right and
bounds0.bottom ā>=ā bounds1.top and
bounds0.top ā<=ā bounds1.bottom
if not, you would have a scenario where 2 rectangles with the same size are 100% overlapping each other, and your function would return āfalseā. Those 4 comparisons should add more weight.
My solution in other hand would fail by one pixel (if they are overlapping in X or Y by one pixel); but for me that is acceptable. Usually I wanted the collider rectangle to be smaller than the clip itself.
Ok I rewrote the code again and made it so it doesnāt use a list and it says mines is about 50-140% faster. I also double checked the code to see if I didnāt accidentally make it rigged because thatās a really big improvement and it doesnāt appear to be.
function hitTest1(c1, c2) {
var dx;
var dy;
dx = c1.x - c2.x;
if(dx<0)
{
dx*=-1;
}
if(dx<0.5*(c1.width+c2.width))
{
dy = c1.y - c2.y;
if (dy<0)
{
dy*=-1;
}
if(dy<0.5*(c1.height+c2.height))
{
return true;
}
}
return false;
}
function hitTest2(c1, c2) {
var c1w = c1.width / 2;
var c1h = c1.height / 2;
var c2w = c2.width / 2;
var c2h = c2.height / 2;
return (
c1 + c1w < c2 - c2w &&
c1 - c1w > c2 + c2w &&
c1 + c1h > c2 - c2h &&
c1 - c1h < c2 + c2h
);
}
var avg1 = 0;
var avg2 = 0;
var times = 999999;
for (let i = 0; i < times; i++) {
let start = performance.now();
hitTest1(this, clip2);
avg1 += performance.now() - start;
}
for (let i = 0; i < times; i++) {
let start = performance.now();
hitTest2(this, clip2);
avg2 += performance.now() - start;
}
avg1 /= times;
avg2 /= times;
var diff = (avg2 - avg1) / avg1;
console.log((diff) * 100 + "%");
For me it takes around 6 seconds until the tab unfreezes and the results are printed. The lower the time s variable is the shorter it will take, but I think it might hinder the estimation.
EDIT: I made it so it checks >= and <= and not > and <. Iām getting around 85%-97% fastertisity.
That is good, could you try mine like this insteadā¦?
project.hitTest = function(clip1, clip2)
{
var dx = Math.abs(clip1.x - clip2.x);
if(dx<(clip1.width_divided_2+clip2.width_divided_2))
{
var dy = Math.abs(clip1.y - clip2.y);
if(dy<(clip1.height_divided_2+clip2.height_divided_2))
{
return true;
}
}
return false;
};
this would require to have these values pre-calculatedā¦
clip1.width_divided_2
clip2.width_divided_2
clip1.height_divided_2
clip2.height_divided_2
Also, Thank you so much for this effortā¦ : ) You are good!
I didnāt saw the scroll in your last replyā¦ definitely your solution is shorter, better and less expensive. I will use it. Thank you so much!!! Iāll use yours, but I would pre-store those first 4 lines of yours so your function should boost a lotā¦ those division should weight something! : )
Before edit
Donāt know if this works, but it does work in my head:
How I thought collision worked ever since I started coding
if((this.x-((this.width/2)+(player.width/2)))-1 > player.x > (this.x+((this.width/2)+>>(player.width/2)))+1){ if((this.y-((this.height/2)+(player.height/2)))-1 > player.y > (this.y+((this.height/2)+>(player.height/2)))+1){ project.collision=true; }else{ project.collision=false; } }
this
is the object or wall that the code is put into, andplayer
is the name of the playerI probably missed something? My code doesnāt quite look as complicated as everyone elseās.
EDIT:
Just looked over the code that I had before this edit, I made a bit of changes and perfectly collision was detected: collision.wick (11.8 KB)
Weāll be working on implementing a few changes under the hood that will actually be able to ignore hit tests that will never collide.
Weāre considering using a structure called a quadtree that lets us know if two things are close enough to even potentially hit. This should make it so that in most cases, a hit test only considers a few elements, rather than every other possible object on screen!
Yup, I understand that approach. Interesting.
So the hitTest will first check if theyāre close enough for a hit to even happen?
@Hamzah_Alani Thank you for sharing this. That should work. In this case, since the project was lagging so much I was looking for a light (less expensive ) solution to increase the performance of the game. @pumpkinhead gave me a very good one, and I updated that one to have less comparisons.
Version 1.1, probably next week:
With new Suits power-ups with new attacks. Here is a sneak peek : )
Yes, in a bigger picture that is what it is. There are several ways to accomplish it. One approach could be by dividing the screen into 4 parts, then having a manager in each part. If one of those parts has 20 blocks verifying if a bullet reach them, the manager should know if the bullet is in his cuadrant and if.not diactivate all those 20 hitTest checks for those 20 blocks. If every cuadrant had 20 blocks, a normal scenario would be for the app to perform 80 hitTest per frame, but with this approach you would have only 20 instead. You might have cuadrants inside cuadrants and so onā¦ if that makes sense.
Well the game still lags a lot even if the project isnāt playing, so I donāt think the hitTest improvements would increase the performance a lot.