Package dwlab.visualizers

Source Code of dwlab.visualizers.Visualizer

/* Digital Wizard's Lab - game development framework
* Copyright (C) 2013, Matt Merkulov

* All rights reserved. Use of this code is allowed under the
* Artistic License 2.0 terms, as specified in the license.txt
* file distributed with this code, or available from
* http://www.opensource.org/licenses/artistic-license-2.0.php */

package dwlab.visualizers;

import dwlab.base.Project;
import dwlab.base.XMLObject;
import dwlab.base.images.Image;
import dwlab.base.service.Service;
import dwlab.base.service.Service.Margins;
import dwlab.base.service.Vector;
import static dwlab.platform.Functions.*;
import dwlab.shapes.Shape;
import dwlab.shapes.Shape.Facing;
import dwlab.shapes.line_segments.LineSegment;
import dwlab.shapes.maps.SpriteMap;
import dwlab.shapes.maps.tilemaps.TileMap;
import dwlab.shapes.maps.tilemaps.TileSet;
import dwlab.shapes.sprites.Camera;
import dwlab.shapes.sprites.Sprite;
import dwlab.shapes.sprites.shape_types.drawing_sprites.DrawingSprite;
import java.util.LinkedList;

/**
* Visualizer is object which contains parameters for drawing the shape.
*/
public class Visualizer extends Color {
  /**
   * Horizontal shift of displaying image from the center of drawing shape in units .
   * @see #setDXDY
   */
  public double dX = 0d;

  /**
   * Vertical shift of displaying image from the center of drawing shape in units .
   * @see #setDXDY
   */
  public double dY = 0d;

  /**
   * Horizontal scaling of displaying image relative to the width of the drawing shape.
   * @see #setVisualizerScale
   */
  public double xScale = 1d;

  /**
   * Vertical scaling of displaying image relative to the height of the drawing shape.
   * @see #setVisualizerScale
   */
  public double yScale = 1d;

  /**
   * Scaling flag.
   * If False then image will be drawn with no scaling at all.
   */
  public boolean scaling = true;

  /**
   * Rotating flag.
   * If False then Angle parameter will not be used.
   */
  public boolean rotating = true;

  /**
   * Image field.
   */
  public Image image;

  // ==================== Creating ====================

  public Visualizer() {
    this.set( 1.0d, 1.0d, 1.0d, 1.0d );
  }
 
  /**
   * Creates new visualizer using given RGB components and transparency.
   * @return New color.
   * @see #fromHex
   */
  public Visualizer( double red, double green, double blue, double alpha ) {
    this.set( red, green, blue, alpha );
  }
 
  public Visualizer( double red, double green, double blue ) {
    this.set( red, green, blue, 1.0d );
  }
 
 
  /**
   * Creates new visualizer from image file.
   * @return New visualizer.
   * @see #fromImage, #fromColor, #fromHexColor
   */
  public Visualizer( String filename, int xCells, int yCells ) {
    this.image = new Image( filename, xCells, yCells );
  }
 
  public Visualizer( String filename ) {
    this.image = new Image( filename, 1, 1 );
  }


  /**
   * Creates new visualizer from existing image (LTImage).
   * @return New visualizer.
   * @see #fromFile, #fromRGBColor, #fromHexColor
   */
  public Visualizer( Image image ) {
    this.image = image;
  }


  /**
   * Creates new visualizer using given color RGB components and transparency.
   * @return New visualizer.
   * @see #fromFile, #fromImage, #fromHexColor
   */
  public Visualizer( double red, double green, double blue, double alpha, double scale, boolean scaling ) {
    this.set( red, green, blue, alpha );
    this.setVisualizerScales( scale );
    this.scaling = scaling;
  }


  /**
   * Creates new visualizer using given hexadecimal color representation and transparency.
   * @return New visualizer.
   * @see #fromFile, #fromImage, #fromRGBColor, #overlaps example.
   */
  public Visualizer( String hexColor, double scale, boolean scaling ) {
    this.set( hexColor );
    this.setVisualizerScales( scale );
    this.scaling = scaling;
  }

  // ==================== Parameters ====================

  /**
   * Sets shifts of the visualizer.
   * Works only with images.
   */
  public void setDXDY( double newDX, double newDY ) {
    dX = newDX;
    dY = newDY;
  }


  /**
   * Sets vertical and horizontal scaling of the visualizer
   * Works only with images.
   *
   * @see #clone example
   */
  public void setVisualizerScale( double newXScale, double newYScale ) {
    xScale = newXScale;
    yScale = newYScale;
  }


  /**
   * Sets scalings of the visualizer to one value
   * Works only with images.
   */
  public final void setVisualizerScales( double newScale ) {
    xScale = newScale;
    yScale = newScale;
  }


  public Image getImage() {
    return image;
  }


  public void setImage( Image newImage ) {
    image = newImage;
  }

  // ==================== Drawing ===================  }


  private static Vector servicePivot = new Vector();
  private static Vector serviceSizes = new Vector();

