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顆行星和一顆恆星做了這個,用戶可以在每個星球上做基本的月球着陸器。這是一場爆炸,但我從來沒有把它變成真正的遊戲。這具有快速計算的優勢。有一些邊緣條件,比如如果你把地圖製作成一個圓環,所以它們在地圖的兩邊翹曲,但基本上這只是簡單的加法和減法。

這對遊戲來說已經足夠了。你沒有製作模擬器。你在做一個遊戲。