Autor |
Beitrag |
galagher
      
Beiträge: 2556
Erhaltene Danke: 45
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: Fr 18.02.11 17:03
Hallo!
Mein Array wird mit Elementen vom Typ TElement befüllt:
Delphi-Quelltext 1: 2: 3: 4:
| type TElements = (elBorder, elBlock, elFree, elBridge, elHole, elDiamond, elHeart, elBomb, elBox, elLocked, elKey, elHaunter, elSkull, elPot, elCannon, elBullet, elWalker, elPlayer); |
Ich habe ein 2-dimensionales Array und möchte etwas Bewegung in mein Spiel bringen: elWalker soll in bestimmten "Bahnen" am Spielfeld umherwandern, und wenn ein Hindernis im Weg ist, soll es umdrehen.
Mein erster Ansatz ist dieser, aber das klappt nicht wie gewünscht:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| for x := 0 to iMaxH do for y := 0 to iMaxV do begin if (aBoard[x, y]) = elWalker then begin if aBoard[x, y+1] = elFree then begin aBoard[x, y] := elFree; DrawBoard(x, y, iFree, imgListElements, tmpBitmap0); aBoard[x, y+1] := elWalker; DrawBoard(x, y+1, iWalker, imgListElements, tmpBitmap0); end; end; end; |
Wie macht man das - ich blicke nicht durch!
Zum besseren Verständnis siehe die Grafik!
Einloggen, um Attachments anzusehen!
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
Xion
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Fr 18.02.11 20:22
galagher hat folgendes geschrieben : | Mein erster Ansatz ist dieser, aber das klappt nicht wie gewünscht: [...] Wie macht man das - ich blicke nicht durch! |
Ich wundere mich etwas, wie ein so "alter" und aktiver Nutzer so eine Fehlerbeschreibung fabrizieren kann... WAS geht nicht?
Also vom Prinzip her sieht das Bewegen ganz gut aus. Du musst nur aufpassen, dass y+1 nicht außerhalb des Feldes liegt. Außerdem ist bei deinem Bildchen [x,y+1] belegt, also siehst du natürlich nichts. Du solltest mal [x+1,y] ausprobieren
Du zählst bei x bis MaxH (MaxHeight?) und bei y bis MaxV(was auch immer V sein soll), ist das Absicht? Weil X ist Width 
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
galagher 
      
