Package TrackRider

Source Code of TrackRider.TrackRider$TurnPoint

package TrackRider;

import engine.GameObject;
import engine.Map;
import java.awt.Point;
import java.util.ArrayDeque;
import org.lwjgl.util.vector.Vector2f;

/**
* Baseclass for all gameobjects running on tracks.
*
* @author Jari Saaranen <rasaari@gmail.com>
* @author simokr
*/
public abstract class TrackRider extends GameObject {
  private static int MAX_KM_H = 80;
 
  // constants for intersection controlling
  public static final int LEFT = -1;
  public static final int RIGHT = 1;
 
  private float powerLevel;     // From 0.0f to 1.0f, power to push train
  private float velocity;    // Actual velocity of the train
 
  // object's weight in kilograms
  private float weight;
 
  // available directions to continue from current train's position
  protected int[] freeDirections;
  protected Map map;
 
  // -1 or LEFT indicates to turn left, 1 or RIGHT to right
  private int intersectionControl;
 
  private boolean mayTurn;
  private float tileProgress, oldAngle, newAngle;
  private TurnPoint nextTurnPoint;
 
  private ArrayDeque<TurnPoint> nextTurns;
 
  protected Coach coach;
 
  // amount of money the rider carries
  private float cash;
 
  // map methods
  public void setMap(Map map) { this.map = map; }
 
  // power methods
  public void setPowerLevel(float powerLevel) {
    this.powerLevel = (float) Math.max(0.0, Math.min(1.0, powerLevel));
  }
 
  public float getPowerLevel() { return this.powerLevel; }
 
  // velocity methods
  public void setVelocity(float velocity) { this.velocity = velocity; }
  public float getVelocity() { return this.velocity; }
  public float getBalancedVelocity() { return getVelocity()*5f; }
 
  // weight methods
  public void setWeight(float weight) { this.weight = weight; }
  public float getWeight() { return this.weight; }
 
  public float getCash() {
    return cash;
  }
 
  public float withdrawCash() {
    float ret = this.cash;
    this.cash = 0;
   
    return ret;
  }
 
  public float withdrawCash(float amount) {
    if(this.cash >= amount) {
      this.cash -= amount;
      return amount;
    }
    return 0.0f;
  }
 
  public void addCash(float amount) {
    cash += amount;
  }
 
  // intersection controlling methods
  public void requestTurn(int dir) {
    this.intersectionControl = dir;
  }
 
  public int getInterSectionDirection() {
    return this.intersectionControl;
  }
 
  private TurnPoint getNextTurnPoint(){
    return this.nextTurnPoint;
  }
 
  public TrackRider() {
    this.coach = null;
    this.freeDirections = new int[8];
    this.intersectionControl = 0;
    mayTurn = false;
    tileProgress = 0.0f;
    oldAngle=0f;
    newAngle=0f;
    nextTurnPoint = null;

    cash = 0;

    nextTurns = new ArrayDeque<>();
  }
 
