Package ch.bfh.ti.kybernetik.gui.slick

Source Code of ch.bfh.ti.kybernetik.gui.slick.GuiSimulator

/**
* Copyright (C) BFH www.bfh.ch 2011
* Code written by: Patrick Dobler, Marc Folly
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package ch.bfh.ti.kybernetik.gui.slick;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
import java.util.concurrent.CopyOnWriteArrayList;

import javax.vecmath.Point2d;
import javax.vecmath.Vector2d;

import org.newdawn.slick.BasicGame;
import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;

import ch.bfh.ti.kybernetik.engine.controller.Simulator;
import ch.bfh.ti.kybernetik.engine.controller.observerCommands.SimulatorObserverCommandState;
import ch.bfh.ti.kybernetik.engine.controller.observerCommands.model.LightBulbModelObserverCommand;
import ch.bfh.ti.kybernetik.engine.controller.observerCommands.model.LightBulbModelObserverCommand.LightBulbModelCommandState;
import ch.bfh.ti.kybernetik.engine.controller.observerCommands.model.LightSensorModelObserverCommand;
import ch.bfh.ti.kybernetik.engine.controller.observerCommands.model.LightSensorModelObserverCommand.LightSensorCommandState;
import ch.bfh.ti.kybernetik.engine.controller.observerCommands.model.RoboterModelObserverCommand;
import ch.bfh.ti.kybernetik.engine.controller.observerCommands.model.RoboterModelObserverCommand.RoboterModelCommandState;
import ch.bfh.ti.kybernetik.engine.controller.observerCommands.model.RoboterMoveListModelObserverCommand;
import ch.bfh.ti.kybernetik.engine.controller.observerCommands.model.RoboterMoveListModelObserverCommand.RoboterMoveModelObserverCommandState;
import ch.bfh.ti.kybernetik.engine.model.LightBulb;
import ch.bfh.ti.kybernetik.engine.model.Roboter;
import ch.bfh.ti.kybernetik.gui.slick.components.LightBulbComponent;
import ch.bfh.ti.kybernetik.gui.slick.components.RoboterComponent;
import ch.bfh.ti.kybernetik.gui.slick.components.RoboterMoveListComponent;
import ch.bfh.ti.kybernetik.gui.slick.components.SelectableSlickComponent;
import ch.bfh.ti.kybernetik.lego.ki.RobKIFactr;
import ch.bfh.ti.kybernetik.lego.ki.RobKIFactr.Wesen;
import ch.bfh.ti.kybernetik.lego.ki.RoboterKI;

/**
*
*
*/
public class GuiSimulator extends BasicGame implements Observer {

  private static final int RENDER_UPDATE_RATE = 60;

  private Simulator simulator;

  private List<RoboterComponent> roboterComponents = new CopyOnWriteArrayList<RoboterComponent>();

  private List<LightBulbComponent> lightBulbComponents = new CopyOnWriteArrayList<LightBulbComponent>();

  private List<RoboterMoveListComponent> roboterMoveListComponent = new CopyOnWriteArrayList<RoboterMoveListComponent>();

  private List<GuiSimulatorListener> guiSimulatorListeners = new CopyOnWriteArrayList<GuiSimulatorListener>();

  private boolean renderTracing = false;

  private enum GuiSimulatorMode {

    REDIRECT_ROBOTS_TO_POINT("Redirect All Robots to Mouse Position"), SLICK_COMPONENT_DRAGDROP("Drag & Drop Component"), ROBOT_DRAGDROP_ROTATION(
        "Set new direction vector");

    private final String displayText;

    GuiSimulatorMode(String displayText) {
      this.displayText = displayText;
    }

    public String getDisplayText() {
      return displayText;
    }
  }

  public void registerGuiSimulatorListener(GuiSimulatorListener guiSimulatorListener) {
    this.guiSimulatorListeners.add(guiSimulatorListener);
  }

  private GuiSimulatorMode mode = null;

  public GuiSimulator(Simulator simulator) {
    super("Kybernetik Simulator");
    this.simulator = simulator;
    this.simulator.addObserver(this);
  }

