   trying to calculate if player hit floor when falling with insane speed
  My player can fall with an increasing speed depending on how long he hasnt collided with the tiles. The thing is, currently when im calculating when the player hits the tiles, i expect that his y-speed isnt greater than player->height+mapblockheight. I recently made a vertical map in my platform game, and i would like to calculate if he has collided with the tiles, even if hes falling with an insane speed. This is the code i came up with:but its not working as i intended. the +18 (on x ) and (-3) on y is to make the collision look more smooth.[source langg = "cpp"]if (jump<0) //if player is falling..   { if(abs(jump) > player->height + mapblockheight){ int ijump = (player->height + mapblockheight)/jump; for(n = 0; n <= ijump; n++) {if (collided(player->x + player->width/2,  player->y + player->height+(player->height * n)-3)||collided(player->x +18 ,  player->y + player->height+(player->height * n)-3)||collided(player->x + player->width-18,  player->y + player->height+(player->height * n)-3) )// if he collided with the foreground tiles {if(jump < -43) //if the player is falling with the speed of -43 or below make player bounce and apply -jump to y-velocityjump *=-0.3 ;    else   jump = JUMPIT;   //player collided so he can jump again    }  }}
  sorry i dont have a code example, but what you need to be doing is, calculating the collision for the NEXT frame, then if it looks like the object is going to collide in the next frame, you should be able to work out exactly how far your object has penentrated, then only move the object the distance moved - the distance penentrated and that should position your object exactly on the floor   ;  I can give you theories that I have studied; I havn't tested all of this myself.You are looking at an effect called TUNNELING, whereby an object goes past another at such speed that it is above on one step, but below the next.Lets say a character is 1 meter high, and you are using time slices of 30ms. The character will have to fall at 30 meters / second before it is capable of "tunneling". The time taken to reach this speed depends on gravity. In a world where gravity is 9.81, it takes [edit: 3.3639144] seconds for a stationary character to accelerate beyond this speed.One solution is that, when an object is moving at an "insane" speed, you split the motion up into smaller steps. e.g, if you drop a pencil of length 15 cm's onto a flat piece of paper, and it moves 45 cm's per frame, it will probably tunnel. So, you split it into (45 / 14) (slightly less than the objects height to be on the safe side) steps, that is, 3 steps. The cost of this algorithm is reduced by the fact that only a very few objects will move this fast. This works well for an object moving two or three times the speed required to tunnel. If an object is very small, and approximately spherical, you can approximate that object using a line segment instead. Cast the line from the current position to the next position. If the line intersects an object, then the moving "particle" is going to collide with that object at SOME point between the two frames. An example of this is a bullet. This works regardless of velocity and direction.Another method can be used if you are using a bounding volume for your characters. Stretch the bounding volume, whatever it may be, in the direction of travel. If it intersects with something, you know that is POSSIBLE that the character inside it will pass through that object in the next frame.I hope all this is technically accurate, best wait until somebody else comments it before doing it.   ;  shotgunnutter: from the code, it looks like he's trying to correct exactly for that, by considering all the intermediate tile positions.OP: Let's first clean that up a bit...- Space and indent your code consistently, please.- "jump" doesn't make sense for the name of a variable that indicates vertical speed. I'm using "dy" (in the mathematical sense: change in y-position over time). Similarly, "ijump" doesn't make sense. But then, we don't really need a variable for that one, so I avoided the naming problem by just putting the calculation into the loop statement. :)- Don't just declare all your counter variables "up at the top" somewhere. In C++, you can and usually should just declare them directly in the for-loop body, as shown.- When you repeat a calculation, it makes sense to pull that result into a variable - that way, you aren't cluttering the code by repeating yourself; if you make a change, you only have to change it in one place; and each time you write it out, you have less chance of stupid typos. :)if (dy < 0) {    int threshold = player->height + mapblockheight;    if (abs(dy) > threshold) {   for (int n = 0; n <= threshold / dy; n++) {  int collision_x = player->x + player->width / 2;  // I rearranged your x-position calculations a little: now the  // "left" and "right" sides are found in terms of the middle.  int collision_dx = 18 - player->width / 2;  int collision_y = player->y + player->height + (player->height * n) - 3;  if (collided(collision_x, collision_y) || collided(collision_x + collision_dx, collision_y) || collided(collision_x - collision_dx, collision_y)) { // I strongly recommend bracing your if's even where you // "don't have to". Avoids typos etc. later. if (dy < -43) {dy *= -0.3; } else {dy = JUMPIT; }  } }    }}Now we have something we can look at. ;) The main problem is that your step size - the "threshold" for doing this calculation, and the distance between tested points - is wrong. It should just be the block size; player height does not matter here. If I fall even one pixel more than the block height, there's a chance that there are two blocks to check against - one that I enter with the very first pixel of downward motion, and the one that I end up just barely in. Similarly, the *points that we check* should be the tile-height apart, not the player-height.But the calculation of the number of blocks to check is wrong, too. First off, we should be dividing the distance fallen *by* the step size, not the other way around. This is why you do word problems in math class :) But also, we need to remember that if we're doing this calculation at all, dy is *negative*, so we should account for that, too.If we think about that, though, there's a *stylistic* problem, too. We're creating too many special cases. Falling a small amount is *not* a special case. Just take out the conditional: then, we process small speeds with the same loop, but since the dy is small, we loop just once - to check the appropriate position.Oh, wait, you say, that won't check the appropriate position? Why not? Oh, it checks the player's current position, instead of the result position? Well spotted. But, that's a problem with the case we've been looking at, too. :) Since the points we check are simply multiples of the player-height away from the *current position*, none of them *necessarily* correspond to the final position. What we want to do instead is consider the final position, as well as tile-height multiples *above* *that*.// Actually, it seems like you consider increasing y to be "downward", but// had the "jump" refer to upward, "jumping speed". This is actually messy;// that kind of thing tends to mess up your algebra - negative numbers are not// special. So, I am now going to assume you really mean increasing y is// downward, therefore dy is *positive* when falling.if (dy > 0) {    // First, we figure out how many checks to do - there will be at least one.    // I no longer have to negate dy, because it's positive. ;)    int tiles_to_check = (dy / mapblockheight) + 1;    // We'll also calculate the "landing" position first.    int bottom_y = player->y + player->height + dy - 3;    // We're *adding* dy; ok, that makes sense.    // Notice that you normally use strict inequality (< rather than <=) with    // for-loops. To make that work, I had to add that suspicious '1' to    // tiles_to_check, but the resulting variable name *makes sense*.    for (int n = 0; n < tiles_to_check; ++n) {   int collision_x = player->x + player->width / 2;   int collision_dx = 18 - player->width / 2;   // Now, calculate the y positions starting from the bottom.   int collision_y = bottom_y - (n * mapblockheight);   // The rest as before.    }}You will probably find that this still has problems:- if you *do* collide, you'll want to be a lot more careful about picking the immediate *position*, as well as the new y-speed.- I have no idea what "JUMPIT" is; it sounds like you're reusing the same variable to hold some kind of magic "jumping state" flag, and that's asking for trouble when your jump speed could be either negative or positive. You presumably want to set dy to zero when you land, and change a *separate* flag, if needed.- If there are multiple blocks in the way, you need to collide with the highest one only, but that's the last one that gets detected in the looping process I gave above.- You might want to think about what happens when the horizontal speed is *also* large :)   