projekt  
  einleitung
  applet
  quellcode
über  
  info
  team
quellcode
 
JAVADOC
SOURCECODE
import java.awt.image.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.geom.*;

public class Screen extends JPanel
{
  /**
   * this screen
   */
  public static Screen screen;
  /**
   * the width and height of this screen
   */
  public static int width;
  public static int height;
  /**
   * the Factor to draw the v-vector longer as it's actually is
   * (for viewing purposes)
   */
  public static double vFactor;
  /**
   * the time after which the screen is redrawn (in milliseconds)
   */
  public static int REFRESH_TIME=33; // = 30fps     final
  /**
   * our offscreen-graphics and image
   */
  private static BufferedImage img;
  /**
   * used to draw on the image
   */
  private static Graphics2D imgG;
  /**
   * the (0|0) - point in screencoordinates
   */
  private static int x0;
  private static int y0;

  private static double m2scrF;

  /**
   * screen-coordinate -> metre-coordinate
   * screen-coordinate = (0|0) is left upper pixel
   */
  private static AffineTransform scr2m;
  /**
   * metre-coordinate -> screen-coordinate
   * metre-coordinate = (0|0) is in center
   */
  private static AffineTransform m2scr;
  /**
   * the position of the previous mouse-DRAG
   */
  private static int dragX;
  private static int dragY;

  public static boolean tracking;

  /**
   * mapping of the second mouse button
   */
  private static int SECOND_MOUSEBUTTON= MouseEvent.BUTTON3_MASK;


  /**
   * create an offscreen-image off a component
   */
  Screen()
  {
    this.setDoubleBuffered(false); //disable the jpanel's internal buffering
    this.setOpaque(true); // tell swing it doesen't have to paint behind it
    screen= this;
    this.addComponentListener(new ComponentAdapter() {
      public void componentResized(ComponentEvent e)
      {
        width= e.getComponent().getSize().width;
        height= e.getComponent().getSize().height;
        x0=width/2;
        y0=height/2;
        img= (BufferedImage)e.getComponent().createImage(width, height);
        imgG= (Graphics2D)img.createGraphics();
        GlobalPanel.update();
      } });
	
	
    this.addMouseListener(new MouseAdapter() {
      public void mouseClicked(MouseEvent e)
      {
        // place new mass
        if( ((JPanel)e.getSource()).getCursor().getType()
          == Cursor.CROSSHAIR_CURSOR )
        {
//          System.out.println(e.getX()+":"+e.getY()+"  ->");
          Point2D p= new Point2D.Double(e.getX(),e.getY());
          scr2m.transform(p,p);
          switch(MassPanel.newActionToExecute)
          {
            case MassPanel.MASS:
            {
              MassPanel.update( Physics.addNewMass(p.getX(), p.getY() ));
    //          System.out.println(p.getX()+":"+p.getY());
              update();
              break;
            }
            case MassPanel.CRAFT:
            {
              MassPanel.update( Physics.addNewCraft(p.getX(), p.getY() ));
              update();
              break;
            }
            case MassPanel.SELECTION:
            {
              MassPanel.update( Physics.whoIsNextTo(p.getX(), p.getY()) );
            }
            case MassPanel.ORBIT:
            {
              int c= MassPanel.getActiveMass() ;
              int t= Physics.whoIsNextTo(p.getX(), p.getY());
              Physics.orbit( c, t, MassPanel.r_orbit );
              MassPanel.update( t );
              //update();
            }
          }
          MassPanel.newActionToExecute=-1;
          Main.main.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
        }
        else
        {
          int active= MassPanel.getActiveMass();
          if(active!=-1)
          {
            Mass mass= (Mass)Physics.masses.get(active);
            Point2D p= new Point2D.Double(e.getX(),e.getY());
            scr2m.transform(p,p);
            // resize v-vector of active mass
            if( (e.getModifiers()&MouseEvent.BUTTON1_MASK) !=0 )
            {
              // mouse.x - mass.x = xv
              mass.xv= (p.getX()-mass.x)/vFactor;
              // mouse.y - mass.y = yv
              mass.yv= (p.getY()-mass.y)/vFactor;
            }
            // alter radius of active mass
            else if( (e.getModifiers()&SECOND_MOUSEBUTTON) !=0 )
            {
              // sqrt( (mouse.x-mass.x)^2 + (mouse.y-mass.y)^2 )  = radius
              mass.r = Math.sqrt( Math.pow(p.getX()-mass.x,2)
                  + Math.pow(p.getY()-mass.y,2) );
            }
            MassPanel.update(active);
            Screen.update();
          }
        }
      }
      public void mousePressed(MouseEvent e)
      {
        dragX=e.getX();
        dragY=e.getY();
      }
      public void mouseReleased(MouseEvent e)
      {
      } });
    this.addMouseMotionListener(new MouseMotionAdapter() {
      public void mouseDragged(MouseEvent e)
      {
        //move mass
        if((e.getModifiers() & MouseEvent.BUTTON1_MASK)!=0)
        {
          int active=MassPanel.getActiveMass();
          if(active!=-1)
          {
            //get screencoordinates of actual mass
            Mass mass= (Mass)Physics.masses.get(active);
            Point2D p= new Point2D.Double(mass.x,mass.y);
            m2scr.transform(p,p);
            //add moved pixel
            p.setLocation(p.getX()+(e.getX()-dragX), p.getY()+(e.getY()-dragY));
            //transform back to metres
            scr2m.transform(p,p);
            mass.x=p.getX();
            mass.y=p.getY();
            //show news
            MassPanel.update(active);
          }
        }
        //move scene
        else if ((e.getModifiers() & SECOND_MOUSEBUTTON)!=0)
        {
          x0+= e.getX()-dragX;
          y0+= e.getY()-dragY;
          updateTransform();
        }
        dragX=e.getX();
        dragY=e.getY();
        //System.out.println("DRAGGEDmods:"+e.getModifiers());
      }
      public void mouseMoved(MouseEvent e)
      {
      } });
  }