  @Override
  public void init(final GameContainer gc) throws SlickException {
    simulator.setWidth(gc.getWidth());
    simulator.setHeight(gc.getHeight());
    gc.setAlwaysRender(true);
    gc.setTargetFrameRate(RENDER_UPDATE_RATE);
    gc.setMaximumLogicUpdateInterval(1 / RENDER_UPDATE_RATE);
    gc.setMaximumLogicUpdateInterval(1 / RENDER_UPDATE_RATE);

    Iterator<Roboter> it = simulator.getRoboterList().iterator();
    while (it.hasNext()) {
      Roboter roboter = it.next();
      RoboterComponent rc = new RoboterComponent(roboter, simulator.getRoboterConstructionForRoboter(roboter));
      this.roboterComponents.add(rc);
    }

    Iterator<LightBulb> it2 = simulator.getLightBulbList().iterator();
    while (it2.hasNext()) {
      LightBulb lightBulb = it2.next();
      this.lightBulbComponents.add(new LightBulbComponent(lightBulb));
    }
    this.mode = GuiSimulatorMode.SLICK_COMPONENT_DRAGDROP;
  }

  @Override
  public void update(GameContainer gc, int delta) throws SlickException {
    final Input input = gc.getInput();
    final Point2d mouseClickedPointPosition = new Point2d(input.getMouseX(), input.getMouseY());

    if (input.isKeyPressed(Input.KEY_S)) {
      simulator.setSimulating(true);
    } else if (input.isKeyPressed(Input.KEY_Q)) {
      simulator.setSimulating(false);
    }

    // SETTING MODE
    if (input.isKeyPressed(Input.KEY_F2)) {
      this.mode = GuiSimulatorMode.REDIRECT_ROBOTS_TO_POINT;
    } else if (input.isKeyPressed(Input.KEY_F1)) {
      this.mode = GuiSimulatorMode.SLICK_COMPONENT_DRAGDROP;
      deselectAllSelectableSlickComponents();
    }

    if (input.isKeyDown(Input.KEY_RIGHT)) {
      simulator.setSimulatorSpeed(simulator.getSimulatorSpeed() + 5);
    } else if (input.isKeyDown(Input.KEY_LEFT)) {
      simulator.setSimulatorSpeed(simulator.getSimulatorSpeed() - 5);
    }

    // INTERPRETE MODE
    if (mode == GuiSimulatorMode.REDIRECT_ROBOTS_TO_POINT) {
      if (input.isMouseButtonDown(0)) {
        redirectRobotsToPoint(mouseClickedPointPosition);
      }
    } else if (mode == GuiSimulatorMode.SLICK_COMPONENT_DRAGDROP || mode == GuiSimulatorMode.ROBOT_DRAGDROP_ROTATION) {
      interpreteDragAndDropMode(input, mouseClickedPointPosition);
    }

  }

