Package TrackRider

Source Code of TrackRider.Train$OverheatSteamEmitters

package TrackRider;

import engine.Animator;
import engine.Engine;
import static engine.Engine.appSpeed;
import static engine.Engine.elapsedAppTime;
import engine.Map;
import engine.Passenger;
import engine.Station;
import graphics.emitter.Emitter;
import graphics.material.Material;
import graphics.model.Model;
import java.awt.Point;
import java.util.ArrayList;
import org.lwjgl.util.vector.Vector2f;
import org.lwjgl.util.vector.Vector3f;

/**
* Train is the only truly player controllable object.
* It is almost identical to Coach. See TrackRider
*
* @author Jari Saaranen <rasaari@gmail.com>
* @author simokr
*/
public class Train extends TrackRider {
  // engine's power in horsepowers
  private float power;

  private float heat;
  private boolean overheat;

  private boolean brakesOn;
  private Emitter smokeEmitter,smokeEmitter2;
  private OverheatSteamEmitters overheatEmitters;
 
  private long coalTimer;
 
  private float passedDistance;
  private float damage;
  private Animator animator;
 
  public Train(Map map) {
    /* Wind effect on steam/smoke */
    Vector3f windSpeed = new Vector3f(-0.2f,0,-0.3f);
   
    // model specific initialization
    smokeEmitter = new Emitter(30, 4000);
    smokeEmitter.setVelocity(new Vector3f(0, 1.6f, 0));
    smokeEmitter.setSizes(5, 200);
    smokeEmitter.setSizesRandomness(1, 100);
    smokeEmitter.setAcceleration(new Vector3f(windSpeed.x, -0.29f, windSpeed.z));
    smokeEmitter.setTranslation(new Vector3f(0, 0.08f, 0.30f));
   
    smokeEmitter2 = new Emitter(30, 3000);
    smokeEmitter2.setVelocity(new Vector3f(0, 1.4f, 0));
    smokeEmitter2.setSizes(5, 75);
    smokeEmitter2.setSizesRandomness(1, 75);
    smokeEmitter2.setAcceleration(new Vector3f(windSpeed.x, -0.19f, windSpeed.z));
    smokeEmitter2.setTranslation(new Vector3f(0, 0.06f, 0.35f));
   
    overheatEmitters = new OverheatSteamEmitters(windSpeed);

    animator = new Animator(36, 0.2f);
   
    this.model = new Model();
    this.model.setMesh(Engine.MeshHandler.get("res/mesh/penydarren/penydarren.obj"));
    this.model.setPosition(0, 1, 1);
   
    // 70 tons
    this.setWeight(30*1000);
   
    this.power = 20.0f;
    this.heat = 0.0f;
    this.damage = 0;
   
    this.coalTimer = elapsedAppTime();
   
    //this.addCash(5000.0f);
   
    this.map = map;
   
    this.passedDistance = 0.0f;
    brakesOn = false;
  }
 
  /**
   * Ask train to turn in next intersection
   * to selected direction.
   *
   * Direction can be -1 or TrackRider.LEFT which means left or
   * 1 or TrackRider.RIGHT which means right.
   * @param dir
   */
  @Override
  public void requestTurn(int dir) {
    super.requestTurn(dir);
   
    //for(Coach c: coaches) {
    //  c.requestTurn(dir);
    //}
  }
 
  public float getHeat() {
    return this.heat;
  }
 
  public boolean getOverheat() {
    return this.overheat;
  }
 
  public float getPassedDistance() {
    return this.passedDistance;
  }
 
  public float getDamage() {
    return this.damage;
  }
 
