示例#1
0
        /// <summary>
        /// Wird aufgerufen, wenn sich die Zeit verändert hat.
        /// </summary>
        /// <param name="spielfeld">Die Simulation, in der wir leben.</param>
        /// <param name="neueZeit">Die ab nun gültige Spielzeit.</param>
        private void ZeitHatSichVerändert( Simulation spielfeld, TimeSpan neueZeit )
        {
            // Neuen Abzug berechnen
            var schwächung = (int) Math.Round( neueZeit.TotalSeconds * 62.5 );
            if (schwächung == m_schwächung)
                return;

            // Übernehmen
            m_schwächung = schwächung;

            // Melden
            LebenskraftWurdeVerändert();
        }
        /// <summary>
        /// Wird aufgerufen, um die Spielumgebung aufzusetzen.
        /// </summary>
        /// <param name="spiel">Ein Spiel, das nun vollständig verfügbar ist. Insbesondere sind die Dimensionen
        /// aller Elemente auf dem Spielfeld bekannt.</param>
        public static void SpielumgebungAufsetzen( this PraesentationsModelle.Spiel spiel )
        {
            // Sichtbaren Bereich ermitteln
            var spielfeld = spiel.Spielfeld;
            var hintergrund = spielfeld.Hintergrund;
            var höheSpielfeld = (decimal) hintergrund.Hoehe;
            var links = (decimal) (spiel.Breite / 2);
            var unten = (decimal) (spiel.Hoehe / 2);
            var breite = (decimal) (hintergrund.Breite - spiel.Breite);
            var höhe = höheSpielfeld - (decimal) spiel.Hoehe;

            // Spielfeld anlegen
            var simulation = new Simulation();

            // Ausdehung der Spielfigur berücksichtigen
            var spielfigur = spiel.Spielfigur;
            if (spielfigur != null)
            {
                // Auslesen
                var breiteDerFigur = (decimal) spielfigur.Breite;
                var höheDerFigur = (decimal) spielfigur.Hoehe;

                // Korrigieren
                links -= breiteDerFigur / 2;
                unten -= höheDerFigur / 2;
                breite += breiteDerFigur;
                höhe += höheDerFigur;

                // Fallgeschwindigkeit schätzen
                simulation.FallGeschwindigkeit = (GenaueZahl) (Ablage.Skalierungswerte.Fallgeschwindigkeit * höheDerFigur / höheSpielfeld);
            }

            // Methode zum zurückrechnen
            Func<Bereich, Rect> absoluteKoordinaten = bereich =>
                new Rect
                (
                    InPixelWandeln( (decimal) bereich.KleinsteHorizontalePosition * breite + links ),
                    InPixelWandeln( (decimal) bereich.KleinsteVertikalePosition * höhe + unten ),
                    InPixelWandeln( (decimal) bereich.Breite * breite ),
                    InPixelWandeln( (decimal) bereich.Höhe * höhe )
                );

            // Alle Elemente dort ergänzen
            foreach (PraesentationsModelle.Element<IVerbinderErzeuger> element in spielfeld.Elemente)
            {
                // Das Element mit dem Spiel verbinden
                element.Spiel = spiel;

                // Elemente oberhalb der Spielfigur werden von der Simulation nicht erfasst
                if (element.Ebene > 0)
                    continue;

                // Koordinaten blind umrechnen
                var relativUnten = (höheSpielfeld - (decimal) (element.VertikalePosition + element.Hoehe) - unten) / höhe;
                var relativLinks = ((decimal) element.HorizontalePosition - links) / breite;
                var relativeBreite = (decimal) element.Breite / breite;
                var relativeHöhe = (decimal) element.Hoehe / höhe;

                // Horizontal beschneiden
                if (relativLinks > 1)
                    continue;
                else if (relativLinks < 0)
                {
                    // Später anfangen und etwas schmaler
                    relativeBreite += relativLinks;
                    relativLinks = 0;
                }

                // Vertikal beschneiden
                if (relativUnten > 1)
                    continue;
                else if (relativUnten < 0)
                {
                    // Später anfangen und etwas niedriger
                    relativeHöhe += relativUnten;
                    relativUnten = 0;
                }

                // Breite beschneiden
                if (relativeBreite <= 0)
                    continue;
                else if ((relativLinks + relativeBreite) > 1)
                    relativeBreite = 1 - relativLinks;

                // Höhe beschneiden
                if (relativeHöhe <= 0)
                    continue;
                else if ((relativUnten + relativeHöhe) > 1)
                    relativeHöhe = 1 - relativUnten;

                // Ausdehung der Fläche zum Element
                var position = Position.Erzeugen( (GenaueZahl) (relativLinks + relativeBreite / 2), (GenaueZahl) (relativUnten + relativeHöhe / 2) );
                var ausdehung = Ausdehnung.Erzeugen( (GenaueZahl) (relativeBreite), (GenaueZahl) (relativeHöhe) );

                // Der Algorithmus zur Erzeugung des Elementes
                var initialisierung = element.InitialisiereVerbinder();

                // Element erzeugen
                var verbinder = initialisierung.Erzeuge( position, ausdehung, breite, höhe, absoluteKoordinaten, element );

                // Element im Spielfeld anmelden
                simulation.ElementHinzufügen( verbinder );
            }

            // Zeitgeber anbinden
            simulation.Zeitgeber += ( s, zeit ) => spiel.GespielteZeit = zeit;

            // Simulation anbinden
            ((PraesentationsModelle.Steuerung) spiel.Steuerung).SimulationSetzen( simulation );
        }
        /// <summary>
        /// Bewegt alle Elemente.
        /// </summary>
        /// <param name="spielfeld">Das aktuelle Spielfeld.</param>
        /// <param name="spielZeit">Die bisherige Spielzeit.</param>
        /// <param name="verpassteZeit">Die seit dem letzten Aufruf verpasste Spielzeit.</param>
        internal static void Ausführen( Simulation spielfeld, TimeSpan spielZeit, TimeSpan verpassteZeit )
        {
            // Verpasste Zeit umrechnen
            var verpassteSekunden = (decimal) verpassteZeit.TotalSeconds;

            // Alle Elemente in Bewegung
            var elemente =
                spielfeld
                    .Elemente
                    .Select( element => new BewegungsInformation( element, spielZeit, verpassteSekunden ) )
                    .Where( info => info.Geschwindigkeit != null )
                    .ToArray();

            // Elementarbewegungen ausführen solange es nötig ist
            for (bool inBewegung = true; inBewegung; )
            {
                // Alle Elemente untersuchen
                inBewegung = elemente.Count(
                    element =>
                    {
                        // Bewegt sich nicht
                        if (!element.ElementarBewegungAusführen( spielfeld.Elemente ))
                            return false;

                        // Merken
                        inBewegung = true;

                        // Wir haben uns bewegt
                        return true;
                    } ) > 0;
            }
        }