(Mir fiel leider kein brauchbarerer Name ein)
Ich programmiere gerade ein Snake-Spiel.
Dabei habe ich ein Panel als Spielfeld und darin eine Schlange aus mehreren Panels (Kopfpanel 6x6Pixel, Körperpanels jeweils 4x4Pixel). Die Panels, aus denen die Schlange besteht befinden sich in einer Liste, damit sie simultan angesteuert werden können.
Ich möchte nun, dass das Spiel gestoppt wird, wenn die Schlange den Rand des Spielfels berührt (genauer gesagt, wenn der Kopf der Schlange das Spielfeld verlassen hat).
Folgendes habe ich mir überlegt:
int kopf = schlange.FindIndex(x => x.Name == "schlangeKopf");
if (!Spielfeld.Bounds.Contains(schlange[kopf].Bounds))
{
geschwindigkeitsRegler.Stop();
zeitZaehler.Stop();
MessageBox.Show("Das Spiel ist zu Ende!\nIhre Punktzahl beträgt " + tbPunktezahl.Text);
}
(geschwindigkeitsRegler und zeitZaehler sind timer)
Folgende Grössen sind gegeben:
X-Koordinate des Spielfelds: 43
Breite des Spielfelds: 400
X-Koordinate des rechten Spielfeldrands demnach 443
X-Koordinate des Startpunkts des Schlangenkopfes: 116px
Die Schlange bewegt sich mit 10px/sec fort und die MessageBox erscheint bei 35sec, also legt die Schlange 350px zurück
X-Koordinate des Schlangenkopfes bei Spielstopp demnach 466
Wieso?
Hallo,
wenn Du die Schlange über einen Timer bewegst, wird das wohl daran liegen, dass im exakten Moment des verlassens gerade kein Tick ausgeführt wird, Du also erst beim nächsten Tick reagierst, an dem die Schlange eigentlich schon etwas weiter ist.
Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
@MarsStein: der Timer tickt 10mal pro Sekunde (bei der langsamsten Geschwindigkeit), da sollte es nicht so einen grossen Unterschied machen.
Zudem ist mir noch etwas aufgefallen: die angegebenen Daten habe ich ermittelt, als die Schlange nach rechts gewandert ist. Wenn sie nach links wandert, wird das Spiel gestoppt, wenn X-Koordinate des Kopfes = 16 (Abbruch also nach 10sec). Dabei ist die Schlange noch vollständig im Spielfeld zu sehen.
Update:
Hab noch etwas rumprobiert und so siehts aus:
rechts und unten kommt der Spielstopp zu spät (Standartschlange (Länge = 22px) verschwindet völlig aus dem Panel.
links und oben kommt er zu früh (Kopf berührt den Rand des Spielfelds nicht mal annähernd).
Hallo,
Du scheinst hier die Koordinaten relativ zum Fenster und die _relativ zum Spielfeld _durcheinander zu bringen:
X-Koordinate des Spielfelds: 43
X-Koordinate des Kopfes = 16
Wenn diese Koordinaten den selben Ursprung hätten, wäre die Schlange bei 16 ja schon lange draussen.
Du musst auf jeden Fall zuallererst zwischen diesen Koordinatensystemen unterscheiden. Wenn Du dann raus hast, mit welchen Koordinaten Du tatsächlich rechnen musst, stimmt es bestimmt schon wieder 😉
Bedenke auch: Der Kopf stellt ja eine ganze Fläche von 6x6px dar. "Die" Koordinate des Kopfes kann also auch nur einer dieser 6x6 Punkte sein.
Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
@MarsStein: ich verstehe deine Logik nicht ganz. Ich SEHE doch, dass es nicht stimmt: rechts ist die Schlange längst weg, wenn die MessageBox kommt und links berührt sie noch nichtmal den Spielfeldrand.
Ich nehme an, dass die X-Koordinate des Spielfelds (ist übrigens der Punkt ganz oben links in der Ecke, wie bei allen WindowsForms-Elementen) relativ zum Form an sich definiert ist.
Der X-Wert des Schlangenkopfes (ebenfalls ganz oben links) könnte gut und gern relativ zum Spielfeld definiert sein (das Spielfeld ist auch parent der Schlange).
Das erklärt das Verhalten aber noch immer nicht.
@Cat: das Spielfeld ist parent der Schlange
Hallo,
Das erklärt das Verhalten aber noch immer nicht.
Das hängt von der Implementierung ab, wie Du die Panels bewegst. Die kennen wir ja nicht. Wenn Du da irgendwo mit den verkehrten Koordinaten/Offsets arbeitest, kann das den Effekt durchaus erklären.
Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
Dann kannst du nicht einfach die Bounds vergleichen (Äpfel mit Birnen oder so ähnlich), sondern du mußt das ClientRectangle vom Spielfeld-Panel nehmen.