示例#1
0
        /// <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();
        }
示例#2
0
 public StateChangedEventArgs(EngineStates oldState, EngineStates newState, Exception errorException = null, string message = null)
     : base()
 {
     OldState       = oldState;
     NewState       = newState;
     ErrorException = errorException;
     Message        = message;
 }
示例#3
0
 public void BeginCruise()
 {
     if (EngineState != EngineStates.Cruise &&
         EngineState != EngineStates.CruiseCharging)
     {
         EngineState    = EngineStates.CruiseCharging;
         ChargePercent  = 0f;
         cruiseAccelPct = 0f;
     }
 }
示例#4
0
 public void CruiseToggle()
 {
     if (EngineState == EngineStates.Cruise ||
         EngineState == EngineStates.CruiseCharging)
     {
         EngineState = EngineStates.Standard;
     }
     else
     {
         BeginCruise();
     }
 }
示例#5
0
 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
     });
 }
示例#6
0
        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);
            }
        }
示例#7
0
        /// <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");
            }
        }
示例#8
0
        //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);
        }
示例#9
0
 public void EndCruise()
 {
     EngineState = EngineStates.Standard;
 }
示例#10
0
        public virtual void Reset()
        {
            this.PreviousState = EngineStates.None;
            this.NextState = EngineStates.None;

            this.CenterDisplayLine1 = false;
            this.CenterDisplayLine2 = false;

            this.DisplayLine1 = "";
            this.DisplayLine2 = "";
        }
 public StateChangedEventArgs(EngineStates oldState, EngineStates newState, Exception errorException = null, string message = null)
     : base()
 {
     OldState = oldState;
     NewState = newState;
     ErrorException = errorException;
     Message = message;
 }
        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);
        }
示例#13
0
文件: Engine.cs 项目: Al90/Project
        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
            }
        }
示例#14
0
文件: Engine.cs 项目: Al90/Project
 /// <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();
 }
示例#15
0
 private void SwitchState(EngineStates nextState)
 {
     this.currentState = nextState;
     this.states[this.currentState].Reset();
 }
示例#16
0
        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
            }
        }