2012-11-09 51 views
5

Tôi đang tạo một trò chơi mà người chơi sẽ (khi phát hành mouseclick) chụp một "ngôi sao" theo một hướng nhất định ở tốc độ ban đầu được xác định bởi khoảng cách mà anh ta đã kéo chuột trước khi nhả chuột. Tôi có một "hành tinh" (vòng tròn cố định) trên canvas mà tôi muốn tạo ra lực hấp dẫn trên hành tinh chuyển động. Tôi tin rằng tôi đang sử dụng các công thức thích hợp cho lực hấp dẫn và như vậy, và tôi có nó hoạt động một phần - hành tinh ảnh hưởng đến quỹ đạo của hành tinh cho đến một điểm nhất định, khi ngôi sao dường như không ngừng tăng tốc và dừng hướng thay đổi dựa trên góc của nó đến ngôi sao. Bất kỳ lời khuyên nào? (Tôi biết rằng các ngôi sao không được phép quay quanh các hành tinh, nó là một cách khác xung quanh. Tôi mã hóa toàn bộ điều với các tên được trao đổi để tha thứ cho số).Mô phỏng lực hấp dẫn của một ngôi sao?

lớp học chính:

phần
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; 
    } 
    } 

thích hợp của lớp shootingstar:

 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; 

     } 
    } 

EDIT:

hiện tại Main Lớp Phương pháp:

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

    } 

hiện tại sao lớp Phương pháp:

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

Sau cả ngày đọc TDWTF, cuối cùng dừng lại ở [this] (http://thedailywtf.com/Articles/Divine-by-Zero.aspx), tôi cảm thấy có nghĩa vụ phải hỏi liệu bạn có muốn mô phỏng trọng lực hay không kéo hoặc chỉ là toán học đằng sau nó. –

Trả lời

0

Tôi không chắc chắn, nhưng cố gắng thay đổi một phần, nơi bạn tính toán các giá trị xAccel và yAccel một cái gì đó như thế này.

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; 

Tôi nghĩ toàn bộ yadayada của bạn với sin và cosin tạo ra một loạt các lỗi khó theo dõi.

+0

Cảm ơn - điều này chắc chắn hoạt động hiệu quả hơn những gì tôi đã diễn ra.Tuy nhiên, vấn đề tương tự vẫn còn ở đó - làm thế nào để tôi tính đến thực tế là vì ngôi sao được vẽ vào trường hấp dẫn của hành tinh, nên nó (và không) tăng tốc. Khi nó bị “đẩy ra” phía bên kia (vì nó không va chạm với hành tinh), nó sẽ giảm tốc. Tốc độ của ngôi sao của tôi không ngừng gia tăng. – user1811903

+0

Điều đó nghe giống như một dấu hiệu lỗi đối với tôi. Chính xác thì bạn sẽ làm gì với các giá trị Acceleratien sau đó? Tôi không hiểu được mã của bạn. Chỉ cần thử: máy tính thời gian 'NewXspeed = OldXspeed + xAccel *; Máy tính thời gian 'NewYspeed = OldYspeed + yAccel *; ' –

+0

câu hỏi cập nhật với mã hiện tại - vẫn còn có hai vấn đề: trường hấp dẫn đang hoạt động theo hướng ngược lại - tất cả các đối tượng đang được đẩy AWAY từ hành tinh trung tâm, và 2) sao không làm một quỹ đạo hoàn chỉnh - nó nhiều hơn một quỹ đạo một phần, nơi họ chỉ nhận được nhanh hơn và nhanh hơn cho đến khi họ đang đi trong một đường thẳng. lời khuyên nào? Cảm ơn nhiều! – user1811903

1

Wow, đó là nỗ lực nhiều hơn những gì bạn "CÓ" để làm.

Nếu vật trên bảng tính toán khoảng cách từ vật thể. Nếu nó xa hơn D thì không làm gì cả. Nếu nó là D đi thì nó nằm trong vật hút hấp dẫn. Chỉ cần thêm một lượng nhỏ vận tốc để nó trỏ vào đối tượng. Hãy nói rằng nó là 1000 X đi và 500 z đi. Chỉ cần làm một cái gì đó đơn giản như chia cho 100, và thêm vào vận tốc đối tượng để nó di chuyển 10 x và 5 y đối với đối tượng. Mỗi lần bạn cập nhật thêm vận tốc một lần nữa.

Có thể bạn cũng sẽ muốn có vận tốc tối đa. Đây là một LOT dễ dàng hơn để tính toán hoạt động tốt, và sẽ cung cấp cho bạn các hiệu ứng như trong trò chơi STAR CONTROL nơi có một hành tinh, hoặc các tàu hấp dẫn kéo về phía nhau một chút. Tôi đã làm điều này với 10 hành tinh và một ngôi sao, và người dùng về cơ bản có thể làm lander land với mỗi hành tinh. Đó là một vụ nổ nhưng tôi chưa bao giờ biến nó thành một trò chơi thực sự. Điều này có lợi thế là được rockingly nhanh để tính toán. Có một số điều kiện cạnh như nếu bạn làm cho bản đồ một hình xuyến để họ dọc qua các cạnh của bản đồ, nhưng về cơ bản nó chỉ đơn giản là cộng và trừ.

Đó là đủ cho một trò chơi. Bạn không tạo mô phỏng. Bạn đang làm một trò chơi.