130 likes | 242 Views
Ultris V10. Bewegen, Drehen und Kollisionserkennung. Akzelleratoren einbinden. Steuerung der Formen mit den Richtungstasten oder mit J, K, L und I. Einfügen der Akzelleratoren über den Ressourcen-Editor:. jeweils zwei Akzelleratoren haben die gleiche ID. Neue Methoden hinzufügen.
E N D
Ultris V10 Bewegen, Drehen und Kollisionserkennung
Akzelleratoren einbinden • Steuerung der Formen mit den Richtungstasten oder mit J, K, L und I. • Einfügen der Akzelleratoren über den Ressourcen-Editor: jeweils zwei Akzelleratoren haben die gleiche ID
Neue Methoden hinzufügen • class ultris { … public: … void bewegen (int dir); void drehen (int dir); }; Richtung der Drehung/Bewegung: +1 für rechts -1 für links
Bewegen • void ultris::bewegen (int dir) { int z, s, neue_spalte; const form *f; f = aktuelle_form(); neue_spalte = spalte + dir; if (neue_spalte < 0) return; if (neue_spalte + f->b >10) return; aktuelle Form wird geholt neue Spalte (also die Spalte nach der Bewegung) wird berechnet falls die neu berechnete Spalte außerhalb des Spielfeldes liegt, ist die Bewegung nicht möglich und es erfolgt ein vorzeitiger Rücksprung
for (z=0; z<f->h; z++) { if (zeile+z < 0) continue; for (s=0; s<f->b; s++) { jede Zeile der Form wird untersucht befindet sich die zu untersuchende Zeile noch unter der Abdeckung, wird diese einfach ignoriert jede Spalte der Form wird untersucht für jede Spalte finden nun Prüfungen statt, die alle erfolgreich sein müssen, damit die Bewegung ausgeführt werden kann schlägt eine Prüfung fehl Rücksprung keine Bewegung
if (f->data[z] [s]) { if ((offset < 16) && spielfeld[zeile+z][neue_spalte+s]) return; if ((offset > 0) && spielfeld[zeile+z+1][neue_spalte+s]) return; } } } Prüfung 1: befindet sich an dieser Stelle der Form ein Segment? Prüfung 2: ist der Bereich neben dem Segment frei? Prüfung 3: ist der Bereich darunter frei?
Prüfung 2 prüft, ob sich neben dem Segment ein Stein befindet. Falls ja, dann ist die Prüfung nicht bestanden und es erfolgt ein vorzeitiger Rücksprung. Aber: Falls das offset größer als oder gleich 16 ist, gilt die Prüfung trotzdem als bestanden, auch wenn sich daneben ein Stein befindet. Dies erleichtert es, den Stein in eine Lücke rein zu bewegen.
falls alle Prüfungen bestanden wurden, das heißt, falls es keinen vorzeitigen Rücksprung gab, kann die Bewegung ausgeführt werden spalte = neue_spalte; ultris_sounds.play(sound_move); }
Drehen void ultris::drehen(int dir) { int sv, sp, zl; int b1, b2, h1, h2, db, dh; int maxb, maxh, minz, mins; int i, j; sv = (formen[0].dv + 4 – dir)%4; b1 = aktuelle_form()->b; b2 = ultris_form[formen[0].ix][sv]->b; h1 = aktuelle_form()->h; h2 = ultris_form[formen[0].ix][sv]->h; neue Drehvariante wird bestimmt und in der Variablen sv gespeichert neue und alte Breiten und Höhen werden bestimmt
durch eine Rechnung werden die Spalte und Zeile der Form nach der Drehung bestimmt (im Beispiel bleiben sie gleich, da db und dh = 0) db = (b1-b2)/2; dh = (h1-h2)/2; sp = spalte + db; zl = zeile + dh; if (sp < 0) sp = 0; if (sp + b2 >= 10) sp = 10 - b2; if (zl + h2 >= 20) return; sorgt dafür, dass die Form innerhalb des Spielfeldes bleibt ist die Form schon zu weit unten, ist keine Drehung möglich
mins = spalte < sp ? spalte : sp; minz = zeile < zl ? zeile : zl; maxb = b1 > b2 ? b1 : b2; maxh = h1 > h2 ? h1 : h2; if (offset) maxh++; for (i = minz; i < minz + maxh; i++) { for (j = mins; j < mins + maxb; j++) { if ((i>=0) && (i<20) && (j<10) && spielfeld[i][j]) return; } } der Bereich, der für die Drehung frei sein muss wird berechnet nötiger Drehbereich wird Zeile für Zeile, Spalte für Spalte geprüft, ob er frei ist wenn nicht, dann erfolgt ein Rücksprung
formen[0].dv = sv; spalte = sp; zeile = zl; ultris_sounds.play(sound_dreh); } • die Form wird letztendlich gedreht, indem die neue Drehvariante zugewiesen und die neue Zeile und Spalte gesetzt wird
Einbindung in die Benutzerschnittstelle LRESULT CALLBACK ultris_windowhandler(...) { switch (msg) { case WM_COMMAND: switch (LOWORD(wParam)) {... case IDM_DREHRECHTS: mein_spiel.drehen(1); return 0; case IDM_DREHLINKS: mein_spiel.drehen(-1); return 0; case IDM_RECHTS: mein_spiel.bewegen(1); return 0; case IDM_LINKS: mein_spiel.bewegen(-1); return 0; ...} break; ...} ...}