  /**
   * Draws given sprite using this visualizer.
   * Change this method if you are making your own visualizer.
   */
  public void drawUsingSprite( Sprite sprite, Sprite spriteShape, Color drawingColor ) {
    if( !sprite.visible ) return;

    if( debug ) Project.spritesDisplayed += 1;
   
    DrawingSprite.handlers[ sprite.shapeType.getNum() ].perform( this, sprite, spriteShape, drawingColor );
  }

  public void drawUsingSprite( Sprite sprite ) {
    drawUsingSprite( sprite, sprite, Color.white );
  }



  /**
   * Draws rectangle for isometric camera using given field coordinates and size.
   */
  public void drawIsoRectangle( double x, double y, double width, double height, Color color ) {
    startPolygon( 4, color, false );
    Camera.current.fieldToScreen( x - 0.5 * width, y - 0.5 * height, servicePivot );
    addPolygonVertex( servicePivot.x, servicePivot.y );
    Camera.current.fieldToScreen( x - 0.5 * width, y + 0.5 * height, servicePivot );
    addPolygonVertex( servicePivot.x, servicePivot.y );
    Camera.current.fieldToScreen( x + 0.5 * width, y + 0.5 * height, servicePivot );
    addPolygonVertex( servicePivot.x, servicePivot.y );
    Camera.current.fieldToScreen( x + 0.5 * width, y - 0.5 * height, servicePivot );
    addPolygonVertex( servicePivot.x, servicePivot.y );
    drawPolygon();
  }



  /**
   * Draws oval for isometric camera using given field coordinates and size.
   */
  public void drawIsoOval( double x, double y, double width, double height, Color color ) {
    startPolygon( 8, color, false );
    double xRadius = 0.5 * width;
    double yRadius = 0.5 * height;
    for( int n=0; n < 16; n += 2 ) {
      double angle = 22.5 * n;
      Camera.current.fieldToScreen( x + xRadius * Math.cos( angle ), y + yRadius * Math.sin( angle ), servicePivot );
      addPolygonVertex( servicePivot.x, servicePivot.y );
    }
    drawPolygon();
  }


  private static Vector servicePivot1 = new Vector();
  private static Vector servicePivot2 = new Vector();
 
  /**
   * Draws given line using this visualizer.
   * Change this method if you are making your own visualizer.
   */
  public void drawUsingLineSegment( LineSegment lineSegment, Color drawingColor ) {
    if( ! lineSegment.visible ) return;
    Camera.current.fieldToScreen( lineSegment.pivot[ 0 ].getX(), lineSegment.pivot[ 0 ].getY(), servicePivot1 );
    Camera.current.fieldToScreen( lineSegment.pivot[ 1 ].getX(), lineSegment.pivot[ 1 ].getY(), servicePivot2 );
    drawLine( servicePivot1.x, servicePivot1.y, servicePivot2.x, servicePivot2.y, 1d, multiplyBy( drawingColor ) );
  }


  private static Margins margins = new Margins();
 
  /**
   * Draws given tilemap using this visualizer.
   * Change this method if you are making your own visualizer.
   */
  public void drawUsingTileMap( TileMap tileMap, LinkedList<Shape> shapes, Color drawingColor ) {
    if( !tileMap.visible ) return;

    TileSet tileSet = tileMap.tileSet;
    if( tileSet == null ) return;

    Image tileSetImage = tileSet.image;

    double cellWidth = tileMap.getTileWidth();
    double cellHeight = tileMap.getTileHeight();

    Service.getEscribedRectangle( tileMap.leftMargin, tileMap.topMargin, tileMap.rightMargin, tileMap.bottomMargin, margins );

    double cornerX = tileMap.leftX();
    double cornerY = tileMap.topY();
    int minTileX = Service.floor( ( margins.min.x - cornerX ) / cellWidth );
    int minTileY = Service.floor( ( margins.min.y - cornerY ) / cellHeight );
    int maxTileX = Service.ceil( ( margins.max.x - cornerX ) / cellWidth );
    int maxTileY = Service.ceil( ( margins.max.y - cornerY ) / cellHeight );

    if( !tileMap.wrapped ) {
      minTileX = Service.limit( minTileX, 0, tileMap.xQuantity - 1 );
      minTileY = Service.limit( minTileY, 0, tileMap.yQuantity - 1 );
      maxTileX = Service.limit( maxTileX, 0, tileMap.xQuantity - 1 );
      maxTileY = Service.limit( maxTileY, 0, tileMap.yQuantity - 1 );
    }

    int tileDX = tileMap.horizontalOrder, tileDY = tileMap.verticalOrder;
    double sDX = cellWidth * tileDX, sDY = cellHeight * tileDY;

    Camera.current.sizeFieldToScreen( cellWidth, cellHeight, serviceSizes );

    if( !Camera.current.isometric ) if ( tileSetImage == null ) return;

    Color color = multiplyBy( drawingColor );
   
    int tileY;
    if( tileDY == 1 ) tileY = minTileY; else tileY = maxTileY;
    double y = cornerY + cellHeight * ( 0.5 + tileY );
    while( true ) {
      if( tileDY == 1 ) {
        if( tileY > maxTileY ) break;
      } else {
        if( tileY < minTileY ) break;
      }

      int tileX;
      if( tileDX == 1 ) tileX = minTileX; else tileX = maxTileX;

      double x = cornerX + cellWidth * ( 0.5 + tileX );

      while( true ) {
        if( tileDX == 1 ) {
          if( tileX > maxTileX ) break;
        } else {
          if( tileX < minTileX ) break;
        }

        if( shapes != null ) {
          for( Shape shape: shapes ) {
            TileMap childTileMap = shape.toTileMap();
            if( childTileMap != null ) {
              drawTile( childTileMap, x, y, serviceSizes.x, serviceSizes.y, tileX, tileY, color );
            } else {
              drawSpriteMapTile( shape.toSpriteMap(), x, y, color );
            }
          }
        } else {
          drawTile( tileMap, x, y, serviceSizes.x, serviceSizes.y, tileX, tileY, color );
        }

        x += sDX;
        tileX += tileDX;
      }

      y+= sDY;
      tileY += tileDY;
    }
  }
 
