2012-11-09 38 views
5

我正在制作一个游戏,玩家将(在发布鼠标点击时)以一定的初始速度在某个方向上拍摄“星星”,该初始速度取决于在释放前拖动鼠标的距离。我在画布上有一个“行星”(固定圈),我想在行星上施加引力。我相信我正在使用正确的引力等公式,并且我已经部分工作 - 行星影响着行星的轨迹直到某个点,当恒星似乎无休止地加速并停止基于它的角度改变方向时到明星。 任何意见? (我知道星星不应该绕着行星运行,反过来也是如此。我把所有的名字都编码在一起,所以原谅)。模拟恒星的引力?

主类:

shootingStar类的
import acm.graphics.GCompound; 
    import acm.graphics.GImage; 
    import acm.graphics.GLabel; 
    import acm.graphics.GLine; 
    import acm.graphics.GMath; 
    import acm.graphics.GObject; 
    import acm.graphics.GPen; 
    import acm.graphics.GPoint; 
    import acm.graphics.GRect; 
    import acm.graphics.GOval; 
    import acm.graphics.GRectangle; 
    import acm.program.GraphicsProgram; 
    import acm.util.RandomGenerator; 
    import java.awt.Color; 
    import java.awt.event.MouseEvent; 
    import java.util.*; 

    public class Space extends GraphicsProgram { 
     public static int APPLICATION_WIDTH = 1000; 
     public static int APPLICATION_HEIGHT = 1000; 
     private int size = 15; 
     public static double pMass = 1000; 
     public static int sMass = 20; 
     public static double G = 200; 
     private RandomGenerator rand = new RandomGenerator(); 
     GOval planet, tempstar; 
     shootingStar star; 
     GLine line; 
     double accel, xAccel, yAccel, xspeed, yspeed, angle; 


     public void init(){ 
     planet = new GOval(APPLICATION_WIDTH/2, APPLICATION_HEIGHT/2, 30, 30); 
     planet.setFilled(true); 
     planet.setFillColor(rand.nextColor()); 
     add(planet); 

     } 


     public void mousePressed(GPoint point) { 
     // draw a line 
     tempstar = new GOval(point.getX() - size/2, point.getY() - size/2, size, size); 
     tempstar.setFilled(true); 
     tempstar.setColor(rand.nextColor()); 
     add(tempstar); 
     line = new GLine(tempstar.getX() + size/2, tempstar.getY() + size/2, 
    point.getX(), point.getY());        
     add(line); 
     line.setVisible(true); 
     } 

     public void mouseDragged(GPoint point) { 
     line.setEndPoint(point.getX(), point.getY()); 
     } 

     public void mouseReleased(GPoint point){ 
     xspeed =    
    -.05*GMath.cosDegrees(getAngle(line))*GMath.distance(line.getStartPoint().getX(),   
    line.getStartPoint().getY(), line.getEndPoint().getX(), line.getEndPoint().getY()); 
     yspeed = 
    .05*GMath.sinDegrees(getAngle(line))*GMath.distance(line.getStartPoint().getX(), 
    line.getStartPoint().getY(), line.getEndPoint().getX(), line.getEndPoint().getY()); 
     System.out.println(xspeed + " " + yspeed); 
     star = new shootingStar(xspeed, yspeed, this); 
     if(xspeed != 0) 
      add(star, tempstar.getX(), tempstar.getY()); 
     new Thread(star).start(); 
     remove(tempstar); 
     remove(line); 

     } 

     private double getAngle(GLine line) { 
     return GMath.angle(line.getStartPoint().getX(), line.getStartPoint().getY(), 
          line.getEndPoint().getX(), line.getEndPoint().getY()); 
     } 


     public void checkPlanet(){ 
     accel = .06*GMath.distance(star.getX(), star.getY(), planet.getX(), 
    planet.getY()); 
     angle = correctedAngle(GMath.angle(planet.getX(), planet.getY(), star.getX(), 
    star.getY()));  
     xAccel = accel*GMath.cosDegrees(GMath.angle(planet.getX(), planet.getY(), 
    star.getX(), star.getY())); 
     yAccel = accel*GMath.sinDegrees(GMath.angle(planet.getX(), planet.getY(), 
    star.getX(), star.getY())); 

     double newX = xspeed - xAccel*.01; 
     double newY = yspeed + yAccel*.01; 

     xspeed = newX + xAccel*Math.pow(.01, 2)/2; 
     yspeed = newY + yAccel*Math.pow(.01, 2)/2; 

     star.setSpeed(xspeed, yspeed); 


     } 

     public double correctedAngle(double x) { 
     return (x%360.0+360.0+180.0)%360.0-180.0; 
    } 
    } 

