collision of a platformer (like mario bros) not working - c++

i've been sitting here for hours now trying to figure out how collision could work for a platformer.. after doing a lot of research i found something useful in the internet.. but it doesn't work yet :/
my character seems to jump one time.. and then gets stuck a short distance above the ground
This is the function where i load my platforms from txt (by calling setupworld)
in my txt i define xstart (where the platform starts) xend (end of platform) ystart (bottom of platform) 2 unnused variables and the texture filter (0-4 atm)
each platform is then created by repeating 2x2 tiles in x direction
numblocks= number of platforms (sry for the bad variable name ^^)
number of blocks is calculated by taking the end coordinate of the platform - start coordinate and dividing by 2.0 (my platforms always have coordinates dividable by 2.. like.. 0 - 16.. or.. 8 - 16.. )
as u see.. the structure block is where all the data is saved to in setupworld() and it has nothing to do with the number of tiles displayed.. sry again for my weird names
GLvoid BuildLists()
{
texture[0]=LoadPNG("data/grass.png");
texture[1]=LoadPNG("data/gnd.png");
texture[2]=LoadPNG("data/pilz_test.png");
texture[3]=LoadPNG("data/rockwall.png");
texture[4]=LoadPNG("data/crate.png");
setupworld();
quad[0]=glGenLists(numblocks);
for(int loop=0;loop<numblocks;loop++)
{
GLfloat xstart,xend,ystart,u,v,u2,v2;
xstart=block.data[loop].xstart;
xend=block.data[loop].xend;
ystart=block.data[loop].ystart;
//u=block.data[loop].u;
//v=block.data[loop].v;
GLuint filter=block.data[loop].filter;
GLfloat blocks=(xend-xstart)/2.0f;
u=0.0f;
v=0.0f;
u2=1.0f*blocks;
v2=1.0f;
glNewList(quad[loop],GL_COMPILE);
glBindTexture(GL_TEXTURE_2D, texture[filter]);
// Start Drawing Quads
for(int y=0;y<blocks;y++)
{
glBegin(GL_QUADS);
glTexCoord2f(u,v);
glVertex3f(xstart,ystart,-1.0f);
glTexCoord2f(u2,v);
glVertex3f(xstart+((y+1)*2.0f),ystart,-1.0f);
glTexCoord2f(u2,v2);
glVertex3f(xstart+((y+1)*2.0f),ystart+2.0f,-1.0f);
glTexCoord2f(u,v2);
glVertex3f(xstart,ystart+2.0f,-1.0f);
glEnd();
}
glEndList();
quad[loop+1]=quad[loop]+1;
}
}
This is where the key actions are processed..
DetectCollision() calls my function where i (try to) check for collisions
ymovement
ypos2=ypos; is just to remind the last position for repositioning
i jump until i reach 5.0f or a collision in y-direction is detected.. then locky turns TRUE; the else is to let my character get back to ground (cause no gravity) even when the player keeps w pressed
the same thing happens when w is not pressed.. and locky is being reset
xmovement
i add to (or subtract from) xpos for movement
as long as the character doesn't reach the border or a collision appears it should do the normal movement
if (active) // Program Active?
{
if (keys[VK_ESCAPE])
{
done=TRUE;
glDeleteTextures(1,&texture[0]);
glDeleteTextures(1,&texture[2]);
glDeleteTextures(1,&texture[1]);
}
if (keys['W'])
{
if(!locky)
{
DetectCollision();
ypos2=ypos;
ypos=ypos+0.2f;
if(ypos>=5.0f)
{
locky=!locky;
}
if(collisiony)
{
ypos=ypos2;
locky=!locky;
}
}
else
{
if(ypos>0.0f && !collisiony)
{
ypos=ypos-0.2f;
}
}
}
if (!keys['W'])
{
locky=!locky;
if(ypos>0.0f && !collisiony)
{
ypos=ypos-0.2f;
}
}
if (keys['A'])
{
if(xpos>0.0f && !collisionx)
{
xpos=xpos-0.2f;
}
}
if (keys['D'])
{
if(xpos< 50.0f && !collisionx)
{
xpos=xpos+0.2f;
xcam=xcam-0.1f;
}
}
glLoadIdentity();
glTranslatef(0,-7.0f,-25.0f);
DrawWorld(); //draws my platforms by calling the display lists compiled in build lists
DrawChar(); //draws the character
SwapBuffers(hDC);
}
Finally the code where i check for collisions
inPlatformx for checking x
is my character between left and right side of the platform being checked
-> function returns TRUE and is written into collisionx
inPlatformy for checking y
same for inPlatformy
bool inPlatformx(float xpos, BLOCK block, int i){
return xpos > block.data[i].xstart &&
xpos < block.data[i].xend;}
bool inPlatformy(float ypos, BLOCK block, int i){
return ypos > block.data[i].ystart &&
ypos < (block.data[i].ystart+0.2);
}
GLvoid DetectCollision(){
for(int i=0; i<numblocks;i++)
{
collisionx=inPlatformx(xpos,block,i);
collisiony=inPlatformy(ypos,block,i);
}
}
finally a screenshot
http://www.grenzlandzocker.de/test.png
I hope u can help me.. either fix my code or give me some tips on collisions.. since it's my first game with opengl :s
if u need any more detail or infos please ask ^^
and thanks in advance !
if (keys['W'])
{
//DetectCollision();
if(!locky)
{
ypos2=ypos;
ypos=ypos+0.2f;
if(ypos>=5.0f)
{
locky=!locky;
}
if(collisiony)
{
ypos=ypos2;
locky=!locky;
}
}
else
{
if(ypos>0.0f)
{
ypos=ypos-0.2f;
}
}
}
if (!keys['W'])
{
locky=!locky;
if(ypos>0.0f && !collisiony)
{
ypos=ypos-0.2f;
}
}
if (keys['A'])
{
//DetectCollision();
if(xpos>0.0f && !collisionx)
{
xpos2=xpos;
xpos=xpos-0.2f;
}
if(collisionx)
{
xpos=xpos2;
}
}
if (keys['D'])
{
//DetectCollision();
if(xpos< 50.0f && !collisionx)
{
xpos2=xpos;
xpos=xpos+0.2f;
xcam=xcam-0.1f;
}
if(collisionx)
{
xpos=xpos2;
}
}
THANKS :)
well i just edited the code for x movement and collision.. so it works properly.. (despite the flickering (but idc atm :) ).. i'm wondering why jumping doesn't work at all anymore.. it's just increasing till i'm stuck.. can't even get up once anymore :/
i put my detectCollision() in front of they key section.. which works for x AND y now (hopefully)..
and i also edited something in DetectCollision()
i had ystart+0.2 instead of ystart+2.0 which is the correct coordinate for the platforms top
but looks like it just got worse at y
i'm still totally confused..
oh and talking about those predefined api's and stuff.. since somebody first showed me some things with glut i tried to make the next step and initialize everything myself.. i guess detection is much easier using predefined stuff.. but i want to learn it and not just get one game to work :)
if u have any more suggestions for my code i would be really grateful.. and if u know any good books for starters till advanced lvl i would really appreciate
and yes.. i know.. display lists are deprecated since opengl 3.0 ^^

