Package cz.cuni.mff.abacs.burglar.visual.play_state

Source Code of cz.cuni.mff.abacs.burglar.visual.play_state.GraphicPlayState

/**
*
*/
package cz.cuni.mff.abacs.burglar.visual.play_state;

import cz.cuni.mff.abacs.burglar.logics.GameMap;
import cz.cuni.mff.abacs.burglar.logics.objects.BaseInterface;
import cz.cuni.mff.abacs.burglar.logics.objects.agents.Agent;
import cz.cuni.mff.abacs.burglar.logics.objects.agents.BeliefBase;
import cz.cuni.mff.abacs.burglar.logics.objects.agents.Burglar;
import cz.cuni.mff.abacs.burglar.logics.objects.agents.Guard;
import cz.cuni.mff.abacs.burglar.logics.objects.positions.*;
import cz.cuni.mff.abacs.burglar.logics.planning.instructions.Instruction;
import cz.cuni.mff.abacs.burglar.visual.VisualBurglar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.newdawn.slick.*;
import org.newdawn.slick.geom.Polygon;
import org.newdawn.slick.geom.Shape;
import org.newdawn.slick.state.StateBasedGame;


/**
* Contains the graphics representation of the {@link PlayState}.
*
* @author abacs
*
*/
public class GraphicPlayState extends InterfacedPlayState {
  // constants:
 
 
  private static int SCALE = 1;
 
  /** Filter representing well known objects. */
  private static Color COLOR_FILTER_KNOWN = Color.white;
  /** Filter representing not known objects. */
  private static Color COLOR_FILTER_UNKNOWN = Color.darkGray;
  /** Filter representing objects that are different than the agent thinks it is. */
  private static Color COLOR_FILTER_MISTAKEN = Color.lightGray;
 
 
  // -------------------------------------------------------------------------
  // properties:
 
 
  private Image _imgBurglar = null;
  private Image _imgBurglarDisguised = null;
 
  private Image _imgGuard = null;
  private Image _imgGuardNaked = null;
  private Image _imgGuardDead = null;
 
