我正在做一个游戏,玩家将(释放鼠标单击时)以一定速度朝某个方向射击“星星”,该速度取决于他释放鼠标之前拖动鼠标的距离。我在 Canvas 上有一个“行星”(平稳圈),我想在移动的行星上施加引力。我相信我使用了正确的引力公式,并且使它部分起作用-行星会影响行星的运动轨迹直到某个点,此时恒星似乎会不断加速并停止根据其角度改变方向到明星。 有什么建议吗? (我知道恒星不应该绕行星运行,反之亦然。我对整个事物进行了编码,其名称互换得如此原谅)。

主类:

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

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;

      }
    }

编辑:

当前的主要类别方法:
    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);

    }

当前星级类(class)方法:
    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;

      }
    }

最佳答案

哇,这比您“要做”的工作要多得多。

如果物体在板上,请计算其与物体的距离。如果它比D更远,则不执行任何操作。如果D消失了,那么它就在物体的引力范围之内。只需向其添加少量速度,使其指向对象。假设它是1000 X远和500 z远。只需做一些简单的事情,例如除以100,然后将其加到对象速度上,使其向对象移动10 x和5 y。每次更新时,请再次添加速度。

您可能还需要最大速度。这是很多容易计算的好方法,并且会给您带来类似星球游戏中的“星际控制”游戏中的效果,或者船在万有引力的作用下彼此靠近。我用10个行星和1个恒星完成了此操作,用户基本上可以对每个行星进行月球着陆。这是一个爆炸,但我从未把它变成一个真正的游戏。这具有快速计算的优点。有一些边缘条件,例如是否使 map 成为圆环,以便它们在 map 的各个侧面弯曲,但基本上,这只是简单的加法和减法。

对于游戏来说已经足够好了。您不是在制作模拟器。您正在制作游戏。

关于java - 模拟星星的引力?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13306596/

10-10 09:59