java 2d 平台碰撞错误
java 2d platformer collision bug
当角色走进一堵他们无法穿过的墙时,但当跳入一堵墙时,玩家会向上或向下传送,具体取决于你击中方块的高度。
我怎样才能让玩家在撞墙时直接倒下?
移动和碰撞检测发生在 Player.java。
我认为这与玩家站在方块上时的签入有关(for 循环中的第一次签到),但我不确定。
a visual representation of my problem
这是我检查碰撞的方式:
public void collisionCheck(){
for (ArrayList<Integer> tile: Game.tileCoordinates){
//current row of the player
int row = y / Game.TILE_SIZE;
// the row below the player
int rowBelow = y / Game.TILE_SIZE + 1;
// the column the left of the player is in
int columnLeft = x / Game.TILE_SIZE;
// the column the right of the player is in
int columnRight = (x + width) / Game.TILE_SIZE;
// check if the player goes through the block below
if (tile.get(1) / Game.TILE_SIZE == rowBelow){
if ((tile.get(0) / Game.TILE_SIZE == columnLeft ||
tile.get(0) / Game.TILE_SIZE == columnRight)) {
y = tile.get(1) - height;
if (jumping) {
jumping = false;
Game.spacePressed = false;
dustAfterShowed = false;
xAfterJump = x;
yAfterJump = y;
}
if (falling){
falling = false;
}
}
}
// check if the player goes through the side of a block
if (y <= tile.get(1) && y + height <= tile.get(1) + Game.TILE_SIZE &&
y + height >= tile.get(1) && row == tile.get(1) / Game.TILE_SIZE) {
// left side
if (x + width >= tile.get(0) && x <= tile.get(0)) {
x = tile.get(0) - width;
}
// right side
if (x + width >= tile.get(0) + Game.TILE_SIZE &&
x <= tile.get(0) + Game.TILE_SIZE) {
x = tile.get(0) + Game.TILE_SIZE;
}
}
// check if the player hits a block from below
if (tile.get(1) / Game.TILE_SIZE == row &&
(tile.get(0) / Game.TILE_SIZE == columnLeft ||
tile.get(0) / Game.TILE_SIZE == columnRight)){
if (jumping) {
y = tile.get(1) + Game.TILE_SIZE;
velocity = 0;
}
}
}
我通过添加一些布尔值修复了它,当玩家从侧面撞墙时,它现在不再检查底部瓷砖碰撞(使玩家掉落而不是停留在半空中)。
检查顶部瓷砖碰撞时,您提前检查。如果您不提前检查,它会检测到侧面碰撞,因为左上角和右上角的像素在图块中。
for (ArrayList<Integer> tile: Game.tileCoordinates){
sideCollision = false;
blockRight = false;
blockLeft = false;
// check for side collision, if colided then disable movement
if ((y / Game.TILE_SIZE == tile.get(1) / Game.TILE_SIZE) &&
(x < tile.get(0) && x + width > tile.get(0) &&
x + width < tile.get(0) + Game.TILE_SIZE)) {
sideCollision = true;
blockRight = true;
x = tile.get(0) - width - 1;
}
if ((y / Game.TILE_SIZE == tile.get(1) / Game.TILE_SIZE) &&
(x < tile.get(0) + Game.TILE_SIZE && x > tile.get(0) &&
x + width > tile.get(0) + Game.TILE_SIZE)) {
sideCollision = true;
blockLeft = true;
x = tile.get(0) + Game.TILE_SIZE + 1;
}
// if player is about to hit head, stop upwards movement
if ((y - velocity <= tile.get(1) + Game.TILE_SIZE &&
y - velocity > tile.get(1)) && ((x >= tile.get(0) &&
x <= tile.get(0) + Game.TILE_SIZE) ||
(x + width >= tile.get(0) &&
x + width <= tile.get(0) + Game.TILE_SIZE))){
y = tile.get(1) + Game.TILE_SIZE;
velocity = 0;
}
// if there is no side collision, check for bottom collision
if (!sideCollision) {
if ((y / Game.TILE_SIZE + 1 == tile.get(1) / Game.TILE_SIZE) &&
(y + height > tile.get(1)) &&
((x >= tile.get(0) && x <= tile.get(0) + Game.TILE_SIZE) ||
(x + width >= tile.get(0) &&
x + width <= tile.get(0) + Game.TILE_SIZE))) {
y = tile.get(1) - height;
if (jumping) {
jumping = false;
Game.spacePressed = false;
dustAfterShowed = false;
xAfterJump = x;
yAfterJump = y;
}
if (falling) {
falling = false;
}
}
}
}
当角色走进一堵他们无法穿过的墙时,但当跳入一堵墙时,玩家会向上或向下传送,具体取决于你击中方块的高度。
我怎样才能让玩家在撞墙时直接倒下?
移动和碰撞检测发生在 Player.java。
我认为这与玩家站在方块上时的签入有关(for 循环中的第一次签到),但我不确定。
a visual representation of my problem
这是我检查碰撞的方式:
public void collisionCheck(){
for (ArrayList<Integer> tile: Game.tileCoordinates){
//current row of the player
int row = y / Game.TILE_SIZE;
// the row below the player
int rowBelow = y / Game.TILE_SIZE + 1;
// the column the left of the player is in
int columnLeft = x / Game.TILE_SIZE;
// the column the right of the player is in
int columnRight = (x + width) / Game.TILE_SIZE;
// check if the player goes through the block below
if (tile.get(1) / Game.TILE_SIZE == rowBelow){
if ((tile.get(0) / Game.TILE_SIZE == columnLeft ||
tile.get(0) / Game.TILE_SIZE == columnRight)) {
y = tile.get(1) - height;
if (jumping) {
jumping = false;
Game.spacePressed = false;
dustAfterShowed = false;
xAfterJump = x;
yAfterJump = y;
}
if (falling){
falling = false;
}
}
}
// check if the player goes through the side of a block
if (y <= tile.get(1) && y + height <= tile.get(1) + Game.TILE_SIZE &&
y + height >= tile.get(1) && row == tile.get(1) / Game.TILE_SIZE) {
// left side
if (x + width >= tile.get(0) && x <= tile.get(0)) {
x = tile.get(0) - width;
}
// right side
if (x + width >= tile.get(0) + Game.TILE_SIZE &&
x <= tile.get(0) + Game.TILE_SIZE) {
x = tile.get(0) + Game.TILE_SIZE;
}
}
// check if the player hits a block from below
if (tile.get(1) / Game.TILE_SIZE == row &&
(tile.get(0) / Game.TILE_SIZE == columnLeft ||
tile.get(0) / Game.TILE_SIZE == columnRight)){
if (jumping) {
y = tile.get(1) + Game.TILE_SIZE;
velocity = 0;
}
}
}
我通过添加一些布尔值修复了它,当玩家从侧面撞墙时,它现在不再检查底部瓷砖碰撞(使玩家掉落而不是停留在半空中)。
检查顶部瓷砖碰撞时,您提前检查。如果您不提前检查,它会检测到侧面碰撞,因为左上角和右上角的像素在图块中。
for (ArrayList<Integer> tile: Game.tileCoordinates){
sideCollision = false;
blockRight = false;
blockLeft = false;
// check for side collision, if colided then disable movement
if ((y / Game.TILE_SIZE == tile.get(1) / Game.TILE_SIZE) &&
(x < tile.get(0) && x + width > tile.get(0) &&
x + width < tile.get(0) + Game.TILE_SIZE)) {
sideCollision = true;
blockRight = true;
x = tile.get(0) - width - 1;
}
if ((y / Game.TILE_SIZE == tile.get(1) / Game.TILE_SIZE) &&
(x < tile.get(0) + Game.TILE_SIZE && x > tile.get(0) &&
x + width > tile.get(0) + Game.TILE_SIZE)) {
sideCollision = true;
blockLeft = true;
x = tile.get(0) + Game.TILE_SIZE + 1;
}
// if player is about to hit head, stop upwards movement
if ((y - velocity <= tile.get(1) + Game.TILE_SIZE &&
y - velocity > tile.get(1)) && ((x >= tile.get(0) &&
x <= tile.get(0) + Game.TILE_SIZE) ||
(x + width >= tile.get(0) &&
x + width <= tile.get(0) + Game.TILE_SIZE))){
y = tile.get(1) + Game.TILE_SIZE;
velocity = 0;
}
// if there is no side collision, check for bottom collision
if (!sideCollision) {
if ((y / Game.TILE_SIZE + 1 == tile.get(1) / Game.TILE_SIZE) &&
(y + height > tile.get(1)) &&
((x >= tile.get(0) && x <= tile.get(0) + Game.TILE_SIZE) ||
(x + width >= tile.get(0) &&
x + width <= tile.get(0) + Game.TILE_SIZE))) {
y = tile.get(1) - height;
if (jumping) {
jumping = false;
Game.spacePressed = false;
dustAfterShowed = false;
xAfterJump = x;
yAfterJump = y;
}
if (falling) {
falling = false;
}
}
}
}