相关部分:

 public void run() { 
     // move the ball by a small interval 
     while (alive) { 
     oneTimeStep(); 
     } 
     } 

     // a helper method, move the ball in each time step 
     private void oneTimeStep() { 
     game1.checkPlanet(); 
     shootingStar.move(xSpeed, ySpeed); 
     pause(20); 
     } 

     public void setSpeed (double xspeed, double yspeed){ 
     xSpeed = xspeed;; 
     ySpeed = yspeed; 

     } 
    } 

编辑:

当前主类方法:

public void checkPlanet(){ 
     double xDistance = star.getX() - planet.getX(); 
     double yDistance = star.getY() - planet.getY(); 
     double distance = Math.sqrt(Math.pow(xDistance, 2) + Math.pow(yDistance, 2)); 
     accel = G*pMass/Math.pow(distance, 2); 

     xAccel = accel * xDistance/distance; 
     yAccel = accel * yDistance/distance; 

      xspeed += xAccel; 

     yspeed += yAccel; 

     star.setSpeed(xspeed, yspeed); 

    } 

当前星类的方法:

public void run() { 
     while (alive) { 
      oneTimeStep(); 
     } 
     } 

     private void oneTimeStep() { 
     game1.checkPlanet(); 
     shootingStar.move(xSpeed, ySpeed); 
     pause(20); 
     } 

     public void setSpeed (double xspeed, double yspeed){ 
     xSpeed = xspeed;; 
     ySpeed = yspeed; 

     } 
    } 
+0

经过整整一天的阅读TDWTF,最终停在[this](http://thedailywtf.com/Articles/Divine-by-Zero.aspx),我立刻感到有义务问你是否想要模拟引力拉或只是在它后面的数学。 –

回答

0

我不知道,但尝试改变,你计算xAccel和yAccel值,这样的事情的一部分。

xDistance = XComponentObject1 - XComponentObject2; 

yDistance = YComponentObject1 - YComponentObject2; 

(xDistance and yDistance can have negative values) 

Distance = sqrt(xDistance^2 + yDistance^2); 

gConstant = constant Value for gravitational strenght in your world; 

MassObject1 = some Mass; 

MassObject2 = some other Mass; 

Accel = gConstant*MassObject1*MassObject2/(Distance^2); 

''NOW COMES THE IMPORTANT PART'' 

xAccel = Accel * xDistance/Distance; 

yAccel = Accel * yDistance/Distance; 

我认为你的整个yadayada与正弦和余弦创建了一大堆难以追踪的错误。

+0

谢谢 - 这肯定比我所做的更有效。然而,同样的问题似乎仍然存在 - 但我如何解释这个事实,即随着恒星被拉入地球的引力场,它应该(并且确实)加速。当它被“推出”另一侧(因为它不会与地球相撞),它应该减速。我的明星的速度无限增加。 – user1811903

+0

这听起来像是一个符号错误,对我来说。之后你对加速器的价值究竟做什么?我不明白你的代码的意义。试试:'NewXspeed = OldXspeed + xAccel * timefactor; 'NewYspeed = OldYspeed + yAccel * timefactor; ' –

+0

用当前代码更新了问题 - 仍然存在两个问题:引力场正在朝相反的方向工作 - 所有物体都从中心星球被推离,以及2)恒星不能完成一个完整的轨道 - 更多的是一个部分轨道,他们只是越来越快,直到他们走直线。有什么建议?非常感谢你! – user1811903

1

哇,这比你“有”要做得多。

如果事情在板上计算它距离物体的距离。如果它远离D,什么也不做。如果它离开,那么它在物体的引力范围内。只需添加少量的速度指向对象。比方说,它是1000 X和500 Z的距离。只需做一些简单的事情,比如除以100,然后将其添加到对象速度中,使其向对象移动10 x和5 y。每次更新时再次添加速度。

您可能还需要最大速度。这是一个很容易计算的很好的工具,并且会给你带来的效果,就像在星球控制游戏中那里有一颗行星,或者船只在一点点上相互牵引。我用10颗行星和一颗恒星做了这个,用户可以在每个星球上做基本的月球着陆器。这是一场爆炸,但我从来没有把它变成真正的游戏。这具有快速计算的优势。有一些边缘条件,比如如果你把地图制作成一个圆环,所以它们在地图的两边翘曲,但基本上这只是简单的加法和减法。

这对游戏来说已经足够了。你没有制作模拟器。你在做一个游戏。