  private Image _imgContainerClosed = null;
  private Image _imgContainerOpened = null;
  private Image _imgContainerLocked = null;
  private Image _imgDoorClosed = null;
  private Image _imgDoorOpened = null;
  private Image _imgDoorLocked = null;
  private Image _imgFloor = null;
  private Image _imgPhone = null;
  private Image _imgCameraOn = null;
  private Image _imgCameraOff = null;
  private Image _imgSelection = null;
  private Image _imgSwitchOff = null;
  private Image _imgSwitchOn = null;
  private Image _imgVenderOff = null;
  private Image _imgVenderOn = null;
  private Image _imgWall = null;
 
 
  // -------------------------------------------------------------------------
  // constructors:
 
 
  /**
   *
   *
   * @param stateID
   * @throws SlickException
   */
  public GraphicPlayState(int stateID)
      throws SlickException {
    super(stateID);
  }
 
 
  // -------------------------------------------------------------------------
 
 
  /**
   * Initialize any needed data before the game loop.
   *
   * @param container
   * @param game
   */
  @Override
  public void init(GameContainer container, StateBasedGame game)
      throws SlickException {
    super.init(container, game);
   
    this._imgBurglar = new Image(VisualBurglar.PATH_IMAGES + "burglar.gif");
    this._imgBurglarDisguised =
        new Image(VisualBurglar.PATH_IMAGES + "burglar_disguised.gif");
   
    this._imgGuard = new Image(VisualBurglar.PATH_IMAGES + "guard.gif");
    this._imgGuardNaked =
        new Image(VisualBurglar.PATH_IMAGES + "guard_naked.gif");
    this._imgGuardDead =
        new Image(VisualBurglar.PATH_IMAGES + "guard_dead.gif");
   
    this._imgContainerClosed = new Image(VisualBurglar.PATH_IMAGES + "container_closed.png");
    this._imgContainerLocked = new Image(VisualBurglar.PATH_IMAGES + "container_locked.png");
    this._imgContainerOpened = new Image(VisualBurglar.PATH_IMAGES + "container_opened.png");
    this._imgDoorClosed = new Image(VisualBurglar.PATH_IMAGES + "door_closed.gif");
    this._imgDoorOpened = new Image(VisualBurglar.PATH_IMAGES + "door_opened.png");
    this._imgDoorLocked = new Image(VisualBurglar.PATH_IMAGES + "door_locked.gif");
    this._imgFloor = new Image(VisualBurglar.PATH_IMAGES + "floor.gif");
    this._imgPhone = new Image(VisualBurglar.PATH_IMAGES + "phone.gif");
    this._imgCameraOn = new Image(VisualBurglar.PATH_IMAGES + "camera_on.gif");
    this._imgCameraOff = new Image(VisualBurglar.PATH_IMAGES + "camera_off.gif");
    this._imgSelection = new Image(VisualBurglar.PATH_IMAGES + "selection.gif");
    this._imgSwitchOff = new Image(VisualBurglar.PATH_IMAGES + "switch_off.gif");
    this._imgSwitchOn = new Image(VisualBurglar.PATH_IMAGES + "switch_on.gif");
    this._imgVenderOff = new Image(VisualBurglar.PATH_IMAGES + "vender_off.gif");
    this._imgVenderOn = new Image(VisualBurglar.PATH_IMAGES + "vender_on.gif");
    this._imgWall = new Image(VisualBurglar.PATH_IMAGES + "wall.gif");
  }
 
 
  /**
   *  Allows to draw the world.
   * 
   *  @param container
   *  @param game
   *  @param graphics
   *  @throws SlickException
   */
  @Override
  public void render(
      GameContainer container,
      StateBasedGame game,
      Graphics graphics
  ) throws SlickException {
    try{
      // draw the map:
      this.drawMap(graphics);
      // selection:
      this.drawSelection();
    }catch(Exception e){
      // invalid game map
      System.err.println(e.toString());
    }
    super.render(container, game, graphics);
  }
 
 
  // -------------------------------------------------------------------------
 
 
  /**
   * Draws the whole map area.
   *
   * @param graphics
   */
  private void drawMap(Graphics graphics) {
    // draw wall:
    if(VisualBurglar.FLAG_SOLID_BACKGROUND == false){
      for(int x = 0; x < this._screen._width; x++){
        for(int y = 0; y < this._screen._height; y++){
          this._imgWall.draw(
              x * VisualBurglar.RESOURCE_BLOCK_SIZE,
              y * VisualBurglar.RESOURCE_BLOCK_SIZE,
              GraphicPlayState.SCALE
          );
        }
      }
    }else{
      graphics.setBackground(new org.newdawn.slick.Color(200,200,200));
    }
   
   
   
    if(this._map == null)
      return;
   
    List<Integer> trapRoomIds = this._map.getTrapRoomIds();
   
    // draw all the positions:
    for(Position pos : this._map.getPositions())
      this.drawPosition(pos, this._player.getSelectedAgent(), trapRoomIds, graphics);
   
    // TODO remove drawing duplication
   
    for(Position pos : this._map.getOperablePositions())
      this.drawPosition(pos, this._player.getSelectedAgent(), trapRoomIds, graphics);
   
    // draw the intent line:
    this.drawIntent(
        this._player.getSelectedAgent(),
        this._player.getIntentDistance(),
        // TODO temporal color change
        org.newdawn.slick.Color.black,//org.newdawn.slick.Color.red,
        graphics
    );
   
    for(Agent agent : this._map.getAgents())
      this.drawAgent(agent, this._player.getSelectedAgent());
  }
 
 
  /**
   *
   *
   * @param position
   * @param viewingAgent
   * @return
   */
  private static Color setColorFilter(Position position, Agent viewingAgent) {
    if(viewingAgent == null)
      return COLOR_FILTER_KNOWN;
   
    if(viewingAgent.getBeliefBase().isKnownPosition(position) == false)
      return COLOR_FILTER_UNKNOWN;
   
    if(viewingAgent.getBeliefBase().matches(position))
      return COLOR_FILTER_KNOWN;
    else
      return COLOR_FILTER_MISTAKEN;
  }
 
 
  /**
   * Sets the color filter based on the viewingAgent's knowledge.
   */
  private static Color setColorFilter(Agent agent, Agent viewingAgent) {
    if(viewingAgent == null || viewingAgent == agent)
      return COLOR_FILTER_KNOWN;
   
    if(viewingAgent.getBeliefBase().isKnownAgent(agent) == false)
      return COLOR_FILTER_UNKNOWN;
   
    if(viewingAgent.getBeliefBase().matches(agent))
      return COLOR_FILTER_KNOWN;
    else
      return COLOR_FILTER_MISTAKEN;
  }
 
 
 
