我正在制作一个空气曲棍球游戏,用户可以使用鼠标控制木槌,计算机可以控制另一个木槌。我想要处理冰球和木槌之间的碰撞,这样圆盘可以根据木槌碰撞时的速度和角度改变方向和速度(或速度),而不会改变木槌的速度。我更喜欢一种在物理学上不一定100%正确的解决方案,因为我不想改变整个游戏,但我希望它能够工作并且有意义。我正在制作这是Java,但我不介意使用伪代码或其他语言的答案,以便其他人可以从这篇文章中受益。这是我游戏中Update方法的代码:
public void update(long tP) {
if (!getPause() && getGameMode()!="menu") {
player.update(player.getDistanceX(), player.getDistanceY(), getFps());
computer.update(puck.getX(), puck.getY());
puck.update();
if (puck.circleCollide(player)||puck.circleCollide(computer)) {
puck.setSpeedX((int)(-5*getScaleFactor()));
}
if (puck.rectCollide(myGoal) || puck.rectCollide(computerGoal)) {
String scorer = puck.rectCollide(myGoal) ? "Computer" : "Player";
puck.setSpeedX(0);
puck.setSpeedY(0);
puck.setX(s.getWidth()/2);
puck.setY(s.getHeight()/2);
if (scorer=="Computer") {
computer.addGoal();
} else if (scorer=="Player") {
player.addGoal();
}
}
}
}
此刻冰球以一定的速度向左移动。这是我想让它做其他事情的地方。所有其他帖子都假设两个圆圈在碰撞后都可以移动,并且不考虑碰撞角度。
答案 0 :(得分:1)
我认为你想要的不是物理意义上的弹性碰撞,因为桨由玩家控制,因此桨+冰球系统没有关闭(即总数)动量和能量不常数)。相反,我认为您正在寻找在碰撞中模拟桨叶上的桨的力量,以便您可以相应地更新冰球的速度。
当两个圆碰撞时,每个圆的力沿着连接其中心的线指向。所以在你的情况下,桨叶在桨上的力是在桨叶中心(黑色)到冰球中心(蓝色)之间的矢量差的方向:
要在更新中实现此功能,您可以执行类似
的操作if (puck.circleCollide(player)) {
double dx, dy, norm, fx, fy;
dx = puck.getX() - player.getX(); // distance between centers in x
dy = puck.getY() - player.getY(); // distance between centers in y
// define unit-length vector (fx, fy) in direction of the force
dist = Math.sqrt(dx*dx + dy*dy); // norm of (dx, dy)
fx = dx/dist;
fy = dy/dist;
// may need to cast arguments to int, depending on your interface...
puck.setSpeedX(puck.getSpeedX() + fmag(dist)*fx);
puck.setSpeedY(puck.getSpeedY() + fmag(dist)*fy);
}
(同样适用于电脑播放器的拨片)。
现在,如何确定力的大小(示例中的函数fmag(dist)
)?一种简单的方法是使其成为常数(独立于dist
),例如:
double fmag(double dist) { return 10.0; }
(当然,这相当于在示例中将fmag(dist)
替换为10
。这意味着每当桨叶和圆盘重叠时,圆盘将以恒定速率远离桨叶的中心加速。这不是最实际的方法,但是最简单的方法。
更现实的方法是使力的大小与桨叶和圆盘之间的重叠量成比例,例如
double fmag(double dist) { return 10.0*((rPaddle + rPuck) - dist); }
其中rPaddle
和rPuck
分别是桨和圆盘的半径。如果桨和圆盘表现为完美的弹簧,这将是物理学,在示例中弹簧常数等于10。
您可以使用fmag(dist)
的函数形式和常量值来获得您满意的行为。