Update: I have figured out the original problem. I was using a string to record which platforms have been collided with, but I had forgotten to account for numbers with more than one digit. This should be easily remedied with separating characters (or a temporary hexadecimal system). Any improvements to my collision system are still welcome and appreciated.
Hi!
I'm a new programming trying to teach myself game programming. My current project is a simple platforming game prototype, and I have almost all of it working except for collision with platforms other than the floor and walls. It worked moderately well with 3 and 6 platforms, but when I up-sized to 15, an odd glitch appeared. When the character touches certain platforms (perhaps at above a certain speed, it's hard to tell), the character will teleport to another platform above it and in another column.
picture (crappy, but it conveys the idea):
My update function (with some other functions vital to collision):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
| protected void update(double delta){ boolean colliding = checkCollisions(); boolean inCanvas = isInCanvas(); boolean isFloating = checkFloating(); if(isFloating){ player.isJumping = true; } if(inCanvas && !colliding){ if(player.isJumping){ player.y += player.yVelo*delta + .5*ACCELGRAV*delta*delta; player.yVelo += ACCELGRAV * delta; } if(!player.isDecelerating){ player.x += player.xVelo*delta + .5*player.xAccel*delta*delta; player.xVelo += player.xAccel*delta; if(player.xVelo > player.maxXVelo){ player.xVelo = player.maxXVelo; } }else{ if((player.xVelo < 0 && player.xAccel > 0) || (player.xVelo > 0 && player.xAccel < 0)){ player.x += player.xVelo*delta + .5*player.xAccel*delta*delta; player.xVelo += player.xAccel*delta; }else if((player.xVelo >= 0 && player.xAccel > 0) || (player.xVelo <= 0 && player.xAccel < 0)){ player.xVelo = 0; player.xAccel = 0; player.isDecelerating = false; } } } if(!inCanvas){ if(playerRect.getMaxY()>canvasRect.getMaxY()){ player.y = canvasRect.getMaxY()-playerSideLen; player.yVelo = 0; player.isJumping = false; } if(playerRect.getMinY()<canvasRect.getMinY()){ player.y = canvasRect.getMinY(); player.yVelo = 0; player.isJumping = true; } if(playerRect.getMaxX()>canvasRect.getMaxX()){ player.x = canvasRect.getMaxX() - playerSideLen; player.xVelo = 0; if(player.isDecelerating){ player.xAccel = 0; player.isDecelerating = false; } } if(playerRect.getMinX()<canvasRect.getMinX()){ player.x = canvasRect.getMinX(); player.xVelo = 0; if(player.isDecelerating){ player.xAccel = 0; player.isDecelerating = false; } } } if(colliding){ String s = ""; for(int i = 0; i < numBlocks; i++){ blockRect.setRect(blocks[i].x, blocks[i].y, blocks[i].width, blocks[i].height); if(playerRect.intersects(blockRect)){ s = s+i; } } for(int i = 0; i<s.length(); i++){ char blockNum = s.charAt(i); int blocknumber = Integer.parseInt(""+blockNum); blockRect.setRect(blocks[blocknumber].x,blocks[blocknumber].y,blocks[blocknumber].width,blocks[blocknumber].height); int outcode = blockRect.outcode(playerRect.getCenterX(), playerRect.getCenterY()); switch (outcode){ case Rectangle.OUT_BOTTOM:{ player.y = blocks[blocknumber].y + blocks[blocknumber].height; player.yVelo = 0; player.isJumping = true; break; } case Rectangle.OUT_TOP:{ player.y = blocks[blocknumber].y - playerSideLen; player.yVelo = 0; player.isJumping = false; break; } case Rectangle.OUT_RIGHT:{ player.x = blocks[blocknumber].x + blocks[blocknumber].width; player.xVelo = 0; if(player.isDecelerating){ player.xAccel = 0; player.isDecelerating = false; } break; } case Rectangle.OUT_LEFT:{ player.x = blocks[blocknumber].x - playerSideLen; player.xVelo = 0; if(player.isDecelerating){ player.xAccel = 0; player.isDecelerating = false; } break; } case (Rectangle.OUT_BOTTOM + Rectangle.OUT_LEFT):{ player.y = blocks[blocknumber].y + blocks[blocknumber].height; player.yVelo = 0; player.isJumping = true; player.x = blocks[blocknumber].x - playerSideLen; player.xVelo = 0; if(player.isDecelerating){ player.xAccel = 0; player.isDecelerating = false; } break; } case (Rectangle.OUT_BOTTOM + Rectangle.OUT_RIGHT):{ player.y = blocks[blocknumber].y + blocks[blocknumber].height; player.yVelo = 0; player.isJumping = true; player.x = blocks[blocknumber].x + blocks[blocknumber].width; player.xVelo = 0; if(player.isDecelerating){ player.xAccel = 0; player.isDecelerating = false; } break; } case (Rectangle.OUT_TOP + Rectangle.OUT_LEFT):{ player.y = blocks[blocknumber].y - playerSideLen; player.yVelo = 0; player.isJumping = false; player.x = blocks[blocknumber].x - playerSideLen; player.xVelo = 0; if(player.isDecelerating){ player.xAccel = 0; player.isDecelerating = false; } break; } case (Rectangle.OUT_TOP + Rectangle.OUT_RIGHT):{ player.y = blocks[blocknumber].y - playerSideLen; player.yVelo = 0; player.isJumping = false; player.x = blocks[blocknumber].x + blocks[blocknumber].width; player.xVelo = 0; if(player.isDecelerating){ player.xAccel = 0; player.isDecelerating = false; } break; } case 0: player.y -= 10;break; } } } } public boolean checkCollisions(){ boolean collision = false; playerRect.setRect(player.x, player.y, playerSideLen, playerSideLen); for(int i = 0; i < numBlocks; i++){ blockRect.setRect(blocks[i].x, blocks[i].y, blocks[i].width, blocks[i].height); if(playerRect.intersects(blockRect)){ collision = true; } } return collision; } public boolean isInCanvas(){ boolean isInCanvas; playerRect.setRect(player.x, player.y, playerSideLen, playerSideLen); isInCanvas = canvasRect.contains(playerRect); return isInCanvas; } public boolean checkFloating(){ boolean floating = true; playerRect.setRect(player.x, player.y+1, playerSideLen, playerSideLen); for(int i = 0; i < numBlocks; i++){ blockRect.setRect(blocks[i].x, blocks[i].y, blocks[i].width, blocks[i].height); if(playerRect.intersects(blockRect) || !canvasRect.contains(playerRect)){ floating = false; } } return floating; } |