  private boolean shouldDraw(Position position) {
    if(! this.isInScreen(position))
      return false;
   
    if(VisualBurglar.FLAG_PLAYER_CONTROL_MODE){
      BeliefBase beliefs = this._map.getBurglar().getBeliefBase();
     
     
     
    //  if(position.isTypeOf(BaseInterface.Type.DOOR)){
    //    int[] rooms = ((Door)position).getRoomIds();
    //    if(beliefs.isKnownRoom(rooms[0]) && beliefs.isKnownRoom(rooms[1]))
    //      return true;
    //  }else{
        if(beliefs.isKnownRoom(position.getRoomId()) || beliefs.isKnownPosition(position))
          return true;
    //  }
      return false;
    }
   
    return true;
  }
 
 
  /**
   * Non-filtered means the burglar knows the position perfectly.
   *
   * Light grey filter means the burglar knows the position,
   * but misses some detail.
   * Dark grey filter means the burglar does not know the position at all.
   *
   * @param position the position to draw
   * @param viewingAgent the agent that's belief base is visualized
   * @param trapRoomIds rooms that are observed by the guards
   * @param graphics
   */
  private void drawPosition(
      Position position,
      Agent viewingAgent,
      List<Integer> trapRoomIds,
      Graphics graphics
  ) {
    if(VisualBurglar.FLAG_PLAYER_CONTROL_MODE){
      this.drawRememberedPosition(position, viewingAgent, trapRoomIds, graphics);
    }else{
      this.drawObjectivePosition(position, viewingAgent, trapRoomIds, graphics);
    }
   
  }
 
