none
Code soll Animation abwarten XAML/C# RRS feed

  • Frage

  • Hallo, 

    ich arbeite gerade an meiner ersten WinRT App, einem Kartenspiel. Es funktioniert schon recht gut, nur habe ich ein Problem mit der Animation:

    Zu Beginn werden die Karten durch eine Animation, die ich mit Blend erstellt und ins Projekt eingebunden habe, ausgeteilt. Diese dauert exakt 5,5 sec. Das Problem dabei ist, dass der Computergegner schon seinen Angriff startet, noch bevor die Animation fertig abgespielt wurde. Die Handkarten/das Spielfeld sind bei mir ObservableCollections, die in der Klasse CKartenspiel gefüllt bzw. hin und her bewegt werden. 

    Ich muss zugeben ich habe noch nicht allzu viel Programmiererfahrung, aber rein logisch müsste mein Code funktionieren.
    Jedoch wird beim Ausführen der Anwendung zuerst gewartet, dann die Page aufgebaut und anschließend die Animation abgespielt, dabei hat der Gegner seinen Zug schon gemacht und das obwohl er seine Karten "eigentlich" noch gar nicht hat.  
    CodeBehind meiner Seite auf der das Spiel stattfindet. 
    public NewGamePage()
    {
       //Aufbau XAML 
       this.InitializeComponent();
       
       //Animation starten
       Storyboard.Begin();
       
       //Code zum Warten 
       new System.Threading.ManualResetEvent(false).WaitOne(5500);
    
       //Instanz erzeugen
       kartenspiel = new CKartenspiel();
       DataContext = kartenspiel;
    
    }

    Ich habe auch versucht den Code zum Warten in meine Klasse zu packen aber gebracht hats nichts. Mir ist bewusst dass das nicht der beste Ansatz ist, aber was anderes fällt mir nicht ein. Die schönste Lösung wäre, wenn die Animation das selbst steuern könnte, ob der Code 'angehalten' wird oder nicht.

    Hat jemand einen Lösungvorschlag?

    Vielen Dank und viele Grüße,
    Julia    
     

    Samstag, 31. Mai 2014 10:05

Antworten

  • Hallo,
    Animationen laufen asynchron und werden ggf. von Windows leistungsschonender ausgeführt. Das hat zur Folge, das die Animation nicht zwingend 5,5s dauert.
    Du hast allerdings im XAML irgendwo dein Storyboard liegen. Von diesem kannst du das Completed-Event abonnieren:

    <Storyboard Completed="OnCompleted" ...

    Dieses Event wird ausgelöst, sobald die Animation vollständig abgespielt wurde. Sobald das Event eintritt, kannst du also das eigentliche Spiel starten.

    Einen wirklichen Sleep-Befehl gibt es nicht mehr. Task.Delay() kommt noch am nächsten heran, ist aber auch nicht exakt das Selbe und sollte vermieden werden.

    Ich weiß nicht, was deine Animation ändert, aber wenn sie die Karten bewegt, dann müssen diese natürlich schon da sein. Also müsste die CKartenspiel-Klasse auch schon als DataContext vorliegen.
    Ich hätte den DataContext von Anfang an zugewiesen und nur das Control im XAML deaktiviert (IsEnabled="false"). Sobald die Animation beendet wurde, würde ich die Eigenschaft wieder auf true setzen. Solange die Eigenschaft false ist, sind keine Interaktionen und somit kein Spielen möglich.

    PS: Da deine Klasse CKartenspiel heißt, das C erinnert an den C++ Präfix für Klassennamen. Das ist in C# größtenteils unüblich. Das heißt das deine Klasse nur Kartenspiel heißen würde. Wenn das C eine Andere Bedeutung hat, ist es natürlich kein Konventionsverstoß.
    Prä- und Suffixe gibt es in C# nur bei Schnittstellen (I...), EventArgs (...EventArgs) und Ausnahmen (...Exception) und Eventuell bei Gruppen von gleichen Elementen (LINQ to XML-Klassen, ...).


    Tom Lambert - C# MVP
    Bitte bewertet- und markiert Beiträge als Antwort. Danke.
    Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter
    Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets

    • Als Antwort markiert 4HToX4 Samstag, 31. Mai 2014 12:07
    Samstag, 31. Mai 2014 10:42

Alle Antworten

  • Hallo,
    Animationen laufen asynchron und werden ggf. von Windows leistungsschonender ausgeführt. Das hat zur Folge, das die Animation nicht zwingend 5,5s dauert.
    Du hast allerdings im XAML irgendwo dein Storyboard liegen. Von diesem kannst du das Completed-Event abonnieren:

    <Storyboard Completed="OnCompleted" ...

    Dieses Event wird ausgelöst, sobald die Animation vollständig abgespielt wurde. Sobald das Event eintritt, kannst du also das eigentliche Spiel starten.

    Einen wirklichen Sleep-Befehl gibt es nicht mehr. Task.Delay() kommt noch am nächsten heran, ist aber auch nicht exakt das Selbe und sollte vermieden werden.

    Ich weiß nicht, was deine Animation ändert, aber wenn sie die Karten bewegt, dann müssen diese natürlich schon da sein. Also müsste die CKartenspiel-Klasse auch schon als DataContext vorliegen.
    Ich hätte den DataContext von Anfang an zugewiesen und nur das Control im XAML deaktiviert (IsEnabled="false"). Sobald die Animation beendet wurde, würde ich die Eigenschaft wieder auf true setzen. Solange die Eigenschaft false ist, sind keine Interaktionen und somit kein Spielen möglich.

    PS: Da deine Klasse CKartenspiel heißt, das C erinnert an den C++ Präfix für Klassennamen. Das ist in C# größtenteils unüblich. Das heißt das deine Klasse nur Kartenspiel heißen würde. Wenn das C eine Andere Bedeutung hat, ist es natürlich kein Konventionsverstoß.
    Prä- und Suffixe gibt es in C# nur bei Schnittstellen (I...), EventArgs (...EventArgs) und Ausnahmen (...Exception) und Eventuell bei Gruppen von gleichen Elementen (LINQ to XML-Klassen, ...).


    Tom Lambert - C# MVP
    Bitte bewertet- und markiert Beiträge als Antwort. Danke.
    Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter
    Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets

    • Als Antwort markiert 4HToX4 Samstag, 31. Mai 2014 12:07
    Samstag, 31. Mai 2014 10:42
  • Hallo Tom, 

    Wahnsinn! ich bin begeistert... Ich plag mit seit Tagen ab und dann gehts doch so einfach. 
    Ich hab nicht soweit gedacht, dass Animationen auch Events haben. Aber das war die Lösung. Jetzt funktionierts. Vielen Dank.

    In meinen Fall hats gereicht den DataContext im Event Completed zu setzen, da die Animation nur das Austeilen von verdeckten Karten ist und dahinter keine Werte sind bzw. davor auch noch keine Karten liegen.

    Ich habe mich davor tatsächlich mit C++ beschäftigt und habe die Gewohnheit wohl noch nicht ganz abgelegt. ;)  Danke für den Tipp 

    Grüße, 
    Julia 

      
    Samstag, 31. Mai 2014 12:06