物体的碰撞系统?

发布于 2024-11-02 17:39:06 字数 445 浏览 1 评论 0原文

我正在制作一个小游戏,2D,并且我有一个播放器。

编辑:

这就是我现在所拥有的:

        int oldX = player.x;
    int oldY = player.y;

    int newX = oldX - player.getSpeedX();
    int newY = oldY - player.getSpeedY();

    if(player.getBounds().intersects(brush1.getBounds())){
        player.x = newX;
        player.y = newY;
    }else{
        player.x = oldX;
        player.y = oldY;
    }

但是,它的表现非常奇怪,当我从一侧进入时,它会改变速度,等等。

I am making a small game, 2D, and I have a player.

EDIT:

This is what I have right now:

        int oldX = player.x;
    int oldY = player.y;

    int newX = oldX - player.getSpeedX();
    int newY = oldY - player.getSpeedY();

    if(player.getBounds().intersects(brush1.getBounds())){
        player.x = newX;
        player.y = newY;
    }else{
        player.x = oldX;
        player.y = oldY;
    }

But, it is acting really weird, it changes speed when I go in from one side, etc.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

晨敛清荷 2024-11-09 17:39:06

有关检查线段和圆相交的公式和代码,请查看此

其余代码应该很清楚,在移动之前,检查是否发生碰撞,如果发生,则不要移动。

根据您喜欢的行为,您还可以尽可能靠近墙壁移动,然后平行于墙壁移动,让圆圈沿着墙壁“滑动”。这可以通过将运动矢量投影到与墙壁方向相同的线上来完成。

编辑:关于如何使用答案中的代码来检查冲突的一些评论:

该代码使用 Dot 函数来计算 两个向量的点积。您可以创建一个 Vector 类(一个很好的练习,对于此类项目很有用),也可以使用 此处的公式

矢量类将使某些代码更易于阅读,但您也可以直接对浮点数进行操作。例如,让我们看一下d(射线的方向向量)和f(从中心球到射线起点的向量)的计算,如本文开头所述回答。使用向量类,这将像那里使用的公式一样简单:

// L, E, C, d and f are of some vector type
d = L - E;
f = E - C;

如果没有向量类,所有变量都将具有单独的 x/y 坐标,这会使代码有点臃肿,但做的事情是一样的:

// Twice as much variables, but all of them are usual floats.
dx = Lx - Ex;
dy = Ly - Ey;
fx = Ex - Cx;
fy = Ey - Cy;

For a formula and code that checks the intersection of a line segment and a circle, have a look at this SO answer.

The rest of the code should be quite clear, before you make a move, check if a collision occurs, if it would, don't move.

Depending on the behaviour you prefer, you could also move as close to the wall as possible and then move parallel to it to let the circle "slide" along the wall. This can be done by projecting the movement vector on a line with the same direction as the wall.

EDIT: Some comments on how to use the code from the answer to check for collisions:

The code uses a Dot function that computes the dot product of two vectors. You can either create a Vector class (a good exercise and it is useful for such projects) or compute just the dot product directly using the formulas here.

A vector class will make some of the code easier to read, but you can also operate on floats directly. For example, let's have a look at the computation of d (Direction vector of ray) and f (Vector from center sphere to ray start) as described at the start of the answer. With a vector class, this will be as easy as the formulas used there:

// L, E, C, d and f are of some vector type
d = L - E;
f = E - C;

Without a vector class, you'll have seperate x/y coordinates for all of the variables, bloating the code a bit but doing just the same:

// Twice as much variables, but all of them are usual floats.
dx = Lx - Ex;
dy = Ly - Ey;
fx = Ex - Cx;
fy = Ey - Cy;
清风疏影 2024-11-09 17:39:06

我认为您的代码片段有一些错误。建议修复:

int oldX = player.x;
int oldY = player.y;

// *add* speed to old pos to get new pos
int newX = oldX + player.getSpeedX();
int newY = oldY + player.getSpeedY();

if(player.getBounds().intersects(brush1.getBounds())){
    // Collision!  Keep old position.
    // Reverse speed (just a suggestion).
    player.setSpeedX(-player.getSpeedX());
    player.setSpeedY(-player.getSpeedY());
}else{
    // No collision.  Set position to *new* pos, not old pos.
    player.x = newX;
    player.y = newY;
}

I think your code snippet has a few bugs. Suggested fixes:

int oldX = player.x;
int oldY = player.y;

// *add* speed to old pos to get new pos
int newX = oldX + player.getSpeedX();
int newY = oldY + player.getSpeedY();

if(player.getBounds().intersects(brush1.getBounds())){
    // Collision!  Keep old position.
    // Reverse speed (just a suggestion).
    player.setSpeedX(-player.getSpeedX());
    player.setSpeedY(-player.getSpeedY());
}else{
    // No collision.  Set position to *new* pos, not old pos.
    player.x = newX;
    player.y = newY;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文