Package games.stendhal.client.sprite

Source Code of games.stendhal.client.sprite.SpriteStore

/* $Id: SpriteStore.java,v 1.27 2010/10/04 19:44:32 nhnb Exp $ */
/***************************************************************************
*                   (C) Copyright 2003-2010 - Stendhal                    *
***************************************************************************
***************************************************************************
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
*                                                                         *
***************************************************************************/
package games.stendhal.client.sprite;


import games.stendhal.client.IGameScreen;
import games.stendhal.client.sprite.TileSprite.TSRef;

import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.Image;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;

import javax.imageio.ImageIO;

import org.apache.log4j.Logger;

/**
* A resource manager for sprites in the game. Its often quite important how and
* where you get your game resources from. In most cases it makes sense to have
* a central resource loader that goes away, gets your resources and caches them
* for future use.
* <p>
* [singleton]
* <p>
*/
public class SpriteStore {
  /** the logger instance. */
  private static final Logger logger = Logger.getLogger(SpriteStore.class);

  /** The single instance of this class. */
  private static SpriteStore single = new SpriteStore();

  /**
   * Screen graphics configuration.
   */
  protected GraphicsConfiguration gc;

  protected SpriteStore() {
    try {
      gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
    } catch (HeadlessException e) {
      logger.warn("Cannot initialize graphic user interface: " + e);
    }
  }

  /**
   * Get the single instance of this class.
   *
   * @return The single instance of this class
   */
  public static SpriteStore get() {
    return single;
  }

  /**
   * Create an animated sprite from a tile sprite using pixel units.
   *
   * @param sprite
   *            The image which contains the different frames.
   * @param x
   *            The base X coordinate (in pixels).
   * @param y
   *            The base Y coordinate (in pixels).
   * @param frameCount
   *            The number of frames in this animation.
   * @param width
   *            The tile width (in pixels).
   * @param height
   *            The tile height (in pixels).
   * @param delay
   *            The minimum delay between frames.
   *
   * @return An animated sprite.
   */
  public AnimatedSprite getAnimatedSprite(final Sprite sprite, final int x,
      final int y, final int frameCount, final int width,
      final int height, final int delay) {
    return new AnimatedSprite(getTiles(sprite, x, y, frameCount, width,
        height), delay, true);
  }

  /**
   * Get sprite tiles from a sprite using pixel units.
   *
   * @param sprite
   *            The base image.
   * @param x
   *            The base X coordinate (in pixels).
   * @param y
   *            The base Y coordinate (in pixels).
   * @param count
   *            The number of tiles.
   * @param width
   *            The tile width (in pixels).
   * @param height
   *            The tile height (in pixels).
   *
   * @return An array of sprites.
   */
  public Sprite[] getTiles(final Sprite sprite, final int x, final int y,
      final int count, final int width, final int height) {
    if (sprite == null) {
      return new Sprite[0];
    }

    final Sprite[] sprites = new Sprite[count];

    int tx = x;

    for (int i = 0; i < count; i++) {
      sprites[i] = getTile(sprite, tx, y, width, height);
      tx += width;
    }

    return sprites;
  }

  private static final String FAILSAFE_ICON_REF = "data/sprites/failsafe.png";

  /**
   * Get the failsafe sprite.
   * The failsafe sprite is needed in case there are newer graphic requested in server than in client.
   *
   * It is ok not to return a handmade one.
   * If we cannot reach the failsafe icon,
   * we have bigger problems then just the need to show anything.
   *
   * @return The failsafe sprite.
   */
  public Sprite getFailsafe() {
    return getSprite(FAILSAFE_ICON_REF);
  }

  /**
   * Retrieve a sprite from the store.
   *
   * @param ref
   *            The reference to the image to use for the sprite
   * @return A sprite instance containing an accelerate image of the request
   *         reference
   */
  public Sprite getSprite(final String ref) {
    final SpriteCache cache = SpriteCache.get();

    Sprite sprite = cache.get(ref);

    if (sprite == null) {

      sprite = loadSprite(ref);
      if (sprite != null) {
        cache.add(ref, sprite);
      }
    }

    return sprite;
  }

