Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.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 - Fatal编程技术网

Java 使用列表进行碰撞检测的最快方法?

Java 使用列表进行碰撞检测的最快方法?,java,Java,所以我正在用java制作一个2D游戏,但我对游戏的运行速度有一些问题(速度相当慢),这是由我的碰撞检测方法造成的,我不太确定如何纠正它。所以基本上,对于我的敌人移动的碰撞检测,我使用了两个列表(ArrayList),一个用于我的墙,一个用于我的敌人(因为我不想让敌人碰撞)。所以我的问题是,如果我使用地图而不是ArrayList,是更合适/更快,还是仅仅是我的实现让游戏运行缓慢?这是我目前掌握的敌人移动代码和ImageTile界面(如果需要任何补充代码,请随意说),谢谢各位: public int

所以我正在用java制作一个2D游戏,但我对游戏的运行速度有一些问题(速度相当慢),这是由我的碰撞检测方法造成的,我不太确定如何纠正它。所以基本上,对于我的敌人移动的碰撞检测,我使用了两个列表(ArrayList),一个用于我的墙,一个用于我的敌人(因为我不想让敌人碰撞)。所以我的问题是,如果我使用地图而不是ArrayList,是更合适/更快,还是仅仅是我的实现让游戏运行缓慢?这是我目前掌握的敌人移动代码和ImageTile界面(如果需要任何补充代码,请随意说),谢谢各位:

public interface ImageTile {

    String getName();
    Position getPosition();

}


public abstract class Enemy implements ImageTile {

    protected Position position;
    protected String name;
    protected int Damage;
    protected int Health;
    protected int Vision;

    public Enemy(Position position){
        this.position=position;
    }


    public abstract void move(Hero hero, List<Wall> walls, List<Enemy> enemies);

    public void loseHealth(int Damage){
        this.Health-=Damage;
    }

    public int getDamage() {
        return Damage;
    }

    public int getVision() {
        return Vision;
    }

    public int getHealth() {
        return Health;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public Position getPosition() {
        return position;
    }
}


public class Bat extends Enemy {    

    public Bat(Position position) {
        super(position);
        this.Damage=100;
        this.Health=150;
        this.Vision=5;
    }

    @Override
    public String getName() {
        return "Bat";
    }