  private void interpreteDragAndDropMode(final Input input, final Point2d mouseClickedPointPosition) {
    SelectableSlickComponent<?> selectedSlickComponent = getSelectedSlickComponent();

    if (input.isMousePressed(0)) {
      // while the user still holds the mouse button pressed
      SelectableSlickComponent<?> newlySelectedSlickCompontent = selectSlickComponent(mouseClickedPointPosition, false, false);
      SelectableSlickComponent<?> currentSelectedSlickComponent = getSelectedSlickComponent();
      if (newlySelectedSlickCompontent != null && newlySelectedSlickCompontent != currentSelectedSlickComponent) {
        // another slick component was selected
        deselectAllSelectableSlickComponents();
        newlySelectedSlickCompontent.setSelected(true);
        mode = GuiSimulatorMode.SLICK_COMPONENT_DRAGDROP;
        for (GuiSimulatorListener guiSimulator : guiSimulatorListeners) {
          if (newlySelectedSlickCompontent instanceof RoboterComponent) {
            guiSimulator.selctedRoboterComponent((RoboterComponent) newlySelectedSlickCompontent);
          } else if (newlySelectedSlickCompontent instanceof LightBulbComponent) {
            guiSimulator.selctedLightComponent((LightBulbComponent) newlySelectedSlickCompontent);
          }
        }
      } else if (newlySelectedSlickCompontent == null && currentSelectedSlickComponent != null) {
        // nothing was selected
        deselectAllSelectableSlickComponents();
        currentSelectedSlickComponent.setSelected(true);
        mode = GuiSimulatorMode.ROBOT_DRAGDROP_ROTATION;
      } else if (newlySelectedSlickCompontent == currentSelectedSlickComponent) {
        // keep on drag and drop mode for the selected component
        mode = GuiSimulatorMode.SLICK_COMPONENT_DRAGDROP;
      }
    } else if (input.isMouseButtonDown(0)) {
      // the user stopped to press the mouse button
      if (mode == GuiSimulatorMode.SLICK_COMPONENT_DRAGDROP) {
        if (selectedSlickComponent != null) {
          // set new position of the slick component
          selectedSlickComponent.setX(mouseClickedPointPosition.getX());
          selectedSlickComponent.setY(mouseClickedPointPosition.getY());
        }
      } else if (mode == GuiSimulatorMode.ROBOT_DRAGDROP_ROTATION) {
        if (selectedSlickComponent instanceof RoboterComponent) {
          redirectRobotToPoint((RoboterComponent) selectedSlickComponent, mouseClickedPointPosition);
        }
      }
    } else if (input.isKeyPressed(Input.KEY_DELETE)) {
      // the user pressed the DELETE KEY
      if (selectedSlickComponent != null) {
        if (selectedSlickComponent instanceof RoboterComponent) {
          simulator.removeRoboter((Roboter) selectedSlickComponent.getModelObject());
        } else if (selectedSlickComponent instanceof LightBulbComponent) {
          simulator.removeLightBulb((LightBulb) selectedSlickComponent.getModelObject());
        }
      }
    } else if (input.isKeyPressed(Input.KEY_0)) {
      // the user pressed the 0 KEY which changes the RoboterKI
      if (selectedSlickComponent instanceof RoboterComponent) {
        RoboterComponent selectedRoboterComponent = (RoboterComponent) selectedSlickComponent;
        RoboterKI selectedRoboterKI = simulator.getRoboterKIForRoboter(selectedRoboterComponent.getModelObject());
        Wesen[] wesenArray = RobKIFactr.Wesen.values();
        int pos = Arrays.binarySearch(wesenArray, selectedRoboterKI.getWesen());
        if (++pos >= wesenArray.length) {
          pos = 0;
        }
        RoboterKI newRoboterKI = RobKIFactr.getRoboterKI(wesenArray[pos]);
        simulator.changeRoboterKIForRoboter(selectedRoboterComponent.getModelObject(), newRoboterKI);
      }
    }
  }

  private void redirectRobotToPoint(RoboterComponent rc, Point2d mouseClickedPointPosition) {
    Roboter roboter = rc.getModelObject();
    Vector2d vec = new Vector2d(mouseClickedPointPosition.getX() - roboter.getX(), mouseClickedPointPosition.getY() - roboter.getY());
    vec.normalize();
    roboter.setDirection(vec);
  }

  private void redirectRobotsToPoint(Point2d mouseClickedPointPosition) {
    Iterator<RoboterComponent> it = this.roboterComponents.iterator();
    while (it.hasNext()) {
      RoboterComponent rc = it.next();
      Roboter roboter = rc.getModelObject();
      Vector2d vec = new Vector2d(mouseClickedPointPosition.getX() - roboter.getX(), mouseClickedPointPosition.getY()
          - roboter.getY());
      vec.normalize();
      roboter.setDirection(vec);
    }
  }

  private void deselectAllSelectableSlickComponents() {
    List<SelectableSlickComponent<?>> aList = new ArrayList<SelectableSlickComponent<?>>();
    aList.addAll(roboterComponents);
    aList.addAll(lightBulbComponents);

    Iterator<SelectableSlickComponent<?>> it2 = aList.iterator();
    while (it2.hasNext()) {
      SelectableSlickComponent<?> rc = it2.next();
      rc.setSelected(false);
    }

  }

