Java game slopes tile collision

I'm trying to figure out how I can make my player move on sloped tiles. My tiles all represent RGB values, and this is how I currently handle collisions and whether the player can move there or not:
// Go through all pixels in the level and add all data related to the level
for (int y = 0; y < img.getHeight(); y++)
for (int x = 0; x < img.getWidth(); x++) {
Color color = new Color(img.getRGB(x, y));
int red = color.getRed();
levelData[y][x] = red;

int tileValue = level.getLevelData()[tileY][tileX];
return switch (tileValue) {
case TRANSPARENT_TILE, SLOPED_TILE -> false;
default -> true;
};
// Go through all pixels in the level and add all data related to the level
for (int y = 0; y < img.getHeight(); y++)
for (int x = 0; x < img.getWidth(); x++) {
Color color = new Color(img.getRGB(x, y));
int red = color.getRed();
levelData[y][x] = red;

int tileValue = level.getLevelData()[tileY][tileX];
return switch (tileValue) {
case TRANSPARENT_TILE, SLOPED_TILE -> false;
default -> true;
};
And here I check if the tile is solid, and if so, the player can move to position and I update his hitbox.x (which is the top left position of the hitbox).
boolean isTopLeftSolid = isSolid(x, y, level);
boolean isTopRightSolid = isSolid(x + width, y, level);
boolean isBottomLeftSolid = isSolid(x, y+height, level);
boolean isBottomRightSolid = isSolid(x+width, y+height, level);

if (canMoveToPosition(hitbox.x + xDirection, hitbox.y, hitbox.width, hitbox.height, level))
hitbox.x += xDirection;
boolean isTopLeftSolid = isSolid(x, y, level);
boolean isTopRightSolid = isSolid(x + width, y, level);
boolean isBottomLeftSolid = isSolid(x, y+height, level);
boolean isBottomRightSolid = isSolid(x+width, y+height, level);

if (canMoveToPosition(hitbox.x + xDirection, hitbox.y, hitbox.width, hitbox.height, level))
hitbox.x += xDirection;
My question is, how can I adjust the player hitbox y position based on what section of a sloped tile he is standing on? I have the section of the tile he is standing on but I don't know how to update the "solidity" of a sloped tile.
boolean isTileSloped(int tileX, int tileY, Level level) {
int tileValue = level.getLevelData()[tileY][tileX];

if (tileValue != SLOPED_TILE)
return false;

float bottomLeft = hitbox.x / TILES_SIZE;
int bottomLeftFloor = (int) Math.floor(bottomLeft);
float difference = bottomLeft - bottomLeftFloor;
int section = (int) (difference * 4) + 1;

if (tileX == bottomLeftFloor) {
System.out.println("Section " + section);
if (section == 1) {
// Need help here with setting the hitbox y position
}
}
return true;
}
boolean isTileSloped(int tileX, int tileY, Level level) {
int tileValue = level.getLevelData()[tileY][tileX];

if (tileValue != SLOPED_TILE)
return false;

float bottomLeft = hitbox.x / TILES_SIZE;
int bottomLeftFloor = (int) Math.floor(bottomLeft);
float difference = bottomLeft - bottomLeftFloor;
int section = (int) (difference * 4) + 1;

if (tileX == bottomLeftFloor) {
System.out.println("Section " + section);
if (section == 1) {
// Need help here with setting the hitbox y position
}
}
return true;
}
68 Replies
JavaBot
JavaBot2y ago
This post has been reserved for your question.
Hey @Erky! Please use /close or the Close Post button above when you're finished. Please remember to follow the help guidelines. This post will be automatically closed after 300 minutes of inactivity.
TIP: Narrow down your issue to simple and precise questions to maximize the chance that others will reply in here.
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Erky
ErkyOP2y ago
@Fischstaebchen im trying to focus on simply setting the hitbox to be at the appropriate height when passing a sector, i can calculate slope angles when i first get this to work. just having trouble with the overall code approach, like how can i update the hitbox.y position to be at the right height? because when setting it like this, he just keeps bouncing because he thinks he is in the air. i have a method isEntityOnGround that checks if the bottom left and bottom right of the hitbox is on the ground, and if so, moves the hitbox down to the ground. so i need to add a checker before that somehow so if i disable falling mechanics, it looks decent when moving fast, but when moving slow i slowly float up to the top tile for some reason?
protected boolean isEntityInAir(Rectangle2D.Float hitbox, Level level) {
// check the bottom left and bottom right corner of the hitbox
boolean isBottomLeftSolid = isSolid(hitbox.x, hitbox.y + hitbox.height + 1, level);
boolean isBottomRightSolid = isSolid(hitbox.x + hitbox.width, hitbox.y + hitbox.height + 1, level);

// returns false if either hitbox for bottom left and bottom right corner is colliding with a solid tile
if (isBottomLeftSolid || isBottomRightSolid)
return false;
else
return true;
}
protected boolean isEntityInAir(Rectangle2D.Float hitbox, Level level) {
// check the bottom left and bottom right corner of the hitbox
boolean isBottomLeftSolid = isSolid(hitbox.x, hitbox.y + hitbox.height + 1, level);
boolean isBottomRightSolid = isSolid(hitbox.x + hitbox.width, hitbox.y + hitbox.height + 1, level);

// returns false if either hitbox for bottom left and bottom right corner is colliding with a solid tile
if (isBottomLeftSolid || isBottomRightSolid)
return false;
else
return true;
}
so this one checks if im in the air or not
Erky
ErkyOP2y ago
Erky
ErkyOP2y ago
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Erky
ErkyOP2y ago
I mean, In my game I only have two types of slopes which is diagonal from top left to top right or vice versa the slope is just an image, which i have defined as non-solid so i can walk through it
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Erky
ErkyOP2y ago
walk through the slope from the right side
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Erky
ErkyOP2y ago
public class Entity

protected boolean canMoveToPosition(float x, float y, float width, float height, Level level) {
// Get x, y, width and height position for player and see if he can move to the next position or not
boolean isTopLeftSolid = isSolid(x, y, level);
boolean isTopRightSolid = isSolid(x + width, y, level);
boolean isBottomLeftSolid = isSolid(x, y + height, level);
boolean isBottomRightSolid = isSolid(x + width, y + height, level);

// If neither corner is solid, the entity can move here
if (!isTopLeftSolid && !isTopRightSolid && !isBottomLeftSolid && !isBottomRightSolid)
return true;

// Returns false by default, meaning cannot move to the position
return false;
}

protected boolean isSolid(float x, float y, Level level) {
int tileX = (int) (x / TILES_SIZE);
int tileY = (int) (y / TILES_SIZE);

if (isTileSolid(tileX, tileY, level))
return true;
else
return false;
}

protected boolean isTileSolid(int tileX, int tileY, Level level) {
// Get every tile value from the level
int tileValue = level.getLevelData()[tileY][tileX];

return switch (tileValue) {
case TRANSPARENT_TILE, SLOPED_TILE -> false;
default -> true;
};
}

// These are in the Player class and are called every tick of the game
public class Player

protected void updateXDirection() {
xDirection = 0;
if (direction == LEFT)
xDirection = -xSpeed;
if (direction == RIGHT)
xDirection = xSpeed;
}

protected void startMovingWithDirection(float xDirection, Level level) {
if (canMoveToPosition(hitbox.x + xDirection, hitbox.y, hitbox.width, hitbox.height, level))
hitbox.x += xDirection; // HERE WE ARE SETTING THE POSITION OF THE HITBOX
}
public class Entity

protected boolean canMoveToPosition(float x, float y, float width, float height, Level level) {
// Get x, y, width and height position for player and see if he can move to the next position or not
boolean isTopLeftSolid = isSolid(x, y, level);
boolean isTopRightSolid = isSolid(x + width, y, level);
boolean isBottomLeftSolid = isSolid(x, y + height, level);
boolean isBottomRightSolid = isSolid(x + width, y + height, level);

// If neither corner is solid, the entity can move here
if (!isTopLeftSolid && !isTopRightSolid && !isBottomLeftSolid && !isBottomRightSolid)
return true;

// Returns false by default, meaning cannot move to the position
return false;
}

protected boolean isSolid(float x, float y, Level level) {
int tileX = (int) (x / TILES_SIZE);
int tileY = (int) (y / TILES_SIZE);

if (isTileSolid(tileX, tileY, level))
return true;
else
return false;
}

protected boolean isTileSolid(int tileX, int tileY, Level level) {
// Get every tile value from the level
int tileValue = level.getLevelData()[tileY][tileX];

return switch (tileValue) {
case TRANSPARENT_TILE, SLOPED_TILE -> false;
default -> true;
};
}

// These are in the Player class and are called every tick of the game
public class Player

protected void updateXDirection() {
xDirection = 0;
if (direction == LEFT)
xDirection = -xSpeed;
if (direction == RIGHT)
xDirection = xSpeed;
}

protected void startMovingWithDirection(float xDirection, Level level) {
if (canMoveToPosition(hitbox.x + xDirection, hitbox.y, hitbox.width, hitbox.height, level))
hitbox.x += xDirection; // HERE WE ARE SETTING THE POSITION OF THE HITBOX
}
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Erky
ErkyOP2y ago
private boolean isTileSloped(int tileX, int tileY, Level level) {
// Get every tile value from the level
int tileValue = level.getLevelData()[tileY][tileX];

if (tileValue != SLOPED_TILE)
return false;

float bottomLeft = hitbox.x / TILES_SIZE;
int bottomLeftFloor = (int) Math.floor(bottomLeft);
float difference = bottomLeft - bottomLeftFloor;
int section = (int) (difference * 4) + 1;

if (tileX > bottomLeftFloor) {
section = 1;
}

System.out.println("Section " + section);
if (section == 1)
hitbox.y -= 1;
if (section == 2)
hitbox.y -= 0.75f;
if (section == 3)
hitbox.y -= 0.5f;
if (section == 4)
hitbox.y -= 0.25f;

return true;
}
private boolean isTileSloped(int tileX, int tileY, Level level) {
// Get every tile value from the level
int tileValue = level.getLevelData()[tileY][tileX];

if (tileValue != SLOPED_TILE)
return false;

float bottomLeft = hitbox.x / TILES_SIZE;
int bottomLeftFloor = (int) Math.floor(bottomLeft);
float difference = bottomLeft - bottomLeftFloor;
int section = (int) (difference * 4) + 1;

if (tileX > bottomLeftFloor) {
section = 1;
}

System.out.println("Section " + section);
if (section == 1)
hitbox.y -= 1;
if (section == 2)
hitbox.y -= 0.75f;
if (section == 3)
hitbox.y -= 0.5f;
if (section == 4)
hitbox.y -= 0.25f;

return true;
}
if (isTileSloped(tileX,tileY,level)) {
System.out.println("sloped");
}
if (isTileSloped(tileX,tileY,level)) {
System.out.println("sloped");
}
so I try to adjust the hitbox according to what section of the tile its standing on. if in section 4 (the leftmost) the tile is almost solid at the top, so make a small change to the hitbox, if in section 1, the tile is nearly transparent and hitbox should almost be on the floor
Erky
ErkyOP2y ago
No description
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Erky
ErkyOP2y ago
yeah thats the problem, this isnt a good solution i dont think. thats why it clashes with the falling mechanics which also sets the hitbox.y
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Erky
ErkyOP2y ago
what do you mean define the slope as a hitbox? how would i do that?
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Erky
ErkyOP2y ago
https://discord.com/channels/648956210850299986/1092511181215899779/1092543191405822032 so i draw the map with rgb values and I define if they are solid or not in the
isTileSolid
isTileSolid
public static final int TRANSPARENT_TILE = 99;
public static final int SLOPED_TILE = 40;
public static final int TRANSPARENT_TILE = 99;
public static final int SLOPED_TILE = 40;
this is their RGB value which is how i can check a specific tile on the map
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Erky
ErkyOP2y ago
no, the map is loaded via a png
No description
Erky
ErkyOP2y ago
each pixel represents a tile
No description
Erky
ErkyOP2y ago
No description
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Erky
ErkyOP2y ago
yeah so how should i approach this
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Erky
ErkyOP2y ago
yeah , so how can I adjust the player hitbox then based on the coordinates inside the tile? should I send over the github?
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Erky
ErkyOP2y ago
thanks
JavaBot
JavaBot2y ago
If you are finished with your post, please close it. If you are not, please ignore this message. Note that you will not be able to send further messages here after this post have been closed but you will be able to create new posts.
Erky
ErkyOP2y ago
just really wanna get these sloped tiles working it would be really awesome 😄
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Erky
ErkyOP2y ago
40 public static final int TILES_SIZE_DEFAULT = 40; public static final float SCALE = 1.5f; public static final int TILES_SIZE = (int) (TILES_SIZE_DEFAULT * SCALE); put then i scale it a little bit, but TILES_SIZE is the value I use to get the tile position
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Erky
ErkyOP2y ago
yes
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Erky
ErkyOP2y ago
yeahh i guess
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Erky
ErkyOP2y ago
what do you mean make sure that its correct?
protected boolean isTileSolid(int tileX, int tileY, Level level) {
// Get every tile value from the level
int tileValue = level.getLevelData()[tileY][tileX];

// sloped tile
if (tileValue == SLOPED_TILE) {
updateSlopePosition(tileX, tileY, level);
return true;
}

return switch (tileValue) {
case TRANSPARENT_TILE -> false;
default -> true;
};
}

private void updateSlopePosition(int tileX, int tileY, Level level) {
// Calculate the section based on the player's x position relative to the sloped tile
float topLeftPosition = hitbox.x / TILES_SIZE;

System.out.println(topLeftPosition);
}
protected boolean isTileSolid(int tileX, int tileY, Level level) {
// Get every tile value from the level
int tileValue = level.getLevelData()[tileY][tileX];

// sloped tile
if (tileValue == SLOPED_TILE) {
updateSlopePosition(tileX, tileY, level);
return true;
}

return switch (tileValue) {
case TRANSPARENT_TILE -> false;
default -> true;
};
}

private void updateSlopePosition(int tileX, int tileY, Level level) {
// Calculate the section based on the player's x position relative to the sloped tile
float topLeftPosition = hitbox.x / TILES_SIZE;

System.out.println(topLeftPosition);
}
where do i go from here
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Erky
ErkyOP2y ago
i think the most logical step would be to update the slope position directly in here, so i check if the tile is sloped and in that case i can determine the behavior in updateslopeposition. because here i can access the hitbox all corners and then i can define how the slope looks and whatnot and then i return that the tile is solid after that, so i should be able to fall through it if coming from the top or the right side
Erky
ErkyOP2y ago
No description
Erky
ErkyOP2y ago
so if im coming from the top and falling down through it, i want to keep falling through and then depending on the position of the slope, set the hitbox.y
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Erky
ErkyOP2y ago
yes thats true, can i add a checker there, so that it exits and doesnt go further if im in a SLOPED_TILE like this: if tileValue == SLOPED_TILE return only problem is i dont know how to get the tileValue inside my entityInAir method, been stuck on that for a while feels like i have everything i need with my section solution where i divide it into 4 sections, later i can optimize this surely, but i just want to set the hitbox.y inside here but i dont know why it isnt working as expected
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Erky
ErkyOP2y ago
wait whaat x == y? i feel like continuing with my solution, just need to set hitbox.y here somehow , thats my main question
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Erky
ErkyOP2y ago
do you know how to set hitbox.y correctly and avoid making the player fall? i have this variable falling that i could adjust also
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Erky
ErkyOP2y ago
protected void startMovingWithDirection(float xDirection, Level level) {
// Update the player hitbox if not colliding with a solid block on the next X position
if (canMoveToPosition(hitbox.x + xDirection, hitbox.y, hitbox.width, hitbox.height, level))
hitbox.x += xDirection;
}
protected void startMovingWithDirection(float xDirection, Level level) {
// Update the player hitbox if not colliding with a solid block on the next X position
if (canMoveToPosition(hitbox.x + xDirection, hitbox.y, hitbox.width, hitbox.height, level))
hitbox.x += xDirection;
}
moveToPosition
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Erky
ErkyOP2y ago
protected void startFalling(Level level) {
if(canMoveToPosition(hitbox.x, hitbox.y + ySpeed, hitbox.width, hitbox.height, level)) {
// Start falling, move Y downwards
hitbox.y += ySpeed;
ySpeed += GRAVITY;
} else {
// Stop falling, reset jump
if (ySpeed > 0) {
ySpeed = 0;
jumping = false;
falling = false;
} else {
// Hit roof, start falling downwards fast!
ySpeed = GRAVITY * 10;
}
}
}
protected void startFalling(Level level) {
if(canMoveToPosition(hitbox.x, hitbox.y + ySpeed, hitbox.width, hitbox.height, level)) {
// Start falling, move Y downwards
hitbox.y += ySpeed;
ySpeed += GRAVITY;
} else {
// Stop falling, reset jump
if (ySpeed > 0) {
ySpeed = 0;
jumping = false;
falling = false;
} else {
// Hit roof, start falling downwards fast!
ySpeed = GRAVITY * 10;
}
}
}
y
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Erky
ErkyOP2y ago
because in the arguments, i check if they can move to the next x position, or the next y position
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Erky
ErkyOP2y ago
ok 👍 appreciate your help 🙂
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Erky
ErkyOP2y ago
oh ok thanks! will keep looking myself, good night 🙂
JavaBot
JavaBot2y ago
If you are finished with your post, please close it. If you are not, please ignore this message. Note that you will not be able to send further messages here after this post have been closed but you will be able to create new posts. 💤 Post marked as dormant
This post has been inactive for over 300 minutes, thus, it has been archived. If your question was not answered yet, feel free to re-open this post or create a new one.
Erky
ErkyOP2y ago
still working on this
JavaBot
JavaBot2y ago
💤 Post marked as dormant
This post has been inactive for over 300 minutes, thus, it has been archived. If your question was not answered yet, feel free to re-open this post or create a new one.
JavaBot
JavaBot2y ago
Post Closed
This post has been closed by <@272473391041347585>.

Did you find this page helpful?