Average Density: 0.08
  1 package nl.tudelft.jpacman.sprite;
  2 
  3 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
  4 
  5 import java.awt.image.BufferedImage;
  6 import java.io.IOException;
  7 import java.io.InputStream;
  8 import java.util.HashMap;
  9 import java.util.Map;
 10 
 11 import javax.imageio.ImageIO;
 12 
 13 /**
 14  * Utility to load {@link Sprite}s.
 15  *
 16  * @author Jeroen Roosen 
 17  */
 18 public class SpriteStore {
 19 
 20     /**
 21      * We only need to load images once, so we keep track
 22      * of them in a hash map.
 23      */
 24     private final Map<String, Sprite> spriteMap;
 25 
 26     /**
 27      * Create a new sprite store.
 28      */
 29     public SpriteStore() {
 30         spriteMap = new HashMap<>();
 31     }
 32 
 33     /**
 34      * Loads a sprite from a resource on the class path.
 35      * Sprites are loaded once, and then stored in the store
 36      * so that they can be efficiently retrieved.
 37      *
 38      * @param resource
 39      *            The resource path.
 40      * @return The sprite for the resource.
 41      * @throws IOException
 42      *             When the resource could not be loaded.
 43      */
 44     public Sprite loadSprite(String resource) throws IOException {
 45         Sprite result = spriteMap.get(resource);
 46         if (result == null) {
 47             result = loadSpriteFromResource(resource);
 48             spriteMap.put(resource, result);
 49         }
 50         return result;
 51     }
 52 
 53     /**
 54      * Loads a sprite from a resource on the class path.
 55      *
 56      * @param resource
 57      *            The resource path.
 58      * @return A new sprite for the resource.
 59      * @throws IOException
 60      *             When the resource could not be loaded.
 61      */
 62     @SuppressFBWarnings(
 63         value = "RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE",
 64         justification = "false positive in java 11"
 65     )
 66     private Sprite loadSpriteFromResource(String resource) throws IOException {
 67         try (InputStream input = SpriteStore.class.getResourceAsStream(resource)) {
 68             if (input == null) {
 69                 throw new IOException("Unable to load " + resource + ", resource does not exist.");
 70             }
 71             BufferedImage image = ImageIO.read(input);
 72             return new ImageSprite(image);
 73         }
 74     }
 75 
 76     /**
 77      * Creates a new {@link AnimatedSprite} from a base image.
 78      *
 79      * @param baseImage
 80      *            The base image to convert into an animation.
 81      * @param frames
 82      *            The amount of frames of the animation.
 83      * @param delay
 84      *            The delay between frames.
 85      * @param loop
 86      *            Whether this sprite is a looping animation or not.
 87      * @return The animated sprite.
 88      */
 89     public AnimatedSprite createAnimatedSprite(Sprite baseImage, int frames,
 90                                                int delay, boolean loop) {
 91         assert baseImage != null;
 92         assert frames > 0;
 93 
 94         int frameWidth = baseImage.getWidth() / frames;
 95 
 96         Sprite[] animation = new Sprite[frames];
 97         for (int i = 0; i < frames; i++) {
 98             animation[i] = baseImage.split(i * frameWidth, 0, frameWidth,
 99                 baseImage.getHeight());
100         }
101 
102         return new AnimatedSprite(animation, delay, loop);
103     }
104 
105 }