Package org.gbcpainter.game.model.monsters

Source Code of org.gbcpainter.game.model.monsters.BombImpl

package org.gbcpainter.game.model.monsters;

import net.jcip.annotations.GuardedBy;
import org.gbcpainter.env.GraphicsEnv;
import org.gbcpainter.game.view.AbstractResourceDrawable;
import org.gbcpainter.loaders.textures.TextureLoader;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.awt.*;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.Arrays;

/**
* Implementation of the {@link org.gbcpainter.game.model.monsters.Bomb} interface.
* <p/>
* The bomb has a countdown start time, an explosion time and an explosion persistence time.
* <p/>
* The explosion area is a square whose size is 10
*
* @author Lorenzo Pellegrini
*/
public class BombImpl extends AbstractResourceDrawable implements Bomb {

  private static final long NOT_ABORTED_ANIMATION_TIME = 0;
  @GuardedBy ("this")
  private long stoppedAnimationTime = NOT_ABORTED_ANIMATION_TIME;

  private static final java.util.List<String> countdownTextures = Arrays.asList( "Bomb3", "Bomb2", "Bomb1" );/*NON-NLS*/

  private static final java.util.List<String> explosionTextures = Arrays.asList( "Explosion1", "Explosion2", "Explosion3", "Explosion4" );/*NON-NLS*/
  @NonNls
  private static final String BEFORE_ACTIVATION_TEXTURE = "Bomb3";

  private static final double EXPLOSION_AREA = 5.0;

  private final long animationStartTime;

  private final long explosionTime;

  private final long animationEndTime;
  @NotNull
  private final Point position;

  /**
   * Creates the bomb with the given countdown start time, explosion time and an explosion persistence end time
   * <p/>
   * All the parameters must be in milliseconds based on the {@link System#currentTimeMillis()} method.
   *
   * @param startTime        The time to start the countdown
   * @param explosionTime    The time the bomb will explode
   * @param endTime          The time the explosion vanishes
   * @param gameGridPosition The position of the bomb
   *
   * @throws java.lang.IllegalArgumentException If explosionTime <= startTime or endTime <= explosionTime
   * @throws Exception                          If an error occurs while loading textures
   */
  public BombImpl( long startTime, long explosionTime, long endTime, @NotNull Point gameGridPosition ) throws Exception {
    super( /*gameGridPosition*/ );
    this.position = new Point( gameGridPosition );
    this.animationStartTime = startTime;
    this.explosionTime = explosionTime;
    this.animationEndTime = endTime;

    if ( this.animationStartTime >= this.explosionTime ) {
      throw new IllegalArgumentException();
    }
    if ( this.explosionTime >= this.animationEndTime ) {
      throw new IllegalArgumentException();
    }

    final TextureLoader loader = GraphicsEnv.getInstance().getTextureLoader();

    for (String countdownTexture : countdownTextures) {
      loader.loadTexture( countdownTexture, true );
    }

    for (String explosionTexture : explosionTextures) {
      loader.loadTexture( explosionTexture, true );
    }

    loader.loadTexture( BEFORE_ACTIVATION_TEXTURE, true );

  }

  @Override
  @NonNls
  public synchronized String toString() {
    return "Bomb{" +
           "animationStartTime=" + this.animationStartTime +
           "explosionTime=" + this.explosionTime +
           ", animationEndTime=" + this.animationEndTime +
           ( ( this.stoppedAnimationTime != NOT_ABORTED_ANIMATION_TIME ) ? "Locked at: " + this.stoppedAnimationTime : "" ) +
           '}';
  }

  @NotNull
  @Override
  public Point getPosition() {
    return new Point( this.position );
  }

  @Nullable
  @Override
  protected synchronized String getResourceName() {
    final long currentTime = this.getTime();

    if ( currentTime < this.animationEndTime ) {
      if ( currentTime < this.animationStartTime ) {

        return BEFORE_ACTIVATION_TEXTURE;
      }
      /*
        If the bomb is activated, select the texture to use using the percentage elapsed
        time as the index of the textures list
       */

      else if ( currentTime < this.explosionTime ) {

        final int nTextures = countdownTextures.size();
        final double totalTime = this.explosionTime - this.animationStartTime;
        final double elapsedTime = currentTime - this.animationStartTime;

        int selectAnimation = (int) Math.floor( ( elapsedTime / totalTime ) * (double) ( nTextures ) );
        selectAnimation = Math.min( selectAnimation, nTextures - 1 );
        return countdownTextures.get( selectAnimation );
      } else {

        final int nTextures = explosionTextures.size();
        final double totalTime = ( this.animationEndTime - this.explosionTime );
        final double elapsedTime = ( currentTime - this.explosionTime );

        int selectAnimation = (int) Math.round( ( elapsedTime / totalTime ) * (double) ( nTextures ) );
        selectAnimation = Math.min( selectAnimation, nTextures - 1 );
        return explosionTextures.get( selectAnimation );
      }
    } else {
      return null;
    }
  }

  @Nullable
  @Override
  public synchronized Shape getExplosion( @NotNull final Point2D positionCenter ) {
    final long currentTime = this.getTime();

    if ( currentTime >= this.explosionTime && currentTime < this.animationEndTime ) {
      /* The explosion are area is a square */
      return new Rectangle2D.Double( positionCenter.getX() - ( EXPLOSION_AREA / 2.0 ),
                                     positionCenter.getY() - ( EXPLOSION_AREA / 2.0 ),
                                     EXPLOSION_AREA, EXPLOSION_AREA );
    } else {
      return null;
    }


  }

  @Override
  public synchronized void lockAnimation( final long stopAtTime ) {
    this.stoppedAnimationTime = stopAtTime;
  }

  @Override
  public synchronized void unlockAnimation() {
    this.stoppedAnimationTime = NOT_ABORTED_ANIMATION_TIME;
  }

  /**
   * Gets the time used when calculating the texture and the shape to use
   *
   * This must take into account locks set using {@link #lockAnimation(long)}.
   *
   * @return The time, in milliseconds, to use
   */
  protected synchronized long getTime() {
    final long localStoppedAnimationTime = this.stoppedAnimationTime;
    if ( localStoppedAnimationTime == NOT_ABORTED_ANIMATION_TIME ) {
      return System.currentTimeMillis();
    } else {
      return localStoppedAnimationTime;
    }
  }

}
TOP

Related Classes of org.gbcpainter.game.model.monsters.BombImpl

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.