Package com.hobbitsadventure.io

Source Code of com.hobbitsadventure.io.MapReader

package com.hobbitsadventure.io;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import com.hobbitsadventure.model.NonPlayerCharacter;
import com.hobbitsadventure.model.RealmCell;
import com.hobbitsadventure.model.RealmMap;
import com.hobbitsadventure.model.Thing;
import com.hobbitsadventure.model.Tile;
import com.hobbitsadventure.model.TileClass;
import com.hobbitsadventure.model.factory.NpcClasses;
import com.hobbitsadventure.model.factory.Things;
import com.hobbitsadventure.model.factory.TileClasses;

/**
* @author Willie Wheeler (willie.wheeler@gmail.com)
*/
public class MapReader {
  private Random random = new Random();
 
  public RealmMap read(String mapId) throws IOException {
    List<RealmCell[]> rowList = new ArrayList<RealmCell[]>();
    InputStream is = ClassLoader.getSystemResourceAsStream("maps/" + mapId + ".txt");
    BufferedReader br = new BufferedReader(new InputStreamReader(is));
    String rowStr;
    while ((rowStr = br.readLine()) != null) {
      int numCols = rowStr.length();
      RealmCell[] row = new RealmCell[numCols];
      for (int j = 0; j < numCols; j++) {
        TileClass tileClass = null;
        Thing thing = null;
        int heightNoise = 0;
       
        char ch = rowStr.charAt(j);
        switch (ch) {
        case '.':
          tileClass = TileClasses.BEACH;
          heightNoise = random.nextInt(2);
          break;
        case '@':
          tileClass = TileClasses.FLOOR_STONE;
          thing = Things.BLUE_GEM;
          break;
        case '$':
          tileClass = TileClasses.FLOOR_STONE;
          thing = Things.CHEST;
          break;
        case '%':
          tileClass = TileClasses.FLOOR_STONE;
          thing = Things.CHEST_OPEN;
          break;
        case ':':
          tileClass = TileClasses.GRASS;
          thing = Things.BRUSH;
          heightNoise = random.nextInt(2);
          break;
        case '#':
          tileClass = TileClasses.WATER;
          thing = Things.DOCK;
          break;
        case '[':
          tileClass = TileClasses.FLOOR_STONE;
          thing = Things.DOOR_CLOSED;
          break;
        case '`':
          tileClass = TileClasses.FLOOR_STONE;
          break;
        case '\'':
          tileClass = TileClasses.FLOOR_WOOD;
          break;
        case '!':
          tileClass = TileClasses.GRASS;
          thing = Things.TREE_TALL;
          heightNoise = random.nextInt(2);
          break;
        case ',':
          tileClass = TileClasses.GRASS;
          heightNoise = random.nextInt(2);
          break;
        case '^':
          tileClass = TileClasses.HILL;
          heightNoise = random.nextInt(2);
          break;
        case 'A':
          tileClass = TileClasses.GRASS;
          thing = Things.ROCK;
          heightNoise = random.nextInt(2);
          break;
        case '_':
          tileClass = TileClasses.ROAD;
          break;
        case 'D':
          tileClass = TileClasses.STAIRS_DOWN;
          break;
        case 'U':
          tileClass = TileClasses.STAIRS_UP;
          break;
        case '*':
          tileClass = TileClasses.GRASS;
          thing = Things.DOOR_CLOSED;
          break;
        case '=':
          // FIXME Need to be able to null this tile instead of rendering two images? Unless the objects are
          // going to be dynamic (e.g. player can build and/or destroy walls).
          tileClass = TileClasses.FLOOR_STONE;
          thing = Things.WALL_TALL;
          break;
        case '~':
          tileClass = TileClasses.WATER;
          break;
        default:
          throw new RuntimeException("Illegal map character: " + ch)
        }
       
        RealmCell cell = new RealmCell();
        cell.setTile(new Tile(tileClass, tileClass.getYOffset() + heightNoise));
        cell.setThing(thing);
        row[j] = cell;
      }
     
      rowList.add(row);
    }
   
    int numRows = rowList.size();
    int numCols = rowList.get(0).length;
    RealmMap realmMap = new RealmMap(numRows, numCols);
    for (int i = 0; i < numRows; i++) {
      for (int j = 0; j < numCols; j++) {
        RealmCell cell = rowList.get(i)[j];
        realmMap.setCell(i, j, cell);
       
        // Add a little more interest to the height map. This is just temporary.
//        double distance = Math.sqrt(((30 - i) * (30 - i)) + ((30 - j) * (30 - j)));
//        int offset = (int) Math.min(distance - 20.0, 0) * 5;
//        Tile tile = cell.getTile();
//        tile.setHeight(tile.getHeight() + offset);
      }
    }
   
   
    // FIXME Not sure we should re-read all the NPCs when reloading the map. Maybe they should have an existence
    // outside the map. Also the NPCs need to maintain their own positions as well (for movement), and updates need
    // to be synchronized with the object map. Maybe there is a better way to do it but that's what I have in mind
    // for now.
    realmMap.setCharacter(30, 25, new NonPlayerCharacter(NpcClasses.BUG));
    realmMap.setCharacter(28, 22, new NonPlayerCharacter(NpcClasses.PRINCESS));
    realmMap.setCharacter(10, 10, new NonPlayerCharacter(NpcClasses.CAT_GIRL));
    realmMap.setCharacter(20, 20, new NonPlayerCharacter(NpcClasses.HORN_GIRL));
    realmMap.setCharacter(40, 40, new NonPlayerCharacter(NpcClasses.PINK_GIRL));
   
    return realmMap;
  }
}
TOP

Related Classes of com.hobbitsadventure.io.MapReader

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.