  private SelectableSlickComponent<?> getSelectedSlickComponent() {
    List<SelectableSlickComponent<?>> aList = new ArrayList<SelectableSlickComponent<?>>();
    aList.addAll(roboterComponents);
    aList.addAll(lightBulbComponents);

    Iterator<SelectableSlickComponent<?>> it2 = aList.iterator();
    while (it2.hasNext()) {
      SelectableSlickComponent<?> rc = it2.next();
      if (rc.isSelected())
        return rc;
    }

    return null;
  }

  private SelectableSlickComponent<?> selectSlickComponent(Point2d mouseClickedPointPosition, boolean selectInModel,
      boolean deselectOthers) {
    List<SelectableSlickComponent<?>> aList = new ArrayList<SelectableSlickComponent<?>>();
    aList.addAll(roboterComponents);
    aList.addAll(lightBulbComponents);

    Iterator<SelectableSlickComponent<?>> it2 = aList.iterator();
    boolean selected = false;
    SelectableSlickComponent<?> selectedRoboterComponent = null;
    while (it2.hasNext()) {
      SelectableSlickComponent<?> rc = it2.next();
      if (rc.intersectWithPoint(mouseClickedPointPosition) && selected == false) {
        if (selectInModel)
          rc.setSelected(true);
        selected = true;
        selectedRoboterComponent = rc;
      } else {
        if (deselectOthers)
          rc.setSelected(false);
      }
    }

    return selectedRoboterComponent;
  }

  @Override
  public void render(GameContainer gc, final Graphics g) throws SlickException {

    g.setAntiAlias(true);

    Iterator<RoboterComponent> it = this.roboterComponents.iterator();
    while (it.hasNext()) {
      RoboterComponent rc = it.next();
      rc.render(gc, g);
    }

    Iterator<LightBulbComponent> it2 = this.lightBulbComponents.iterator();
    while (it2.hasNext()) {
      LightBulbComponent lbc = it2.next();
      lbc.render(gc, g);
    }

    if (renderTracing) {
      Iterator<RoboterMoveListComponent> it3 = this.roboterMoveListComponent.iterator();
      while (it3.hasNext()) {
        RoboterMoveListComponent rtc = it3.next();
        rtc.render(gc, g);
      }
    }

    // Render current mode
    g.setColor(Color.green);
    if (mode != null) {
      g.drawString("Mode: " + mode.getDisplayText(), 300, 0);
    }

    // Draw Simulator Speed
    g.drawString("Simulating Speed: " + simulator.getSimulatorSpeed(), 300, 30);

    // Draw Selected Roboter Info
    SelectableSlickComponent<?> ssc = this.getSelectedSlickComponent();
    if (ssc instanceof RoboterComponent) {
      RoboterComponent rc = (RoboterComponent) ssc;
      if (rc != null) {
        RoboterKI roboterKI = simulator.getRoboterKIForRoboter(rc.getModelObject());
        g.drawString("Roboter KI: " + roboterKI.getRoboterKIName(), 300, 60);
      }
    }

  }

