/// <summary> /// Prüft, ob das Element eine Bewegung ausführen soll. /// </summary> /// <param name="bewegung">Die Konfiguration der Bewegung.</param> /// <param name="element">Das Element auf dem Spielfeld.</param> /// <param name="breite">Die gesamte Breite der Simulation.</param> /// <param name="höhe">Die gesamte Höhe der Simulation.</param> public static void Aktivieren( this Ablage.ElementBewegung bewegung, GrundElement element, decimal breite, decimal höhe ) { // Keine Bewegung if (bewegung == null) return; // Alle unterstützten Bewegungen prüfen if (!s_bewegungsArten.Any( art => art( bewegung, element, breite, höhe ) )) throw new NotSupportedException( bewegung.GetType().Name ); }
/// <summary> /// Versucht, eine Bewegungsregel anzuwenden. /// </summary> /// <param name="bewegung">Die zu prüfende Bewegung.</param> /// <param name="element">Die Fläche auf dem Spielfeld.</param> /// <param name="breite">Die Breite des Spielfelds.</param> /// <param name="höhe">Die Höhe des Spielfelds.</param> /// <returns>Gesetzt, wenn eine Aktivierung stattgefunden hat.</returns> private static bool Aktivieren( HorizontaleBewegung bewegung, GrundElement element, decimal breite, decimal höhe ) { // Sind wir nicht if (bewegung == null) return false; // Durchreichen bewegung.StandardAktivierung( element, breite, höhe ); // Fertig return true; }
/// <summary> /// Erstellt eine Regel aus der Konfiguration. /// </summary> /// <param name="regel">Eine beliebige Regel.</param> /// <param name="element">Das zugehörige Element.</param> public static void AnwendenAuf( this Kollisionsregel regel, GrundElement element ) { // Prüfen if (regel == null) throw new NullReferenceException( "regel" ); if (element == null) throw new ArgumentNullException( "element" ); // Alle bekannten Regelarten prüfen if (!s_KollisionsArten.Any( art => art( regel, element ) )) throw new NotSupportedException( regel.GetType().Name ); }
/// <summary> /// Erstellt eine Regel aus der Konfiguration. /// </summary> /// <param name="regel">Eine beliebige Regel.</param> /// <param name="element">Das zugehörige Element.</param> /// <returns>Gesetzt, wenn die Regel ausgewertet werden konnte.</returns> private static bool RegelAnwenden( Energieregel regel, GrundElement element ) { // Prüfen if (regel == null) return false; // Lebensenergie auslesen und Regel erzeugen var lebensenergie = regel.Lebensenergie; if (lebensenergie != 0) element.RegelAnmelden( regel.ArtDerKollision, KollisionsRegel.LebenskraftDesSpielersÄndern( lebensenergie ) ); // Fertig return true; }
/// <summary> /// Aktiviert eine freie Bewegung auf einem Element. /// </summary> /// <param name="element">Das Element.</param> /// <param name="geschwindigkeiten">Die einzelnen Geschwindigkeiten mit einem relativen Bezugspunkt auf den Anfang des Spiels.</param> public static void Aktivieren( GrundElement element, params TemporaereGeschwindigkeit[] geschwindigkeiten ) { // Prüfen if (element == null) throw new ArgumentNullException( "element" ); // Nichts zu tun if (geschwindigkeiten == null) return; if (geschwindigkeiten.Length < 1) return; // Aktuellen index setzen var index = 0; // Aktivierungsregel Action<Geschwindigkeit> nächsteGeschwindigkeit = null; // Regel definieren nächsteGeschwindigkeit = beendeteGeschwindigkeit => { // Geschwindigkeit auslesen var geschwindigkeit = geschwindigkeiten[index++]; // Auf den nächsten Schritt vorbereiten index %= geschwindigkeiten.Length; // Realative Zeitangabe in eine absolute umrechnen var absoluteGeschwindigkeit = TemporaereGeschwindigkeit.Erzeugen ( geschwindigkeit.HorizontaleGeschwindigkeit, geschwindigkeit.VertikaleGeschwindigkeit, element.Spielfeld.VerbrauchteZeit + geschwindigkeit.GültigBis ); // Überwachung auf Ende anmelden absoluteGeschwindigkeit.Deaktiviert += nächsteGeschwindigkeit; // Aktivieren element.GeschwindigkeitsRegel.GeschwindigkeitErgänzen( absoluteGeschwindigkeit ); }; // Falls wir schon im Spiel sind können wir direkt loslegen, ansonsten müssen wir etwas warten if (element.Spielfeld != null) nächsteGeschwindigkeit( null ); else element.SpielfeldZugeordnet += e => nächsteGeschwindigkeit( null ); }
/// <summary> /// Prüft, ob das Element eine Bewegung ausführen soll. /// </summary> /// <param name="bewegung">Die Konfiguration der Bewegung.</param> /// <param name="element">Das Element auf dem Spielfeld.</param> /// <param name="breite">Die gesamte Breite der Simulation.</param> /// <param name="höhe">Die gesamte Höhe der Simulation.</param> private static void StandardAktivierung( this Ablage.ElementBewegung bewegung, GrundElement element, decimal breite, decimal höhe ) { // Regeln anwendern var schritte = bewegung.Schritte.ToArray(); if (schritte.Length < 1) return; // In die Präsentationssprache wandeln var geschwindigkeiten = schritte.Select( schritt => TemporaereGeschwindigkeit.Erzeugen ( (GenaueZahl) (schritt.HorizontaleDistanz / schritt.Dauer.TotalSeconds) / breite, (GenaueZahl) (schritt.VertikaleDistanz / schritt.Dauer.TotalSeconds) / höhe, schritt.Dauer ) ); // Anmelden FreieBewegung.Aktivieren( element, geschwindigkeiten.ToArray() ); }
/// <summary> /// Führt alle Aktionen zu einer Kollision aus. /// </summary> /// <param name="elementInBewegung">Das Element, dessen Bewegung für die Kollision verantwortlich ist.</param> /// <returns>Gesetzt, wenn weitere Aktionen und Bewegungen ausgeführt werden dürfen.</returns> internal bool KollisionAuswerten( GrundElement elementInBewegung ) { // Prüfen if (elementInBewegung == null) throw new ArgumentNullException( "elementInBewegung" ); // Regeln des anderen Elementes mit berücksichtigen var weitereRegeln = elementInBewegung.KollisionsRegel; // Alle Regeln WennDann[] regeln; lock (m_regeln) lock (weitereRegeln.m_regeln) regeln = m_regeln.Concat( weitereRegeln.m_regeln ).ToArray(); // Auswerten for (int i = 0; i < regeln.Length; i++) if (regeln[i].Bedingung( m_element, elementInBewegung )) if (!regeln[i].Reaktion( m_element, elementInBewegung )) return false; // Weiter machen return true; }
/// <summary> /// Erstellt ein neues Regelwerk. /// </summary> /// <param name="zugehörigesElement">Das zugehörige Element.</param> internal KollisionsRegel( GrundElement zugehörigesElement ) { // Merken m_element = zugehörigesElement; }
/// <summary> /// Deaktiviert ein Element. /// </summary> /// <param name="element">Das gewünschte Element.</param> /// <returns>Die Aktion, die das Element verschwinden läßt.</returns> public static KollisionsAktion BestimmtesElementDeaktivieren( GrundElement element ) { // Methode anlegen return ( fest, beweglich ) => { element.IstDeaktiviert = true; return true; }; }
/// <summary> /// Erzeugt eine neue Beschreibung. /// </summary> /// <param name="element">Das zugehörige Element.</param> /// <param name="spielZeit">Die bisher verstrichene Spielzeit.</param> /// <param name="sekunden">Die Anzahl der Sekunden seit der letzten Berechnung.</param> public BewegungsInformation( GrundElement element, TimeSpan spielZeit, decimal sekunden ) { // Nicht nutzbar if (element.IstDeaktiviert) return; // Merken m_verbleibendeSchritte = (int) Math.Round( 1000m * sekunden ); Element = element; // Geschwindigkeit auslesen var geschwindigkeit = element.GeschwindigkeitsRegel.AktuelleGeschwindigkeitBerechnen( spielZeit ); if (geschwindigkeit == null) return; // Anfangsposition auslesen var aktuellePosition = element.Position; // Endposition berechnen var xEnde = (aktuellePosition.HorizontalePosition + geschwindigkeit.HorizontaleGeschwindigkeit * sekunden).ZwischenNullUndEins(); var yEnde = (aktuellePosition.VertikalePosition + geschwindigkeit.VertikaleGeschwindigkeit * sekunden).ZwischenNullUndEins(); // Ziel und Geschwindigkeit merken Geschwindigkeit = geschwindigkeit; // Schrittweiten berechnen m_xSchritt = (xEnde - aktuellePosition.HorizontalePosition) / m_verbleibendeSchritte; m_ySchritt = (yEnde - aktuellePosition.VertikalePosition) / m_verbleibendeSchritte; // Es witd sich nichts verändern if (m_xSchritt == GenaueZahl.Null) if (m_ySchritt == GenaueZahl.Null) return; // Dem Element mitteilen, dass es nun losgeht element.Bewegen( aktuellePosition ); }
/// <summary> /// Erzeugt eine Regel, die ein Element bei Kollision aktiviert. /// </summary> /// <param name="regel">Die zu untersuchende Regel.</param> /// <param name="element">Das betroffene Element auf dem Spielfeld.</param> /// <returns>Gesetzt, wenn die Regel angewendet wurde.</returns> private static bool RegelAnwenden( Erscheineregel regel, GrundElement element ) { // Prüfen if (regel == null) return false; // Erzeugen und anwenden element.RegelAnmelden( regel.ArtDerKollision, KollisionsRegel.ElementAktivieren( regel.Name ) ); // Fertig return true; }
/// <summary> /// Erzeugt eine Regel, die ein Element bei Kollision ausblendet. /// </summary> /// <param name="regel">Die zu untersuchende Regel.</param> /// <param name="element">Das betroffene Element auf dem Spielfeld.</param> /// <returns>Gesetzt, wenn die Regel angewendet wurde.</returns> private static bool RegelAnwenden( Verschwinderegel regel, GrundElement element ) { // Prüfen if (regel == null) return false; // Erzeugen und anwenden switch (regel.WasSollVerschwinden) { case WasSollVerschwinden.Fest: element.RegelAnmelden( regel.ArtDerKollision, KollisionsRegel.ElementDeaktivieren ); break; case WasSollVerschwinden.Beweglich: element.RegelAnmelden( regel.ArtDerKollision, KollisionsRegel.BeweglichesElementDeaktivieren ); break; case WasSollVerschwinden.Selbst: element.RegelAnmelden( regel.ArtDerKollision, KollisionsRegel.BestimmtesElementDeaktivieren( element ) ); break; default: throw new NotSupportedException( regel.WasSollVerschwinden.ToString() ); } // Fertig return true; }
/// <summary> /// Erzeugt eine Kollisionsregeln, die das Spiel beendet. /// </summary> /// <param name="regel">Die zu untersuchende Regel.</param> /// <param name="element">Das betroffene Element auf dem Spielfeld.</param> /// <returns>Gesetzt, wenn die Regel angewendet wurde.</returns> private static bool RegelAnwenden( Enderegel regel, GrundElement element ) { // Prüfen if (regel == null) return false; // Erzeugen und anwenden element.RegelAnmelden( regel.ArtDerKollision, regel.Gewonnen ? KollisionsRegel.SpielGewonnen : KollisionsRegel.SpielVerloren ); // Fertig return true; }
/// <summary> /// Erstellt eine Regel aus der Konfiguration. /// </summary> /// <param name="regel">Eine beliebige Regel.</param> /// <param name="element">Das zugehörige Element.</param> /// <returns>Gesetzt, wenn die Regel ausgewertet werden konnte.</returns> private static bool RegelAnwenden( Punkteregel regel, GrundElement element ) { // Prüfen if (regel == null) return false; // Punkte verteilen var punkte = regel.Punkte; if (punkte != 0) element.RegelAnmelden( regel.ArtDerKollision, KollisionsRegel.PunkteAnDenSpielerÜbergeben( punkte ) ); // Fertig return true; }
/// <summary> /// Versucht, eine Bewegungsregel anzuwenden. /// </summary> /// <param name="bewegung">Die zu prüfende Bewegung.</param> /// <param name="element">Die Fläche auf dem Spielfeld.</param> /// <param name="breite">Die Breite des Spielfelds.</param> /// <param name="höhe">Die Höhe des Spielfelds.</param> /// <returns>Gesetzt, wenn eine Aktivierung stattgefunden hat.</returns> private static bool Aktivieren( BewegungRelativZurSpielfigur bewegung, GrundElement element, decimal breite, decimal höhe ) { // Sind wir nicht if (bewegung == null) return false; // Anmelden element.BewegungRelativZumSpielerAktivieren( bewegung.HorizontaleGeschwindigkeit, bewegung.Angriff ); // Fertig return true; }
/// <summary> /// Erstellt eine Regel aus der Konfiguration. /// </summary> /// <param name="regel">Eine beliebige Regel.</param> /// <param name="element">Das zugehörige Element.</param> /// <returns>Gesetzt, wenn die Regel ausgewertet werden konnte.</returns> private static bool RegelAnwenden( Verschieberegel regel, GrundElement element ) { // Prüfen if (regel == null) return false; // Anwenden element.RegelAnmelden( regel.ArtDerKollision, KollisionsRegel.HindernisVerschieben() ); // Fertig return true; }
/// <summary> /// Ergänzt ein einzelnes Element. /// </summary> /// <param name="element">Ein Element, das auf diesem Spielfeld eingesetzt werden soll.</param> /// <exception cref="ArgumentNullException">Es wurde kein Element angegeben.</exception> public void ElementHinzufügen( GrundElement element ) { // Prüfen if (element == null) throw new ArgumentNullException( "element" ); // Verbinden element.Spielfeld = this; // Merken m_elemente.Add( element ); }