![]() |
Rotierendes Array
Hallo zusammen,
im Rahmen der Programmierung eines Spiels (nicht mit Delphi) stoße ich auf ein Problem, welches mir wirklich Kopfzerbrechen bereitet. Realisiert werden soll ein von oben nach unten scrollender Sternenhintergrund. Dazu habe ich mir 4 "Tiles" á 64x64 Punkte erstellt, die dann bei einer 1024x768 Auflösung in 12 Zeilen zu 16 Spalten in einem Array liegen. Aus programmtechnischer Sicht benötige ich natürlich eine 13. Zeile im oberen nicht-sichtbaren Bereich, der ja reingescrollt wird. Nehmen wir mal diesen Code, um das BGMAP-Array zu füllen:
Code:
FOR iY=0 TO 12
FOR iX=0 to 15 BGMAP(iX,iY)=RND(3) NEXT iX NEXT iY So, jetzt gibt es die "Game-Loop", die den Hintergrund forwährend scrollt:
Code:
Damit werden die Tiles kontinuierlich auf dem Screen gezeichnet und anschließend wird der Y-Wert zum Pasten um 1 Pixel erhöht, bis die nicht-sichtbare Reihe von oben vollständig im Screen ist (nach 64 Pixeln) - funktioniert auch soweit.
DO
FOR iY=0 TO 12 FOR iX=0 to 15 PASTE IMAGE BGMAP(iX,iY),(iX*64),(iY*64)+iStarScroll NEXT iX NEXT iY INC iStarScroll IF iStarScroll>64 iStarScroll=0 ENDIF SYNC LOOP Jetzt kommt aber das Problem: Sobald ein Umlauf von 64 Pixeln erfolgt ist, muss ich die unten rausgescrollte Zeile natürlich wieder oben anfügen und da hakt es im Moment... Zur Verdeutlichung, wie es sein müsste (die angegebenen Werte beziehen sich auf den Y-Wert im Array BGMAP - momentan noch iY): 1. Durchlauf 0,1,2,3,4,5,6,7,8,9,10,11,12 2. Durchlauf 12,0,1,2,3,4,5,6,7,8,9,10,11 3. Durchlauf 11,12,0,1,2,3,4,5,6,7,8,9,10 usw. Da ich das Array selbst nicht anfassen möchte, suche ich einen Weg, dieses im Code zu realisieren, also irgendwie mathematisch ein "rotieren" des Arrays in der Schleife abzubilden. Gruß Igotcha |
Re: Rotierendes Array
Der uebliche Trick fuehrt ueber den Modulo Operator mod.
Das Array der Tiles sollte ab 0 indiziert sein.
Delphi-Quellcode:
Damit laeuft I immer von 0 bis 12.
// Anfangsinitialisierung
I := 0; // in der Schleife Inc(I); I := I mod 13; |
Re: Rotierendes Array
Zitat:
1. Durchlauf 0,1,2,3,4,5,6,7,8,9,10,11,12 2. Durchlauf 12,0,1,2,3,4,5,6,7,8,9,10,11 3. Durchlauf 11,12,0,1,2,3,4,5,6,7,8,9,10 usw. und nach dem 13. Durchlauf wieder bei "0" anfangen (wie im 1. Durchlauf). |
Re: Rotierendes Array
Ah du laeufst rueckwaerts. 12x die Inc + mod Operation durchfuehren. Das ist ein Umlauf.
Nach jedem Umlauf um eins zuruecksetzen. Das geht nicht mit mod, sondern das muss man mit if I < 0 then I := 12; machen. Jetzt einfach den naechsten Umlauf. |
Re: Rotierendes Array
man könnte es ja so machen:
Delphi-Quellcode:
dreizhenter und Zaehler müssen natürlich vorher deklariert werden(außer, wenn du es in basic machst(warscheinlich auch bei anderen programmiersprachen)).
dreizehnter:=I[13];
for Zaehler:=0 to 13 do begin //muss nicht unbedingt if Zaehler<13 then I[Zaehler]:=I[Zaehler+1] //alle eins aufrücken! hopp hopp hopp else I[Zaehler{also 13}]:=dreizehnter; end; //wenn oben begin weg, dann auch das hier weg! |
Re: Rotierendes Array
Zitat:
Aber jetzt habe ich einen schönen Multilayer-Parallax-Sternen-Hintergrund :hello: Danke nochmals... |
Re: Rotierendes Array
Zitat:
|
Re: Rotierendes Array
Also eins versteh ich auch nicht!
Warum bewegt ihr die Daten im Array??? 0,1,2,3,4,5,6,7,8,9,10,12 Würde ich so immer beibehalten. Nur einen Zeiger definieren der mir zeigt, welches Element derzeit das erste ist. Von diesem Element würde ich dann immer die Daten darstellen. ==> Wesentlich schneller als das Array umzukopieren!!! |
Re: Rotierendes Array
stimmt auch wieder
|
Re: Rotierendes Array
Das ist ja was ich angeboten habe. I ist der Index bzw Zeiger in das Array.
|
Re: Rotierendes Array
Also die Lösung hatte ich ja bereits nun (das Array umkopieren), aber ich glaube, die beiden anderen Kollegen haben das eigentliche Problem nicht gesehen, oder ich habe die Lösung nicht verstanden ;-)
Das könnten wir ja nochmal klären. Beispielarray (2,2) der Tile-Map:
Code:
Der "Screen" ist jetzt mal 2 Zeilen hoch ;-)
Array Arrayindex-Y
1|2|3 0 4|5|6 1 7|8|9 2 Beim Start wird das "Grundarray" angezeigt und am Bildschirm sieht man (s.o. > unsichtbare Zeile):
Code:
Jetzt werden die 64x64 Großen Tiles pixelweise nach unten verschoben, so dass sich nach einem "Umlauf" (also 64 Pixel nach unten geschoben) folgendes auf dem Screen befindet:
Array Arrayindex-Y
4|5|6 1 7|8|9 2
Code:
Der Teil mit 7|8|9 ist unten "rausgefallen" und kommt jetzt aus technischer Sicht wieder oben auf:
Array Arrayindex-Y
1|2|3 0 4|5|6 1
Code:
Programmtechnisch das Problem in eine Do-Loop-Schleife verpackt:
Array Arrayindex-Y
7|8|9 2 1|2|3 0 4|5|6 1
Code:
Da bringt meiner Meinung nach ein MOD bzw. die Abfrage IF xx > 2 in diesem Falle nichts, oder sehe ich das falsch?
DO
FOR iY=0 to 2 FOR iX=0 to 2 ZEIGE ARRAY([Hier muss der passende Y-Index des Arrays rein], iX),iX*64,(iY-1)*64+iScrollY {Das Array wird hier bei jedem Umlauf 3-Mal mit inkrementierenden Y-Werten angesprochen: 1.1. Durchlauf: 0 1.2. Durchlauf: 1 1.3. Durchlauf: 2 2.1. Durchlauf: 2 2.2. Durchlauf: 0 2.3. Durchlauf: 1 3.1. Durchlauf: 1 3.2. Durchlauf: 2 3.3. Durchlauf: 0 danach wäre das komplette Array einmal über den Screen gescrollt und wir können wieder bei 1.1 anfangen} NEXT iX NEXT iY INC iScrollY IF iScrollY > 64 iScrollY=0 {Nach diesem Umlauf muss jetzt die Korrektur des Arrayindex-Y erfolgen, also Änderung des Arrayindex-Y von z.B. 1.1 > 2.1, 2.1 > 3.1 oder 3.1 > 1.1} ENDIF LOOP Gruß Igotcha |
Re: Rotierendes Array
Zitat:
also:
Code:
(schematisch)
... anfang=1 anzeigen(anfang) .. proceure anzeigen(anfang) if anfang<0 then anfang=2 if anfang>2 then anfang=0 anzahl=2 y=anfang for n=1 to anzahl do begin zeige(array(y)) inc(y) if y>2 then y=0 end end Anzeige: Array Arrayindex-Y 4|5|6 1 7|8|9 2 hochrücken: .. dec(anfang) anzeigen(anfang) .. anzeige 1|2|3 0 4|5|6 1 ... so sollte der ablauf funktionieren ... |
Re: Rotierendes Array
Könnte funktionieren - hab's aber nicht getestet.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:43 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz