Java Mario游戏与敌人和块之间的碰撞

时间:2014-12-28 13:53:21

标签: java collision-detection collision 2d-games

我在java游戏编程方面很开心,而且我对游戏有一个小问题(对我而言)。 我正在尝试在敌人和街区之间进行碰撞它不起作用,我不知道为什么。它应该工作,但它只是以每秒一个fps的速度减慢游戏并且不做任何事情。

我有一个名为Game的主类 使用这个主要的Init()函数

public void init(){
    WIDTH = getWidth();
    HEIGHT = getHeight();
    tex = new Texture();

    BufferImageLoader loader = new BufferImageLoader();
    level = loader.loadImage("/level.png"); // loading level
    cloud = loader.loadImage("/cloud.png"); // loading clouds

    handler = new Handler();
    cam = new Camera(0,0);
    LoadImageLevel(level);

    this.addKeyListener(new KeyInput(handler));
}

而不是LoadImageLevel函数,我逐个像素地读取level.png,并通过不同的颜色我设置每个对象的位置。

private void LoadImageLevel (BufferedImage image){
    int w = image.getWidth();
    int h = image.getHeight();
    //System.out.println(w + " , " + h);

    for(int xx = 0; xx < h; xx++){
        for(int yy = 0; yy < w ; yy++){
            int pixel = image.getRGB(xx, yy);
            int red = (pixel >> 16) & 0xff;
            int green = (pixel >> 8) & 0xff;
            int blue = (pixel) & 0xff;

            if(red == 255 && green == 255 && blue == 255) 
                handler.addObject(new Block(xx*32,yy*32,1,ObjectId.Block));
            if(red == 0 && green == 0 && blue == 255) 
                handler.addObject(new Player(xx*32,yy*32,1,handler,ObjectId.Player));
            if(red == 0 && green == 255 && blue == 0) 
                handler.addObject(new Enemy(xx*32,yy*32,handler,ObjectId.Enemy));
        }
    }

}

在类中,Player是两个重要的函数tick和collision,其中tick是被称为collison。