  @Override
  public synchronized void update(Observable o, Object observerCommand) {
    if (observerCommand instanceof SimulatorObserverCommandState) {
      SimulatorObserverCommandState simulatorCommand = (SimulatorObserverCommandState) observerCommand;
      if (simulatorCommand == SimulatorObserverCommandState.MOVED_ALL_ROBOTOS) {

      }
    } else if (observerCommand instanceof RoboterModelObserverCommand) {
      RoboterModelObserverCommand rmoc = (RoboterModelObserverCommand) observerCommand;
      if (rmoc.getState() == RoboterModelCommandState.ROBOTER_ADDED) {
        RoboterComponent newRoboterComponent = new RoboterComponent(rmoc.getModel(),
            simulator.getRoboterConstructionForRoboter(rmoc.getModel()));
        this.roboterComponents.add(newRoboterComponent);
      } else if (rmoc.getState() == RoboterModelCommandState.ROBOTER_REMOVED) {
        RoboterComponent rc = findOrAddRoboterComponent(rmoc.getModel());
        this.roboterComponents.remove(rc);
      }
    } else if (observerCommand instanceof LightSensorModelObserverCommand) {
      LightSensorModelObserverCommand lsmoc = (LightSensorModelObserverCommand) observerCommand;
      if (lsmoc.getState() == LightSensorCommandState.SENSOR_INTENSITY_CHANGED) {
        RoboterComponent rc = findOrAddRoboterComponent(lsmoc.getModel());
        rc.hightLightRoboterElement(lsmoc.getPayLoad());
      } else if (lsmoc.getState() == LightSensorCommandState.SENSOR_INTENSITY_REMAINS) {
        RoboterComponent rc = findOrAddRoboterComponent(lsmoc.getModel());
        rc.unHightLightRoboterElement(lsmoc.getPayLoad());
      }
    } else if (observerCommand instanceof RoboterMoveListModelObserverCommand) {
      RoboterMoveListModelObserverCommand rmlmoc = (RoboterMoveListModelObserverCommand) observerCommand;
      if (rmlmoc.getState() == RoboterMoveModelObserverCommandState.ROBOTER_MOVE_ADDED) {
        RoboterMoveListComponent rtc = findOrAddRoboterTraceComponent(rmlmoc.getModel());
        rtc.setMoves(rmlmoc.getPayLoad());
      }
    } else if (observerCommand instanceof LightBulbModelObserverCommand) {
      LightBulbModelObserverCommand lbmoc = (LightBulbModelObserverCommand) observerCommand;
      if (lbmoc.getState() == LightBulbModelCommandState.LIGHTBULB_ADDED) {
        this.lightBulbComponents.add(new LightBulbComponent(lbmoc.getModel()));
      } else if (lbmoc.getState() == LightBulbModelCommandState.LIGHTBULB_REMOVED) {
        LightBulbComponent rc = findOrAddLightBulbComponent(lbmoc.getModel());
        this.lightBulbComponents.remove(rc);
      }
    }
  }

  private LightBulbComponent findOrAddLightBulbComponent(LightBulb lightBulb) {
    Iterator<LightBulbComponent> it = this.lightBulbComponents.iterator();
    while (it.hasNext()) {
      LightBulbComponent rc = it.next();
      if (rc.getModelObject() == lightBulb) {
        return rc;
      }
    }
    LightBulbComponent rc = new LightBulbComponent(lightBulb);
    this.lightBulbComponents.add(rc);
    return rc;
  }

  private RoboterComponent findOrAddRoboterComponent(Roboter roboter) {
    Iterator<RoboterComponent> it = this.roboterComponents.iterator();
    while (it.hasNext()) {
      RoboterComponent rc = it.next();
      if (rc.getModelObject() == roboter) {
        return rc;
      }
    }
    RoboterComponent rc = new RoboterComponent(roboter, simulator.getRoboterConstructionForRoboter(roboter));
    this.roboterComponents.add(rc);
    return rc;
  }

  private RoboterMoveListComponent findOrAddRoboterTraceComponent(Roboter roboter) {
    Iterator<RoboterMoveListComponent> it = this.roboterMoveListComponent.iterator();
    while (it.hasNext()) {
      RoboterMoveListComponent rtc = it.next();
      if (rtc.getRoboter() == roboter) {
        return rtc;
      }
    }
    RoboterMoveListComponent rtc = new RoboterMoveListComponent(roboter);
    rtc.setColor(findOrAddRoboterComponent(roboter).getColor());
    this.roboterMoveListComponent.add(rtc);
    return rtc;
  }

  public void setRenderTracing(boolean renderTracing) {
    this.renderTracing = renderTracing;
  }

  public boolean isRenderTracing() {
    return renderTracing;
  }
}
TOP

Related Classes of ch.bfh.ti.kybernetik.gui.slick.GuiSimulator

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.