  @Override
  public void render() {
    this.getModel().render();
    if(this.coach != null) {
      this.coach.render();
   
   
    this.overheatEmitters.render();
   
    this.smokeEmitter.render();
    this.smokeEmitter2.render();
  }
 
  @Override
  public void update() {
    this.calculateVelocity();
    //this.setVelocity(Math.min(this.getVelocity(), 33.3333f/5f));
    for(TrackRider rider = this.coach; rider != null; rider = rider.coach){
      rider.setVelocity(this.getVelocity());
    }
   
    float distanceThisFrame = this.getVelocity()*(appSpeed()/60.0f);
    float oneStep = 0.1f;
   
    this.passedDistance += distanceThisFrame;
   
    /* Iterate over the distance the train moves this frame with steps of 0.1 */
    while(distanceThisFrame > 0f){
      float movement = Math.min(oneStep, distanceThisFrame);
      Point currentTile = this.getGridLocation();
      this.move(movement, currentTile, null);
     
      TrackRider prev = this;
      for(TrackRider rider = this.coach; rider != null; rider = rider.coach){
        rider.move(movement, rider.getGridLocation(), prev);
        prev = rider;
      }
      distanceThisFrame -= oneStep;
    }
    this.updateModel();
   
    this.smokeEmitter.setVelocity(new Vector3f(0, 0.9f+0.6f*this.getPowerLevel(), 0));
    this.smokeEmitter.setUpdateIntervalMultiplier(1.0f+5f*(1.0f-this.getPowerLevel()));
    this.smokeEmitter.setPosition(this.getLocation().x, 0.60f, this.getLocation().y);
    this.smokeEmitter.setRotation(this.model.getRotation());
    this.smokeEmitter.update();
   
    this.smokeEmitter2.setVelocity(new Vector3f(0, 0.9f+0.6f*this.getPowerLevel(), 0));
    this.smokeEmitter2.setUpdateIntervalMultiplier(1.0f+5f*(1.0f-this.getPowerLevel()));
    this.smokeEmitter2.setPosition(this.getLocation().x, 0.60f, this.getLocation().y);
    this.smokeEmitter2.setRotation(this.model.getRotation());
    this.smokeEmitter2.update();
   
   
   
    if(this.getOverheat()){
      this.overheatEmitters.resume()
    }
    else{
      this.overheatEmitters.pause();
    }

    this.overheatEmitters.update();
   
    if(elapsedAppTime() - coalTimer > 1000) {
      coalTimer = elapsedAppTime();

      CoalCoach coalCoach = findUsefulCoalCoach();
      if(coalCoach != null)
        coalCoach.useCoals((long)(this.getPowerLevel()*40));
    }
   
    if(this.coach != null) {
      this.coach.update();
    }
               
    if(this.getCoals() == 0 || this.overheat || this.damage >= 1)
      this.setPowerLevel(0.0f);
   
    if(this.getVelocity() == 0.0f)
      this.collectCash();
   
    // heat
    float heatChange = (float) Math.sin(this.getPowerLevel())*2-1;
   
    this.heat += heatChange*0.001f*appSpeed();
   
    if(heat < 0) {
      heat = 0;
      this.overheat = false;
    }

    if(heat > 1) {
      heat = 1;
      this.overheat = true;
    }
   
    // damage
    if(damage < 0)
      damage = 0;
   
    if(damage > 1) {
      damage = 1;
      // game over
    }
   
    damage += (float) Math.sin(this.getPowerLevel())*0.0001*appSpeed();
   
    animator.setTimeScale(this.getVelocity()/3.1f);
    animator.update();
   
    // test animation
    this.model.animate(animator.getFrameBend(), animator.getFrame(), animator.getFrame()+1);
  }

  @Override
  protected void onTurn() {
    if(this.coach != null) {
      this.coach.requestTurn(this.getInterSectionDirection());
    }
  }
 
  @Override
  public void calculateVelocity() {
    float totalWeight = getTotalWeight();
    float totalWeightN = totalWeight * 9.81f;
    float vel = this.getVelocity();
    float TE = 0f;
   
    /*
     * Super complicated TE calculation for real steam engines
     *
     * TE = 0.8 * p * D * S * z / 2d
     *
     * 0.8 = losses to friction etc.
     * p = boler pressure (N/m^2)
     * D = cylinder area (m^2)
     * S = cylinder stroke (m)
     * z = number of cylinders
     * d = driving wheel diameter (m)
     */
   
    /*
    float p = 1621200.384f;
    float D = 0.2601f;
    float S = 0.66f;
    float z = 3;
    float d = 1.42f;
   
    // nominal = 235187.311369N = 235kN
    TE = 0.8f * p * D * S * z / 2*d;
    */
   
    // maximum TE = train (engine) mass * gravity * multiplier = 240kN
    float TEmax = this.getWeight() * 9.81f * 0.3f;
    // engine power (watts)
    float powerW = this.power*this.getPowerLevel()*745.699872f;
    // engine max force = engine power (watts) / speed (ms)
    float Fmax = powerW / Math.max(this.getVelocity(),1f);
   
    // Actual TE is the lower of these two
    TE = Math.min(Fmax, TEmax);
   
    //Fnet = TEeffective - c0 * W - c1 * W * v - c2 * v2 - Fincl
   
    // c0 = 0.1% axle resistance
    float c0 = 0.001f;
   
    if(this.brakesOn)
      c0 += 0.1f;
   
    // c1 = 0.15% * ((142.22ms + currentSpeed)/142.22ms) rolling friction
    float c1 = 0.0015f * ((142.22f + vel) / 142.22f);
    // c2 = 0.5 * air mass density (kg/m3) * speed^2 (ms) * train drag Coeff * area (m2)  = ?N air resistance
    float c2 = 0.5f * 1.229f * vel * vel * 1.8f * 6 * (this.getCoachCount()+1);
   
    float resistance = c0 * totalWeightN + c1 * totalWeightN + c2;
   
    // effort to move train at all
    // 1 ton takes 35 Newtons of force to move on a level track
    //float baseN = totalWeight/1000 * 35;
   
    //float maxSpeed = powerkW/(baseN/1000);
    float Fnet;
   
    //if(!this.brakesOn){
      //this.smokeEmitter.resume();
      Fnet = TE-resistance;
      vel += Fnet/totalWeight*(appSpeed()/60);
      if(vel < 0)
        vel = 0f;
    /*}
    else{
      if(vel <= 0){
        vel = 0f;
        Fnet = 0f;
        //this.setPowerLevel(0f);
        //this.smokeEmitter.pause();
      }
      else{
        Fnet = -TE-resistance;
        vel += Fnet/totalWeight*(appSpeed()/60);
      }
     
    }
    */
   
    //System.out.println("Fmax: "+ TE + " Fnet: " + Fnet);
    //System.out.println("PL: "+ this.getPowerLevel() + " acc: " + (Fnet*1000/totalWeight) + " maxvel: "+ maxSpeed);
    //System.out.format(Locale.UK, "PL: %.2f Acc: %.2fm/s2 Fmax: %.2fkN Fnet: %.2fkN\n", this.getPowerLevel(), (Fnet/totalWeight), TE/1000, Fnet/1000);

    setVelocity(vel);
  }
 
  public void setBrakes(boolean isOn){
    this.brakesOn = isOn;
  }
 
  public void addCoach(int type) {
    TrackRider that;
    that = this;
   
    while(that.coach != null) {
      that = that.coach;
    }
   
    if(type == Coach.PASSENGER)
      that.coach = new PassengerCoach(this.map);
    else if(type == Coach.COAL)
      that.coach = new CoalCoach(this.map);
     
    // set new position to new coach behind the previous.
    // TODO: make it direction-independent
    Vector2f newLoc = new Vector2f(that.getLocation());
    newLoc.x--;
   
    that.coach.setLocation(newLoc);
  }
 
  public int getCoachCount(){
    int count = 0;
    for(TrackRider rider = this.coach; rider != null; rider = rider.coach){
      count++;
    }
   
    return count;
  }
 
  /**
   * Get total weight of the train and its coaches
   * @return float total weight (kg)
   */
  public float getTotalWeight() {
    float totalWeight = 0.0f;
   
    TrackRider that = this;
    while(that != null) {
      totalWeight += that.getWeight();
      that = that.coach;
    }
   
    return totalWeight;
  }
 
  public long getCoals() {
    long coals = 0L;
   
    TrackRider that = this;
    while(that != null) {
     
      if(that instanceof CoalCoach) {
        CoalCoach coalCoach = (CoalCoach)that;
        coals += coalCoach.getCoals();
      }
     
      that = that.coach;
    }
   
    return coals;
  }
 
  public int getPassengerCount() {
    int passengers = 0;
   
    TrackRider that = this;
    while(that != null) {
     
      if(that instanceof PassengerCoach) {
        PassengerCoach passengerCoach = (PassengerCoach)that;
        passengers += passengerCoach.getPassengerCount();
      }
     
      that = that.coach;
    }
   
    return passengers;
  }
 
  public int getPassengersToStation(Station station) {
    int passengers = 0;
   
    TrackRider that = this;
    while(that != null) {
     
      if(that instanceof PassengerCoach) {
        PassengerCoach passengerCoach = (PassengerCoach)that;
       
        for(Passenger passenger: passengerCoach.getPassengers()) {
          if(passenger.getDestination().equals(station))
            passengers++;
        }
      }
     
      that = that.coach;
    }
   
    return passengers;
  }
 
  public CoalCoach findUsefulCoalCoach() {
    TrackRider that = this;
    while(that != null) {
     
      if(that instanceof CoalCoach) {
        CoalCoach coalCoach = (CoalCoach)that;
        if(coalCoach.getCoals() > 0)
        return coalCoach;
      }
     
      that = that.coach;
    }
   
    return null;
  }
 
  public CoalCoach findNotfullCoalCoach() {
    TrackRider that = this;
    while(that != null) {
     
      if(that instanceof CoalCoach) {
        CoalCoach coalCoach = (CoalCoach)that;
        if(coalCoach.getCoals() < coalCoach.getCapacity())
          return coalCoach;
      }
     
      that = that.coach;
    }
   
    return null;
  }
 
  /**
   * Collect ticket income from coaches
   */
  public void collectCash() {
    TrackRider that = this;
    while(that != null) {
     
      if(that instanceof PassengerCoach) {
        PassengerCoach passengerCoach = (PassengerCoach)that;
        this.addCash(passengerCoach.withdrawCash());
      }
     
      that = that.coach;
    }
  }

  @Override
  public void free() {
    this.smokeEmitter.free();
    this.smokeEmitter2.free();
    this.overheatEmitters.free();
   
    for(TrackRider rider = this.coach; rider != null; rider = rider.coach){
      rider.free();
    }
  }
 
  public void repair(float cost) {
    if(this.damage > 0.01f && this.withdrawCash(cost) > 0)
      this.damage -= 0.01f;
  }

  public ArrayList<Passenger> getPassengerListToStation(Station station) {
    ArrayList<Passenger> passengers = new ArrayList();
   
    TrackRider that = this;
    while(that != null) {
     
      if(that instanceof PassengerCoach) {
        PassengerCoach passengerCoach = (PassengerCoach)that;
       
        for(Passenger passenger: passengerCoach.getPassengers()) {
          if(passenger.getDestination().equals(station))
            passengers.add(passenger);
        }
      }
     
      that = that.coach;
    }
   
    return passengers;
  }
 
  class OverheatSteamEmitters{
    private Emitter overheatEmitter[];

    public OverheatSteamEmitters(Vector3f windSpeed) {
      Material smokeMat = new Material();
      smokeMat.setTexture(0, "res/texture/smoke_dark.png");
      overheatEmitter = new Emitter[6];
      for(int i=0;i<6;i++){
        overheatEmitter[i] = new Emitter(40, 1000);
        overheatEmitter[i].setMaterial(smokeMat);
        overheatEmitter[i].setVelocity(new Vector3f(0, 0.5f, -0.5f));
        overheatEmitter[i].setSizes(5, 10);
        overheatEmitter[i].setSizesRandomness(1, 40);
        overheatEmitter[i].setAcceleration(new Vector3f(windSpeed.x, -0.05f, windSpeed.z));

      }
      overheatEmitter[0].setTranslation(new Vector3f(-0.227f, -0.06f, 0.30f));
      overheatEmitter[1].setTranslation(new Vector3f(-0.227f, -0.06f, 0.20f));
      overheatEmitter[2].setTranslation(new Vector3f(-0.227f, -0.06f, 0.10f));

      overheatEmitter[3].setTranslation(new Vector3f(0.227f, -0.06f, 0.30f));
      overheatEmitter[4].setTranslation(new Vector3f(0.227f, -0.06f, 0.20f));
      overheatEmitter[5].setTranslation(new Vector3f(0.227f, -0.06f, 0.10f));
    }
 
    public void update(){
      double rotYrad = Math.toRadians(model.getRotation().y);
      float sin = (float)Math.sin(rotYrad);
      float cos = (float)Math.cos(rotYrad);
      float heatPow2 = getHeat()*getHeat();
      for(int i=0;i<6;i++){
        float smokeDir = (i<3)?-1.8f*heatPow2-0.2f:1.8f*heatPow2+0.2f;

        this.overheatEmitter[i].setVelocity(new Vector3f((-cos*smokeDir), 1.8f*heatPow2+0.2f, sin*smokeDir));
        this.overheatEmitter[i].setPosition(getLocation().x, 0.60f, getLocation().y);
        this.overheatEmitter[i].setRotation(model.getRotation());
        this.overheatEmitter[i].update();
      }
    }
   
    public void pause(){
      for(int i=0;i<6;i++){
        this.overheatEmitter[i].pause();
      }
    }
   
    public void resume(){
      for(int i=0;i<6;i++){
        this.overheatEmitter[i].resume();
      }
    }
   
    public void render(){
      for(int i=0;i<6;i++){
        this.overheatEmitter[i].render();
      }
    }
   
    public void free(){
      for(int i=0;i<6;i++){
        this.overheatEmitter[i].free();
      }
    }
  }
}
TOP

Related Classes of TrackRider.Train$OverheatSteamEmitters

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.