Beiträge: 2556
Erhaltene Danke: 45
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: Fr 18.02.11 20:43
Xion hat folgendes geschrieben : | galagher hat folgendes geschrieben : | Mein erster Ansatz ist dieser, aber das klappt nicht wie gewünscht: [...] Wie macht man das - ich blicke nicht durch! |
Ich wundere mich etwas, wie ein so "alter" und aktiver Nutzer so eine Fehlerbeschreibung fabrizieren kann...WAS geht nicht?
Also vom Prinzip her sieht das Bewegen ganz gut aus. Du musst nur aufpassen, dass y+1 nicht außerhalb des Feldes liegt. Außerdem ist bei deinem Bildchen [x,y+1] belegt, also siehst du natürlich nichts. Du solltest mal [x+1,y] ausprobieren
Du zählst bei x bis MaxH (MaxHeight?) und bei y bis MaxV(was auch immer V sein soll), ist das Absicht? Weil X ist Width  |
Ok, für die Fehlerbeschreibung werde ich wohl keinen Orden bekommen.
Also nochmal genau erklärt: Ich möchte auf einem Spielbrett Figuren herumwandern lassen, dazu schreibe ich in ein Array.
iMaxH und iMaxX sind Integer-Variablen, die die Anzahl der vertikalen und horizontalen Felder (und die Array-Plätze) angeben. Mit den for-Schleifen durchlaufe ich das Array und besetze die "Plätze" im Array. Dann zeichne ich das Ganze. Mir geht es jetzt nur um das Array, das Zeichnen ist einfach.
Mein Code stellt ein Beispiel dar, wie ich ein Element im Array, ich nenne es elWalker (weil es sich eben bewegt), vertikal nach unten bewege, daher auch y+1. Für nach oben wäre das dann y-1, nach links x-1, nach rechts x+1. Das funktioniert zwar, aber bei mehreren elWalker's wird dabei einer nach dem anderen bewegt, ich möchte aber, dass sich alle zugleich bewegen.
Ich wäre zufrieden, wenn mir eine Lösung gelingt, bei der alle elWalker's auf "ihren" Bahnen laufen, hin und her, auf und ab, und die Richtung ändern, wenn irgendetwas ihren Weg versperrt, zB. gibt es da Böcke (elBlock) oder Kisten (elBox), und "kein Hindernins", also nix im Weg, nenne ich elFree.
Mit diesen Elementen ist das Array befüllt, die grafische Darstellung erfolgt per ImageList mit 20x20 Pixel grossen Bitmaps.
Mein eigentliches Ziel ist es, beliebig viele elWalker's in alls möglichen Richtungen wandern zu lassen, also etwa bei Wegkreuzungen auch mal von senkrecht auf waagrecht zu schwenken. Und zwar alle zugleich, alle gleichzeitig!
Und das kriege ich nicht hin, ich kann mir einfach nicht vorstellen, wie der Code zu so etwas aussehen könnte.
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
Xion
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Fr 18.02.11 21:24
Ok. Vom Prinzip her:
Du musst pro Walker irgendwie ne Bewegungsrichtung speichern. Um dein System beizubehalten würde ich vorschlagen, es gibt neue Elemente:
elWalkerUp
elWalkerDown
elWalkerLeft
elWaklkerRight
Dann gehst du alle Walker durch und guckst, wieviele Felder außenrum (außer nach "hinten") frei sind. Sind 0 frei, dann musst du umdrehen. Ist 1 frei, dann gehst du einfach weiter. Sind mehr als 1 frei, dann hast du die Möglichkeit abzubiegen.
Als Code:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29:
| var freecount: integer; ... for x:= 0 to iMaxH do for y:=0 to iMaxv do if (aBoard[x,y]=elWalkerUp) or (aBoard[x,y]=elWalkerLeft) or (aBoard[x,y]=elWalkerDown) or (aBoard[x,y]=elWalkerRight) then begin freecount:=0; if (aBoard[x,y-1]=elFree)and(aBoard[x,y]<>elWalkerDown) then freecount:=freecount+1; if (aBoard[x+1,y]=elFree)and(aBoard[x,y]<>elWalkerLeft) then
freecount:=freecount+1; if (aBoard[x,y+1]=elFree)and(aBoard[x,y]<>elWalkerUp) then freecount:=freecount+1; if (aBoard[x-1,y]=elFree)and(aBoard[x,y]<>elWalkerRight) then freecount:=freecount+1;
if freecount=0 then else if freecount=1 then else end; |
Um Unmengen if Abfragen zu sparen (z.B. alleine beim umdrehen müsste man ja gucken in welche Richtung er gerade guckt und dann das Gegenteil setzen) wäre vielleicht eine Konvertierung des Element-Typs in einen int möglich.
zB: Up=0 Right=1 Down=2 Left=3
umdrehen: (Status+2) mod 4
oder die Richtung gleich als TPoint:
z.B: Up=(0,-1) Right=(1,0) Down=(0,1) Left=(-1,0)
umdrehen: Status.X=-Status.X; Status.Y:=-Status.Y;
weitergehen: [x+Status.X,y+Status.y] wird betreten
Also Raum zur Optimierung bleibt da sicher, aber mit if-Strukturen geht es sicher auch.
//Edit:
Eben bemerkt: Ist nur ein benachbartes Feld frei, kann es natürlich auch eine Kurve sein! Du musst also noch gucken, in welche Richtung die Biegung evtl geht  Auf jeden Fall gehst du bei freecount=1 einfach "weiter" und drehst weder um, noch biegst du ab
//Edit2:
Man könnte es sich auch noch ganz anders vorstellen. Du fügst deinem 2-D array noch ein integer hinzu (also nicht array of array of integer sondern eines Types). Dann kannst du dort den Index des Walkers in einem separaten "Walker-Array" speichern. Dort kannst du die Daten dann viel schöner Abspeichern (z.B. Richtung als Integer). Sollen die Walker sowas wie Hitpoints, separate Geschwindigkeit oder so kriegen, wäre das sehr zu empfehlen 
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
Zuletzt bearbeitet von Xion am Fr 18.02.11 21:33, insgesamt 2-mal bearbeitet
|
|
bummi
      
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: Fr 18.02.11 21:24
Array fertig berechnen und dann zeichnen.
_________________ Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
|
|
galagher 
      