  protected void updateModel() {
    // update model location and rotation
    Vector2f newLocation = new Vector2f(this.getLocation());
    if(oldAngle == 6 && newAngle == 0)
      newAngle = 8;
    else if(oldAngle == 0 && newAngle == 6){
      oldAngle = 8;
   
    }
   
    float change = (newAngle-oldAngle)*(this.tileProgress);
    double rad = (-(oldAngle-2+change))*(2.0*Math.PI/8.0);
    float angle = (float) Math.toDegrees(rad);
   
    /*
    if(oldAngle < newAngle){
      Point loc = this.getGridLocation();
      double pointRad = (-(newAngle))*(2.0*Math.PI/8.0);
     
      newLocation.x = loc.x+((0.5f)*(float)Math.cos(pointRad)+(0.5f)*(float)Math.sin(pointRad));
      newLocation.y = loc.y+((0.5f)*(float)Math.cos(pointRad)-(0.5f)*(float)Math.sin(pointRad));

      double rotateRad = (-(newAngle+change))*(2.0*Math.PI/8.0);
      newLocation.x += (float)Math.cos(rotateRad)*-0.5f;
      newLocation.y += (float)Math.sin(rotateRad)*0.5f;
    }
    */
   
    /*
    else if(newAngle < oldAngle){
      Point loc = this.getGridLocation2();
      double pointRad = (-(oldAngle))*(2.0*Math.PI/8.0);

      newLocation.x = loc.x+((-0.5f)*(float)Math.cos(pointRad)+(-0.5f)*(float)Math.sin(pointRad));
      newLocation.y = loc.y+((0.5f)*(float)Math.cos(pointRad)-(0.5f)*(float)Math.sin(pointRad));
      System.out.println("smooth left");
      double rotateRad = (-(oldAngle+change))*(2.0*Math.PI/8.0);
      newLocation.x += (float)Math.cos(rotateRad)*0.5f;
      newLocation.y += (float)Math.sin(rotateRad)*-0.5f;
    }
    */
   
    /*
    if(oldAngle == 0 && newAngle == 2){
     
     
      newLocation.x += Math.sin(this.tileProgress*Math.PI/2.0)*0.5;
      newLocation.y -= Math.cos(this.tileProgress*Math.PI/2.0)*0.5;
    }
    else if(oldAngle == 2 && newAngle == 4){
     
     
      newLocation.x += Math.cos(this.tileProgress*Math.PI/2.0)*0.5;
      newLocation.y += Math.sin(this.tileProgress*Math.PI/2.0)*0.5;
    }
    else if(oldAngle == 4 && newAngle == 6){
     
     
      newLocation.x -= Math.sin(this.tileProgress*Math.PI/2.0)*0.5;
      newLocation.y += Math.cos(this.tileProgress*Math.PI/2.0)*0.5;
    }
    else if(oldAngle == 6 && newAngle == 8){
     
     
      newLocation.x -= Math.cos(this.tileProgress*Math.PI/2.0)*0.5;
      newLocation.y -= Math.sin(this.tileProgress*Math.PI/2.0)*0.5;
    }
    */
   
   
   
 
   
    this.model.setRotation(
        0,
        angle,
        0);
   
    this.model.setPosition(
        newLocation.x,
        0,
        newLocation.y);
  }
 
  protected void calculateVelocity() {
    // TODO: make some serious calculation here
    this.velocity = this.powerLevel*0.3f;
  }
 
