二维碰撞检测

时间:2014-06-09 00:32:53

标签: java 2d collision-detection

我在Java中创建基于图块的2D游戏。一切都很好,但我陷入了碰撞检测。我尝试了这种方法来进行碰撞:

public boolean getCollision(Entity en) {
    try {
        Rectangle i = new Rectangle(en.x, en.y, en.width, en.height);
        for (int y = 0; y < image.getHeight(); y++) {
            for (int x = 0; x < image.getWidth(); x++) {
                if (rect[x][y] != null && tile[x][y] != null && rect[x][y].intersects(i))
                    return true;
            }
        }
    } catch (ArrayIndexOutOfBoundsException e) {
    }
    return false;
}

它奏效了,但玩家卡住了。我该如何解决?

代码详情

rectjava.awt.Rectangle[][],表示基于图块的不可见矩形。它被初始化为:

 for (int y = 0; y < myLevelHeight; y++) {
    for (int x = 0; x < myLevelWidth; x++) {
        if (rect[x][y] == null)
            rect[x][y] = new Rectangle(x * myGameTileSize, y * myGameTileSize, myGameTileSize, myGameTileSize);
    }
}

Entity 只保存实体的x和y坐标,宽度和高度。

image.getWidth()image.getHeight()是图块级别的宽度/高度。

任何人都可以修复此碰撞,并创建向下,向左和向右或为此创建一个方法吗?

编辑:一个MCVE,我尽力减少代码,但你应该明白这一点。

    package com.game.lost;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.image.BufferStrategy;

import javax.swing.JFrame;

public class Demo extends Canvas implements Runnable {

    public int tileSize = 16;
    public static final int width = 400, height = 400;
    public JFrame frame = new JFrame();
    public int levelWidth = width / tileSize + 1, levelHeight = height / tileSize + 1;
    public Color[][] tiles = new Color[levelWidth][levelHeight];
    public Rectangle[][] rect = new Rectangle[levelWidth][levelHeight];
    private Thread thread;
    private boolean running = false;
    private int x = tileSize * 10, y = tileSize * 10;
    private boolean up, down = true, left, right;

    public void genLevel() {
        tiles[10][20] = new Color(0, 0, 0);
        tiles[0][19] = new Color(0, 0, 0);
    }

    public void update() {
        for (int y = 0; y < levelHeight; y++) {
            for (int x = 0; x < levelWidth; x++) {
                if (rect[x][y] == null)
                    rect[x][y] = new Rectangle(x * tileSize, y * tileSize, tileSize, tileSize);
                else if (rect[x][y] != null)
                    rect[x][y].setBounds(x * tileSize, y * tileSize, tileSize, tileSize);
            }
        }

        if (!getDownCollision() && down)
            y += 2;
        else if (getDownCollision() || up) {
            up = true;

            if (!getLeftCollision())
                x -= 2;
            else {
                up = false;
                tiles[0][19] = new Color(255, 0, 0);
            }

            tiles[10][20] = new Color(255, 0, 0);
            down = false;
        }
    }

    public void render() {
        BufferStrategy bs = getBufferStrategy();
        if (bs == null) {
            createBufferStrategy(2);
            return;
        }
        Graphics g = bs.getDrawGraphics();
        g.setColor(Color.white);
        g.fillRect(0, 0, width, height);

        g.setColor(Color.red);
        g.fillRect(x, y, tileSize, tileSize);

        for (int y = 0; y < tiles[0].length; y++) {
            for (int x = 0; x < tiles.length; x++) {
                if (tiles[x][y] != null) {
                    g.setColor(tiles[x][y]);
                    g.fillRect(rect[x][y].x, rect[x][y].y, rect[x][y].width, rect[x][y].height);
                }
            }
        }

        g.dispose();
        bs.show();
    }

    public void start() {
        genLevel();
        running = true;
        thread = new Thread(this);
        thread.start();
    }

    public void run() {
        while (running) {
            update();
            render();

            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public boolean getUpCollision() {
        try {
            Point p1 = new Point(x, y);
            for (int y = 0; y < levelHeight; y++) {
                for (int x = 0; x < levelWidth; x++) {
                    if (rect[x][y - 1] != null && tiles[x][y - 1] != null && rect[x][y - 1].contains(p1))
                        return true;
                }
            }
        } catch (ArrayIndexOutOfBoundsException e) {
        }
        return false;
    }

    public boolean getDownCollision() {
        try {
            Point p1 = new Point(x, y + tileSize);
            for (int y = 0; y < levelHeight; y++) {
                for (int x = 0; x < levelWidth; x++) {
                    if (rect[x][y + 1] != null && tiles[x][y + 1] != null && rect[x][y + 1].contains(p1))
                        return true;
                }
            }
        } catch (ArrayIndexOutOfBoundsException e) {
        }
        return false;
    }

    public boolean getLeftCollision() {
        try {
            Point p1 = new Point(x, y);
            for (int y = 0; y < levelHeight; y++) {
                for (int x = 0; x < levelWidth; x++) {
                    if (rect[x][y - 1] != null && tiles[x][y - 1] != null && rect[x][y - 1].contains(p1))
                        return true;
                }
            }
        } catch (ArrayIndexOutOfBoundsException e) {
        }
        return false;
    }

    public boolean getRightCollision() {
        try {
            Point p1 = new Point(x + tileSize, y);
            for (int y = 0; y < levelHeight; y++) {
                for (int x = 0; x < levelWidth; x++) {
                    if (rect[x][y + 1] != null && tiles[x][y + 1] != null && rect[x][y + 1].contains(p1))
                        return true;
                }
            }
        } catch (ArrayIndexOutOfBoundsException e) {
        }
        return false;
    }

    public static void main(String[] args) {
        Demo demo = new Demo();

        demo.frame.setResizable(false);
        demo.frame.add(demo);
        demo.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        demo.frame.setSize(width, height);
        demo.frame.setLocationRelativeTo(null);
        demo.frame.setTitle("Demo");
        demo.frame.setVisible(true);

        demo.start();
    }
}

PS:我认为这些信息是你创建碰撞所需要的,但是 如果您需要更多信息来创建碰撞,请在评论中提问

感谢

0 个答案:

没有答案