Unless I am not following your code correcty, once you reach the apex of your jump and set your locky to !locky, you start hitting your else statement, which never checks for collision. IF you are moving in the x or -x direction, you likely want to be doing this as the ground may not be in the same place as your origin of the jump.
Additionally, your locky check is checking if the ypos >= 5.0f , which will immediately be the case if you are already on some part of your game world above the 5.0 mark. You likely want this to be a variable such as limitY = ypos + 5.0f; and then check if ypos >= limitY, so it works regardless of origin.
As for the issue you are seeing now, it should be easy to debug and look at the current value of your y coordinate and see if there is anything obvious (such as not executing a final ypos -= 0.2f ) which is cause for you floating slightly above the ground after a jump. (I don't see an obvious error in the way you are doing your code, although I would not have designed it in the way you are doing it yourself.)
If you are developing this for Windows you may want to look into XNA development, which makes collision detection and resolution a lot easier.

Are you initializing locky to true or false? because all the code i can see inverts the state of locky, so depending on how the input is processed, your locky value is flipping every loop or possibly being set out of sync with your expectations.
I would recommend setting locky to true and false explicitly in the code you've shown, rather than using locky=!locky, it's clearer about the state of the system.

Related

OpenGL Collisions between 2 spheres sometimes not detected

For this project i use OpenGl.
I'm trying to detect the collision between two spheres, I think it's pretty simple.
It works but sometimes (very often actually...) the collision between these two spheres is not detected, and I really don't know why...
I tried to change the algorithm of detection and it allways ends by a non detection sometimes...
void MyGlWindow::checkMoverIsHit()
{
for (size_t i = 0; i < m_container->m_movers.size(); i++)
{
if (m_container->m_ball != m_container->m_movers[i]) {
float size = m_container->m_ball->m_size + m_container->m_movers[i]->m_size;
if (size >= (m_container->m_ball->m_position - m_container->m_movers[i]->m_position).magnitude())
{
score += 10;
m_container->m_movers.erase(std::remove(m_container->m_movers.begin(), m_container->m_movers.end(), m_container->m_movers[i]), m_container->m_movers.end());
for (size_t i = 0; i < (score / 10) + 1; i++)
createMover();
reload();
}
}
}
}
I call this function in my update function
void MyGlWindow::update()
{
TimingData::get().update();
if (!run) return;
float lastFrameDuration = (float)TimingData::get().lastFrameDuration;
float duration = lastFrameDuration * 0.003;
totalTimePrecise += lastFrameDuration;
totalTimeSec = totalTimePrecise / 1000;
if (totalTimeSec > 60) {
writeBestScoreInFile();
restart();
}
if (totalTimeSec == 40)
windBlowing = true;
if (duration <= 0.0f) return;
m_container->update(duration);
if (windBlowing == true)
m_container->windBlow();
checkBallDetachFromAnchor();
checkMoverIsHit(); // !!! ITS CALLED HERE !!!
m_world->runPhysics(duration);
}
m_container is my container of movers: it contains basically all the "movers" of my scene.
m_container->m_ball is a pointer of one of these movers. It's the ball I launched to "shoot" the other movers.
After I think everything is pretty clear, ask me if something is not.
Hope someone can help me... I've done everything in my project it's the only thing bugging !
Here is a GIF, the first ball worked, the second didn't:
I finally manage to find out what was happening.
The problem is that my world is avoiding collisions. What I mean by that is: when two objects collide, they automatically bounce against each other.
This behaviour was the problem because the goal of my hunting ball is to collide against the other objects so.... randomly... it was not detecting some collisions, because it was boucing.
To fix it, I removed from my hunting ball the fact that it was iteracting with the other movers of the scene. So now it's only checking in my function checkMoverIsHit(); if it's colliding with the other movers.
It now works perfectly.

Proper collision in SFML (C++)

So, I had a test going on to see how collision operates in SFML. I have made this snippet of code:
if (floor.getGlobalBounds().intersects(SuperMario.getGlobalBounds())) // Floor
{
SuperMario.setPosition(SuperMario.getPosition().x, floor.getPosition().y - SuperMario.getOrigin().y);
IsTouching = true;
}
As the code suggests, Mario will change his position when he touches the floor object and will teleport above the floor.
However, this has the following side-effect, illustrated by the pictures below.
Note that the "green box" is the floor object I mentioned earlier. Also, ignore the word "left" in picture 1, I mean "right".
Of course, this behaviour is intended (i.e. is not a bug), but it is unwanted.
So my question is: How can I eliminate this "side-effect"? I mean, how can I modify my code, so Mario will not teleport above the floor, when he touches its sides(making platforming work like a proper platforming)? I want Mario to be stopped by the box, not to be teleported.
UPDATE: So now, I have this:
for (unsigned int i = 0; i <= solidObjects.size() - 1; i++)
{
if (solidObjects[i].getGlobalBounds().intersects(SuperMario.getGlobalBounds()))
{
if (SuperMario.getPosition().x - solidObjects[i].getPosition().x < SuperMario.getPosition().y - solidObjects[i].getPosition().y)
{
SuperMario.setPosition(solidObjects[i].getPosition().x - SuperMario.getOrigin().x, SuperMario.getPosition().y);
IsTouching = false;
}
else if (SuperMario.getPosition().y - solidObjects[i].getPosition().y < SuperMario.getPosition().x - solidObjects[i].getPosition().x)
{
SuperMario.setPosition(SuperMario.getPosition().x, solidObjects[i].getPosition().y - SuperMario.getOrigin().y);
IsTouching = true;
}
else if (SuperMario.getPosition().x - solidObjects[i].getTextureRect().width < SuperMario.getPosition().y - solidObjects[i].getPosition().y)
{
SuperMario.setPosition(solidObjects[i].getTextureRect().width + SuperMario.getOrigin().x, SuperMario.getPosition().y);
IsTouching = false;
}
}
else
{
IsTouching = false;
}
}
However, there is one problem. When Mario touches the sides of the floor, he sticks on them meaning he is unable to move right.
If I am not clear enough, please specify what i should add or clarify more.
This feels really weird, because you'd typically define solid areas rather than those the player can walk inside. You'll want your player to jump after all, rather than having them glued to the ground.
The rest is pretty straightforward:
Iterate over all solid objects and determine whether the player and the solid rectangle overlap.
If they do, determine which distance is smaller (x or y). This lets you determine which axis to move the player.
Determine which direction the player leaves the solid area quicker, i.e. which direction to push the player.
Push the player in the calculated direction and repeat the checks.
Depending on your map complexity this can become rather complex, so you'll most likely want some sorting/spatialisation to reduce the number of comparisons (e.g. skip checking impossible/far away shapes).

C++ Collision Detection doesn't work on last check?

Over the last few days I have been trying to implement simple collision detection of objects drawn using OpenGL.
With the aid of the Pearson, Computer Graphics with OpenGL I have managed to write the following function:
void move(){
if(check_collision(sprite,platform1) || check_collision(sprite,platform2)){ //if colliding...
if (downKeyPressed ){ y_Vel += speed; downKeyPressed = false;} //going down
else if(upKeyPressed ){ y_Vel -= speed; upKeyPressed = false;} //going up
else if(rightKeyPressed){ x_Vel -= speed; rightKeyPressed = false;} //going right
else if(leftKeyPressed ){ x_Vel += speed; leftKeyPressed = false;} //going left
} // always glitches on whatever is last else if above?!?!
else{ glTranslatef(sprite.x+x_Vel, sprite.y+y_Vel, 0.0); }
}
My sprite moves in accordance to keyboard inputs (the arrow keys). If it collides with a stationary object it stops moving and stays in its position.
So far, it works when colliding with the top, left side and bottom of the stationary object. Unfortunately (even though I use the same logic) the right hand side doesn't work and upon a collision the sprite is redrawn at its original x/y coordinates. I'm baffled.
As it turns out, which-ever is the last check in the move() function (the last else-if) is the one that doesn't work... I have swapped the left with the right and sure enough when left is then the last one and the one that plays up :(
Any advice or ideas on how I can improve this and stop it glitching?
Please excuse my naivety and amateur coding. I'm merely a self-taught beginning. Thanks.
You should not use an else if. There is a possibility that it is hitting a side and the top or the bottom in the same frame. Trying changing those to all ifs because you want to check each one. or at the least change it to this.
if( /* check top */)
{
}
else if( /* check bot */)
{
}
if( /* check right */ )
{
}
else if( /* check left */)
{
}
Also, you should avoid declaring global variables like Y_VEL and X_VEL as this creates confusion. You may just be doing this to get your feet wet but I would avoid it. Create a class for each object and then have the velocities as members of that class.
Well, it seems to me that you have an issue when it comes to translating the actual object.
Your move code states
if(there is a collision)
{
//do stuff
}
else
{
glTranslateF( );
}
SO, whenever there is a collision, the translate function never gets called.
My opinion is that you should pull the glTranslateF() call out of the else {...}, just have it get called every time. However, it seems you're using the exact same 'draw' function for every rectangle, not just the player sprite. You'll probably have to ind a way to distinguish between regular rectangles (such as the platforms) and the player rectangle. Perhaps the simplest way for you to implement this, would be to have two different drawSprite functions: one for regular platforms, and the other for the player. Only call the move() function from within the player's draw function (perhaps called drawPlayer()?)
I don't quite have the time to look over all of your code to make a more educated and specific suggestion at the moment; however, I'll be free later this evening if this question is still open and needing help.
As you've already figured out, the problem is related to glTranslate(). Since you operate on both sprite's position and velocity, you should repeatedly update the positions using the velocities. That is:
sprite.x += x_vel;
sprite.y += y_vel;
and do it simply all the time (i.e. by some timer or every frame, if the scne is redrawn repeatedly). A collision then is equivalent to changing the velocity vector (x_vel, y_vel) in some way to simulate the collision effect: either zero it to stop any movement at all, or change the velocity component sign (x_vel = -x_vel) to make it rebound in an absolutely elastic manner, or do something else that fits.
What happens now with glTranslate() is that x_vel, y_vel actually hold offsets from the starting position, but not velocities of movement.

Moving to Mouse Pos OpenGL

ive got a program that is moving an object with my mouse click im using gluUnProject and sometimes when i click somewhere the object isnt moving the way i want it my equation seems to be doing fine sometimes but sometimes its not working and i think its somehow rotating the object and getting x and z wrong... so this is how im doing this
im initializing these 2 variables like this
PosP = CVector(20.0,20.0,-30);//PosP is the Starting Position for the char
oldPos = PosP;//PosP is the Position I am modifying when mouse is clicked
so when i click im getting PosP like this
gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);
std::cout<< posX<<" "<<posY<<" "<<posZ<<std::endl;//printing the results to check everything's fine
PosP.x = posX;
PosP.z = posZ;
all of this is on a render function so each frame is doing 1 cycle
Char(oldPos);
if((int)oldPos.x != (int)PosP.x)
{
if((int)PosP.x <= 0)
{
oldPos.x--;//Checking if posP.x < 0 then its a negative value and decrement
}
else
{
oldPos.x++;//Checking if posP.x < 0 then its a positive value and increment
}
}
if((int)oldPos.z != (int)PosP.z)
{
if((int)PosP.z <= 0)
{
oldPos.z--;
}
else
{
oldPos.z++;
}
}
ok i know whats the error now but i dont know how to solve it the thing is the object is moving whatever it has left to move in x or z randomly lol any ideas?
I think your approach is overcomplicated. Think in vectors intead of individual x,y,z. Here's one way (pseudocode):
if (click) {
posP = clickPos
d = length(posP - oldPos)
numSteps = roundUp(d/speed) // speed in world units per frame. Make sure numSteps > 0!
delta = (posP - oldPos) / numSteps
}
//each frame:
if (numSteps > 0) {
oldPos += delta;
--numSteps;
}
i found what was wrong today :S it seems like im not using the gluUnproject function the way it should be used and im not normalizing my position vectors so im getting really big numbers :S sry

