예제 #1
0
파일: Map.java 프로젝트: AlanTR/solarus
  /**
   * Changes the position of an entity on the map, by specifying the coordinates of its origin
   * point.
   *
   * @param entity an entity
   * @param x x coordinate of the origin point
   * @param y y coordinate of the origin point
   * @throws MapException if the coordinates are not multiple of 8
   */
  public void setEntityPosition(MapEntity entity, int x, int y) throws MapException {
    entity.setPositionInMap(x, y);
    entity.updateImageDescription();

    setChanged();
    notifyObservers();
  }
예제 #2
0
파일: Map.java 프로젝트: AlanTR/solarus
  /**
   * Changes the position of a group of entities.
   *
   * @param entities the entities to move
   * @param dx number of pixels to move on x
   * @param dy number of pixels to move on y
   * @throws MapException if the coordinates of an entity are not multiple of 8
   */
  public void moveEntities(List<MapEntity> entities, int dx, int dy) throws MapException {

    for (MapEntity entity : entities) {
      entity.move(dx, dy);
    }

    setChanged();
    notifyObservers();
  }
예제 #3
0
파일: Map.java 프로젝트: AlanTR/solarus
  /**
   * Returns the highest layer where a specified rectangle overlaps an existing entity.
   *
   * @param rectangle a rectangle
   * @return the highest layer where an entity exists in this rectangle, or Layer.LOW if there is
   *     nothing here
   */
  public Layer getLayerInRectangle(Rectangle rectangle) {

    Layer[] layers = {Layer.HIGH, Layer.INTERMEDIATE, Layer.LOW};
    for (Layer layer : layers) {
      for (MapEntity entity : allEntities[layer.getId()]) {
        if (rectangle.intersects(entity.getPositionInMap())) {
          return layer;
        }
      }
    }
    return Layer.LOW;
  }
예제 #4
0
파일: Map.java 프로젝트: AlanTR/solarus
  /**
   * Changes the direction of an entity.
   *
   * @param entity the entity to change the direction
   * @param direction the new direction
   * @throws MapException if this entity has no direction
   */
  public void setEntityDirection(MapEntity entity, int direction) throws MapException {

    int oldDirection = entity.getDirection();

    if (direction != oldDirection) {

      entity.setDirection(direction);
      entity.updateImageDescription();

      setChanged();
      notifyObservers();
    }
  }
예제 #5
0
파일: Map.java 프로젝트: AlanTR/solarus
  /**
   * Returns the first entity under a point of the map, in the specified layer.
   *
   * @param layer the layer
   * @param x x of the point
   * @param y y of the point
   * @return the entity found, or null if there is no entity here
   */
  public MapEntity getEntityAt(Layer layer, int x, int y) {

    MapEntities entities = allEntities[layer.getId()];
    ListIterator<MapEntity> iterator = entities.listIterator(entities.size());
    while (iterator.hasPrevious()) {

      MapEntity entity = iterator.previous();
      if (entity.containsPoint(x, y)) {
        return entity;
      }
    }

    return null;
  }
예제 #6
0
파일: Map.java 프로젝트: AlanTR/solarus
  /**
   * Changes the layer of an entity. You should call this method instead of calling directly
   * MapEntity.setLayer(), because the entity of the 3 layers are stored in 3 different structures.
   * If the entity is not known by the map (yet), this method just calls MapEntity.setLayer().
   *
   * @param entity the entity to change the layer
   * @param layer the new layer
   */
  public void setEntityLayer(MapEntity entity, Layer layer) {

    Layer oldLayer = entity.getLayer();

    if (layer != oldLayer) {
      entity.setLayer(layer);

      if (allEntities[oldLayer.getId()].remove(entity)) {
        allEntities[layer.getId()].add(entity);
      }

      setChanged();
      notifyObservers();
    }
  }
예제 #7
0
파일: Map.java 프로젝트: AlanTR/solarus
  /**
   * Changes the position of an entity on the map, by specifying two points. The entity is resized
   * (i.e. repeatX and repeatY are updated) so that it fits exactly in the rectangle formed by the
   * two points.
   *
   * @param entity an entity
   * @param x1 x coordinate of the first point
   * @param y1 y coordinate of the first point
   * @param x2 x coordinate of the second point
   * @param y2 y coordinate of the second point
   * @throws MapException if the entity is not resizable of the rectangle width or its height is
   *     zero or the coordinates or the coordinates are not multiple of 8
   */
  public void setEntityPosition(MapEntity entity, int x1, int y1, int x2, int y2)
      throws MapException {
    entity.setPositionInMap(x1, y1, x2, y2);

    setChanged();
    notifyObservers();
  }
예제 #8
0
파일: Map.java 프로젝트: AlanTR/solarus
  /**
   * Removes an entity from the map.
   *
   * @param entity the entity to remove
   */
  public void removeEntity(MapEntity entity) {

    allEntities[entity.getLayer().getId()].remove(entity);

    setChanged();
    notifyObservers();
  }