public class Player extends GameObject{

private float width = 32, // 48
        height = 64; // 96

private float gravity = 0.5f;
private final float MAX_SPEED = 10; 
private int facing = 1;
private int last = 0; // last position left or right
private Handler handler;

Texture tex = Game.getInstance();
private int type;

private Animation playerWalk, playerWalkLeft,jump;

public Player(float x, float y,int type , Handler handler ,ObjectId id) {
    super(x, y, id);
    this.handler = handler;
    this.type = type;

    playerWalk = new Animation(2,tex.player[2],tex.player[3],
            tex.player[4],tex.player[5]);
    playerWalkLeft = new Animation(2,tex.player[7],tex.player[8],
            tex.player[9],tex.player[10]);
    jump = new Animation(2,tex.player[11],tex.player[12]);
}

public void tick(LinkedList<GameObject> object) {
    x += velX;
    y += velY;

    if(velX < 0) facing = -1;
    else if(velX > 0) facing = 1;

    if(falling || jumping){
        velY += gravity;

        if(velY > MAX_SPEED){
            velY = MAX_SPEED;
        }
    }
    Collision(object);
    //System.out.println(velX + " " + velY);

    playerWalk.runAnimation();
    playerWalkLeft.runAnimation();
    jump.runAnimation();
}

private void Collision(LinkedList<GameObject> object){
    for(int i = 0; i < handler.object.size();i++){
        GameObject tempObject = handler.object.get(i);
        if(tempObject.getId() == ObjectId.Block ){

            if(getBoundsTop().intersects(tempObject.getBounds())){
                y = tempObject.getY() + 32;
                velY = 0;
            }


            if(getBounds().intersects(tempObject.getBounds())){
                y = tempObject.getY() - height;
                velY = 0;
                falling = false;
                jumping = false;
            }else 
                falling = true;

            if(getBoundsRight().intersects(tempObject.getBounds())){
                x = tempObject.getX() - width;
            }


            if(getBoundsLeft().intersects(tempObject.getBounds())){
                x = tempObject.getX() + 35;
            }
        }

        /* new */

    }

}


public void render(Graphics g) {

    /*
    g.setColor(Color.blue);
    g.fillRect((int)x,(int)y,(int)width,(int)height);

    Graphics2D g2d = (Graphics2D) g;
    g.setColor(Color.red);
    g2d.draw(getBounds());
    g2d.draw(getBoundsRight());
    g2d.draw(getBoundsLeft());
    g2d.draw(getBoundsTop());
    */

    if(velX != 0){
        if (facing == 1){
        playerWalk.drawAnimation(g,(int) x, (int)y,32,64);
        last = 1;
        }
        else{
            playerWalkLeft.drawAnimation(g,(int) x, (int)y,32,64);
            last =  0;
        }   
    }


    else
        if (last == 1)
        g.drawImage(tex.player[1], (int)x,(int) y,32,64,null);
        else
        g.drawImage(tex.player[6], (int)x,(int) y,32,64,null); // 6 ,32,64

    //System.out.println("Y: " + y); // 513 je max
    if (y >= 513){
        g.setColor(Color.red);
        g.drawString("Game Over", (int) x, 200);
    }
}

public Rectangle getBounds() {
    return new Rectangle((int) ((int)x+(width/2)-((width/2)/2)),(int) ((int)y+(height/2)),(int)width/2,(int)height/2);
}

public Rectangle getBoundsTop() {
    return new Rectangle((int) ((int)x+(width/2)-((width/2)/2)),(int)y,(int)width/2,(int)height/2);
}

public Rectangle getBoundsRight() {
    return new Rectangle((int) ((int)x+width-5),(int)y+5,(int)5,(int)height-10);
}
public Rectangle getBoundsLeft() {
    return new Rectangle((int)x,(int)y+5,(int)5,(int)height-10);
}

玩家不会遇到块碰撞问题。

public class Block extends GameObject {

Texture tex = Game.getInstance();
private int type;


public Block(float x, float y,int type,ObjectId id) {
    super(x, y, id);
    this.type = type;
}

public void tick(LinkedList<GameObject> object) {

}

public void render(Graphics g) {
    if(type == 0)
        g.drawImage(tex.block[0], (int) x, (int) y ,null);
    if(type == 1)
        g.drawImage(tex.block[1], (int) x, (int) y ,null);
}


public Rectangle getBounds() {
    return new Rectangle((int)x,(int)y,32,32);
}
}

但是,当我尝试创建Enemy类并使它像Player类中一样时,我的意思是碰撞它只会让游戏更慢而没有别的。

public class Enemy extends GameObject{

private Handler handler;
public Enemy(float x, float y,Handler handler, ObjectId id) {
    super(x, y, id);
    this.handler = handler;
}

public void tick(LinkedList<GameObject> object) {
    for(int i = 0; i < handler.object.size();i++){
        GameObject tempObject = handler.object.get(i);
        if(tempObject.getId() == ObjectId.Block ){

            if(getBoundsTop().intersects(tempObject.getBounds())){

            }


            if(getBounds().intersects(tempObject.getBounds())){

            }

            if(getBoundsRight().intersects(tempObject.getBounds())){

            }


            if(getBoundsLeft().intersects(tempObject.getBounds())){

            }
        }
    }
}

public void render(Graphics g) {
    g.setColor(Color.red);
    g.fillRect((int)x,(int) y, 32, 32);
}

public Rectangle getBoundsTop() {
    return new Rectangle((int)x,(int)y,32,32);
}

public Rectangle getBoundsLeft() {
    return new Rectangle((int)x,(int)y,32,32);
}

public Rectangle getBoundsRight() {
    return new Rectangle((int)x,(int)y,32,32);
}

public Rectangle getBounds() {
    return new Rectangle((int)x,(int)y,32,32);
}}

我知道边界不应该返回相同的“新矩形”,并且当我设置勾选方法x--时,没有任何敌人的移动;只是尝试如果敌人停在它到达阻止的边缘,但它不起作用我不知道什么是错的,我花了两天以上来解决这个问题。如果它可以帮助你有一个整个项目的链接(Eclipse)You can download it from dropbox

我只是想让一个左右移动的敌人与阻挡相撞,这意味着当他从左侧“触碰”到他“转身”并向右移动直到他“触碰”时他的右侧等......玩家和敌人之间的其他碰撞对我来说不是问题。但就是这样。 我非常感谢每一条建议:)

1 个答案:

答案 0 :(得分:0)

问题在于您的getBounds()方法。

您在getBounds()方法中说要返回包含width=32height=32的矩形。由于您的矩形是32乘32(如fillrect(x,y,32,32)中所述),因此getBounds()返回高度和宽度的交点。

换句话说,尽量不要将返回的左上角或右边界与自己碰撞。

enemy()中,您在加载时声明set.color = red您正在使用green。请尝试使用red==255, green==0, blue==0代替if(red == 0 && green == 255 && blue == 0)