Powered by PulpCore

TileMap.java  cursor.properties  cursor.png  Dirt Block.png  Grass Block.png  Water Block.png  Stone Block.png  Tree Tall.png 

// TileMap
// Shows a scrolling tile-map with click-to-move.
// Pixel-snapping is used to improve rendering speed of the map.
// Rendering speed can be further improved by using opaque tiles.
// Tile images from http://www.lostgarden.com/2007/05/dancs-miraculously-flexible-game.html
import pulpcore.animation.Easing;
import pulpcore.animation.Int;
import pulpcore.image.BlendMode;
import pulpcore.image.CoreGraphics;
import pulpcore.image.CoreImage;
import pulpcore.Input;
import pulpcore.scene.Scene2D;
import pulpcore.sprite.FilledSprite;
import pulpcore.sprite.Group;
import pulpcore.sprite.ImageSprite;
import pulpcore.sprite.Sprite;
import pulpcore.Stage;
import static pulpcore.image.Colors.*;

public class TileMap extends Scene2D {
    
    String[] tiles = {
        "Water Block.png",
        "Stone Block.png",
        "Grass Block.png",
        "Dirt Block.png",
    };
    
    String[] map = {
        "WWWWWWWWWWWWWWWWWWWWWWWWWWW",
        "WWWWWWWWWWWWWWWWWWWWWWWWWWW",
        "WSSSSSWWSSSSSSSSSSSSSSSSSWW",
        "WSGGGSWWSGGGGGGGGGGGGGGGSWW",
        "WSGGGSWWSSSSSSSGGSSSSSGGSWW",
        "WSGGGSWWWWWSDDSGGSDDDSGGSWW",
        "WSGGGSWWWWWSDDSGGSDDDSGGSWW",
        "WSGGGSWWWWWSDDSGGSDDDSGGSWW",
        "WSGGGSSSSSSSSSSGGSSSSSGGSWW",
        "WSGGGGGGGGGGGGGGGGGGGGGGSWW",
        "WSSSSSSSSSSSSSSSSSSSSSSSSWW",
        "WWWWWWWWWWWWWWWWWWWWWWWWWWW",
        "WWWWWWWWWWWWWWWWWWWWWWWWWWW",
    };
    
    TileMapSprite tileMap;
    ImageSprite cursor;
    Group mapSprites;
    
    @Override
    public void load() {
        // Add the background (sky-blue)
        add(new FilledSprite(rgb(185, 209, 255)));
        
        // Add the tileset
        tileMap = createTileMapSprite(tiles, map, 100, 80);
        add(tileMap);
        
        // Add some trees
        mapSprites = new Group();
        mapSprites.add(new ImageSprite("Tree Tall.png", 300, 280));
        mapSprites.add(new ImageSprite("Tree Tall.png", 1900, 440));
        mapSprites.x.bindTo(tileMap.viewX);
        mapSprites.y.bindTo(tileMap.viewY);
        add(mapSprites);
        
        // Add the cursor
        setCursor(Input.CURSOR_OFF);
        cursor = new ImageSprite("cursor.png", 0, 0);
        cursor.setBlendMode(BlendMode.Add());
        add(cursor);
    }
    
    @Override
    public void update(int elapsedTime) {
        cursor.setLocation(Input.getMouseX(), Input.getMouseY());
        
        // When scrolling, disable dirty rectangles and hide the cursor
        setDirtyRectanglesEnabled(!tileMap.isScrolling());
        cursor.visible.set(Input.isMouseInside() && !tileMap.isScrolling());

        // Click-to-scroll
        if (Input.isMousePressed()) {
            int x = Input.getMousePressX();
            int y = Input.getMousePressY();
            int goalX = tileMap.viewX.get() - (x - Stage.getWidth() / 2);
            int goalY = tileMap.viewY.get() - (y - Stage.getHeight() / 2);
            tileMap.viewX.animateTo(goalX, 500, Easing.REGULAR_OUT);
            tileMap.viewY.animateTo(goalY, 500, Easing.REGULAR_OUT);
        }
    }
    
    TileMapSprite createTileMapSprite(String[] tiles, String[] map, int tileWidth, int tileHeight) {
        // Load tile images
        CoreImage[] tileImages = new CoreImage[tiles.length];
        for (int i = 0; i < tiles.length; i++) {
            tileImages[i] = CoreImage.load(tiles[i]);
        }
        
        // Create the tile map
        int mapWidth = map[0].length();
        int mapHeight = map.length;
        CoreImage[][] tileMapImages = new CoreImage[mapWidth][mapHeight];
        for (int i = 0; i < mapWidth; i++) {
            for (int j = 0; j < mapHeight; j++) {
                
                // Convert the map char to the first letter of the tile name
                // i.e., 'W' = "Water Block.png"
                char ch = map[j].charAt(i);
                int index = 0;
                for (int k = 0; k < tiles.length; k++) {
                    if (tiles[k].charAt(0) == ch) {
                        index = k;
                        break;
                    }
                }
                tileMapImages[i][j] = tileImages[index];
            }
        }
        return new TileMapSprite(tileMapImages, tileWidth, tileHeight);
    }
    
    /**
        A simple tile map.
        Limitation: the maximum width and height of a TileMap 
        (i.e. tileWidth*numTilesAcross and tileHeight*numTilesDown) should be less than 32768.
    */
    static class TileMapSprite extends Sprite {
        
        private CoreImage[][] tileMap;
        private int tileWidth;
        private int tileHeight;
        private int numTilesAcross;
        private int numTilesDown;
        
        public final Int viewX = new Int(this);
        public final Int viewY = new Int(this);
        
        public TileMapSprite(CoreImage[][] tileMap, int tileWidth, int tileHeight) {
            super(0, 0, Stage.getWidth(), Stage.getHeight());
            this.tileMap = tileMap;
            this.tileWidth = tileWidth;
            this.tileHeight = tileHeight;
            numTilesAcross = tileMap.length;
            numTilesDown = tileMap[0].length;
        }
        
        public int getMapWidth() {
            return tileWidth * numTilesAcross;
        }
        
        public int getMapHeight() {
            return tileHeight * numTilesDown;
        }
        
        public boolean isScrolling() {
            return viewX.isAnimating() || viewY.isAnimating();
        }
        
        @Override 
        public void update(int elapsedTime) {
            super.update(elapsedTime);
            viewX.update(elapsedTime);
            viewY.update(elapsedTime);
        }
        
        @Override
        protected void drawSprite(CoreGraphics g) {
            int y = viewY.get();
            for (int j = 0; j < numTilesDown; j++) {
                int x = viewX.get();
                for (int i = 0; i < numTilesAcross; i++) {
                    g.drawImage(tileMap[i][j], x, y);
                    x += tileWidth;
                }
                y += tileHeight;
            }
        }
    }
}