Beiträge: 2556
Erhaltene Danke: 45
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: Sa 19.02.11 13:45
Delphi-Quelltext 1: 2: 3: 4: 5:
| for x:= 0 to iMaxH do for y:=0 to iMaxv do ... if (aBoard[x,y-1]=elFree)and(aBoard[x,y] ... |
aBoard[x, y] = das gibt immer genau ein Element zu einem Zeitpunkt an einer Position im Array an. Man braucht, um die Bewegungen überhaupt wahrnehmen zu können, so etwas wie ein Sleep oder Delay und sieht dann, wie jedes Element extra, eins nach dem anderen, abgearbeitet wird und nicht alle zusammen.
Ich brauche etwas, dass mir alle Positionen aller elWalker's ermittelt und dann damit zugleich etwas macht. Also alle runter, rauf links, rechts, jedes je nachdem, ob der jeweilige Platz frei ist oder nicht.
Ihr kennt doch sicher zB. Super-Mario - da bewegen sich etwa alle Schildkröten zugleich, nicht erst die eine und dann die andere!
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
Xion
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Sa 19.02.11 14:33
galagher hat folgendes geschrieben : | Ich brauche etwas, dass mir alle Positionen aller elWalker's ermittelt und dann damit zugleich etwas macht. |
Du kannst nicht echt gleichzeitig alle Walker bewegen (theoretisch nur, wenn du mindestens so viele Prozessoren hast wie Walker).
Es reicht völlig das nacheinander zu machen. Erst alle (nacheinander) berechnen, dann zeichnen. Das dauert dann 1 Millisekunde oder so. Das ist also auch sowas wie gleichzeitig. Wenn es länger dauert, dann machst du was falsch.
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
galagher 
      
Beiträge: 2556
Erhaltene Danke: 45
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: So 20.02.11 14:37
Xion hat folgendes geschrieben : | Du kannst nicht echt gleichzeitig alle Walker bewegen (theoretisch nur, wenn du mindestens so viele Prozessoren hast wie Walker). |
Klar, weiss ich, ich meinte optisch gleichzeitig!
Diese Prozedur bewegt die elWalker's zwar, allerdings hüpfen sie nur je 1 Feld auf und ab, da die Prozedur sich selbst aufruft:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36:
| procedure TForm1.RunWalker; var x, y: Integer; begin for x := 0 to iMaxH do for y := 0 to iMaxV do begin if (aBoard[x, y] = elWalker) and (aBoard[x, y+1] = elFree) then begin aBoard[x, y] := elFree; aBoard[x, y+1] := elWalker; break; end; end;
DrawBoard; Delay(300);
for x := 0 to iMaxH do for y := 0 to iMaxV do begin if (aBoard[x, y] = elWalker) and (aBoard[x, y-1] = elFree) then begin aBoard[x, y] := elFree; aBoard[x, y-1] := elWalker; break; end; end;
DrawBoard; Delay(300);
RunWalker; end; |
Ich schaffe es nicht, dass die elWalker's zuerst alle freien Felder hinunter, dann alle freien Felder wieder hinauf usw. gesetzt werden, wie gesagt, immer nur je 1 Feld...
Wie schaffe ich es, dass jede der Schleifen für jeden elWalker alle freien Felder ermittelt, ohne schon nach je 1 Feld abzubrechen?
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
Xion
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: So 20.02.11 14:41
galagher hat folgendes geschrieben : |
Delphi-Quelltext |
Pfui, Wääh, PÖSE!
Nehm einen TTimer! Dort packst du dann EINE Bewegung rein. Beim nächsten Timer-Intervall macht er dann die nächste Bewegung.
//Edit:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27:
| for x := 0 to iMaxH do for y := 0 to iMaxV do if (aBoard[x,y]=elWalkerDown)or(aBoard[x,y]=elWalkerUp) then begin if (aBoard[x, y] = elWalkerDown) and (aBoard[x, y+1] = elFree) then begin aBoard[x, y] := elFree; aBoard[x, y+1] := elWalkerDown; end else if (aBoard[x, y] = elWalkerUp) and (aBoard[x, y-1] = elFree) then begin aBoard[x, y] := elFree; aBoard[x, y-1] := elWalkerUp; end else if (aBoard[x,y] = elWalkerDown) and (aBoard[x, y+1] <> elFree) then begin aBoard[x, y] := elWalkerUp; end else if (aBoard[x,y] = elWalkerUp) and (aBoard[x, y-1] <> elFree) then begin aBoard[x, y] := elWalkerDown; end end; |
Dieser Code geht vom Prinzip her. Nur wie ich schon sagte, musst du die Bewegungsrichtung speichern, sonst weiß er natürlich nicht, dass er weiter nach obene gehen muss, anstatt nach unten zu gehen
//Edit2:
Statt dem DrawBoard solltest du besser dein altes System mit der Funktion DrawBoard(x,y) nutzen. Das Board immer ganz zeichnen, ist unnötig langsam. Du weißt ja, welche Walker du verschoben hast. Immer beim setzen eines array-Werts, gleich zeichnen.
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
galagher 
      
Beiträge: 2556
Erhaltene Danke: 45
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: So 20.02.11 14:59
Xion hat folgendes geschrieben : | Pfui, Wääh, PÖSE! |
Ist doch ein netter Purche, dieses Delay!
Ohne break wird das "Hinabwandern" aber nicht dargestellt, und wenn ich DrawBoard innerhalb der for-Schleife habe, wird natürlich bei jedem elWalker gezeichnet, optisch werden die elWalker's also nacheinander versetzt.
Ich kriege das einfach nicht hin!
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
Xion
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: So 20.02.11 15:01
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
galagher 
      
Beiträge: 2556
Erhaltene Danke: 45
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: So 20.02.11 15:18
Xion hat folgendes geschrieben : | musst du die Bewegungsrichtung speichern, sonst weiß er natürlich nicht, dass er weiter nach obene gehen muss, anstatt nach unten zu gehen  |
Habe ich versucht, mit Bool'schen Variablen, war alles nichts. Es bewegt sich dann gar nichts, jedenfalls habe ich es offenbar falsch gemacht.
Xion hat folgendes geschrieben : | Statt dem DrawBoard solltest du besser dein altes System mit der Funktion DrawBoard(x,y) nutzen. |
Ja, hast recht, das habe ich aber nun treffender "RefreshBoard" benannt.
Xion hat folgendes geschrieben : | Xion hat folgendes geschrieben : | Nehm einen TTimer! |
Du weißt schon, was ein Timer ist, oder?  |
Na klar weiss ich das!
Danke, jetzt ist's aber genug!
Nein, im Ernst, ich möchte es lieber so machen, muss doch auch gehen, aber, wie gesagt, irgendwas mit der Bewegungsrichtung raffe ich dabei nicht.
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
Xion
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: So 20.02.11 15:43
galagher hat folgendes geschrieben : | Xion hat folgendes geschrieben : | musst du die Bewegungsrichtung speichern, sonst weiß er natürlich nicht, dass er weiter nach obene gehen muss, anstatt nach unten zu gehen  | Habe ich versucht, mit Bool'schen Variablen, war alles nichts. Es bewegt sich dann gar nichts, jedenfalls habe ich es offenbar falsch gemacht. |
Das geht auch...aber mit den Elementen wie oben gezeigt gehts erstmal einfacher
galagher hat folgendes geschrieben : | Nein, im Ernst, ich möchte es lieber so machen, muss doch auch gehen, aber, wie gesagt, irgendwas mit der Bewegungsrichtung raffe ich dabei nicht. |
Na meinetwegen. Dann musst du auch nur beide Codeschnippsel von oben mischen
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38:
| procedure TForm1.RunWalker; var x, y: Integer; begin for x := 0 to iMaxH do for y := 0 to iMaxV do if (aBoard[x,y]=elWalkerDown)or(aBoard[x,y]=elWalkerUp) then begin if (aBoard[x, y] = elWalkerDown) and (aBoard[x, y+1] = elFree) then begin
aBoard[x, y] := elFree; aBoard[x, y+1] := elWalkerDown; end else if (aBoard[x, y] = elWalkerUp) and (aBoard[x, y-1] = elFree) then begin aBoard[x, y] := elFree; aBoard[x, y-1] := elWalkerUp; end else if (aBoard[x,y] = elWalkerDown) and (aBoard[x, y+1] <> elFree) then begin aBoard[x, y] := elWalkerUp; end else if (aBoard[x,y] = elWalkerUp) and (aBoard[x, y-1] <> elFree) then begin aBoard[x, y] := elWalkerDown; end end;
DrawBoard; Delay(300);
RunWalker; end; |
So, und dann musst du nur noch elWalkerDown + elwalkerUp zu deinem Set hinzufügen und elWalker rauslöschen.
Wenn du nicht ein Senior-Member wärst, würd ich sagen, wir machen hier keine fertigen Programme kostenlos
Vielleicht noch zum Verständis:
elWalkerUp ist ein Walker, der kann nur nach oben gehen. Es ist sozusagen ein andrer Walker als elWalkerDown, der ist einer der kann nur nach unten gehen. Und die können sich ineinander umwandeln wenn nötig 
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
galagher 
      
Beiträge: 2556
Erhaltene Danke: 45
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: So 20.02.11 17:12
Xion hat folgendes geschrieben : | Wenn du nicht ein Senior-Member wärst, würd ich sagen, wir machen hier keine fertigen Programme kostenlos |
Danke für den Code, aber ...
... jetzt laufen sie nach oben, "fallen" dann nach unten, laufen wieder hoch und so weiter. Wenn ich nebenbei mit den Pfeiltasten die Spielerfigur steuere, erhalte ich nach einiger Zeit plötzlich eine Zugriffsverletzung.
Habe auch versucht, den Code mit nur einem elWalker zu gestalten und stattdessen mit einer Bool-Var für die Richtingsumkehr. Dann laufen sie ständig nur nach oben über alle anderen Elemente hinweg, also auch, wenn nicht elFree! Zudem versetzen sie sich dabei um ein Feld nach rechts. Also auch nix.
Weiss nicht, woher jetzt auf einmal die Zugriffsverletzung kommt. Ich versuche jetzt erstmal, herauszufinden, warum sie nicht auch nach unten laufen.
//Edit: Wenn ich die for-Schleifen umkehre, wandern sie herunter und "fallen" hinauf.
Delphi-Quelltext 1: 2:
| for x := iMaxH downto 0 do for y := iMaxV downto 0 do |
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
Xion
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: So 20.02.11 17:32
galagher hat folgendes geschrieben : | ... jetzt laufen sie nach oben, "fallen" dann nach unten, laufen wieder hoch und so weiter. |
Hmm, da haste recht. Das ist ja fieser als ich dachte (dadurch, dass du ihn nach unten schiebst, wird er beim durchlauf der Schleife bei der neuen Zelle wieder erwischt und bewegt  )
galagher hat folgendes geschrieben : | Wenn ich nebenbei mit den Pfeiltasten die Spielerfigur steuere, erhalte ich nach einiger Zeit plötzlich eine Zugriffsverletzung. |
Das wundert mich nicht, da in dem Code ohne Prüfung auf [x,y+1] zugegriffen wird. Ist dieses Element außerhalb des arrays => Access Violation (aber nicht immer  )
galagher hat folgendes geschrieben : | Zudem versetzen sie sich dabei um ein Feld nach rechts. |
Da musst du sie irgendwie in x verschieben, das sollest du nicht machen
Edit:
Machs mal etwas komfortabler:
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| type TWalker=record Pos: TPoint; Direction: integer; end;
var Walker: array of TWalker; |
JETZT machen wirs ordentlich:
1. Du musst das array erstmal füllen, mit SetLength, Position und Richtung setzen.
2.
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| for A:= 0 to High(Walker) do begin x:=Walker[A].Pos.X; y:=Walker[A].Pos.Y; end; |
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
galagher 
      
Beiträge: 2556
Erhaltene Danke: 45
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: So 20.02.11 22:57
Ich habe eine Lösung gefunden, wie es auch mit for-Schleifen klappt: Je eine eigene Prozedur für auf und ab, die einander wechselseitig aufrufen. Da noch eine Abbruch-Anweisung hinein, wenn zB. das Programm beendet wird, und es klappt auch bestens auch mit links/rechts laufenden Dingern. Bremst auch das Programm nicht merklich aus, alles bleibt schön flott!
Einziger Nachteil: Jede dieser Prozeduren, eigentlich jede andere for-Schleife, stoppt diese Prozeduren. Während zB. die senkrechten Elemente laufen, stehen die waagrecht laufenden still und umgekehrt. Ich habe auch meine Schleifen mit den breaks behalten, ergibt auch interessante Effekte mit den senkrecht hüpfenden Figuren, aber auch hier bleibt alles stehen, sobald eine andere Schleifen läuft.
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
Xion
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Mo 21.02.11 10:53
Ich habs mal eben gebastelt  Allerdings mit Timer und Shapes. So hast du ja eine gute Vorlage, wenn du keinen Timer willst, musst du nur die "Timerfunktion" am Ende nach einem Delay wieder aufrufen.
Die Shapes hab ich nur genommen, weil ichs damit auf die Schnelle einfacher fand
Einloggen, um Attachments anzusehen!
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
galagher 
      
Beiträge: 2556
Erhaltene Danke: 45
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: Mo 21.02.11 22:37
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
Xion
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Mo 21.02.11 22:46
Ja wie gesagt, den Timer kannst du weglassen indem du die Funktion am Ende wieder selbst aufrufst (+Delay).
Das Zeichnen hast du ja schon selbst gemacht, da musst du nur deine alte Zeichenfunktion einbauen (statt dem Update der Shapes).
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
galagher 
      
Beiträge: 2556
Erhaltene Danke: 45
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: Mi 23.02.11 22:08
Ich steuere jetzt doch alles über Timer, hat den Vorteil, dass die Bewegungen trotz anderweitg ausgeführter for-Schleifen nicht ins Stocken geraten. Auch mit mehreren elWalker's! 
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
|