我在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;
}
它奏效了,但玩家卡住了。我该如何解决?
代码详情:
rect
是java.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:我认为这些信息是你创建碰撞所需要的,但是 如果您需要更多信息来创建碰撞,请在评论中提问。
感谢