gpt4 book ai didi

java - 复杂形状的碰撞检测

转载 作者:IT老高 更新时间:2023-10-28 20:41:17 25 4
gpt4 key购买 nike

我想做一个游戏,每个关卡都从图像加载。我想在 Photoshop 中绘制整个关卡,然后将其设置为背景并允许玩家走过它。我想要另一个不可见的图像越过顶部,它在我想要碰撞的所有地方都是黑色的。

我不想使用矩形碰撞等更容易的瓷砖的原因是因为会有复杂的角落,并不是所有东西都是矩形的。

这是一个好主意,是否可以轻松做到?这会占用大量 CPU,还是有更好的方法来做到这一点?

关卡图片

Level image

障碍物以红色显示

Obstacle in Red

最佳答案

..there will be complex corners and not everything will be rectangle.

这可以通过绘制和处理 ShapeArea 实例来实现。例如

  • Yellow 是一个小动画“播放器”。
  • 图像的边界表示包含玩家路径的墙壁(它会从墙壁反弹)。
  • 障碍物在不发生碰撞时涂成绿色,否则涂成红色。

ShapeCollision

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import javax.swing.*;

class ShapeCollision {

private BufferedImage img;
private Area[] obstacles = new Area[4];
private Area walls;

int x;
int y;
int xDelta = 3;
int yDelta = 2;

/** A method to determine if two instances of Area intersect */
public boolean doAreasCollide(Area area1, Area area2) {
boolean collide = false;

Area collide1 = new Area(area1);
collide1.subtract(area2);
if (!collide1.equals(area1)) {
collide = true;
}

Area collide2 = new Area(area2);
collide2.subtract(area1);
if (!collide2.equals(area2)) {
collide = true;
}

return collide;
}

ShapeCollision() {
int w = 400;
int h = 200;
img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
final JLabel imageLabel = new JLabel(new ImageIcon(img));
x = w/2;
y = h/2;

//circle
obstacles[0] = new Area(new Ellipse2D.Double(40, 40, 30, 30));

int[] xTriangle = {330,360,345};
int[] yTriangle = {60,60,40};
//triangle
obstacles[1] = new Area(new Polygon(xTriangle, yTriangle, 3));

int[] xDiamond = {60,80,60,40};
int[] yDiamond = {120,140,160,140};
//diamond
obstacles[2] = new Area(new Polygon(xDiamond, yDiamond, 4));

int[] xOther = {360,340,360,340};
int[] yOther = {130,110,170,150};
// other
obstacles[3] = new Area(new Polygon(xOther, yOther, 4));

walls = new Area(new Rectangle(0,0,w,h));

ActionListener animate = new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
animate();
imageLabel.repaint();
}
};
Timer timer = new Timer(50, animate);

timer.start();
JOptionPane.showMessageDialog(null, imageLabel);
timer.stop();
}

public void animate() {
Graphics2D g = img.createGraphics();
g.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);

g.setColor(Color.BLUE);
g.fillRect(0, 0, img.getWidth(), img.getHeight());
x+=xDelta;
y+=yDelta;
int s = 15;
Area player = new Area(new Ellipse2D.Double(x, y, s, s));

// Acid test of edge collision;
if (doAreasCollide(player,walls)) {
if ( x+s>img.getWidth() || x<0 ) {
xDelta *= -1;
}
if(y+s>img.getHeight() || y<0 ) {
yDelta *= -1;
}
}
g.setColor(Color.ORANGE);
for (Area obstacle : obstacles) {
if (doAreasCollide(obstacle, player)) {
g.setColor(Color.RED);
} else {
g.setColor(Color.GREEN);
}
g.fill(obstacle);
}

g.setColor(Color.YELLOW);
g.fill(player);


g.dispose();
}

public static void main(String[] args) {
Runnable r = new Runnable() {

@Override
public void run() {
new ShapeCollision();
}
};
// Swing GUIs should be created and updated on the EDT
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
SwingUtilities.invokeLater(r);
}
}

编辑

make it detect all the red color and set that as the collision bounds

在启动时,使用 Smoothing a jagged path 中的源代码获取红色像素轮廓的问题(请参阅 getOutline(Color target, BufferedImage bi) 方法)。将该 Area 存储为启动时的单一障碍。

关于java - 复杂形状的碰撞检测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14574045/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com