我已经和LWJGL一起工作了几个星期了。自从我增加了跳跃能力后,向上碰撞给我带来了很多问题。
该游戏是基于2D拼贴的侧面滚动条。总的来说,除了玩家跳跃时,碰撞几乎是完美的。起初我想“哦,也许我只需要改变跳跃机制”,但后来我意识到只有当玩家通过某个x坐标时才会发生。
现在,对于实际问题本身:如果玩家在通过某个x坐标时跳转,他们将通过该图块并测试顶部碰撞返回false。
这是整个Player类:
package Minecraft2D;
import static Minecraft2D.World.BLOCK_SIZE;
import Minecraft2D.Tools.Tools;
import Minecraft2D.UI.Inventory;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import static Minecraft2D.Boot.*;
import org.lwjgl.util.Rectangle;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
public class Player {
private float x;
private float y;
public int width = 32;
public int height = 50;
private float DX = 0;
private float DY = 0;
private Texture left = null;
private Texture right = null;
Texture texture = null;
public boolean direction[] = { false, false, false, false };
public boolean collision = false;
public boolean ground = false;
public boolean jump = false;
public boolean top = false;
public Player(float x, float y) {
this.x = x;
this.y = y;
try {
this.left = TextureLoader.getTexture("PNG", new FileInputStream(new File(path + "player_left.png")));
this.right = TextureLoader.getTexture("PNG", new FileInputStream(new File(path + "player_right.png")));
this.texture = this.right;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void draw() {
Tools.drawTexture((int)x, (int)y, width, height, texture);
}
public void checkCollision(Player player, Block block) {
if (player.getY() < block.getY() + BLOCK_SIZE && player.getX() < block.getX() + BLOCK_SIZE && player.getY() + this.height > block.getY() && player.getX() + this.width > block.getX() && block.getType() != BlockType.AIR) {
Rectangle top = new Rectangle();
top.setBounds((int) player.x + 4, (int) player.y + 1, this.width - 8, 1);
Rectangle bottom = new Rectangle();
bottom.setBounds((int) player.x + 4, (int) player.y + this.height, this.width - 8, 1);
Rectangle left = new Rectangle();
left.setBounds((int) player.x, (int) player.y + 1, 1, this.height - 5);
Rectangle right = new Rectangle();
right.setBounds((int) player.x + player.width, (int) player.y + 1, 1, this.height - 5);
Rectangle blok = new Rectangle();
blok.setBounds((int) block.getX(), (int) block.getY(), BLOCK_SIZE, BLOCK_SIZE);
if (bottom.intersects(blok)) {
player.setY((block.getY() - this.height - 1));
ground = true;
jump = false;
} else if (top.intersects(blok)) {
DY = 0;
this.top = true;
y -= (player.y) - (block.getY() + BLOCK_SIZE);
}
if (!top.intersects(blok)) {
if (left.intersects(blok)) {
player.setX(block.getX() + this.width);
} else if (right.intersects(blok)) {
player.setX(block.getX() - this.width);
}
}
} else {
collision = false;
ground = false;
}
if (!collision && !jump) {
setDY(.003f);
}
if (ground && !jump) {
DY = 0;
}
if (jump && DY < 0.003f) {
DY += 0.0001;
} else {
// jump = false;
}
if (top) {
DY = 0f;
top = false;
}
x += DX;
y += DY;
if (x > Boot.SCREEN_WIDTH) {
x = 0;
}
if (x < 0) {
x = Boot.SCREEN_WIDTH;
}
}
public float getX() {
return x;
}
public void setX(float x) {
this.x = x;
}
public float getY() {
return y;
}
public void setY(float y) {
this.y = y;
}
public void setDX(float dx) {
this.DX = dx;
}
public void setDY(float dy) {
this.DY = dy;
}
public void setJump() {
if (!jump) {
jump = true;
ground = false;
DY = -0.13f;
y -= 1;
}
}
public void setTexture(int tex) {
if (tex == 0) {
this.texture = this.left;
}
if (tex == 1) {
this.texture = this.right;
}
}
}
==============
编辑:我不知道为什么,但随着我的角色越来越靠近地图的0 x坐标,角色的y坐标增长得非常慢。这可能与我遇到的问题有关。我正在研究它,我怀疑当我将玩家的x和y值从双打投射到整数以便在顶部,底部,左侧和右侧矩形中使用时可能会有一些事情要做。再次编辑: 我不知道这是否重要,但我一直在检查碰撞:(这是在“Boot”类中。)
private void checkCollision() {
for (int x = 0; x < BLOCKS_WIDTH - 1; x++) {
for (int y = 0; y < BLOCKS_HEIGHT - 1; y++) {
Block blk = grid.getAt(x, y);
player.checkCollision(blk);
}
}
}
答案 0 :(得分:4)
为什么要将玩家传递给checkCollision?看起来你不应该在玩家中传球,而是使用调用checkCollision方法的玩家的成员。我认为这可能会给你带来一些困惑。如:
y -= (player.y) - (block.getY() + BLOCK_SIZE);
这看起来就像你试图将玩家推到他们跳跃过程中与他们交叉的b / c下方。如果是这种情况,它应该只是
y = (block.getY() + BLOCK_SIZE);
我会从函数参数中删除播放器并重写函数,看看你得到了什么。希望有所帮助。
修改
您的评论声明您无法再将播放器传递给该功能。不确定你的确切实现,但这是我通常看到的游戏:
public class Player
{
private int x, y, dx, dy;
public void checkCollision(Block block)
{
if (isTopCollision(block))
fall(block.getY() + block.getHeight());
}
private boolean isTopCollision(Block block)
{
return y > block.getY() + block.getSize() && y < block.getY();
}
private void fall(int adjustedY)
{
y = adjustedY;
top = true;
dy = 0;
// etc
}
}
public class MyGame
{
public void gameloop()
{
for (Block b : blocks)
player.checkCollision(b);
}
}