  /**
   * Checks if a file exists.
   *
   * @param ref
   *            the file name
   * @return if sprite exists in store false otherwise
   */
  public boolean existsSprite(final String ref) {
    final URL url = this.getClass().getClassLoader().getResource(ref);
    return url != null;
  }

  /**
   * Load a sprite from a resource reference.
   *
   * @param ref
   *            The image resource name.
   *
   * @return A sprite, or <code>null</code> if missing/on error.
   */
  protected Sprite loadSprite(final String ref) {
    BufferedImage sourceImage = null;

    try {
      URL url;
      if (ref.startsWith("http://")) {
        logger.info("Loading sprite from a URL...");
        url = new URL(ref);
      } else {
        url = this.getClass().getClassLoader().getResource(ref);
      }
      if (url == null) {
        logger.error("Can't find ref: " + ref);

        // avoid infinite loop and stack overflow in case of missing
        // failsafe icon
        if (ref.equals(FAILSAFE_ICON_REF)) {
          logger.error("Cannot find FAILSAFE_ICON_REF: " + FAILSAFE_ICON_REF);
          return null;
        } else {
          return getFailsafe();
        }
      }

      // use ImageIO to read the image in
      sourceImage = ImageIO.read(url);
    } catch (final IOException e) {
      logger.error("Failed to read: " + ref, e);

      if (ref.equals(FAILSAFE_ICON_REF)) {
        logger.error("Cannot read FAILSAFE_ICON_REF: " + FAILSAFE_ICON_REF);
        return null;
      } else {
        return getFailsafe();
      }
    }

    // create an accelerated image of the right size to store our sprite in
    final int mode = Transparency.BITMASK;

    // ALPHA channel makes it runs 30% slower.
    // mode=Transparency.TRANSLUCENT;

    final Image image = gc.createCompatibleImage(sourceImage.getWidth(),
        sourceImage.getHeight(), mode);

    // draw our source image into the accelerated image
    image.getGraphics().drawImage(sourceImage, 0, 0, null);

    // create a sprite, add it the cache then return it
    final Sprite sprite = new ImageSprite(image, ref);

    return sprite;
  }

  /**
   * Get an empty sprite with the size of a single tile.
   *
   * @return An empty sprite.
   */
  public Sprite getEmptySprite() {
    return getEmptySprite(IGameScreen.SIZE_UNIT_PIXELS,
        IGameScreen.SIZE_UNIT_PIXELS);
  }

  /**
   * Get an empty sprite.
   *
   * @param width
   *            The width.
   * @param height
   *            The height.
   *
   * @return An empty sprite.
   */
  public Sprite getEmptySprite(final int width, final int height) {
    final SpriteCache cache = SpriteCache.get();

    final Object reference = EmptySprite.createReference(width, height);

    Sprite sprite = cache.get(reference);

    if (sprite == null) {
      sprite = new EmptySprite(width, height, reference);
      cache.add(reference, sprite);
    }

    return sprite;
  }

  /**
   * Create a sprite tile (sub-region).
   * @param sprite
   * @param x
   * @param y
   *
   *
   *
   * @param width
   *            The width.
   * @param height
   *            The height.
   * @return tile found in cache or new one created from sprite
   */
  public Sprite getTile(final Sprite sprite, final int x, final int y, final int width, final int height) {
    final SpriteCache cache = SpriteCache.get();

    final TSRef reference = TileSprite.createReference(sprite, x, y, width,
        height);

    Sprite tile = cache.get(reference);

    if (tile == null) {
      tile = sprite.createRegion(x, y, width, height, reference);
      // tile = new TileSprite(sprite, x, y, width, height, reference);

      if (reference != null) {
        cache.add(reference, tile);
      }
    }

    return tile;
  }

}
TOP

Related Classes of games.stendhal.client.sprite.SpriteStore

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.