  /**
   * turns on ability of processKeyEvent
   */
  /*public boolean isFocusTraversable()
  {
    return true;
  } */

  /**
   * view follows center of mass
   */
  public static void track()
  {
    int activeMass= MassPanel.getActiveMass();
    Mass m= (Mass)Physics.masses.get(activeMass);
    // set centerpixels of screen to new calculated mass-position:
    x0= (width/2)-(int)(m.x*m2scr.getScaleX());
    y0= (height/2)-(int)(m.y*m2scr.getScaleY());;
    // no update - to slow...
    updateTransform();
    //m2scr= (m2scrF,0,0,-m2scrF,x0,y0);
    //scr2m= (1/m2scrF,0,0,-1/m2scrF,-x0/m2scrF,y0/m2scrF);
  }

  /**
   * sets the transformation for
   * 1) m2scr  (from metres to pixel)
   * 2) scr2m (from pixel to metres)
   * using as parameter:
   * a) GlobalPanel.getXMetres / Screen.width  as "zoomfactor"
   * b) (x0|y0) as screencoordinates where the (0|0) - point should be
   */
  public static void updateTransform()
  {
    //  / m2scrF   0     width/2 \    / x \    / x' \
    // |     0  -m2scrF  height/2 | * | y |  = | y' |
    // \     0     0        1     /    \ 1 /    \ 1 /
    // alter m2scr-transformation
    m2scrF= Screen.width/GlobalPanel.getXMetres();
    m2scr= new AffineTransform(m2scrF,0,0,-m2scrF,x0,y0);
    scr2m= new AffineTransform(1/m2scrF,0,0,-1/m2scrF,-x0/m2scrF,y0/m2scrF);
    update();
  }

  /**
   * draws a new offscreen-image using all data
   */
  public static void update()
  {
    //if(tracking) track();
    imgG.setColor(Color.black);
    imgG.fillRect(0,0,width,height);
    int activeMass= MassPanel.getActiveMass();
//    System.out.println(""+activeMass);
    double scaleX= m2scr.getScaleX();  // metre*scaleX=pixel
    for(int i=0; i255) red=255;
        if(green>255) green=255;
        if(blue>255) blue=255;
      }
      if(i==activeMass) // mark the selected one
      {
        imgG.setColor(Color.yellow);
        imgG.drawOval(pixX-pixR, pixY-pixR, 2*pixR, 2*pixR);
//        System.out.println("mass"+activeMass+" has "+m.xv+":"+m.yv);
//        imgG.setStroke(new BasicStroke((float)0.0001));
        p.setLocation(m.x+(m.xv*vFactor), m.y+(m.yv*vFactor));
        m2scr.transform(p,p);
        imgG.drawLine(pixX, pixY, (int)p.getX(), (int)p.getY());

	    if(m instanceof Craft)
		{
		  Craft c= (Craft)m;
		  double d= (c.a*Math.pow(Physics.deltaT,2))/2;
		  double xe= 0.0;
		  double ye= 0.0;
		  xe+= d*Math.cos(c.heading);
          ye+= d*Math.sin(c.heading);
		  imgG.setColor(Color.red);
		  p.setLocation(m.x+(xe*vFactor), m.y+(ye*vFactor));
          m2scr.transform(p,p);
          imgG.drawLine(pixX, pixY, (int)p.getX(), (int)p.getY());
		}
	
	  }
    }
    screen.repaint();
  }

  /**
   * copy the offscreen-image in this component.
   * we can't get access to the jpanel's graphics-object, so rely on
   * this one.
   */
  protected void paintComponent(Graphics g)
  {
    super.paintComponent(g);
    g.drawImage(img, 0, 0, this);
  }

  static class DrawLoop
  {
    //indicates when this loop should stop
    static boolean stop=false;
    //the loop which calculates the physics and then draws it.
    //must be run in an extra thread
    static public void loop()
    {
      while(stop==false)
      {
        Physics.calculate();
        if(tracking) track();
        //ControlPanel.update();
        update();
        try {
        Thread.sleep(REFRESH_TIME);
        } catch(InterruptedException e) {} //should not happen
      }
    }
  }

}