GameGrid: Game programming with Java

Research project PHBern  
HomePrintJava-Online

Newton

The movements of multiple bodies after the Newtonian gravitational theory can be simulated nicely with the help of JGameGrid.

In this example three bodies are generated as instances of the class Body. With the method act() the new postitions of the three bodies are recalculated regarding their pull to each other.



Run this example

 

Edit this example in the Online-Editor

 
Program code
// Newton.java
// Simulation of many-body movement in space

import ch.aplu.jgamegrid.*;
import java.awt.Color;
import java.util.*;

public class Newton extends GameGrid
{
  public Newton()
  {
    super(8006001nulltrue);
    setSimulationPeriod(50);
    Body body1 = new Body(11E26new GGVector(01E4));
    addActor(body1, new Location(200150));
    Body body2 = new Body(21E27new GGVector(00));
    addActor(body2, new Location(600150));
    Body body3 = new Body(31E25new GGVector(-1E31E4));
    addActor(body3, new Location(40050));
    show();
  }

  public static void main(String[] args)
  {
    new Newton();
  }
}

// -------------------- class Body ---------------------------
class Body extends Actor
{
  private final double scaleFactor = 1E6;
  private final double G = 6.67E-11// Gravitational constant
  private final double mass;
  private double timeFactor = 500;
  private Location oldLocation = new Location(-1-1);
  private GGVector startVelocity;
  private GGVector position;
  private GGVector velocity;
  private GGVector acceleration;
  private boolean drawTrace = true;
  private int id;

  public Body(int id, double mass, GGVector startVelocity)
  {
    super("sprites/body" + id + ".gif");
    this.id = id;
    this.mass = mass;
    this.startVelocity = startVelocity;
  }

  public void reset()
  {
    position = toPosition(getLocationStart());
    velocity = startVelocity.clone();
    oldLocation.x = -1;
    oldLocation.y = -1;
  }

  public GGVector getPosition()
  {
    return position.clone();
  }

  public GGVector getVelocity()
  {
    return velocity.clone();
  }

  public double getMass()
  {
    return mass;
  }

  private GGVector toPosition(Location location)
  {
    return new GGVector(location.x * scaleFactor, location.y * scaleFactor);
  }

  private Location toLocation(GGVector position)
  {
    return new Location((int)(position.x / scaleFactor)(int)(position.y / scaleFactor));
  }

  public void act()
  {
    ArrayList<Actor> neighbours = gameGrid.getActors(Body.class);
    neighbours.remove(this);  // Remove self
    GGVector totalForce = new GGVector();
    for (Actor neighbour : neighbours)
    {
      Body body = (Body)neighbour;
      GGVector r = body.getPosition().sub(position);
      double rmag = r.magnitude();
      GGVector force = r.mult(* mass * body.getMass() / (rmag * rmag * rmag));
      totalForce = totalForce.add(force);
    }
    acceleration = totalForce.mult(1 / mass);
    velocity = velocity.add(acceleration.mult(timeFactor));
    position = position.add(velocity.mult(timeFactor));
    Location location = toLocation(position);
    setLocation(location);

    if (drawTrace)
    {
      switch (id)
      {
        case 1:
          getBackground().setPaintColor(Color.yellow);
          break;
        case 2:
          getBackground().setPaintColor(Color.red);
          break;
        case 3:
          getBackground().setPaintColor(Color.green);
          break;
      }
      if (oldLocation.x != -1)
        getBackground().drawLine(oldLocation.x, oldLocation.y, location.x, location.y);
      oldLocation.x = location.x;
      oldLocation.y = location.y;
    }
  }
}