/// <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; } }