![]() |
[Gelöst] Verwendung von TQueue
'Nabend DP,
Ich habe da ein kleines Spiel (Tron :) ) geplant. Soweit läuft auch alles gut. Aaaaber: Mir ist aufgefallen, dass ich 2x ganz schnell eine Taste drücken kann und das 'Bike' fährt gegen seine eigene Mauer (dreht sich um 180°) Daher habe ich zunächst einfach weitere Tasteneingaben gesperrt, bis das Bike eine Position weiter ist. Das finde ich aber eigenltich sehr unschön, und würde die Tastendrücke gerne nacheinander abaerbeiten. Somit bin ich dann bei TStack und TQueue gelandet. Soweit ich das richtig verstanden habe gibt es für meine Delphi Version (D7 Enterprise) keine TStack <Integer> ö.Ä. - er nimmt nur Zeiger an :? Nun zu meinem eigentlichen Problem:
Delphi-Quellcode:
Angenommen es liegt auf dem Stack ein Zeiger der auf Key zeigt. Dann würde doch bei meinem nächsten Tastendruck beide Items auf den selben Key zeigen oder irre ich da :?:
procedure TMain.MainKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState); begin case Key of 70: Tasten.Push(@Key); // [F] - LINKS 74: Tasten.Push(@Key); // [J] - RECHTS end; end; Und wenn es trotzdem unterschiedliche Werte sein sollten - wie wertet man den Stack wieder aus ? Ich hatte mir gedacht, dass vor jeder Bewegung geprüft wird, welche Richtung er gehen soll:
Delphi-Quellcode:
Nun meckert der Compiler aber, dass 'i' kein Integer sondern ein Char sein soll .. wobei der Zeiger doch auf einen Integer zeigt :roll:
procedure TMain.Timer1Timer(Sender: TObject);
var i: ^Integer; begin i := Tasten.Pop; case ^i of 70: Spieler[0].dreheLinks; 74: Spieler[0].dreheRechts; darstellen(Sender); end; Ich hoffe ich konnte mich halbwegs verständlich ausdrücken :( Ist für mich das Erste mal dass ich mit Zeigern hantieren muss:oops: //Edit: Habe es soweit hinbekommen, dass ich keine Fehlermeldung bekomme.
Delphi-Quellcode:
allerdings scheint es so, als würde er nichts auf den Stack schieben (jedenfalls enthällt er im Debug mode keine Zeiger) :o
procedure TMain.Timer1Timer(Sender: TObject);
var i: ^Integer; begin if Tasten.Count > 0 then begin i := Tasten.Pop; case Ord(^i) of 70: Spieler[0].dreheLinks; // [F] - LINKS 74: Spieler[0].dreheRechts; // [J] - RECHTS end; end; darstellen(Sender); end; |
AW: Verwendung von TStack
Zitat:
Wenn das Bike frontal gegen seine eigene Mauer fährt, dann wird die Kollision ignoriert und die Richtung um 180 Grad gedreht. |
AW: Verwendung von TStack
Zitat:
Doch angenommen ich habe mich nun 2x nach Rechts bewegt - wie erkennt der Computer, dass ich mich nicht nocheinmal nach Rechts bewegen darf ? Eigendlich soll es dann ja eine Koorlision geben, aber wenn die Position des Bikes mit der seiner Wand entspricht, "prallen" sie ja nicht aufeinaner :?: So müsste ich irgendwie speichern, welche seine letzte Richtungsänderung war und danach entscheiden ob die nächste Bewegung möglich ist - oder wie hattest du dir das vorgestellt :oops: (Im Extrem Fall Bewegt man sich 2x Rechts .. wartet .. wieder 2x Rechts. Dann würde sich wieder ein Stack anbieten um die Richtungsänderungen zu speichern :roll:) Wenn ich es gar nicht mit Stacks hinkrege werde ich wohl dadrauf zurückgreifen. Wäre aber trotzdem nett wenn mir jemand meinen Fehler bei dem Stack zeigen könnte :? |
AW: Verwendung von TStack
Du poppst die Speicheradresse der Variable auf deinen Stack?
*wo ist der ich hau dir auf die finger*-Smiley ? Dein Stack wird zeitverzögert aufgerufen, daß heißt die Variable gibt es dann nicht mehr. Da dieses Variable zufällig auf dem Stack (des Programms) liegt, greifst du also auf irgendwas zu, aber vermutlich nicht mehr auf den Wert der gedrückten Taste. (da der Stack aber immer da ist, gibt es wenigstens keine Zugriffsverletzung) Warum poppst du nicht einfach den "Wert" der gedrückten Taste drauf, bzw. warum verarbeitest du das nicht sofort? |
AW: Verwendung von TStack
Nur mal nebenbei, nicht auf's Problem konkret bezogen:
Zitat:
|
AW: Verwendung von TStack
Zitat:
Zitat:
Okey wenn ich das so abändere gibt es schonmal keine Fehlermldung. Jedoch scheint er dann auf Speicher zuzugreifen, der nicht mehr meine Tastennummer enthällt :? Meintest du das himitsu ? Bin da nicht ganz durchgestiegen, was du mit der Zeitverzögerung meintest :cry: Aber schonmal vielen Dank für die hilfreichen Antworten, ich stelle mich bestimmt mal wieder recht dusselig an :roll: |
AW: Verwendung von TStack
Zitat:
Es will einen "Wert", den es speichern kann. Wie bei TList also nicht einen Zeiger auf einen beliebigen Speicher. Willst du wirklich einen Pointer speichern, dann müßtest du dafür sorgen, daß der Speicher nicht verloren geht, also z.B. per New einen Speicher vom Typ PWord (du willst ja ein Word speichern) erstellen, diesen puschen und am Ende (nach dem Pop) natürlich nicht das Dispose vergessen, oder du kastes das Word infach in einen Pointer und wieder zurück. Wie gesagt, diese Variable "Key" ist nach Verlassen der Ereignisprozedur ungültig und damit auch der Zeiger auf sie. In anktuelleren Delphis (D2009+) könnte man stattdessen auch den generischen Stack nutzen TStack<Word>, welcher direkt den "Wert" speichert. |
AW: Verwendung von TStack
Oder einfach den Wert auf Pointer (und später zurück) casten:
Delphi-Quellcode:
und zurück:
procedure TMain.MainKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState); begin case Key of 70: Tasten.Push(Pointer(Key)); // [F] - LINKS 74: Tasten.Push(Pointer(Key)); // [J] - RECHTS end; end;
Delphi-Quellcode:
Achtung, TQueue ist die gewünschte Klasse, nicht TStack.
procedure TMain.Timer1Timer(Sender: TObject);
var i: ^Integer; begin i := Tasten.Pop; case Word(i) of 70: Spieler[0].dreheLinks; 74: Spieler[0].dreheRechts; darstellen(Sender); end; TQueue ist FIFO (First In, First Out), TStack ist FILO (First In, Last Out). ...:cat:... |
AW: Verwendung von TStack
Zitat:
//Edit: Argh habe den Post von sakura nicht gesehen. Werde es eben mal so testen //Edit2: So wie sakura es vorgeschlagen hat klappt es :bouncing4: Das klärt auch meine Frage wie ich ihm einen Wert übergebe wenn er einen Pointer erwartet :) Vielen Dank an euch |
AW: Verwendung von TStack
Zitat:
Delphi-Quellcode:
Ist einfacher, Bezeichner wie "dirLeft" und "dirRight" zu assoziieren, als 70, 74:
type
TDirections = (dirLeft, dirRight); // ... case Key of 70: Tasten.Push(Pointer(dirLeft)); // [F] - LINKS 74: Tasten.Push(Pointer(dirRight)); // [J] - RECHTS end;
Delphi-Quellcode:
procedure TMain.Timer1Timer(Sender: TObject);
var i: ^Integer; begin i := Tasten.Pop; case TDirection(i) of dirLeft: Spieler[0].dreheLinks; dirRight: Spieler[0].dreheRechts; darstellen(Sender); end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:54 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