Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/384.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java游戏中的二维碰撞问题_Java_Collision Detection - Fatal编程技术网

Java游戏中的二维碰撞问题

Java游戏中的二维碰撞问题,java,collision-detection,Java,Collision Detection,我已经和LWJGL合作了几个星期了。自从我增加了跳跃的能力,向上的碰撞给了我很多问题 这个游戏是一个基于2D瓷砖的侧滚游戏。总的来说,碰撞几乎是完美的,除了玩家跳跃的时候。起初我想“哦,也许我只需要改变跳跃的机制”,但后来我意识到只有当玩家通过某个x坐标时才会发生这种情况 现在,对于实际问题本身:如果玩家在通过某个x坐标时跳跃,他们将通过平铺,并且顶部碰撞测试返回false 这是整个玩家等级: package Minecraft2D; import static Minecraft2D.Wor

我已经和LWJGL合作了几个星期了。自从我增加了跳跃的能力,向上的碰撞给了我很多问题

这个游戏是一个基于2D瓷砖的侧滚游戏。总的来说,碰撞几乎是完美的,除了玩家跳跃的时候。起初我想“哦,也许我只需要改变跳跃的机制”,但后来我意识到只有当玩家通过某个x坐标时才会发生这种情况

现在,对于实际问题本身:如果玩家在通过某个x坐标时跳跃,他们将通过平铺,并且顶部碰撞测试返回false

这是整个玩家等级:

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

}
package-Minecraft2D;
导入静态Minecraft2D.World.BLOCK_大小;
导入Minecraft2D.Tools.Tools;
导入Minecraft2D.UI.Inventory;
导入java.io.File;
导入java.io.FileInputStream;
导入java.io.FileNotFoundException;
导入java.io.IOException;
导入静态Minecraft2D.Boot.*;
导入org.lwjgl.util.Rectangle;
导入org.newdawn.slick.opengl.Texture;
导入org.newdawn.slick.opengl.TextureLoader;
公开课选手{
私人浮动x;
私人游船;
公共整数宽度=32;
公共内部高度=50;
专用浮点数DX=0;
私有浮动DY=0;
私有纹理左=空;
private-Texture-right=null;
纹理=空;
公共布尔方向[]={false,false,false,false};
公共布尔冲突=false;
公共布尔基=假;
公共布尔跳跃=假;
公共布尔top=false;
公共播放器(浮动x,浮动y){
这个.x=x;
这个。y=y;
试一试{
this.left=TextureLoader.getTexture(“PNG”,新文件输入流(新文件(path+“player_left.PNG”));
this.right=TextureLoader.getTexture(“PNG”,新文件输入流(新文件(path+“player_right.PNG”));
this.texture=this.right;
}catch(filenotfounde异常){
e、 printStackTrace();
}捕获(IOE异常){
e、 printStackTrace();
}
}
公众抽签(){
工具.绘图纹理((int)x,(int)y,宽度,高度,纹理);
}
公共无效检查碰撞(玩家、区块){
如果(player.getY()block.getY()&&player.getX()+this.width>block.getX()&&block.getType()!=BlockType.AIR){
矩形顶部=新矩形();
顶部.setBounds((int)player.x+4,(int)player.y+1,this.width-8,1);
矩形底部=新矩形();
底部.立根((int)player.x+4,(int)player.y+this.height,this.width-8,1);
矩形左=新矩形();
左。后退((int)player.x,(int)player.y+1,1,this.height-5);
矩形右=新矩形();
右。后退((int)player.x+player.width,(int)player.y+1,1,this.height-5);
矩形块=新矩形();
blok.setBounds((int)block.getX(),(int)block.getY(),block\u SIZE,block\u SIZE);
if(底部相交(blok)){
setY((block.getY()-this.height-1));
地面=真实;
跳跃=假;
}else if(顶部相交(blok)){
DY=0;
this.top=true;
y-=(player.y)-(block.getY()+block_SIZE);
}
如果(!top.intersects(blok)){
if(左相交(blok)){
player.setX(block.getX()+this.width);
}else if(右相交(blok)){
player.setX(block.getX()-this.width);
}
}
}否则{
冲突=错误;
地面=假;
}
如果(!碰撞&&!跳跃){
setDY(.003f);
}
if(接地和跳跃){
DY=0;
}
如果(跳转和动态<0.003f){
DY+=0.0001;
}否则{
//跳跃=假;
}
如果(顶部){
DY=0f;
顶部=假;
}
x+=DX;
y+=DY;
如果(x>引导屏幕宽度){
x=0;
}
if(x<0){
x=开机屏幕宽度;
}
}
公共浮点getX(){
返回x;
}
公共无效集合x(浮动x){
这个.x=x;
}
公共浮球{
返回y;
}
公共无效setY(浮动y){
这个。y=y;
}
公共void setDX(float dx){
this.DX=DX;
}
公共无效设置(浮动设置){
this.DY=DY;
}
公共无效setJump(){
如果(!跳转){
跳跃=真;
地面=假;
DY=-0.13f;
y-=1;
}
}
公共void setTexture(int-tex){
如果(tex==0){
this.texture=this.left;
}
如果(tex==1){
this.texture=this.right;
}
}
}
==============

编辑:我不知道为什么,但当我的角色靠近地图的0X坐标时,角色的y坐标增长非常缓慢。这可能与我遇到的问题有关。我正在研究它,我怀疑当我将玩家的x和y值从双精度转换为整数,用于顶部、底部、左侧和右侧矩形时,可能与此有关

再次编辑: 我不知道这是否重要,但我一直在像这样检查碰撞:(这是在“Boot”类中)

private void checkCollision(){
对于(int x=0;x
你为什么要把玩家传给checkCollision?看起来您不应该传入一个播放器,而是使用调用checkCollision方法的播放器的成员。我想这可能会给你带来一些困惑。例如:

y -= (player.y) - (block.getY() + BLOCK_SIZE);
这看起来像是你试图将球员推到b/c区下方,他们在跳跃时与b/c区相交。如果是这样的话,应该是这样的

y = (block.getY() + BLOCK_SIZE);
我将从函数参数中删除播放器,然后重写函数,看看得到什么。H
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);
     }
 }