Mehrere Animationen abspielen mit Sharpex2D

  • C#
  • .NET (FX) 4.0

Es gibt 15 Antworten in diesem Thema. Der letzte Beitrag () ist von KaskadekingDE.

    Mehrere Animationen abspielen mit Sharpex2D

    Hey ;) ,

    ich versuche derzeit in einen kleinen Spiel mehrere Animationen abzuspielen und zu warten bis alle vollständig abgespielt wurden (s. DrawAndWait). Dazu hab ich 2 Klassen erstellt (MultiAnimation& Animation) in welchen AnimatedSpriteSheet's verwendet werden. Allerdings hab ich dort wahrscheinlich ein Denkfehler drinne. Denn entweder die Animation spielt nur für paar Millisekunden oder sie spielt gar nicht.

    Ich wäre froh, wenn ich mir helfen könntet :)

    Spoiler anzeigen

    C#-Quellcode

    1. public class MultiAnimation : IUpdateable, IDrawable
    2. {
    3. public bool Enabled { get; set; }
    4. public Animation[] Animations { get; }
    5. public MultiAnimation(IList<AnimatedSpriteSheet> spriteSheets, IList<Rectangle> positions, bool enabled)
    6. {
    7. if (spriteSheets.Count != positions.Count && positions.Count != 1)
    8. throw new NotSupportedException("positions must have the same quantity as spriteSheets or 1");
    9. var anis = new List<Animation>();
    10. for (var i = 0; i < spriteSheets.Count; i++)
    11. {
    12. var sheet = spriteSheets[i];
    13. var rect = positions.Count == 1 ? positions[0] : positions[i];
    14. sheet.ActivateKeyframe(0);
    15. var images = ReflectionHelper<List<Keyframe>,
    16. AnimatedSpriteSheet>.GetPrivateField(sheet, "_keyframes",
    17. BindingFlags.NonPublic | BindingFlags.Instance);
    18. var ani = new Animation(sheet, images.Count, rect);
    19. anis.Add(ani);
    20. }
    21. Animations = anis.ToArray();
    22. Enabled = enabled;
    23. }
    24. public void Update(GameTime gameTime)
    25. {
    26. if (!Enabled) return;
    27. foreach (var ani in Animations)
    28. {
    29. ani.Sheet.Update(gameTime);
    30. }
    31. }
    32. public void Draw(SpriteBatch spriteBatch, GameTime gameTime)
    33. {
    34. if (!Enabled) return;
    35. spriteBatch.Begin();
    36. foreach (var ani in Animations)
    37. {
    38. spriteBatch.DrawTexture(ani.Sheet, ani.Position, Color.White);
    39. }
    40. spriteBatch.End();
    41. }
    42. public void DrawAndWait(SpriteBatch batch, GameTime time, List<int> loops)
    43. {
    44. if (!Enabled) return;
    45. var aniList = Animations.ToList();
    46. var aniLoops = new Dictionary<Animation, int>();
    47. for (var i = 0; i < aniList.Count; i++)
    48. {
    49. var ani = aniList[i];
    50. var aniLoop = loops[i];
    51. aniLoops.Add(ani, aniLoop);
    52. }
    53. var aniTuple =
    54. aniList.Select(
    55. ani =>
    56. new Quartet<Animation, int, int, Keyframe> { Item1 = ani, Item2 = 0, Item3 = 0, Item4 = null })
    57. .ToList();
    58. while (!aniTuple.All(a => a.Item3 >= aniLoops[a.Item1]))
    59. {
    60. while (!aniTuple.All(a => a.Item2 >= a.Item1.Images))
    61. {
    62. foreach (var tuple in aniTuple.Where(a => a.Item2 < a.Item1.Images))
    63. {
    64. var ani = tuple.Item1;
    65. ani.Sheet.Update(time);
    66. if (tuple.Item4 != null && tuple.Item4 == ani.Sheet.CurrentKeyframe)
    67. {
    68. continue;
    69. }
    70. tuple.Item4 = ani.Sheet.CurrentKeyframe;
    71. if (tuple.Item4 == null)
    72. continue;
    73. tuple.Item2++;
    74. if (tuple.Item2 >= ani.Images)
    75. {
    76. tuple.Item3++;
    77. if (tuple.Item3 >= aniLoops[ani])
    78. continue;
    79. }
    80. batch.Begin();
    81. if (ani.Sheet.CurrentKeyframe != null)
    82. batch.DrawTexture(ani.Sheet, ani.Position, Color.White);
    83. batch.End();
    84. }
    85. }
    86. foreach (var tuple in aniTuple)
    87. {
    88. tuple.Item2 = 0;
    89. }
    90. }
    91. }
    92. }
    93. public class Animation
    94. {
    95. public AnimatedSpriteSheet Sheet { get; }
    96. public int Images { get; set; }
    97. public Rectangle Position { get; }
    98. public Animation(AnimatedSpriteSheet sheet, int images, Rectangle position)
    99. {
    100. Sheet = sheet;
    101. Images = images;
    102. Position = position;
    103. }
    104. }

    Und falls das notwendig sein sollte:
    Spoiler anzeigen

    C#-Quellcode

    1. public class Quartet<T1, T2, T3, T4>
    2. {
    3. public T1 Item1 { get; set; }
    4. public T2 Item2 { get; set; }
    5. public T3 Item3 { get; set; }
    6. public T4 Item4 { get; set; }
    7. }
    8. public static class ReflectionHelper<T, TI>
    9. {
    10. public static T GetPrivateField(TI parentClass, string name, BindingFlags flags)
    11. {
    12. var fieldInfo = parentClass.GetType().GetField(name, flags);
    13. if (fieldInfo != null)
    14. {
    15. var fi = fieldInfo.GetValue(parentClass);
    16. return (T)fi;
    17. }
    18. return default(T);
    19. }
    20. }

    KaskadekingDE on GitHub :)
    Bitte keine Fragen über Programmierung per PN! Dafür ist das Forum hier.

    Who cares? ¯\_(ツ)_/¯

    ThuCommix schrieb:

    Der Animated SpriteSheet macht doch schon das was du willst, oder verstehe ich da was falsch?

    Ich will halt mehrere gleichzeitig abspielen und warten bis die Animation durchgelaufen ist. Ich benutz die Version von GitHub (api-2-working).

    ThuCommix schrieb:

    Wieso greifst du mit Reflection auf die internen Member von SpriteSheet zu?

    Weil ich die Anzahl der Teilbilder brauchte.
    KaskadekingDE on GitHub :)
    Bitte keine Fragen über Programmierung per PN! Dafür ist das Forum hier.

    Who cares? ¯\_(ツ)_/¯
    Ja, ich weiß. War ja auch nur ne Quick & Dirty Lösung. Werd ich später auch noch machen ;)

    EDIT: Hier mal der aktuelle Code:
    Spoiler anzeigen

    C#-Quellcode

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using Sharpex2D.Framework;
    5. using Sharpex2D.Framework.Rendering;
    6. namespace ChainReact.Core.Game.Animations
    7. {
    8. public class MultiAnimation : IUpdateable, IDrawable
    9. {
    10. public bool Enabled { get; set; }
    11. public Animation[] Animations { get; }
    12. public MultiAnimation(IList<AnimatedSpriteSheet> spriteSheets, IList<Rectangle> positions, bool enabled)
    13. {
    14. if (spriteSheets.Count != positions.Count && positions.Count != 1)
    15. throw new NotSupportedException("positions must have the same quantity as spriteSheets or 1");
    16. var anis = new List<Animation>();
    17. for (var i = 0; i < spriteSheets.Count; i++)
    18. {
    19. var sheet = spriteSheets[i];
    20. var rect = positions.Count == 1 ? positions[0] : positions[i];
    21. sheet.ActivateKeyframe(0);
    22. var ani = new Animation(sheet, sheet.KeyframeCount, rect);
    23. anis.Add(ani);
    24. }
    25. Animations = anis.ToArray();
    26. Enabled = enabled;
    27. }
    28. public void Update(GameTime gameTime)
    29. {
    30. if (!Enabled) return;
    31. foreach (var ani in Animations)
    32. {
    33. ani.Sheet.Update(gameTime);
    34. }
    35. }
    36. public void Draw(SpriteBatch spriteBatch, GameTime gameTime)
    37. {
    38. if (!Enabled) return;
    39. spriteBatch.Begin();
    40. foreach (var ani in Animations)
    41. {
    42. spriteBatch.DrawTexture(ani.Sheet, ani.Position, Color.White);
    43. }
    44. spriteBatch.End();
    45. }
    46. public void DrawAndWait(SpriteBatch batch, GameTime time, List<int> loops)
    47. {
    48. if (!Enabled) return;
    49. var aniList = Animations.ToList();
    50. foreach (var ani in aniList)
    51. ani.Loops = 0;
    52. var aniLoops = new Dictionary<Animation, int>();
    53. for (var i = 0; i < aniList.Count; i++)
    54. {
    55. var ani = aniList[i];
    56. var aniLoop = loops[i];
    57. aniLoops.Add(ani, aniLoop);
    58. }
    59. var aniTuple = aniList.ToDictionary<Animation, Animation, Keyframe>(ani => ani, ani => null);
    60. while (!aniTuple.All(a => a.Key.Loops >= aniLoops[a.Key]))
    61. {
    62. while (!aniTuple.All(a => a.Key.Sheet.CurrentKeyframeIndex >= a.Key.Images))
    63. {
    64. foreach (var tuple in aniTuple.Where(a => a.Key.Sheet.CurrentKeyframeIndex < a.Key.Images))
    65. {
    66. var ani = tuple.Key;
    67. var keyframe = tuple.Value;
    68. ani.Sheet.Update(time);
    69. if (keyframe != null && keyframe == ani.Sheet.CurrentKeyframe)
    70. {
    71. continue;
    72. }
    73. keyframe = ani.Sheet.CurrentKeyframe;
    74. if (keyframe == null)
    75. continue;
    76. if (ani.Sheet.CurrentKeyframeIndex >= ani.Images)
    77. {
    78. ani.Loops++;
    79. if (ani.Loops >= aniLoops[ani])
    80. continue;
    81. }
    82. batch.Begin();
    83. if (ani.Sheet.CurrentKeyframe != null)
    84. batch.DrawTexture(ani.Sheet, ani.Position, Color.White);
    85. batch.End();
    86. }
    87. }
    88. foreach(var ani in aniTuple)
    89. ani.Key.Sheet.Update(time);
    90. var itemsToRemove = aniTuple.Where(a => a.Key.Loops >= aniLoops[a.Key]).ToArray();
    91. foreach (var item in itemsToRemove)
    92. aniTuple.Remove(item.Key);
    93. }
    94. }
    95. }
    96. public class Animation
    97. {
    98. public AnimatedSpriteSheet Sheet { get; }
    99. public int Images { get; set; }
    100. public int Loops { get; set; }
    101. public Rectangle Position { get; }
    102. public Animation(AnimatedSpriteSheet sheet, int images, Rectangle position)
    103. {
    104. Sheet = sheet;
    105. Images = images;
    106. Position = position;
    107. }
    108. }
    109. }

    Wenn ich batch.Begin() aufrufe passiert nichts, wenn ich allerdings batch.Begin(SpriteSortMode.Deferred) verwende dann sieht man es nur für ein Bruchteil einer Sekunde
    KaskadekingDE on GitHub :)
    Bitte keine Fragen über Programmierung per PN! Dafür ist das Forum hier.

    Who cares? ¯\_(ツ)_/¯

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „KaskadekingDE“ ()

    Hi, sorry das ich mich erst so spät melde. Ich habe einen Patch hochgeladen welcher dir die Anzahl der und den aktuellen KeyframeIndex zurück liefert. Außerdem gibts jetzt eine Eigenschaft die bestimmt ob die Animation fertig ist. (Nur für den Fall das die Animation nicht mit der Eigenschaft Loop in Schleife läuft)

    Sofern du AutoUpdate aktiviert hast, wird das AnimatedSpriteSheet automatisch den nächstes Keyframe auswählen, sodass du einfach alle in einer Schleife updatest und wenn alle Finished sind ist dein AnimationSet fertig.


    Edit: An deinem Code ist der Fehler das du in deinem DrawAndWait alle Animationen in einen Frame zeichnest. - Damit siehst du dann bestenfalls noch die letzte.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ThuCommix“ ()

    Kein Problem ;)

    ThuCommix schrieb:

    Edit: An deinem Code ist der Fehler das du in deinem DrawAndWait alle Animationen in einen Frame zeichnest. - Damit siehst du dann bestenfalls noch die letzte.

    Und wie kann man das "herrauszögern"? ^^ So siehts jetzt aus:
    Spoiler anzeigen

    C#-Quellcode

    1. public void DrawAndWait(SpriteBatch batch, GameTime time, int loops)
    2. {
    3. if (!Enabled) return;
    4. var aniList = Animations.ToList();
    5. for (var i = 0; i <= loops; i++)
    6. {
    7. ResetAnimations(aniList);
    8. while (!aniList.All(a => a.Sheet.IsFinished))
    9. {
    10. foreach (var ani in aniList)
    11. {
    12. ani.Sheet.Update(time);
    13. batch.Begin();
    14. batch.DrawTexture(ani.Sheet, ani.Position, Color.White);
    15. batch.End();
    16. }
    17. }
    18. }
    19. }
    20. private void ResetAnimations(IEnumerable<Animation> anis)
    21. {
    22. foreach (var ani in anis)
    23. {
    24. ani.Sheet.AutoUpdate = true;
    25. ani.Sheet.ActivateKeyframe(0);
    26. }
    27. }
    KaskadekingDE on GitHub :)
    Bitte keine Fragen über Programmierung per PN! Dafür ist das Forum hier.

    Who cares? ¯\_(ツ)_/¯
    Eher so:

    C#-Quellcode

    1. ​public class AnimationSet : IUpdateable, IDrawable
    2. {
    3. public bool AllFinished { private set; get; }
    4. private readonly IEnumerable<AnimatedSpriteSheet> _animations;
    5. public AnimationSet(IEnumerable<AnimatedSpriteSheet> animations)
    6. {
    7. _animations = animations;
    8. foreach (var animatedSpriteSheet in animations)
    9. {
    10. animatedSpriteSheet.AutoUpdate = true;
    11. animatedSpriteSheet.Loop = false;
    12. }
    13. }
    14. public void Update(GameTime gameTime)
    15. {
    16. if (_animations.All(x => x.IsFinished))
    17. {
    18. AllFinished = true;
    19. return;
    20. }
    21. foreach (var animatedSpriteSheet in _animations)
    22. {
    23. animatedSpriteSheet.Update(gameTime);
    24. }
    25. }
    26. public void Draw(SpriteBatch spriteBatch, GameTime gameTime)
    27. {
    28. spriteBatch.Begin();
    29. foreach (var animatedSpriteSheet in _animations)
    30. {
    31. spriteBatch.DrawTexture(animatedSpriteSheet.Texture2D, animatedSpriteSheet.Rectangle,
    32. new Rectangle(10, 10, animatedSpriteSheet.Texture2D.Width, animatedSpriteSheet.Texture2D.Height));
    33. //eventuell die position mit geben und hier füer 10, 10 einsetzen
    34. }
    35. spriteBatch.End();
    36. }
    37. }
    Und wie warte ich nun bis die Animationen durch sind? Ich hab versucht ein Event zu implementieren, aber irgendwie wirft es mir beim Event eine Exception

    In der Game-Klasse:
    Spoiler anzeigen

    C#-Quellcode

    1. public override void Update(GameTime time) {
    2. foreach(var wabe in _game.Wabes.Cast<Wabe>.ToList().Where(x => x.Animation.IsRunning) {
    3. wabe.Animation.Update(time);
    4. }
    5. }
    6. public override void Draw(SpriteBatch batch, GameTime time) {
    7. foreach(var wabe in _game.Wabes.Cast<Wabe>.ToList().Where(x => x.Animation.IsRunning) {
    8. wabe.Animation.Draw(batch, time);
    9. }
    10. }


    In der Klasse:
    Spoiler anzeigen

    C#-Quellcode

    1. public int PoweredSpheres
    2. {
    3. get { return _poweredSpheres; }
    4. set
    5. {
    6. if(SphereCount < value)
    7. throw new IndexOutOfRangeException($"Unable to power {value} spheres. There're only {SphereCount} spheres in this wabe.");
    8. if (SphereCount == value)
    9. {
    10. Animation.Start();
    11. }
    12. else
    13. {
    14. _poweredSpheres = value;
    15. }
    16. }
    17. }
    18. public Wabe(ChainReactGame game, WabeType type, int x, int y, MultiAnimation animation)
    19. {
    20. //...
    21. Animation = animation;
    22. Animation.AnimationFinished += Explode;
    23. }
    24. private void Explode(object sender, EventArgs e)
    25. {
    26. var nearWabes = _game.FindNearWabes(X, Y).OrderBy(w => w.X + w.Y);
    27. var poweredFields = Fields.ToList().Where(w => w.Type == WabeFieldType.Powered).OrderBy(w => w.Id);
    28. var results = new Dictionary<Wabe, WabeField>();
    29. _poweredSpheres = 0;
    30. var owner = Owner;
    31. Owner = null;
    32. for (var i = 0; i < nearWabes.Count(); i++)
    33. {
    34. var nearWabe = nearWabes.ElementAt(i);
    35. var poweredField = poweredFields.ElementAt(i); // <--- Hier tritt ohne Event kein Fehler auf. (IndexOutOfBoundsException(?))
    36. var x = 1;
    37. var y = 1;
    38. switch (poweredField.Id)
    39. {
    40. case 1:
    41. x = 1;
    42. y = 2;
    43. break;
    44. case 3:
    45. x = 2;
    46. y = 1;
    47. break;
    48. case 5:
    49. x = 0;
    50. y = 1;
    51. break;
    52. case 7:
    53. x = 1;
    54. y = 0;
    55. break;
    56. }
    57. var field = nearWabe.ConvertVector2ToWabeField(new Vector2(x, y));
    58. if (field.Type != WabeFieldType.Unpowered)
    59. field = nearWabe.GetNearestPowerableField(field);
    60. results.Add(nearWabe, field);
    61. }
    62. foreach (var field in Fields.Where(f => f.Type == WabeFieldType.Powered))
    63. {
    64. field.Type = WabeFieldType.Unpowered;
    65. }
    66. foreach (var wabePair in results)
    67. {
    68. var wabe = wabePair.Key;
    69. var field = wabePair.Value;
    70. wabe.Set(owner, field);
    71. }
    72. }[/spoiler][spoiler]


    Animation-Klasse:
    Spoiler anzeigen

    C#-Quellcode

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Threading;
    5. using Sharpex2D.Framework;
    6. using Sharpex2D.Framework.Rendering;
    7. namespace ChainReact.Core.Game.Animations
    8. {
    9. public class MultiAnimation : IUpdateable, IDrawable
    10. {
    11. private int _loops;
    12. public List<Animation> Animations { get; }
    13. public int Loops { get; }
    14. public bool IsRunning { get; private set; }
    15. public bool AllFinished { get; private set; }
    16. public event EventHandler AnimationFinished;
    17. public MultiAnimation(IEnumerable<Animation> animations, int loops)
    18. {
    19. Animations = animations.ToList();
    20. Loops = loops;
    21. foreach (var ani in Animations)
    22. {
    23. ani.AnimationSheet.AutoUpdate = true;
    24. ani.AnimationSheet.Loop = false;
    25. }
    26. }
    27. public void Update(GameTime time)
    28. {
    29. if (Animations.All(x => x.AnimationSheet.IsFinished))
    30. {
    31. if (_loops >= Loops)
    32. {
    33. Stop();
    34. AllFinished = true;
    35. AnimationFinished?.Invoke(this, new EventArgs());
    36. return;
    37. }
    38. _loops++;
    39. foreach (var ani in Animations)
    40. {
    41. ani.AnimationSheet.ActivateKeyframe(0);
    42. ani.AnimationSheet.Update(time);
    43. }
    44. }
    45. if (!IsRunning) return;
    46. foreach (var ani in Animations)
    47. {
    48. ani.AnimationSheet.Update(time);
    49. }
    50. }
    51. public void Draw(SpriteBatch batch, GameTime time)
    52. {
    53. if (!IsRunning) return;
    54. batch.Begin();
    55. foreach (var ani in Animations)
    56. {
    57. batch.DrawTexture(ani.AnimationSheet.Texture2D, ani.AnimationSheet.Rectangle, ani.Position, Color.White);
    58. }
    59. batch.End();
    60. }
    61. public void Start()
    62. {
    63. IsRunning = true;
    64. }
    65. public void Stop()
    66. {
    67. IsRunning = false;
    68. }
    69. public void Reset()
    70. {
    71. Stop();
    72. _loops = 0;
    73. AllFinished = false;
    74. foreach(var ani in Animations)
    75. ani.AnimationSheet.ActivateKeyframe(0);
    76. }
    77. }
    78. public class Animation
    79. {
    80. public AnimatedSpriteSheet AnimationSheet { get; }
    81. public Rectangle Position { get; set; }
    82. public Animation(AnimatedSpriteSheet sheet, Rectangle position)
    83. {
    84. AnimationSheet = sheet;
    85. Position = position;
    86. }
    87. }
    88. }


    Ich kann auch das ganze Projekt hochladen falls nötig. ;)
    KaskadekingDE on GitHub :)
    Bitte keine Fragen über Programmierung per PN! Dafür ist das Forum hier.

    Who cares? ¯\_(ツ)_/¯
    In einem Spiel wartet man nicht, man pollt die ganze Zeit bis sich was ändert.

    C#-Quellcode

    1. if(animationSet.AllFinished)
    2. {
    3. //alle deine animationen sind abgeschlossen
    4. // irgendwas generieren
    5. }
    6. else
    7. {
    8. // nichts machen
    9. }


    Warum willst du denn warten? Mache einfach solang nicht mit der Game-Logik weiter bis AllFinished true ist.
    Hab's endlich hingekriegt. ;)

    ThuCommix schrieb:

    Warum willst du denn warten?

    Ich will halt warten, damit man nicht irgendwas drückt und sich fragt warum das Spielfeld jetzt plötzlich ganz anders aussieht. (Ist ein bisschen schwer zu erklären :D )
    KaskadekingDE on GitHub :)
    Bitte keine Fragen über Programmierung per PN! Dafür ist das Forum hier.

    Who cares? ¯\_(ツ)_/¯
    Es gibt doch noch irgendwo ein Problem :/ . Bei dem ersten AnimationSet läuft die Animation richtig durch, bei allen anderen wird sie schneller abgespielt als sie soll.
    Heute hab ich überlegt, ob es an der GameTime liegen könnte und es scheint daran zu liegen. Hier paar Bilder von den Werten (beim 1. Update, beim 3. und beim 5.)
    Beim 5. Durchlauf springt der Wert von 20-30 auf über 10000.

    Code:
    Spoiler anzeigen

    C#-Quellcode

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Threading;
    5. using Sharpex2D.Framework;
    6. using Sharpex2D.Framework.Rendering;
    7. namespace ChainReact.Core.Game.Animations
    8. {
    9. public class MultiAnimation : IUpdateable, IDrawable
    10. {
    11. private Sharpex2D.Framework.Game _game;
    12. private int _loops;
    13. public List<Animation> Animations { get; }
    14. public int Loops { get; }
    15. public Vector2 AbsolutePosition { get; set; }
    16. public bool IsRelative { get; set; } = true;
    17. public bool IsRunning { get; private set; }
    18. public bool AllFinished { get; private set; }
    19. public MultiAnimation(Sharpex2D.Framework.Game game, IEnumerable<Animation> animations, int loops)
    20. {
    21. _game = game;
    22. Animations = animations.ToList();
    23. Loops = loops;
    24. foreach (var ani in Animations)
    25. {
    26. ani.AnimationSheet.AutoUpdate = true;
    27. ani.AnimationSheet.Loop = false;
    28. }
    29. }
    30. public void Update(GameTime time)
    31. {
    32. if (Animations.All(x => x.AnimationSheet.IsFinished))
    33. {
    34. if (_loops >= Loops - 1)
    35. {
    36. Stop();
    37. AllFinished = true;
    38. return;
    39. }
    40. _loops++;
    41. foreach (var ani in Animations)
    42. {
    43. ani.AnimationSheet.ActivateKeyframe(0);
    44. ani.AnimationSheet.Update(time);
    45. }
    46. }
    47. if (!IsRunning) return;
    48. foreach (var ani in Animations)
    49. {
    50. ani.AnimationSheet.Update(time);
    51. }
    52. }
    53. public void Draw(SpriteBatch batch, GameTime time)
    54. {
    55. if (!IsRunning) return;
    56. batch.Begin();
    57. foreach (var ani in Animations)
    58. {
    59. var pos = (!IsRelative) ? ani.Position : ani.Position + AbsolutePosition;
    60. batch.DrawTexture(ani.AnimationSheet, pos, Color.White);
    61. }
    62. batch.End();
    63. }
    64. public void Start()
    65. {
    66. IsRunning = true;
    67. }
    68. public void Stop()
    69. {
    70. IsRunning = false;
    71. }
    72. public void Reset()
    73. {
    74. Stop();
    75. _loops = 0;
    76. AllFinished = false;
    77. foreach (var ani in Animations)
    78. {
    79. ani.AnimationSheet.ActivateKeyframe(0);
    80. }
    81. }
    82. }
    83. public class Animation
    84. {
    85. public AnimatedSpriteSheet AnimationSheet { get; }
    86. public Rectangle Position { get; set; }
    87. public Animation(AnimatedSpriteSheet sheet, Rectangle position)
    88. {
    89. AnimationSheet = sheet;
    90. Position = position;
    91. }
    92. }
    93. }
    Bilder
    • 45813.png

      48,75 kB, 742×516, 115 mal angesehen
    • Normal1.png

      35,42 kB, 757×510, 110 mal angesehen
    • Normal2.png

      35,84 kB, 737×506, 109 mal angesehen
    KaskadekingDE on GitHub :)
    Bitte keine Fragen über Programmierung per PN! Dafür ist das Forum hier.

    Who cares? ¯\_(ツ)_/¯
    Ich habe nun den Fehler gefunden nachdem @ThuCommix mich auf eine Idee gebracht hat. ^^
    Der Fehler lag hier:
    github.com/KaskadekingDE/Chain…re/Game/Field/Wabe.cs#L67
    Aus der vorhandenen MultiAnimation habe ich eine weitere erstellt, allerdings mit den selben Animationen.
    Diese wurden als Referenz übergeben, da Animation eine Klasse ist. So das bei jeder MultiAnimation die Animations-Liste gleich war und so es mehrfach geupdatet wurde.

    Eigentlich wollte ich die Animation Klasse zu einem struct machen, allerdings müsste dort das SpriteSheet auch ein struct sein. Deswegen habe ich es jetzt so gelöst:
    Animation

    C#-Quellcode

    1. public class Animation
    2. {
    3. private readonly Texture2D _asset;
    4. public AnimatedSpriteSheet AnimationSheet { get; }
    5. public Rectangle Position { get; set; }
    6. public Animation(Texture2D sheet, Rectangle position)
    7. {
    8. _asset = sheet;
    9. AnimationSheet = new AnimatedSpriteSheet(_asset);
    10. for (var i = 0; i < 12; i++)
    11. {
    12. var x = 134 * i;
    13. var kf = new Keyframe(new Rectangle(x, 0, 134, 134), 60f);
    14. AnimationSheet.Add(kf);
    15. }
    16. AnimationSheet.Rectangle = new Rectangle(0, 0, 134, 134);
    17. AnimationSheet.AutoUpdate = true;
    18. Position = position;
    19. }
    20. public Animation CopyFromAnimation()
    21. {
    22. return new Animation(_asset, Position);
    23. }
    24. }

    Wabe-Konstruktor

    C#-Quellcode

    1. public Wabe(ChainReactGame game, WabeType type, int x, int y, MultiAnimation animation, Vector2 size)
    2. {
    3. _game = game;
    4. Type = type;
    5. Fields = new WabeField[9];
    6. X = x;
    7. Y = y;
    8. var animations = animation.Animations.Select(templateAni => templateAni.CopyFromAnimation()).ToList();
    9. var ani = new MultiAnimation(game.Game, animations, animation.Loops, animation.Sound);
    10. Animation = ani;
    11. Layout = new WabeLayout(this, new Vector2(0, 5));
    12. switch (Type)
    13. {
    14. case WabeType.FourWabe:
    15. SphereCount = 4;
    16. for (var i = 0; i <= 8; i++)
    17. {
    18. Fields[i] = new WabeField(Layout.Fields[i], i);
    19. }
    20. break;
    21. case WabeType.ThreeWabe:
    22. SphereCount = 3;
    23. for (var i = 0; i <= 8; i++)
    24. {
    25. Fields[i] = new WabeField(Layout.Fields[i], i);
    26. }
    27. break;
    28. case WabeType.TwoWabe:
    29. SphereCount = 2;
    30. for (var i = 0; i <= 8; i++)
    31. {
    32. Fields[i] = new WabeField(Layout.Fields[i], i);
    33. }
    34. break;
    35. }
    36. _size = size;
    37. Animation.AbsolutePosition = GetPositionOfWabeCenter();
    38. }

    Allerdings will ThuCommix dann, wenn er Zeit hat auch das SpriteSheet zu einem struct machen. Dann könnte ich meine Klasse auch zu einem struct machen ^^
    KaskadekingDE on GitHub :)
    Bitte keine Fragen über Programmierung per PN! Dafür ist das Forum hier.

    Who cares? ¯\_(ツ)_/¯