    @Override
    public void move(Hero hero, List<Wall> walls, List<Enemy> enemies){
        int x = hero.getPosition().getX();
        int y = hero.getPosition().getY();
        int x0 = position.getX();
        int y0 = position.getY();
        if((int) Math.sqrt((x0-x) * (x0-x) + (y0-y) * (y0-y))<Vision){
            if(x>x0 && y>y0){
                if(x0<9 && y0<9){
                    if(!walls.contains(new Wall(new Position(x0+1,y0+1))) && !hero.getPosition().equals(new Position(x0+1,y0+1)))
                          x0++; y0++;
                    if(hero.getPosition().equals(new Position(x0+1,y0+1)))
                          hero.loseHealth(getDamage());
                }
            }
            if(x>x0 && y<y0){
                if(x0<9 && y0>1){
                    if(!walls.contains(new Wall(new Position(x0+1,y0-1))) && !hero.getPosition().equals(new Position(x0+1,y0-1)))
                         x0++; y0--;
                    if(hero.getPosition().equals(new Position(x0+1,y0-1)))
                       hero.loseHealth(getDamage());
                }
            }
            if(x<x0 && y>y0){
                if(x0>1 && y0<9){
                    if(!walls.contains(new Wall(new Position(x0-1,y0+1))) && !hero.getPosition().equals(new Position(x0-1,y0+1)))
                         x0--; y0++;
                    if(hero.getPosition().equals(new Position(x0-1,y0+1)))
                       hero.loseHealth(getDamage());
                }
            }

            if(x<x0 && y<y0){
                if(x0>1 && y0>1){
                    if(!walls.contains(new Wall(new Position(x0-1,y0-1))) && !hero.getPosition().equals(new Position(x0-1,y0-1)))
                         x0--; y0--;
                    if(hero.getPosition().equals(new Position(x0-1,y0-1)))
                       hero.loseHealth(getDamage());
                }
            }
            this.position=new Position(x0,y0);
        }else{
            Random random = new Random();
            int i=random.nextInt(4);
            if(i==0){
                if(x0>1){
                    if(!walls.contains(new Wall(new Position(x0-1,y0))))
                        this.position=position.plus(Direction.LEFT.asVector());
                }
            }
            if(i==1){
                if(x0<9){
                   if(!walls.contains(new Wall(new Position(x0+1,y0))))
                        this.position=position.plus(Direction.RIGHT.asVector());
                }
            }
            if(i==2){
                if(y0>1){
                    if(!walls.contains(new Wall(new Position(x0,y0-1))))
                        this.position=position.plus(Direction.UP.asVector());
                }
            }
            if(i==3){
                if(y0<9){
                    if(!walls.contains(new Wall(new Position(x0,y0+1))))
                        this.position=position.plus(Direction.DOWN.asVector());
                }
            }
        }
    }
}
公共接口ImageTile{
字符串getName();
Position getPosition();
}
公共抽象类ImageTile{
保护位置;
受保护的字符串名称;
受保护的内部损坏;
保护儿童健康;
保护视力;
公敌(阵地){
这个位置=位置;
}
公共抽象虚空移动(英雄-英雄,列出墙壁,列出敌人);
公共健康(智力伤害){
这。健康-=损害;
}
公共int getDamage(){
退货损失;
}
公共int getVision(){
回归视野;
}
公共卫生{
恢复健康;
}
@凌驾
公共字符串getName(){
返回名称;
}
@凌驾
公共位置getPosition(){
返回位置;
}
}
公营蝙蝠扩展敌人{
公共Bat(位置){
超级(职位);
这个。损失=100;
这是健康=150;
这个。愿景=5;
}
@凌驾
公共字符串getName(){
返回“Bat”;
}
@凌驾
公共虚空移动(英雄,列出墙壁,列出敌人){
intx=hero.getPosition().getX();
int y=hero.getPosition().getY();
int x0=position.getX();
int y0=position.getY();
如果((int)数学sqrt((x0-x)*(x0-x)+(y0-y)*(y0-y))x0&&y>y0){

如果(x0,一种方法是预启动网格。这意味着您需要进行一些预加载,但在运行时处理速度非常快

假设您的“世界”大小为300 x 300,您可以制作一个网格:

byte[][]网格=新字节[100][100]

更改此大小以获得更好/更差的分辨率、测试性能等

现在,在运行游戏之前,您可以通过将墙和其他所有内容的
1
设置为
0
来填充
网格

您的可移动对象在网格中保持自己的坐标,例如:

Public class Enemy{
    private int x;
    private int y;
    //Or use Coordinate, whichever you prefer
} 
现在,当一个可移动的物体(敌人/玩家)想要移动时,您只需检查是否会发生碰撞,例如:

//Move right
if (grid[enemy.getX()+1][enemy.getY()] == 1){
    //Cannot move
}
else {
    //Move right
    enemy.setX(enemy.getX()+1);
    //And whatever else you want to do
}

希望这能有所帮助,但可能会有点重构。基本上,我们的想法是,如果玩家在a房间,就不需要在B房间或C房间检查碰撞。将游戏划分为块,只检查玩家和对象在同一块中的碰撞。是的,我知道你可以这样做,或者使用矩形碰撞也是一样,但我试图找到使用列表的最佳方法。不过还是谢谢你。有一点建议,你可以将Vision*Vision预先计算为SquareVision,然后不必每次都做Math.sqrt,只需将(x0-x)*(x0-x)+(y0-y)*(y0-y))与SquareVisionOk进行比较,谢谢你的帮助,我会尝试使用这种方法。