AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

[Gelöst] Verwendung von TQueue

Ein Thema von MrMooed · begonnen am 13. Okt 2012 · letzter Beitrag vom 14. Okt 2012
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von MrMooed
MrMooed

Registriert seit: 18. Feb 2012
101 Beiträge
 
Delphi 7 Enterprise
 
#1

[Gelöst] Verwendung von TQueue

  Alt 13. Okt 2012, 17:02
'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:
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;
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

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:
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;
Nun meckert der Compiler aber, dass 'i' kein Integer sondern ein Char sein soll .. wobei der Zeiger doch auf einen Integer zeigt


Ich hoffe ich konnte mich halbwegs verständlich ausdrücken Ist für mich das Erste mal dass ich mit Zeigern hantieren muss


//Edit: Habe es soweit hinbekommen, dass ich keine Fehlermeldung bekomme.
Delphi-Quellcode:
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;
allerdings scheint es so, als würde er nichts auf den Stack schieben (jedenfalls enthällt er im Debug mode keine Zeiger)

Geändert von MrMooed (14. Okt 2012 um 16:32 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

Registriert seit: 15. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#2

AW: Verwendung von TStack

  Alt 13. Okt 2012, 17:41
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°)
Man das Problem auch anderst angehen.
Wenn das Bike frontal gegen seine eigene Mauer fährt, dann wird die Kollision ignoriert und die Richtung um 180 Grad gedreht.
  Mit Zitat antworten Zitat
Benutzerbild von MrMooed
MrMooed

Registriert seit: 18. Feb 2012
101 Beiträge
 
Delphi 7 Enterprise
 
#3

AW: Verwendung von TStack

  Alt 13. Okt 2012, 17:55
Man das Problem auch anderst angehen.
Wenn das Bike frontal gegen seine eigene Mauer fährt, dann wird die Kollision ignoriert und die Richtung um 180 Grad gedreht.
Echt gute Idee
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
(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 )

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
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.166 Beiträge
 
Delphi 12 Athens
 
#4

AW: Verwendung von TStack

  Alt 13. Okt 2012, 17:59
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?
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (13. Okt 2012 um 18:01 Uhr)
  Mit Zitat antworten Zitat
nuclearping

Registriert seit: 7. Jun 2008
708 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#5

AW: Verwendung von TStack

  Alt 13. Okt 2012, 18:06
Nur mal nebenbei, nicht auf's Problem konkret bezogen:
Delphi-Quellcode:
procedure TMain.Timer1Timer(Sender: TObject);
var
  i: ^Integer; // <-- Es gibt auch den Typ PInteger
begin
  i := Tasten.Pop;
  case ^i of // Was ist das? i ist doch schon ^Integer (PInteger) und du willst hier die Adresse der Adresse abfragen? :D
    70: Spieler[0].dreheLinks;
    74: Spieler[0].dreheRechts;
  darstellen(Sender);
end;
Nun meckert der Compiler aber, dass 'i' kein Integer sondern ein Char sein soll .. wobei der Zeiger doch auf einen Integer zeigt
Ja, probier's mal mit i^ statt ^i ...
  Mit Zitat antworten Zitat
Benutzerbild von MrMooed
MrMooed

Registriert seit: 18. Feb 2012
101 Beiträge
 
Delphi 7 Enterprise
 
#6

AW: Verwendung von TStack

  Alt 13. Okt 2012, 18:35
Warum poppst du nicht einfach den "Wert" der gedrückten Taste drauf, bzw. warum verarbeitest du das nicht sofort?
Weil Delphi bei TStack.Push(AItem: TPointer) erwartet. (Was doch soviel bedeutet wie "gib mir einen Zeiger auf deinen Wert"

Nur mal nebenbei, nicht auf's Problem konkret bezogen:
Ja, probier's mal mit i^ statt ^i ...
Ups da war mir die Verwendung des Daches wohl nicht 100%ig klar, doch wenn ich es so ändere

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

Aber schonmal vielen Dank für die hilfreichen Antworten, ich stelle mich bestimmt mal wieder recht dusselig an
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.166 Beiträge
 
Delphi 12 Athens
 
#7

AW: Verwendung von TStack

  Alt 13. Okt 2012, 19:16
Weil Delphi bei TStack.Push(AItem: TPointer) erwartet. (Was doch soviel bedeutet wie "gib mir einen Zeiger auf deinen Wert"
TStack ist wie TList
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.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von sakura
sakura

Registriert seit: 10. Jun 2002
Ort: München
11.412 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Verwendung von TStack

  Alt 13. Okt 2012, 19:38
Oder einfach den Wert auf Pointer (und später zurück) casten:
Delphi-Quellcode:
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;
und zurück:
Delphi-Quellcode:
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;
Achtung, TQueue ist die gewünschte Klasse, nicht TStack.

TQueue ist FIFO (First In, First Out), TStack ist FILO (First In, Last Out).

......
Daniel W.
Ich bin nicht zurück, ich tue nur so
  Mit Zitat antworten Zitat
Benutzerbild von MrMooed
MrMooed

Registriert seit: 18. Feb 2012
101 Beiträge
 
Delphi 7 Enterprise
 
#9

AW: Verwendung von TStack

  Alt 13. Okt 2012, 19:43
TStack ist wie TList
Es will einen "Wert", den es speichern kann.

Wie gesagt, diese Variable "Key" ist nach Verlassen der Ereignisprozedur ungültig und damit auch der Zeiger auf sie.
Aber wie kann ich ihm den Wert übergeben, wenn er einen Zeiger erwartet stehe da gerade auf dem Schlauch

//Edit:
Argh habe den Post von sakura nicht gesehen. Werde es eben mal so testen

//Edit2:
So wie sakura es vorgeschlagen hat klappt es Das klärt auch meine Frage wie ich ihm einen Wert übergebe wenn er einen Pointer erwartet Vielen Dank an euch

Geändert von MrMooed (13. Okt 2012 um 19:58 Uhr)
  Mit Zitat antworten Zitat
nuclearping

Registriert seit: 7. Jun 2008
708 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#10

AW: Verwendung von TStack

  Alt 13. Okt 2012, 22:00
So wie sakura es vorgeschlagen hat klappt es Das klärt auch meine Frage wie ich ihm einen Wert übergebe wenn er einen Pointer erwartet Vielen Dank an euch
Statt dem Key kannst du ihm auch einen State übergeben.

Delphi-Quellcode:
type
  TDirections = (dirLeft, dirRight);

// ...

case Key of
  70: Tasten.Push(Pointer(dirLeft)); // [F] - LINKS
  74: Tasten.Push(Pointer(dirRight)); // [J] - RECHTS
end;
Ist einfacher, Bezeichner wie "dirLeft" und "dirRight" zu assoziieren, als 70, 74:
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;
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:37 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz