2015-06-27 80 views
0

我正在制作一款空气曲棍球游戏,用户可以使用鼠标控制木槌,并且计算机可以控制另一个木槌。我想要处理冰球和木槌之间的碰撞,所以冰球可以根据木槌碰撞时的速度和角度改变方向和速度(或速度),而不改变木槌的速度。我更喜欢在物理学中不一定100%正确的解决方案,因为我不想改变整个游戏,但我希望它能够工作并且合理。我使这是Java,但我不介意在伪代码或其他语言的答案,以便其他人可以从这篇文章中受益。这里是我在游戏中更新方法的代码:与圆圈的弹性碰撞

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(); 
      } 
     } 
    } 
} 

此时冰球刚以特定速度向左移动。这是我想让它做别的事情的地方。所有其他帖子都假设两个圆圈在碰撞后可以移动,并且不考虑碰撞角度。

+1

注意:你可能不想比较一个'String'和'!='。做'!getGameMode()。equals(“menu”)' – TameHog

+0

你做过“冰球”,“球员”和“计算机”类吗?如果是这样,他们的代码可能会有用。 – ricky3350

+0

的确,我应该考虑一下。为了不比较参考,但价值。 –

回答

1

我认为你想要的不是弹性碰撞在物理意义上,因为桨由球员控制,因此桨+球系统没有关闭(也就是说,总动量和能量是不是常数)。相反,我认为你需要在碰撞时模拟桨上的桨的力,以便相应地更新球的速度。

当两个圆碰撞时,每个圆的相互作用力沿着连接其中心的线被导向。所以你的情况桨对冰球的力是桨(黑色)的中心之间的矢量差的方向圆盘的中心(蓝色):

direction of force of the paddle (black) on puck (blue)

为了实现这在你的更新中,你可以做类似

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; } 

(当然,这是等效于例如通过10替换fmag(dist))。这意味着,只要桨和冰球重叠,冰球就会以恒定的速度加速离开桨的中心。这不是最现实的方法,而是最简单的方法。

更现实的方法是使正比于桨和圆盘之间的重叠量的力的大小,例如

double fmag(double dist) { return 10.0*((rPaddle + rPuck) - dist); } 

其中rPaddlerPuck是桨和所述的半径冰球分别。如果桨和冰球表现得像完美的弹簧那样,这是你得到的物理量,在这个例子中弹簧常数等于10。

你可以玩fmag(dist)的函数形式和常数值来获得你满意的行为。

+0

这听起来不错,我可能会测试它,但问题是,它不采取足够的因素,因此不够精确。我的意思是,我想要的是用户能够控制冰球移动的位置,以及不仅根据木槌和冰球速度的大小而且根据它们相撞的角度确定角度。例如,如果它是碰撞头部,则应该对具有相同速度的掠射碰撞有不同的响应。但是,这有什么好处,即使其中一个圈子没有移动,也会有回应。 –