Package org.gbcpainter.view.draw

Source Code of org.gbcpainter.view.draw.ZoomRedrawJob

package org.gbcpainter.view.draw;

import org.gbcpainter.env.GraphicsEnv;
import org.gbcpainter.game.levels.Level;
import org.gbcpainter.game.model.Monster;
import org.gbcpainter.game.model.Player;
import org.gbcpainter.game.model.grid.Face;
import org.gbcpainter.game.model.grid.Junction;
import org.gbcpainter.game.model.grid.OpaqueRandomFace;
import org.gbcpainter.game.model.grid.Pipe;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jgrapht.Graph;
import org.jgrapht.graph.UnmodifiableUndirectedGraph;

import java.awt.*;
import java.awt.geom.GeneralPath;
import java.util.*;

/**
* Draws the entire level to screen
* <p/>
* This is class is used as a development tool.
*
* @author Lorenzo Pellegrini
* @exclude
*/
public class ZoomRedrawJob extends ComposableRedrawJob<Object> {

  @Nullable
  private Map<Face, Integer> faces = null;

  @NotNull
  private final Rectangle levelBounds;

  public ZoomRedrawJob(@NotNull Canvas whereTo, @NotNull Level level) {
    super(whereTo, level, 1, Collections.singletonList( new Object() ));
    this.levelBounds = makeBoundRectangle( level.getMap() );
    tryCreateFaces();
  }


  @NotNull
  private static Rectangle makeBoundRectangle( @NotNull
                                               Graph<Junction, Pipe> levelGraph ) {
    int minY = Integer.MAX_VALUE;
    int maxY = 0;
    int minX = Integer.MAX_VALUE;
    int maxX = 0;
    for (Junction vertex : levelGraph.vertexSet()) {
      final Point vertexPosition = vertex.getPosition();
      minX = Math.min( vertexPosition.x, minX );
      maxX = Math.max( vertexPosition.x, maxX );
      minY = Math.min( vertexPosition.y, minY );
      maxY = Math.max( vertexPosition.y, maxY );
    }

    return new Rectangle( minX, minY, maxX - minX, maxY - minY );
  }

  /**
   * Draws the component on screen
   * <p/>
   * The Graphics object is clipped to the position specified from {@link
   * #getComponentRect(Object)}
   *
   * @param component The component to be drawn
   * @param g2d       The grphics object
   *
   * @throws Exception If an error occurs
   */
  @Override
  protected void drawComponent( @NotNull final Object component,
                                @NotNull final Graphics2D g2d )
      throws Exception {
    final Rectangle screenBounds = GraphicsEnv.getInstance()
                                            .gameRectangleToActualScreen(
                                                this.levelBounds );
    final Point screenCenter = new Point( (int) screenBounds.getCenterX() ,
                                          (int) screenBounds.getCenterY() );
    g2d.translate( - screenCenter.x/2, - screenCenter.y/2 );
    final Level level = getLevel();
    final Player player = level.getPlayer();

    for (Map.Entry<Face, Integer> faceEntry : this.faces.entrySet()) {
      final Face face = faceEntry.getKey();
      face.setColored( level.isFaceColored( faceEntry.getValue() ) );
      face.draw( g2d );
    }

    for (Pipe pipe : level.getMap().edgeSet()) {
      pipe.draw( g2d );
    }

    for (Junction junction : level.getMap().vertexSet()) {
      junction.draw( g2d );
    }

    for (Monster mob : level.getMonsters()) {
      mob.draw( g2d );
    }

    player.draw( g2d ) ;
  }

  /**
   * Returns the clip of the component
   *
   * @param component The component whose size is required
   *
   * @return The size of the component or null if the element is hidden
   */
  @Nullable
  @Override
  protected Rectangle getComponentRect( @NotNull final Object component ) {
    final Dimension windowSize = GraphicsEnv.getInstance().getWindowSize();
    return new Rectangle( windowSize );
  }

  protected boolean tryCreateFaces() {
    try {
      final Level level = getLevel();
      Map<Set<Pipe>, Integer> facesMap = level.getFacesMap();
      UnmodifiableUndirectedGraph<Junction, Pipe> levelMap = level.getMap();
      faces = new HashMap<>( facesMap.size() );

      for (Map.Entry<Set<Pipe>, Integer> faceAndId : facesMap.entrySet()) {
      /* Per ogni faccia ... */
        Pipe firstPipe = faceAndId.getKey().iterator().next();
        Junction lastJunction = levelMap.getEdgeSource( firstPipe );
        Pipe lastPipe = null;
        GeneralPath faceShape = new GeneralPath();
        faceShape.moveTo( lastJunction.getPosition().x, lastJunction.getPosition().y );
        while ( ! firstPipe.equals( lastPipe ) ) {
        /* Aggiunge la linea*/

          Pipe nextPipe = null;
          final Set<Pipe> connectedSegments = new HashSet<>( levelMap.edgesOf( lastJunction ) );
          if ( lastPipe == null ) {
          /* È il primo loop */
            lastPipe = firstPipe;
          }

        /* Scarta il segmento già percorso */
          connectedSegments.remove( lastPipe );

          for (Pipe perimeterSegment : faceAndId.getKey()) {
          /* Tra tutti i segmenti del perimetro seleziona solo quello che confina con il vertice corrente */
            if ( connectedSegments.contains( perimeterSegment ) ) {
              nextPipe = perimeterSegment;
              break;
            }
          }


          if ( nextPipe == null ) {
            throw new IllegalArgumentException();
          }

          lastPipe = nextPipe;

          final Junction edgeSource = levelMap.getEdgeSource( nextPipe );
          lastJunction = edgeSource.equals( lastJunction ) ? levelMap.getEdgeTarget( nextPipe ) : edgeSource;

          final Point junctionPosition = lastJunction.getPosition();
          faceShape.lineTo( junctionPosition.x, junctionPosition.y );
        }
        faceShape.closePath();

        faces.put( new OpaqueRandomFace( faceShape ), faceAndId.getValue() );
      }
      return true;
    } catch ( Exception e ) {
      this.faces = null;
      return false;
    }
  }
}
TOP

Related Classes of org.gbcpainter.view.draw.ZoomRedrawJob

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.