2D Platformer Collision Handling

I am trying to create a 2D platformer (Mario-type) game and I am some having some issues with handling collisions properly. I am writing this game in C++, using SDL for input, image loading, font loading, etcetera. I am also using OpenGL via the FreeGLUT library in conjunction with SDL to display graphics.
My method of collision detection is AABB (Axis-Aligned Bounding Box), which is really all I need to start with. What I need is an easy way to both detect which side the collision occurred on and handle the collisions properly. So, basically, if the player collides with the top of the platform, reposition him to the top; if there is a collision to the sides, reposition the player back to the side of the object; if there is a collision to the bottom, reposition the player under the platform.
I have tried many different ways of doing this, such as trying to find the penetration depth and repositioning the player backwards by the penetration depth. Sadly, nothing I've tried seems to work correctly. Player movement ends up being very glitchy and repositions the player when I don't want it to. Part of the reason is probably because I feel like this is something so simple but I'm over-thinking it.
If anyone thinks they can help, please take a look at the code below and help me try to improve on this if you can. I would like to refrain from using a library to handle this (as I want to learn on my own) or the something like the SAT (Separating Axis Theorem) if at all possible. Thank you in advance for your help!
void world1Level1CollisionDetection()
{
for(int i; i < blocks; i++)
{
if (de2dCheckCollision(ball,block[i],0.0f,0.0f)==true)
{
de2dObj ballPrev;
ballPrev.coords[0] = ball.coords[0];
ballPrev.coords[1] = ball.coords[1];
ballPrev.coords[2] = ball.coords[2];
ballPrev.coords[3] = ball.coords[3];
ballPrev.coords[0] -= ball.xspeed;
ballPrev.coords[1] -= ball.yspeed;
ballPrev.coords[2] -= ball.xspeed;
ballPrev.coords[3] -= ball.yspeed;
int up = 0;
int left = 0;
int right = 0;
int down = 0;
if (ballPrev.coords[0] < block[i].coords[0] && ballPrev.coords[2] < block[i].coords[0] && (((ball.coords[1] < block[i].coords[1]) || (ball.coords[3] < ball.coords[1])) || ((ball.coords[1] < block[i].coords[3]) || ball.coords[3] < block[i].coords[3])))
{
left = 1;
}
if (ballPrev.coords[0] > block[i].coords[2] && ballPrev.coords[2] > block[i].coords[2] && (((ball.coords[1] < block[i].coords[1]) || (ball.coords[3] < ball.coords[1])) || ((ball.coords[1] < block[i].coords[3]) || (ball.coords[3] < block[i].coords[3]))))
{
right = 1;
}
if(ballPrev.coords[1] < block[i].coords[1] && block[i].coords[1] < ballPrev.coords[3] && ballPrev.coords[3] < block[i].coords[3])
{
up = 1;
}
if(block[i].coords[1] < ballPrev.coords[1] && ballPrev.coords[1] < block[i].coords[3] && block[i].coords[3] < ballPrev.coords[3])
{
down = 1;
}
cout << left << ", " << right << ", " << up << ", " << down << ", " << endl;
if (left == 1)
{
ball.coords[0] = block[i].coords[0] - 18.0f;
ball.coords[2] = block[i].coords[0] - 2.0f;
}
else if (right == 1)
{
ball.coords[0] = block[i].coords[2] + 2.0f;
ball.coords[2] = block[i].coords[2] + 18.0f;
}
else if (down == 1)
{
ball.coords[1] = block[i].coords[3] + 4.0f;
ball.coords[3] = block[i].coords[3] + 20.0f;
}
else if (up == 1)
{
ball.yspeed = 0.0f;
ball.gravity = 0.0f;
ball.coords[1] = block[i].coords[1] - 17.0f;
ball.coords[3] = block[i].coords[1] - 1.0f;
}
}
if (de2dCheckCollision(ball,block[i],0.0f,0.0f)==false)
{
ball.gravity = -0.5f;
}
}
}
To explain what some of this code means:
The blocks variable is basically an integer that is storing the amount of blocks, or platforms. I am checking all of the blocks using a for loop, and the number that the loop is currently on is represented by integer i.
The coordinate system might seem a little weird, so that's worth explaining.
coords[0] represents the x position (left) of the object (where it starts on the x axis).
coords[1] represents the y position (top) of the object (where it starts on the y axis).
coords[2] represents the width of the object plus coords[0] (right).
coords[3] represents the height of the object plus coords[1] (bottom).
de2dCheckCollision performs an AABB collision detection.
Up is negative y and down is positive y, as it is in most games.
Hopefully I have provided enough information for someone to help me successfully. If there is something I left out that might be crucial, let me know and I'll provide the necessary information. Finally, for anyone who can help, providing code would be very helpful and much appreciated.
Thank you again for your help!
Edit 2: I have updated my code with a new algorithm that checks where the ball was previously before collision. Corner cases work on that single platform correctly now, and when I have a wall of objects, I can slide against it correctly now. The only remaining problem is that there is a small jittering effect that happens when I am on the ground, where the ball is constantly going up and down as if it is being pulled by gravity and then the ball falls back into the object again.
Edit: Here is a URL to an image trying to show the kinds of problems I am having:
http://img8.imageshack.us/img8/4603/collisionproblem.png
In case the explanation in the picture doesn't make too much sense, the ball cannot move left past the corner of an object unless I jump over it. However, the ball can move right, but it gets repositioned to the right of the object while moving, which is not needed. This creates a skipping movement essentially, where it appears as the the ball is skipping over half of the object or so when I move right. If this doesn't make sense, please ask me and I'll try to clarify more.
One problem with your code is that you only detect situations like this:
If the circle happens to be fully inside the block, you don't reposition at all. And that's a problem.
You're trying to think about your simulation as if it were continuous, but keep in mind it's discrete. In general, if you only look at the current state of the ball, you really cannot know which side it collided with. Look at these two possibilities:
The first solution that comes to mind is to look at the last position of the ball as well; more precisely, look at the delta vector. See if the delta vector intersects a wall. If it does, reposition in an axis-aligned direction towards the wall intersected by the delta vector.
Edit: When I said "delta vector", I forgot that you're moving a square and not a single point. So, if you just look at the delta vector of the top-left corner, that's not going to be enough because it may not detect that part of the ball entered a block. Instead, you can look at the delta vectors of all 4 corners.