  /**
   * Non-filtered means the burglar knows the position perfectly.
   *
   * Light grey filter means the burglar knows the position,
   * but misses some detail.
   * Dark grey filter means the burglar does not know the position at all.
   *
   * @param position the position to draw
   * @param viewingAgent the agent that's belief base is visualized
   * @param trapRoomIds rooms that are observed by the guards
   * @param graphics
   */
  private void drawObjectivePosition(
      Position position,
      Agent viewingAgent,
      List<Integer> trapRoomIds,
      Graphics graphics
  ) {
   
    if(this.shouldDraw(position) == false)
      return;
   
    int x = this._screen.mapXToScreenX(position.getX());
    int y = this._screen.mapYToScreenY(position.getY());
   
    // the filter indicates the whether
    // the burglar agent knows the position
    Color filter = setColorFilter(position, viewingAgent);
   
   
    // draws a default floor background
    if(trapRoomIds.contains(position.getRoomId())){
      if(VisualBurglar.FLAG_SOLID_BACKGROUND == false){
        this._imgFloor.draw(x, y, GraphicPlayState.SCALE);
      }else{
        graphics.setColor(new Color(255, 255, 102));
        graphics.fillRect(
            x, y,
            VisualBurglar.RESOURCE_BLOCK_SIZE * GraphicPlayState.SCALE,
            VisualBurglar.RESOURCE_BLOCK_SIZE * GraphicPlayState.SCALE
        );
      }
    }else{
      if(VisualBurglar.FLAG_SOLID_BACKGROUND == false){
        this._imgFloor.draw(x, y, GraphicPlayState.SCALE, COLOR_FILTER_MISTAKEN);
      }else{
        graphics.setColor(COLOR_FILTER_MISTAKEN);
        graphics.fillRect(
            x, y,
            VisualBurglar.RESOURCE_BLOCK_SIZE * GraphicPlayState.SCALE,
            VisualBurglar.RESOURCE_BLOCK_SIZE * GraphicPlayState.SCALE
        );
      }
    }
   
    switch(position.getType()){
    case CAMERA:
      if(((Camera)position).isActive()){
        this._imgCameraOn.draw(x, y, GraphicPlayState.SCALE, filter);
      }else{
        this._imgCameraOff.draw(x, y, GraphicPlayState.SCALE, filter);
      }
      break;
    case CONTAINER:
      if(((Container)position).isClosed()){
        if(((Container)position).isLocked()){
          this._imgContainerLocked.draw(x, y, GraphicPlayState.SCALE, filter);
        }else{
          this._imgContainerClosed.draw(x, y, GraphicPlayState.SCALE, filter);
        }
      }else{
        this._imgContainerOpened.draw(x, y, GraphicPlayState.SCALE, filter);
      }
      break;
    case DOOR:
     
      if(((Door)position).isClosed()){
        if(((Door)position).isLocked())
          this._imgDoorLocked.draw(x, y - 16, GraphicPlayState.SCALE, filter);
        else
          this._imgDoorClosed.draw(x, y - 16, GraphicPlayState.SCALE, filter);
      }else{
        this._imgDoorOpened.draw(x, y - 16, GraphicPlayState.SCALE, filter);
      }
      break;
    case FLOOR:
      // floor background already drawn
      break;
    case PHONE:
      this._imgPhone.draw(x, y, GraphicPlayState.SCALE, filter);
      break;
    case SWITCH:
      if(((Switch)position).isActive())
        this._imgSwitchOn.draw(x, y, GraphicPlayState.SCALE, filter);
      else
        this._imgSwitchOff.draw(x, y, GraphicPlayState.SCALE, filter);
      break;
    case VENDER:
      if(((Vender)position).hasDropped())
        this._imgVenderOn.draw(x, y - 16, GraphicPlayState.SCALE, filter);
      else
        this._imgVenderOff.draw(x, y - 16, GraphicPlayState.SCALE, filter);
      break;
    default:
     
    }
  }
 
 
  /**
   * Non-filtered means the burglar knows the position perfectly.
   *
   * Light grey filter means the burglar knows the position,
   * but misses some detail.
   * Dark grey filter means the burglar does not know the position at all.
   *
   * @param position the position to draw
   * @param viewingAgent the agent that's belief base is visualized
   * @param trapRoomIds rooms that are observed by the guards
   * @param graphics
   */
  private void drawRememberedPosition(
      Position position,
      Agent viewingAgent,
      List<Integer> trapRoomIds,
      Graphics graphics
  ) {
    if(this.shouldDraw(position) == false)
      return;
   
    int x = this._screen.mapXToScreenX(position.getX());
    int y = this._screen.mapYToScreenY(position.getY());
   
   
    BeliefBase burglarBeliefs = this._map.getBurglar().getBeliefBase();
   
    boolean observedRoom = burglarBeliefs.isObservedRoom(position.getRoomId());
   
    if(observedRoom){
      if(VisualBurglar.FLAG_SOLID_BACKGROUND == false){
        this._imgFloor.draw(x, y, GraphicPlayState.SCALE);
      }else{
        graphics.setColor(new Color(255, 255, 102));
        graphics.fillRect(
            x, y,
            VisualBurglar.RESOURCE_BLOCK_SIZE * GraphicPlayState.SCALE,
            VisualBurglar.RESOURCE_BLOCK_SIZE * GraphicPlayState.SCALE
        );
      }
    }else{
      if(VisualBurglar.FLAG_SOLID_BACKGROUND == false){
        this._imgFloor.draw(x, y, GraphicPlayState.SCALE, COLOR_FILTER_MISTAKEN);
      }else{
        graphics.setColor(COLOR_FILTER_MISTAKEN);
        graphics.fillRect(
            x, y,
            VisualBurglar.RESOURCE_BLOCK_SIZE * GraphicPlayState.SCALE,
            VisualBurglar.RESOURCE_BLOCK_SIZE * GraphicPlayState.SCALE
        );
      }
    }
   
    if(position.isTypeOf(BaseInterface.Type.FLOOR))
      return;
   
    if(burglarBeliefs.isKnownPosition(position))
      position = burglarBeliefs.getKnownPosition(position.getId());
    Color filter = COLOR_FILTER_KNOWN;
   
    switch(position.getType()){
    case CAMERA:
      if(((Camera)position).isActive()){
        this._imgCameraOn.draw(x, y, GraphicPlayState.SCALE, filter);
      }else{
        this._imgCameraOff.draw(x, y, GraphicPlayState.SCALE, filter);
      }
      break;
    case CONTAINER:
      if(((Container)position).isClosed()){
        if(((Container)position).isLocked()){
          this._imgContainerLocked.draw(x, y, GraphicPlayState.SCALE, filter);
        }else{
          this._imgContainerClosed.draw(x, y, GraphicPlayState.SCALE, filter);
        }
      }else{
        this._imgContainerOpened.draw(x, y, GraphicPlayState.SCALE, filter);
      }
      break;
    case DOOR:
     
      if(((Door)position).isClosed()){
        if(((Door)position).isLocked())
          this._imgDoorLocked.draw(x, y - 16, GraphicPlayState.SCALE, filter);
        else
          this._imgDoorClosed.draw(x, y - 16, GraphicPlayState.SCALE, filter);
      }else{
        this._imgDoorOpened.draw(x, y - 16, GraphicPlayState.SCALE, filter);
      }
      break;
    case FLOOR:
      // floor background already drawn
      break;
    case PHONE:
      this._imgPhone.draw(x, y, GraphicPlayState.SCALE, filter);
      break;
    case SWITCH:
      if(((Switch)position).isActive())
        this._imgSwitchOn.draw(x, y, GraphicPlayState.SCALE, filter);
      else
        this._imgSwitchOff.draw(x, y, GraphicPlayState.SCALE, filter);
      break;
    case VENDER:
      if(((Vender)position).hasDropped())
        this._imgVenderOn.draw(x, y - 16, GraphicPlayState.SCALE, filter);
      else
        this._imgVenderOff.draw(x, y - 16, GraphicPlayState.SCALE, filter);
      break;
    default:
     
    }
  }
 
 
  /**
   * Draws a single agent with possible filters.
   *
   * @param agent
   * @param viewingAgent the agent that's belief base is visualized
   */
  private void drawAgent(Agent agent, Agent viewingAgent) {
   
    switch(agent.getType()){
    case BURGLAR:
      this.drawBurglar((Burglar)agent, viewingAgent);
      break;
    case DOG:
      // TODO dog
      break;
    case GUARD:
      this.drawGuard((Guard)agent, viewingAgent);
      break;
    default:
    }
  }
 
 
  /**
   * Draws a burglar agent.
   *
   * @param agent burglar agent
   * @param viewingAgent the agent that's belief base is visualized
   */
  private void drawBurglar(Burglar agent, Agent viewingAgent) {
    Position position = agent.getPosition();
    if(! this.isInScreen(position))
      return;
   
    int x = this._screen.mapXToScreenX(position.getX());
    int y = this._screen.mapYToScreenY(position.getY());
   
    Color filter = GraphicPlayState.setColorFilter(agent, viewingAgent);
   
    if(agent.isDisguised()){
      this._imgBurglarDisguised.draw(x, y - 16, GraphicPlayState.SCALE, filter);
    }else{
      this._imgBurglar.draw(x, y - 16, GraphicPlayState.SCALE, filter);
    }
  }
 
 
  /**
   * Draws a guard agent.
   *
   * @param agent
   * @param viewingAgent the agent that's belief base is visualized
   */
  private void drawGuard(Guard agent, Agent viewingAgent) {
    Position position = agent.getPosition();
    if(! this.isInScreen(position))
      return;
   
    if(VisualBurglar.FLAG_PLAYER_CONTROL_MODE){
      if(this._map.getBurglar().getBeliefBase().isKnownAgent(agent) == false){
        return;
      }
    }
   
    int x = this._screen.mapXToScreenX(position.getX());
    int y = this._screen.mapYToScreenY(position.getY());
   
    Color filter = GraphicPlayState.setColorFilter(agent, viewingAgent);
   
    switch(agent.getState()){
      case WELL:
        this._imgGuard.draw(x, y - 16, GraphicPlayState.SCALE, filter);
        break;
      case STUNNED:
        if(agent.hasItemOfType(BaseInterface.Type.UNIFORM)){
          this._imgGuardDead.draw(x - 4, y, GraphicPlayState.SCALE, filter);
        }else{
          this._imgGuardNaked.draw(x - 4, y, GraphicPlayState.SCALE, filter);
        }
        break;
    }
  }
 
 
  /**
   * Agent intent line to draw.
   *
   * @param agent
   * @param distance number of steps to show. if less than 0, shows all of them.
   * @param lineColor
   * @param graphics
   */
  private void drawIntent(
      Agent agent,
      int distance,
      Color lineColor,
      Graphics graphics
  ) {
    if(agent == null)
      return;
   
    Position agentPos = agent.getPosition();
   
    Map<Position, String> stringsByPosition = new HashMap<Position, String>();
   
    int counter = 0;
    for(Instruction instruction : agent.getInstructions()){
     
      if(counter++ == distance)
        break;
     
      graphics.setColor(lineColor);
     
      Position subjectPos = this._map.getPosition(instruction._subjectId);
     
      switch(instruction._code){
      case MOVE:
        this.drawIntentMovement(agentPos, subjectPos, graphics);
        agentPos = subjectPos;
        break;
      case OPEN:
        this.appendToIntentString(stringsByPosition, subjectPos, STR_OPEN);
        break;
      case CLOSE:
        this.appendToIntentString(stringsByPosition, subjectPos, STR_CLOSE);
        break;
      case UNLOCK:
        this.appendToIntentString(stringsByPosition, subjectPos, STR_UNLOCK);
        break;
      case LOCK:
        this.appendToIntentString(stringsByPosition, subjectPos, STR_LOCK);
        break;
      case PICK_UP:
        this.appendToIntentString(stringsByPosition, subjectPos, STR_PICK_UP);
        break;
      case TAKE_CLOTHES:
        this.appendToIntentString(stringsByPosition, subjectPos, STR_TAKE_UNIFORM);
        break;
      case USE:
        this.appendToIntentString(stringsByPosition, subjectPos, STR_USE);
      default:
      }
    }
   
    // draw all strings gathered by positions:
    for(Entry<Position, String> entry : stringsByPosition.entrySet()){
      this.drawIntentStr(entry.getValue(), entry.getKey(), graphics);
    }
  }
 
 
  private void appendToIntentString(
      Map<Position, String> stringsByPosition,
      Position position,
      String toAppend
  ) {
    if(stringsByPosition.containsKey(position)){
      String newString = stringsByPosition.get(position) + ", " + toAppend;
      stringsByPosition.put(position, newString);
    }else{
      stringsByPosition.put(position, toAppend);
    }
  }
 
 
  /**
   * Draws an intent string to a selected position.
   *
   * Uses the previously selected line color.
   *
   * @param text
   * @param pos game position to draw the text
   * @param graphics
   */
  private void drawIntentStr(String text, Position pos, Graphics graphics) {
   
    if(this.isInScreen(pos)){
      int x = this._screen.mapXToScreenX(pos.getX());
      int y = this._screen.mapYToScreenY(pos.getY());
      graphics.drawString(text, x, y);
    }
  }
 
 
  /**
   * Draws movement intent from one position to another.
   *
   * @param agentPos
   * @param aimPos
   * @param graphics
   */
  private void drawIntentMovement( Position agentPos, Position aimPos, Graphics graphics) {
    if(
      this.isInScreen(agentPos) &&
      this.isInScreen(aimPos)
    ){
      int blockSize = VisualBurglar.RESOURCE_BLOCK_SIZE;
     
      int deltaX = blockSize / 2;
      int deltaY = blockSize / 2;
     
      int x1 = this._screen.mapXToScreenX(agentPos.getX()) + deltaX;
      int y1 = this._screen.mapYToScreenY(agentPos.getY()) + deltaY;
      int x2 = this._screen.mapXToScreenX(aimPos.getX()) + deltaX;
      int y2 = this._screen.mapYToScreenY(aimPos.getY()) + deltaY;
     
      int circleSize = blockSize / 8;
      graphics.drawOval(
          x2 - circleSize,
          y2 - circleSize,
          circleSize * 2,
          circleSize * 2
      );
     
      deltaX += circleSize;
      deltaY += circleSize;
     
      switch(this._map.getDirection(agentPos, aimPos)){
        case SOUTH_EAST:
          drawArrow(
              x1 + deltaX,
              y1 + deltaY,
              circleSize,
              GameMap.Direction.SOUTH_EAST,
              graphics
          );
          break;
        case EAST:
          drawArrow(
              x1 + deltaX,
              y1,
              circleSize,
              GameMap.Direction.EAST,
              graphics
          );
          break;
        case NORTH_EAST:
          drawArrow(
              x1 + deltaX,
              y1 - deltaY,
              circleSize,
              GameMap.Direction.NORTH_EAST,
              graphics
          );
          break;
        case SOUTH:
          drawArrow(
              x1,
              y1 + deltaY,
              circleSize,
              GameMap.Direction.SOUTH,
              graphics
          );
          break;
        case NORTH:
          drawArrow(
              x1,
              y1 - deltaY,
              circleSize,
              GameMap.Direction.NORTH,
              graphics
          );
          break;
        case SOUTH_WEST:
          drawArrow(
              x1 - deltaX,
              y1 + deltaY,
              circleSize,
              GameMap.Direction.SOUTH_WEST,
              graphics
          );
          break;
        case WEST:
          drawArrow(
              x1 - deltaX,
              y1,
              circleSize,
              GameMap.Direction.WEST,
              graphics
          );
          break;
        case NORTH_WEST:
          drawArrow(
              x1 - deltaX,
              y1 - deltaY,
              circleSize,
              GameMap.Direction.NORTH_WEST,
              graphics
          );
          break;
      }
         
      graphics.drawLine(x1, y1, x2, y2);     
    }
  }
 
 
  /**
   * Draws an arrow on the coordinates x,y with the selected orientation.
   *
   * Uses the previously selected line color.
   *
   * @param x x coordinate in the window
   * @param y y coordinate in the window
   * @param length half length of the rectangle that contains the arrowhead
   * @param direction direction of the arrow
   * @param graphics
   */
  private static void drawArrow(
      int x,
      int y,
      int halfLength,
      GameMap.Direction direction,
      Graphics graphics
  ) {
    float[] points = null;
    switch(direction){
    case EAST:
      points = new float[]{
        x + halfLength, y,
        x - halfLength, y + halfLength,
        x - halfLength, y - halfLength,
      };
      break;
    case NORTH:
      points = new float[]{
        x,          y - halfLength,
        x + halfLength, y + halfLength,
        x - halfLength, y + halfLength,
      };
      break;
    case WEST:
      points = new float[]{
        x - halfLength, y,
        x + halfLength, y - halfLength,
        x + halfLength, y + halfLength,
      };
      break;
    case SOUTH:
      points = new float[]{
        x,          y + halfLength,
        x - halfLength, y - halfLength,
        x + halfLength, y - halfLength,
      };
      break;
    case NORTH_WEST:
      points = new float[]{
        x - halfLength, y - halfLength,
        x + halfLength, y - halfLength,
        x - halfLength, y + halfLength,
      };
      break;
    case NORTH_EAST:
      points = new float[]{
        x + halfLength, y - halfLength,
        x + halfLength, y + halfLength,
        x - halfLength, y - halfLength,
      };
      break;
    case SOUTH_EAST:
      points = new float[]{
        x + halfLength, y + halfLength,
        x - halfLength, y + halfLength,
        x + halfLength, y - halfLength,
      };
      break;
    case SOUTH_WEST:
      points = new float[]{
        x - halfLength, y - halfLength,
        x + halfLength, y + halfLength,
        x - halfLength, y + halfLength,
      };
      break;
    }
    Shape shape = new Polygon(points);
    graphics.fill(shape);
  }
 
 
  /**
   * Draws a selection rectangle to it's required place.
   */
  private void drawSelection() {
    if(this._selection._x >= this._screen._x &&
       this._selection._x <= this._screen._x + this._screen._width - 1 &&
       this._selection._y >= this._screen._y &&
       this._selection._y <= this._screen._y + this._screen._height - 1)
      this._imgSelection.draw(
        this._screen.mapXToScreenX(this._selection._x),
        this._screen.mapYToScreenY(this._selection._y),
        GraphicPlayState.SCALE
      );
  }
 
 
  /**
   * Is the selected position currently visible?
   *
   * @param position
   * @return true if the position is visible.
   */
   private boolean isInScreen(Position position) {
     if(position.getX() this._screen._x ||
        position.getX() >= this._screen._x + this._screen._width ||
        position.getY() this._screen._y ||
        position.getY() >= this._screen._y + this._screen._height)
       return false;
     return true;
   }
 
  
}
TOP

Related Classes of cz.cuni.mff.abacs.burglar.visual.play_state.GraphicPlayState

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.