  protected void move(float movement, Point oldTile, TrackRider prev) {
    if(map == null){
      System.out.println("No map");
      return;
    }
   
    /* Get how much to move without turning */
    double yVel = Math.sin(Math.toRadians(getDirection()*45))*movement;
    double xVel = Math.cos(Math.toRadians(getDirection()*45))*movement;
   
    Vector2f newLocation = new Vector2f(this.getLocation());
    newLocation.x += xVel;
    newLocation.y += yVel;
    Point newTile = new Point(Math.round(newLocation.x), Math.round(newLocation.y));
   
    /* Get how much we have moved in this tile (0.0 - 1.0) */
    float tileProgress = 0f;
    if(getDirection() == 0){
      tileProgress = newLocation.x - (float)oldTile.x + 0.5f;
    }
    else if(getDirection() == 2){
      tileProgress = newLocation.y - (float)oldTile.y + 0.5f;
    }
    else if(getDirection() == 4){
      tileProgress = (float)oldTile.x - newLocation.x + 0.5f;
    }
    else if(getDirection() == 6){
      tileProgress = (float)oldTile.y - newLocation.y + 0.5f;
    }
    this.tileProgress = tileProgress;
   
    if(prev == null){
      /* Currently the train is active */
     
      if(!oldTile.equals(newTile)){
        /* We have moved in to a new tile, so calculate next turn */
        this.mayTurn = true;
        int nextDirection = this.getDirection();

        boolean freeDirs[] = map.scanRideable(newTile.x, newTile.y);

        int right = (getDirection()+2)%8;
        int left = (getDirection()-2)%8;
        if(left < 0)
          left += 8;

        if((!freeDirs[getDirection()] && freeDirs[right] && !freeDirs[left])
          || (!freeDirs[getDirection()] && freeDirs[right] && freeDirs[left] && this.getInterSectionDirection() == 0)){
          /* Can only turn right */
          nextDirection = this.getTurnDirection(2);
          System.out.println("Forced right turn");
        }
        else if(!freeDirs[getDirection()] && !freeDirs[right] && freeDirs[left]){
          /* Can only turn left */
          nextDirection = this.getTurnDirection(-2);
          System.out.println("Forced left turn");
        }
        else if((!freeDirs[getDirection()] && !freeDirs[right] && !freeDirs[left])){
          /* Can only reverse */
          nextDirection = this.getTurnDirection(-4);
          System.out.println("Reversing");
        }
        else{
          if(this.getInterSectionDirection() == LEFT && freeDirs[left]){
            /* Can't go forward but can go right & left, left chosen */
            nextDirection = this.getTurnDirection(-2);
            this.intersectionControl = 0;
            System.out.println("Left turn");
          }
          else if(this.getInterSectionDirection() == RIGHT && freeDirs[right]){
            /* Can't go forward but can go right & left, right chosen */
            nextDirection = this.getTurnDirection(2);
            this.intersectionControl = 0;
            System.out.println("Right turn");
          }
        }
       
        /* Update model angles to have a smooth turn */
        oldAngle = this.getDirection();
        newAngle = nextDirection;
       
        /* We are starting a turn, so set lastTurn to this tile */
        if(this.getDirection() != nextDirection)
          this.nextTurnPoint = new TurnPoint(newTile, nextDirection);

        /* Adjust tileProgress, since we moved in to a new tile */
        this.tileProgress = tileProgress-1f;
      }
    }
    else{
      /* Currently a coach is active */
     
      if(prev.getNextTurnPoint() != null && (this.nextTurns.isEmpty() || !this.nextTurns.peekLast().getTile().equals(prev.getNextTurnPoint().getTile()))){   
        /* Query previous TrackRider's latest turn and compare it to the last one in this queue.
         * Add it to the end of queue, if it isn't already there.
         */
        this.nextTurns.add(prev.getNextTurnPoint());
      }

      if(!oldTile.equals(newTile)){
        if(!this.nextTurns.isEmpty()){
          /* There are turns queued */
          if(newTile.equals(this.nextTurns.peekFirst().getTile())){
            /* Current tile matches the tile at the front of turn queue, so execute a turn. */
            this.mayTurn = true;
            TurnPoint nextTurn = this.nextTurns.pollFirst();
            this.nextTurnPoint = new TurnPoint(nextTurn.getTile(), nextTurn.getDirection());
          }
        }
       
        /* Update model angles to have a smooth turn */
        oldAngle = this.getDirection();
        newAngle = (this.nextTurnPoint != null)?this.nextTurnPoint.getDirection():this.getDirection();
       
        /* Adjust tileProgress, since we moved in to a new tile */
        this.tileProgress = tileProgress-1f;
      }
    }
   
    if(this.mayTurn && this.tileProgress > 0.5f){
      /* Turn flag has been set and the TrackRider is over half way the current tile,
       * so try to turn to the next direction.
       */
     
      if(this.nextTurnPoint != null && this.getDirection() != this.nextTurnPoint.getDirection()){
        /* Current direction is different from next turn direction, so turn */
        this.setDirection(this.nextTurnPoint.getDirection());
       
        /* Set position to the center of current tile and add how much is
         * still needed to adjust position with the new direction in mind.
         */
        double overhead = tileProgress-0.5f;
        //System.out.println("Turn "+((prev==null)?"Train":"Coach")+" "+overhead);
        yVel = Math.sin(Math.toRadians(getDirection()*45))*overhead;
        xVel = Math.cos(Math.toRadians(getDirection()*45))*overhead;
        newLocation.set((float)(newTile.x+xVel), (float)(newTile.y+yVel));
       
        /* TrackRider has turned. Unset the turn point.  */
        this.nextTurnPoint = null;
      }
     
      /* TrackRider can attempt a turn only once per tile */
      this.mayTurn = false;
    }
   
    /* Set the new position */
    this.setLocation(newLocation);
  }
 
  abstract public void update();
  abstract public void render();
  abstract public void free();
 
  /**
   * Callback function performed after
   * object has turned to left or to right.
   */
  abstract protected void onTurn();
 
  public void setDirections(int[] data) {
    this.freeDirections = data;
  }
 
  private class TurnPoint{
    private Point tile;
    private int direction;
   
    public TurnPoint(Point tile, int direction){
      this.tile = new Point(tile);
      this.direction = direction;
    }
   
    public void set(Point tile, int direction){
      this.tile = new Point(tile);
      this.direction = direction;
    }
   
    public void set(TurnPoint point){
      this.tile = new Point(point.tile);
      this.direction = point.direction;
    }
   
    public Point getTile(){
      return this.tile;
    }
   
    public int getDirection(){
      return this.direction;
    }
  }
}
TOP

Related Classes of TrackRider.TrackRider$TurnPoint

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.