/// <summary> /// Konstruktor /// </summary> public Engine() { Lines = new List <Line>(); Rider = new Player(new Point(100, 500), 60, global::LineRider.Properties.Resources.player_gerade); Playtime = new TimeSpan(); GameButtons = new List <GameButton>(); Origin = new Point(); Messages = new ConcurrentQueue <UI_Message>(); Offset = new Point(0, 600); int Size = 40; Play = new GameButton(new Point((int)(800 / 2 - (2 * Size + 1.5 * 10)), 10), Size, true, global::LineRider.Properties.Resources.Button_Play_icon); Pause = new GameButton(new Point((int)(800 / 2 - (1 * Size + 0.5 * 10)), 10), Size, true, global::LineRider.Properties.Resources.Button_Pause_icon); Save = new GameButton(new Point((int)(800 / 2 + (0.5 * 10)), 10), Size, true, global::LineRider.Properties.Resources.Save_icon); Load = new GameButton(new Point((int)(800 / 2 + (1 * Size + 1.5 * 10)), 10), Size, true, global::LineRider.Properties.Resources.Open_Folder_icon); GameButtons.Add(Play); GameButtons.Add(Pause); GameButtons.Add(Save); GameButtons.Add(Load); State = EngineStates.Editor; Deadpoints = new List <PointF>(); Move = new AutoResetEvent(false); Process = new AutoResetEvent(true); MoveTimer = new System.Windows.Forms.Timer(); MoveTimer.Interval = 50; MoveTimer.Tick += MoveTimer_Tick; MoveTimer.Start(); }
public StateChangedEventArgs(EngineStates oldState, EngineStates newState, Exception errorException = null, string message = null) : base() { OldState = oldState; NewState = newState; ErrorException = errorException; Message = message; }
public void BeginCruise() { if (EngineState != EngineStates.Cruise && EngineState != EngineStates.CruiseCharging) { EngineState = EngineStates.CruiseCharging; ChargePercent = 0f; cruiseAccelPct = 0f; } }
public void CruiseToggle() { if (EngineState == EngineStates.Cruise || EngineState == EngineStates.CruiseCharging) { EngineState = EngineStates.Standard; } else { BeginCruise(); } }
void startGame() { _currentPhase = GamePhases.Main1; cp.AllowedLandsToBePlayed = 1; //it's normaly set in the untap phase... cp.UpdateUi(); State = EngineStates.CurrentPlayer; MagicEvent(new PhaseEventArg { Type = MagicEventType.BeginPhase, Phase = _currentPhase, Player = cp }); }
protected virtual void OnStateChanged(EngineStates newState, Exception errorException = null, string message = null) { var oldState = CurrentState; CurrentState = newState; var e = new StateChangedEventArgs(oldState, newState, errorException, message); EventHandler <StateChangedEventArgs> handler = StateChanged; if (handler != null) { handler(this, e); } }
/// <summary> /// Set vehicle state (This system of setting states needs to be changed some day) /// </summary> public void SetEngineState(EngineStates state, DashboardStates dashstate, float startTime) { //Start time if (startTime != -1) { starterFsm.Fsm.GetFsmFloat("StartTime").Value = startTime; } // Engine states if (state == EngineStates.WaitForStart) { starterFsm.SendEvent("MP_Wait for start"); } else if (state == EngineStates.ACC) { starterFsm.SendEvent("MP_ACC"); } else if (state == EngineStates.TurnKey) { starterFsm.SendEvent("MP_Turn key"); } else if (state == EngineStates.StartingEngine) { starterFsm.SendEvent("MP_Starting engine"); } else if (state == EngineStates.StartEngine) { starterFsm.SendEvent("MP_Start engine"); } else if (state == EngineStates.MotorRunning) { starterFsm.SendEvent("MP_Motor running"); } else if (state == EngineStates.Wait) { starterFsm.SendEvent("MP_Wait"); } else if (state == EngineStates.CheckClutch) { starterFsm.SendEvent("MP_Check clutch"); } else if (state == EngineStates.StartOrNot) { starterFsm.SendEvent("MP_Start or not"); } else if (state == EngineStates.Glowplug) { starterFsm.SendEvent("MP_ACC / Glowplug"); } // Dashboard states if (dashstate == DashboardStates.ACCon) { dashboardFsm.SendEvent("MP_ACC on"); } else if (dashstate == DashboardStates.Test) { dashboardFsm.SendEvent("MP_Test"); } else if (dashstate == DashboardStates.ACCon2) { dashboardFsm.SendEvent("MP_ACC on 2"); } else if (dashstate == DashboardStates.MotorStarting) { dashboardFsm.SendEvent("MP_Motor starting"); } else if (dashstate == DashboardStates.ShutOff) { dashboardFsm.SendEvent("MP_Shut off"); } else if (dashstate == DashboardStates.MotorOff) { dashboardFsm.SendEvent("MP_Motor OFF"); } else if (dashstate == DashboardStates.WaitButton) { dashboardFsm.SendEvent("MP_Wait button"); } else if (dashstate == DashboardStates.WaitPlayer) { dashboardFsm.SendEvent("MP_Wait player"); } }
//TODO: Engine Kill public override void FixedUpdate(double time) { if (!Active) { return; } //Component checks var engine = Parent.GetComponent <SEngineComponent>(); //Get mounted engine var power = Parent.GetComponent <PowerCoreComponent>(); if (Parent.PhysicsComponent == null) { return; } if (Parent.PhysicsComponent.Body == null) { return; } if (engine == null) { return; } if (power == null) { return; } //Drag = -linearDrag * Velocity var drag = -engine.Engine.Def.LinearDrag * Parent.PhysicsComponent.Body.LinearVelocity; if (EngineState == EngineStates.CruiseCharging) { EnginePower = 1f; } var engine_force = EnginePower * engine.Engine.Def.MaxForce; power.CurrentThrustCapacity += power.Equip.ThrustChargeRate * (float)(time); power.CurrentThrustCapacity = MathHelper.Clamp(power.CurrentThrustCapacity, 0, power.Equip.ThrustCapacity); foreach (var thruster in Parent.GetChildComponents <CThrusterComponent>()) { thruster.Enabled = false; } if (ThrustEnabled) { foreach (var thruster in Parent.GetChildComponents <CThrusterComponent>()) { engine_force += thruster.Equip.Force; thruster.Enabled = true; power.CurrentThrustCapacity -= (float)(thruster.Equip.Drain * time); power.CurrentThrustCapacity = MathHelper.Clamp(power.CurrentThrustCapacity, 0, power.Equip.ThrustCapacity); if (power.CurrentThrustCapacity == 0) { ThrustEnabled = false; } } } if (EngineState == EngineStates.CruiseCharging) { EnginePower = 1f; ChargePercent += (1.0f / engine.Engine.Def.CruiseChargeTime) * (float)time; if (ChargePercent >= 1.0f) { EngineState = EngineStates.Cruise; } if (ChargePercent >= 0.6f) { var fxPct = (ChargePercent - 0.6f) / 0.4f * 0.1f; engine.Speed = 0.9f + fxPct; } else { engine.Speed = 0.901f; } } else if (EngineState == EngineStates.Cruise) { //Cruise has entirely different force calculation cruiseAccelPct += (float)(time * 1.0f / engine.Engine.CruiseAccelTime); if (cruiseAccelPct > 1.0f) { cruiseAccelPct = 1.0f; } var cruise_force = engine.Engine.CruiseSpeed * engine.Engine.Def.LinearDrag; engine_force = engine.Engine.Def.MaxForce + (cruise_force - engine.Engine.Def.MaxForce) * cruiseAccelPct; //Set fx sparam. TODO: This is poorly named engine.Speed = 1.0f; } else { engine.Speed = EnginePower * 0.9f; } Vector3 strafe = Vector3.Zero; //TODO: Trying to strafe during cruise should drop you out if (EngineState != EngineStates.Cruise) //Cannot strafe during cruise { if ((CurrentStrafe & StrafeControls.Left) == StrafeControls.Left) { strafe -= Vector3.UnitX; } else if ((CurrentStrafe & StrafeControls.Right) == StrafeControls.Right) { strafe += Vector3.UnitX; } if ((CurrentStrafe & StrafeControls.Up) == StrafeControls.Up) { strafe += Vector3.UnitY; } else if ((CurrentStrafe & StrafeControls.Down) == StrafeControls.Down) { strafe -= Vector3.UnitY; } if (strafe != Vector3.Zero) { strafe.Normalize(); strafe = Parent.PhysicsComponent.Body.RotateVector(strafe); //Apply strafe force strafe *= Ship.StrafeForce; } } var totalForce = ( drag + strafe + (Parent.PhysicsComponent.Body.RotateVector(-Vector3.UnitZ) * engine_force) ); Parent.PhysicsComponent.Body.AddForce(totalForce); //steer //based on the amazing work of Why485 (https://www.youtube.com/user/Why485) var steerControl = new Vector3(Math.Abs(PlayerPitch) > 0 ? PlayerPitch : Pitch, Math.Abs(PlayerYaw) > 0 ? PlayerYaw : Yaw, Roll); double pitch, yaw, roll; DecomposeOrientation(Parent.PhysicsComponent.Body.Transform, out pitch, out yaw, out roll); if (Math.Abs(PlayerPitch) < float.Epsilon && Math.Abs(PlayerYaw) < float.Epsilon) { steerControl.Z = MathHelper.Clamp((float)rollPID.Update(0, roll, (float)time), -0.5f, 0.5f); } else { rollPID.Reset(); } var angularForce = Parent.PhysicsComponent.Body.RotateVector(steerControl * Ship.SteeringTorque); angularForce += (Parent.PhysicsComponent.Body.AngularVelocity * -1) * Ship.AngularDrag; //transform torque by direction = unity's AddRelativeTorque Parent.PhysicsComponent.Body.AddTorque(angularForce); }
public void EndCruise() { EngineState = EngineStates.Standard; }
public virtual void Reset() { this.PreviousState = EngineStates.None; this.NextState = EngineStates.None; this.CenterDisplayLine1 = false; this.CenterDisplayLine2 = false; this.DisplayLine1 = ""; this.DisplayLine2 = ""; }
protected virtual void OnStateChanged(EngineStates newState, Exception errorException = null, string message = null) { var oldState = CurrentState; CurrentState = newState; var e = new StateChangedEventArgs(oldState, newState, errorException, message); EventHandler<StateChangedEventArgs> handler = StateChanged; if (handler != null) handler(this, e); }
private void RenderGraphics(object obj) { Frame = new Bitmap(800, 600); Graphics f_handle = Graphics.FromImage(Frame); Pause.State = true; bool flag_linestart = false; bool flag_lineend = false; Line Editorline = new Line(); int Ground = 0; DateTime Starttime = DateTime.Now; Font Time_f = new Font("Arial", 24f); Brush Time_b = new SolidBrush(Color.Blue); bool Clockwise = false; Bitmap Stone = global::LineRider.Properties.Resources.grabstein; Brush Time_rect = new SolidBrush(Color.Salmon); while (true) { // Auf Verarbeitungsbefehl warten Process.WaitOne(100); #region Spielzustand // Spielzustand switch (State) { default: case EngineStates.Editor: Load.Enabled = true; Save.Enabled = true; Pause.State = true; Pause.Enabled = true; Play.Enabled = true; Load.State = false; Save.State = false; Pause.State = true; Play.State = false; if (flag_lineend) { Editorline.Calculate(); Lines.Add(Editorline); Editorline = new Line(); flag_lineend = false; flag_linestart = false; } break; case EngineStates.Load: Load.Enabled = false; Save.Enabled = false; Load.State = true; Pause.Enabled = false; Play.Enabled = false; Save.State = false; Pause.State = false; Play.State = false; break; case EngineStates.Run: Load.Enabled = false; Save.Enabled = false; Play.State = true; Pause.Enabled = true; Play.Enabled = true; Load.State = false; Save.State = false; Pause.State = false; break; case EngineStates.Save: Load.Enabled = false; Save.Enabled = false; Save.State = true; Pause.Enabled = false; Play.Enabled = false; Load.State = false; Pause.State = false; Play.State = false; break; } #endregion #region Berechnungen // Berechnungen anstellen if ((Move.WaitOne(0) == true) && (State == EngineStates.Run)) { // Fahrdauer rechnen Playtime = DateTime.Now - Starttime; // Geschwindigkeit des Spielers rechnen if (Rider.Contacted == null) { #region Freier Fall double y_speed = Rider.Speed * Math.Sin(Rider.Angle / 360 * 2 * Math.PI) - 1; double x_speed = Rider.Speed * Math.Cos(Rider.Angle / 360 * 2 * Math.PI); Rider.Speed = Math.Sqrt((y_speed * y_speed) + (x_speed * x_speed)); if (Rider.Speed > MAX_SPEED) { double factor = MAX_SPEED / Rider.Speed; y_speed = y_speed * factor; x_speed = x_speed * factor; Rider.Speed = MAX_SPEED; } if (Rider.Speed == 0) { Rider.Angle = 270; } else { if (x_speed > 0) { Rider.Angle = (Math.Asin(y_speed / Rider.Speed) * 360 / (2 * Math.PI)) % 360; } else { Rider.Angle = (180 - Math.Asin(y_speed / Rider.Speed) * 360 / (2 * Math.PI)) % 360; } } if (Rider.Angle < 0) { Rider.Angle += 360; } #endregion } else { #region Auf Linie // Speed prüfen, falls zu klein, Spielerwinkel drehen if (Rider.Speed == 0 || Math.Abs(Rider.Speed) < Rider.Contacted.acc) { Rider.Angle = (Rider.Angle + 180) % 360; // Loopingrichtung wechseln Clockwise = !Clockwise; } // Je nach Winkel Beschleunigung addieren if (Rider.Angle > 0 && Rider.Angle < 180) { Rider.Speed -= Rider.Contacted.acc; } else { if (Rider.Angle != 0 && Rider.Angle != 180) { Rider.Speed += Rider.Contacted.acc; } } // speed begrenzen if (Rider.Speed > MAX_SPEED) { Rider.Speed = MAX_SPEED; } #endregion } #region Schneiden mit anderen Linien // Bewegungslinie rechnen PointF NextPos = getNextPosition(Rider); Line Movement = new Line(); Movement.Start = new Point((int)Rider.Position.X, (int)Rider.Position.Y); Movement.End = new Point((int)NextPos.X, (int)NextPos.Y); // Schnittlinie und Schnittpunkt erstellen Line CutLine = Rider.Contacted; PointF CutPoint = Rider.Position; double NewAngle = Clockwise ? 360 : 0; // Schnittpunkt mit anderen linien prüfen foreach (Line L in Lines) { // Eigene Linie ignorieren if (L == Rider.Contacted) { continue; } // Schnittpunkt zwischen der Linie und der Bewegungslinie berechnen PointF Cut = getCutPoint(Movement, L); // Schnittpunkt innerhalb der Bewegung? if (inRange(Cut, Movement) && inRange(Cut, L)) { if (CutLine != null) { // Winkel zwischen Kontaktierter und neuer Linie Rechnen double Angle = getNewAngle(CutLine.Angle, L); // Winkel des Spielers? if (Clockwise) { if (Angle < NewAngle) { // Copy Line CutLine = L; CutPoint = Cut; // Copy Angle NewAngle = Angle; } } else { if (Angle > NewAngle) { // Copy Line CutLine = L; CutPoint = Cut; // Copy Angle NewAngle = Angle; } } } else { // Copy Line CutLine = L; CutPoint = Cut; } } } // Kontaktierte Linie zwischenspeichern Line Contacted_Old = Rider.Contacted; // Neue Kontaktierte Linie? if ((CutLine != null) && (CutLine != Rider.Contacted)) { // Kontaktierte Linie wechseln Rider.Contacted = CutLine; // Spieler bewegen Rider.Position = CutPoint; } // Kontaktierte Linie vorhanden? if (Rider.Contacted != null) { // prüfen, ob Linie ausser Reichweite if (inRange(Rider.Position, Rider.Contacted) == false) { // Linie entfernt Rider.Contacted = null; } } #endregion #region Geschwindigkeitsänderung bei neuem Kontakt mit Linien // prüfen, ob sich kontaktierte linie geändert hat if (Contacted_Old != Rider.Contacted) { // kontaktierte linie hat sich verändert, nullprüfung? if (Rider.Contacted != null) { // linienwechsel, oder Fall auf linie, bei freiem fall auf linie, speed verkleinern if (Contacted_Old == null) { Rider.Speed = Rider.Speed * 0.8; } else { Rider.Speed = Rider.Speed * 0.9; } // Neuer Spielerwinkel rechnen Rider.Angle = getNewAngle(Rider.Angle, Rider.Contacted); } else { // kein Kontakt mehr } } #endregion #region Linie Färben // Abfrage Linie kontaktiert if (Rider.Contacted != null) { // Kontaktierte Linie rot färben Rider.Contacted.Color = Color.Red; } // Alle nicht kontaktierten Linien schwarz färben Lines.ForEach(x => { if (x != Rider.Contacted) { x.Color = Color.Black; } }); #endregion #region Bewegung des Spielers rechnen // Verschiebung in X rechnen Rider.Position.X += (float)(Rider.Speed * Math.Cos(Rider.Angle * Math.PI / 180)); // Verschiebung in Y rechnen Rider.Position.Y += (float)(Rider.Speed * Math.Sin(Rider.Angle * Math.PI / 180)); // Feststellen ob Spiel zu ende ist if (Rider.Position.Y < Ground) { // Spieler Tod position merken Deadpoints.Add(Rider.Position); while (Deadpoints.Count > 11) { Deadpoints.RemoveAt(0); } State = EngineStates.Editor; Rider.Position.X = 100; Rider.Position.Y = 500; Rider.Angle = 270f; Rider.Speed = 0; Play.Clicked = false; } else { // Verschiebung Ursprungskoordinaten Origin.X = -(int)Rider.Position.X + 400; Origin.Y = -(int)Rider.Position.Y + 300; } #endregion } #endregion #region Zeichnen // Hintergrund zeichnen f_handle.Clear(Color.Honeydew); // Linien zeichnen Lines.ForEach(x => x.Draw(f_handle, Offset, Origin)); // Editorlinie zeichnen if (flag_linestart) { Editorline.Draw(f_handle, Offset, Origin); } // Grabsteine zeichnen foreach (PointF Pos in Deadpoints) { f_handle.DrawImage(Stone, (int)(Offset.X + (Origin.X + Pos.X) - 0.5 * 30.55), (int)(Offset.Y - (Origin.Y + Pos.Y) - 0.5 * 36), 30.55f, 36f); } // Spieler zeichnen Rider.Draw(f_handle, Offset, Origin); // Spielzeitzähler f_handle.FillRectangle(Time_rect, 5f, 557f, 150f, 34f); f_handle.DrawString(Playtime.ToString("hh\\:mm\\:ss"), Time_f, Time_b, 10f, 556f); // Menu GameButtons.ForEach(x => x.Draw(f_handle)); // Frame zeichnen g.DrawImage(Frame, 0, 0); #endregion #region Nachrichtenverarbeitung // Nachrichtenpostfach abarbeiten while (Messages.IsEmpty == false) // Anzahl der Nachrichten wird gezählt { // Nachricht aus Postfach holen UI_Message Message; if (Messages.TryDequeue(out Message) == false) { continue; } // Schauen, welcher Button geklickt wurde GameButtons.ForEach(x => x.Handle_UI(Message)); if (Play.Clicked) { if (State != EngineStates.Run) { State = EngineStates.Run; Starttime = DateTime.Now; if (Lines.Count == 0) { Ground = 0; } else { Ground = Lines.Min(x => x.Start.Y); if (Ground > Lines.Min(x => x.End.Y)) { Ground = Lines.Min(x => x.End.Y); } Ground -= 100; } Clockwise = false; } } else { if (Pause.Clicked) { State = EngineStates.Editor; Rider.Position.X = 100; Rider.Position.Y = 500; Rider.Angle = 270f; Rider.Speed = 0; // Verschiebung Nullpunkt auf Null Origin.X = 0; Origin.Y = 0; } else { if (Load.Clicked) { if (State != EngineStates.Load) { State = EngineStates.Load; LoadGame.Invoke(this, null); } } else { if (Save.Clicked) { if (State != EngineStates.Save) { State = EngineStates.Save; SaveGame.Invoke(this, null); } } else { } } } } // Wenn im State Editor, vom Benutzer eingegebene Punkte zu einer Linie umrechnen if ((State == EngineStates.Editor) && (Pause.Clicked == false)) { switch (Message.Type) { // Mit einem Linksklick wird der Start einer Linie markiert case UI_Message.Clicktype.Left: flag_linestart = true; Editorline.Start.X = Offset.X - Origin.X + Message.Position.X; Editorline.Start.Y = Offset.Y - Origin.Y - Message.Position.Y; Editorline.End.X = Editorline.Start.X; Editorline.End.Y = Editorline.Start.Y; break; // Mit einem Rechtsklick wird eine Linie gelöscht case UI_Message.Clicktype.Right: Point Shifted = new Point(Offset.X - Origin.X + Message.Position.X, Offset.Y - Origin.Y - Message.Position.Y); deleteLine(Shifted); break; // Mit dem bewegen der Maus wird der Endpunkt verschoben case UI_Message.Clicktype.Move: if (flag_linestart) { Editorline.End.X = Offset.X - Origin.X + Message.Position.X; Editorline.End.Y = Offset.Y - Origin.Y - Message.Position.Y; Editorline.Calculate(); } break; // Mit Loslassen der Linkstaste wird der Enpunkt der Linie gesetzt case UI_Message.Clicktype.Released: if (flag_linestart) { Editorline.End.X = Offset.X - Origin.X + Message.Position.X; Editorline.End.Y = Offset.Y - Origin.Y - Message.Position.Y; flag_lineend = true; } break; default: break; } } else { // Flags zurücksetzen flag_linestart = false; flag_lineend = false; } } #endregion } }
/// <summary> /// Konstruktor /// </summary> public Engine() { Lines = new List<Line>(); Rider = new Player(new Point(100,500),60,global::LineRider.Properties.Resources.player_gerade); Playtime = new TimeSpan(); GameButtons = new List<GameButton>(); Origin = new Point(); Messages = new ConcurrentQueue<UI_Message>(); Offset = new Point(0, 600); int Size = 40; Play = new GameButton(new Point((int)(800 / 2 - (2 * Size + 1.5 * 10)), 10), Size, true, global::LineRider.Properties.Resources.Button_Play_icon); Pause = new GameButton(new Point((int)(800 / 2 - (1 * Size + 0.5 * 10)), 10), Size, true, global::LineRider.Properties.Resources.Button_Pause_icon); Save = new GameButton(new Point((int)(800 / 2 + (0.5 * 10)), 10), Size, true, global::LineRider.Properties.Resources.Save_icon); Load = new GameButton(new Point((int)(800 / 2 + (1 * Size + 1.5 * 10)), 10), Size, true, global::LineRider.Properties.Resources.Open_Folder_icon); GameButtons.Add(Play); GameButtons.Add(Pause); GameButtons.Add(Save); GameButtons.Add(Load); State = EngineStates.Editor; Deadpoints = new List<PointF>(); Move = new AutoResetEvent(false); Process = new AutoResetEvent(true); MoveTimer = new System.Windows.Forms.Timer(); MoveTimer.Interval = 50; MoveTimer.Tick += MoveTimer_Tick; MoveTimer.Start(); }
private void SwitchState(EngineStates nextState) { this.currentState = nextState; this.states[this.currentState].Reset(); }