예제 #9
0
파일: Map.java 프로젝트: AlanTR/solarus
  /**
   * Checks that the map is valid, i.e. that it can be played without risk.
   *
   * @throws MapException if the map is not valid (e.g. no tileset is selected, or some entities are
   *     not in a valid state).
   */
  public void checkValidity() throws MapException {

    // check that a tileset is selected
    if (tilesetId.length() == 0) {
      throw new MapException("No tileset is selected");
    }

    // check that all entities are valid
    for (MapEntities entities : allEntities) {
      for (MapEntity entity : entities) {
        if (!entity.isValid()) {
          throw new InvalidEntityException("The map contains an invalid entity.", entity);
        }
      }
    }
  }
예제 #10
0
파일: Map.java 프로젝트: AlanTR/solarus
  /**
   * Brings the specified entities to the front, keeping their layer. The order of the specified
   * entities in the map is unchanged.
   *
   * @param entities the entities to move
   */
  public void bringToFront(List<MapEntity> entities) {

    List<MapEntity> sortedEntities = getSortedEntities(entities);

    // bring to front each entity from sortedEntities
    ListIterator<MapEntity> iterator = sortedEntities.listIterator(0);
    while (iterator.hasNext()) {

      MapEntity entity = iterator.next();
      Layer layer = entity.getLayer();
      allEntities[layer.getId()].remove(entity);
      allEntities[layer.getId()].addLast(entity);
    }

    setChanged();
    notifyObservers();
  }
예제 #11
0
파일: Map.java 프로젝트: AlanTR/solarus
  /**
   * Brings the specified entities to the back, keeping their layer. The order of the specified
   * entities in the map is unchanged.
   *
   * @param entities the entities to move
   */
  public void bringToBack(List<MapEntity> entities) {

    List<MapEntity> sortedEntities = getSortedEntities(entities);

    // bring to back each entity from sortedEntities
    ListIterator<MapEntity> iterator = sortedEntities.listIterator(sortedEntities.size());
    while (iterator.hasPrevious()) {

      MapEntity entity = iterator.previous();
      Layer layer = entity.getLayer();
      allEntities[layer.getId()].remove(entity);
      allEntities[layer.getId()].addFirst(entity);
    }

    setChanged();
    notifyObservers();
  }
예제 #12
0
파일: Map.java 프로젝트: AlanTR/solarus
  /**
   * Changes the tileset of the map.
   *
   * @param tilesetId id of the new tileset, or an empty string to set no tileset
   * @return true if the tileset was loaded successfuly, false if some tiles could not be loaded in
   *     this tileset
   * @throws MapException if this tileset could be applied
   */
  public boolean setTileset(String tilesetId) throws ZSDXException {

    this.badTiles = false;

    // if the tileset is removed
    if (tilesetId.length() == 0 && this.tilesetId.length() != 0) {

      this.tilesetId = tilesetId;
      this.tileset = null;

      setChanged();
      notifyObservers();
    }

    // if the tileset is changed
    else if (!tilesetId.equals(this.tilesetId)) {

      this.tileset = new Tileset(tilesetId);

      for (Layer layer : Layer.values()) {

        LinkedList<MapEntity> entitiesToRemove = new LinkedList<MapEntity>();
        for (MapEntity entity : allEntities[layer.getId()]) {

          try {
            entity.setTileset(tileset);
          } catch (NoSuchTilePatternException ex) {
            // the entity is not valid anymore, we should remove it from the map
            entitiesToRemove.add(entity);
            badTiles = true;
          }
        }

        for (MapEntity entity : entitiesToRemove) {
          allEntities[layer.getId()].remove(entity);
        }
      }

      this.tilesetId = tilesetId;

      setChanged();
      notifyObservers(tileset);
    }

    return !badTiles;
  }
예제 #13
0
파일: Map.java 프로젝트: AlanTR/solarus
  /**
   * Returns the entities located in a rectangle defined by two points.
   *
   * @param x1 x coordinate of the first point
   * @param y1 y coordinate of the first point
   * @param x2 x coordinate of the second point
   * @param y2 y coordinate of the second point
   */
  public List<MapEntity> getEntitiesInRectangle(int x1, int y1, int x2, int y2) {

    List<MapEntity> entitiesInRectangle = new LinkedList<MapEntity>();

    int x = Math.min(x1, x2);
    int width = Math.abs(x2 - x1);

    int y = Math.min(y1, y2);
    int height = Math.abs(y2 - y1);

    Rectangle rectangle = new Rectangle(x, y, width, height);

    for (Layer layer : Layer.values()) {

      for (MapEntity entity : allEntities[layer.getId()]) {
        if (rectangle.contains(entity.getPositionInMap())) {
          entitiesInRectangle.add(entity);
        }
      }
    }

    return entitiesInRectangle;
  }
