Snake-Spiel

Saheeda

Mitglied
Snake-Spiel

Hi,

ich bastel gerade an einem Snake-Spiel. Die Schlange habe ich dabei als List<Point> implementiert, wobei Index[0] der Kopf ist.
Beim Start wird zu jedem Punkt ein Rechteck mit den Maßen 10x10 erstellt und auf der Canvas(playground) dargestellt. Die Schrittweite soll dementsprechend auch bei 10 Pixel/Schritt liegen.

Funktion AnimateSnake
Ich schaue zunächst, wo der nächste Abschnitt hinter dem Kopf liegt, um zu entscheiden, in welche Richtung sie sich bewegen soll. (Ist der nächste Abschnitt links vom Kopf, geht die Schlange nach rechts weiter, etc...)

Mit der Liste cacheTail übertrage ich jeden Wert auf den "Vorgänger", damit die Schlange sich nicht komplett in eine Richtung bewegt, sondern entlang ihres bisher gegangenen Weges.


Jetzt zu meiner Frage:
Steuere ich die Schlange z.B. nach rechts, bewegt sie sich nicht 10, sondern 20 Pixel weiter. Mir ist auch klar, warum.
Meine Idee wäre, eine Funktion in Richtung "Wenn keine Taste gedrückt wird, führe AnimateSnake aus, ansonsten MoveControl", ich weiß nur nicht, wie ich das implementieren soll.

Code:
namespace Snake
{
    public partial class Window1 : Window
    {
        private List<Point> tail = new List<Point>();
        DispatcherTimer timer = new DispatcherTimer();
        private int maxSize = 100;

        public Window1()
        {
            InitializeComponent();
            for (int i = maxSize; i > 0; i -= 10)
            {
                tail.Add(new Point(0, i));
            }
            CreateSnake();
            timer.Start();
            timer.Interval = TimeSpan.FromSeconds(1);
            timer.Tick += AnimateSnake;
        }

        private void CreateSnake()
        {
            playground.Children.Clear();
            foreach (Point p in tail)
            {
                Rectangle r = new Rectangle();
                r.Width = 10;
                r.Height = 10;
                r.Fill = new SolidColorBrush(Colors.Indigo);
                playground.Children.Add(r);
                Canvas.SetLeft(r, p.X);
                Canvas.SetTop(r, p.Y);
            }
        }

        private void AnimateSnake(object sender, EventArgs e)
        {
            Point first = tail[0];
            Point second = tail[1];
            double xDis = first.X - second.X;
            double yDis = first.Y - second.Y;

            List<Point> cacheTail = new List<Point>();
            for (int i = 0; i < tail.Count; i++)
            {
                 cacheTail.Add(tail[i]);
            }
            Point p = tail[0];
            p.Y += yDis;
            p.X += xDis;
            tail[0] = p;

            for (int i = 1; i < maxSize / 10; i++)
            {
                tail[i] = cacheTail[i - 1];
            }

            CreateSnake();

        }

        private void MoveControl(object sender, KeyEventArgs e)
        {
            List<Point> cacheTail = new List<Point>();
            for (int i = 0; i < tail.Count; i++)
            {
                Point s = tail[i];
                cacheTail.Add(s);
            }

            if (e.Key == Key.D)
            {
                Point p = tail[0];
                p.X += 10;
                tail[0] = p;
            }

            if (e.Key == Key.A)
            {
                Point p = tail[0];
                p.X -= 10;
                tail[0] = p;
            }
            if (e.Key == Key.W)
            {
                Point p = tail[0];
                p.Y -= 10;
                tail[0] = p;

            }
            if (e.Key == Key.S)
            {
                Point p = tail[0];
                p.Y += 10;
                tail[0] = p;

            }

            for (int i = 1; i < tail.Count; i++)
            {
                tail[i] = cacheTail[i - 1];
            }

        }


    }
}
 
Dein Timer, den du für AnimateSnake benutzt, ist doch schon mal ein Ansatz.

Du fügst deiner Window1-Klasse ein boolsches Flag für Tastegedrückt hinzu, und initialisierst es mit false.
Wenn dein MoveControl aufgerufen wird, und eine der Bewegungstasten gedrückt ist, setzt du das Flag auf true.

Wenn in AnimateSnake das Flag auf false steht, rufst du MoveControl auf, damit die Schlange sich normal bewegt. Am Ende von AnimateSnake setzt du das Flag wieder auf false für die nächste Timer-Runde.
 
Zurück