  public void drawUsingTileMap( TileMap tileMap ) {
    drawUsingTileMap( tileMap, null, Color.white );
  }



  /**
   * Draws tile of given tilemap with given coordinates using this visualizer.
   * X and Y are center coordinates of this tile on the screen.
   * If you want to make your own tilemap visualizer, make class which extends LTVisualizer and rewrite this method.
   *
   * @see #drawUsingTileMap
   */
  public void drawTile( TileMap tileMap, double x, double y, double width, double height, int tileX, int tileY, Color drawingColor ) {
    TileSet tileSet =tileMap.tileSet;
    int tileValue = getTileValue( tileMap, tileX, tileY );
    if( tileValue == tileSet.emptyTile ) return;

    Image tileSetImage = tileSet.image;
    if( tileSetImage == null ) return;

    Camera.current.fieldToScreen( x, y, servicePivot );

    Visualizer visualizer = tileMap.visualizer;
    width *= visualizer.xScale;
    height *= visualizer.yScale;

    tileSetImage.draw( tileValue, servicePivot.x + visualizer.dX * width, servicePivot.y + visualizer.dY * height, width, height, 0d, drawingColor );

    if( debug ) Project.tilesDisplayed += 1;
  }


  /**
   * Function which defines which tile to draw.
   * @return Tile number for given tilemap and tile coordinates.
   */
  public int getTileValue( TileMap tileMap, int tileX, int tileY ) {
    return tileMap.value[ tileMap.wrapY( tileY ) ][ tileMap.wrapX( tileX ) ];
  }


  public void drawSpriteMapTile( SpriteMap spriteMap, double x, double y, Color drawingColor ) {
    if( !spriteMap.visible ) return;
    int tileX = Service.floor( x / spriteMap.cellWidth ) & spriteMap.xMask;
    int tileY = Service.floor( y / spriteMap.cellHeight ) & spriteMap.yMask;
    for( int n=0; n <= spriteMap.listSize[ tileY ][ tileX ]; n++ ) {
      spriteMap.lists[ tileY ][ tileX ][ n ].draw( drawingColor );
    }
  }


  public Facing getFacing() {
    return xScale < 0 ? Facing.LEFT : Facing.RIGHT;
  }


  public void setFacing( Facing newFacing ) {
    xScale = Math.abs( xScale ) * ( newFacing == Facing.LEFT ? -1d : 1d );
  }

  // ==================== Other ====================

  /**
   * Clones the visualizer.
   * @return Clone of the visualizer.
   */
  @Override
  public Visualizer clone() {
    Visualizer visualizer = new Visualizer();
    copyVisualizerTo( visualizer );
    return visualizer;
  }



  public void copyVisualizerTo( Visualizer visualizer ) {
    copyColorTo( visualizer );

    visualizer.dX = dX;
    visualizer.dY = dY;
    visualizer.xScale = xScale;
    visualizer.yScale = yScale;
    visualizer.scaling = scaling;
    visualizer.rotating = rotating;
    visualizer.image = image;
  }



  @Override
  public void xMLIO( XMLObject xMLObject ) {
    super.xMLIO( xMLObject );

    dX = xMLObject.manageDoubleAttribute( "dx", dX );
    dY = xMLObject.manageDoubleAttribute( "dy", dY );
    xScale = xMLObject.manageDoubleAttribute( "xscale", xScale, 1.0 );
    yScale = xMLObject.manageDoubleAttribute( "yscale", yScale, 1.0 );
    scaling = xMLObject.manageBooleanAttribute( "scaling", scaling, true );
    rotating = xMLObject.manageBooleanAttribute( "rotating", rotating, true );
    image = xMLObject.manageObjectField( "image", image );
  }
}
TOP

Related Classes of dwlab.visualizers.Visualizer

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.