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):
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;
}