예제 #14
0
파일: Map.java 프로젝트: AlanTR/solarus
  /**
   * Changes the size of an entity on the map.
   *
   * @param entity an entity
   * @param width the new width
   * @param height the new height
   * @throws MapException if the entity is not resizable or the size specified is lower than or
   *     equal to zero or the size specified is not divisible by 8
   */
  public void setEntitySize(MapEntity entity, int width, int height) throws MapException {
    entity.setSize(width, height);

    setChanged();
    notifyObservers();
  }
예제 #15
0
파일: Map.java 프로젝트: AlanTR/solarus
  /**
   * Changes the position of an entity on the map, by specifying its rectangle. The entity is
   * resized so that it fits exactly in the rectangle.
   *
   * @param entity an entity
   * @param position a rectangle
   * @throws MapException if the entity is not resizable of the rectangle width or its height is
   *     zero
   */
  public void setEntityPosition(MapEntity entity, Rectangle position) throws MapException {
    entity.setPositionInMap(position);

    setChanged();
    notifyObservers();
  }
예제 #16
0
파일: Map.java 프로젝트: AlanTR/solarus
  /**
   * Loads the map from its file.
   *
   * @throws ZSDXException if the file could not be read
   */
  public void load() throws ZSDXException {

    int lineNumber = 0;
    try {

      // get the map name in the game resource database
      Resource mapResource = Project.getResource(ResourceType.MAP);
      setName(mapResource.getElementName(mapId));

      File mapFile = Project.getMapFile(mapId);
      BufferedReader in = new BufferedReader(new FileReader(mapFile));

      // read the map general info
      // syntax: width height world floor x y small_keys_variable tileset_id music_id
      String line = in.readLine();

      if (line == null) {
        throw new ZSDXException("The map file is empty");
      }

      lineNumber++;
      StringTokenizer tokenizer = new StringTokenizer(line);

      int width = Integer.parseInt(tokenizer.nextToken());
      int height = Integer.parseInt(tokenizer.nextToken());
      setSize(new Dimension(width, height));

      setWorld(Integer.parseInt(tokenizer.nextToken()));
      setFloor(Integer.parseInt(tokenizer.nextToken()));

      int x = Integer.parseInt(tokenizer.nextToken());
      int y = Integer.parseInt(tokenizer.nextToken());
      setLocation(new Point(x, y));

      setSmallKeysVariable(Integer.parseInt(tokenizer.nextToken()));
      setTileset(tokenizer.nextToken());
      setMusic(tokenizer.nextToken());

      // read the map entities
      line = in.readLine();
      while (line != null) {
        lineNumber++;

        try {
          MapEntity entity = MapEntity.createFromString(this, line);
          addEntity(entity);
        } catch (NoSuchTilePatternException ex) {
          badTiles = true;
        }
        line = in.readLine();
      }

      in.close();

      history.setSaved();
    } catch (NumberFormatException ex) {
      throw new ZSDXException("Line " + lineNumber + ": Integer expected");
    } catch (IndexOutOfBoundsException ex) {
      throw new ZSDXException("Line " + lineNumber + ": Value expected");
    } catch (ZSDXException ex) {
      throw new ZSDXException("Line " + lineNumber + ": " + ex.getMessage());
    } catch (IOException ex) {
      throw new ZSDXException(ex.getMessage());
    }

    setChanged();
    notifyObservers();
  }
예제 #17
0
파일: Map.java 프로젝트: AlanTR/solarus
  /**
   * Saves the map into its file.
   *
   * @throws ZSDXException if the file could not be written for various reasons
   */
  public void save() throws ZSDXException {

    // check that the map is valid
    checkValidity();

    try {

      // open the map file
      File mapFile = Project.getMapFile(mapId);
      PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(mapFile)));

      // print the map general info
      // syntax: width height world floor x y small_keys_variable tileset_id music_id
      out.print(size.width);
      out.print('\t');
      out.print(size.height);
      out.print('\t');
      out.print(world);
      out.print('\t');
      out.print(floor);
      out.print('\t');
      out.print(location.x);
      out.print('\t');
      out.print(location.y);
      out.print('\t');
      out.print(smallKeysVariable);
      out.print('\t');
      out.print(tilesetId);
      out.print('\t');
      out.print(musicId);
      out.println();

      for (Layer layer : Layer.values()) {

        MapEntities entities = allEntities[layer.getId()];

        // print the entities
        for (MapEntity entity : entities) {
          out.print(entity.toString());
          out.println();
        }
      }

      out.close();

      history.setSaved();

      // also update the map name in the global resource list
      Resource mapResource = Project.getResource(ResourceType.MAP);
      mapResource.setElementName(mapId, name);
      Project.getResourceDatabase().save();

      // upate the dungeon elements of this map
      if (isInDungeon()) {
        Dungeon.saveMapInfo(this);
      }

      // create a script for the map if necessary
      File scriptFile = Project.getMapScriptFile(mapId);
      if (!scriptFile.exists()) {
        scriptFile.createNewFile();
      }
    } catch (IOException ex) {
      throw new MapException(ex.getMessage());
    }
  }