Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi solange taste gedrücktt tue! ??? (https://www.delphipraxis.net/84837-solange-taste-gedruecktt-tue.html)

flori-da 22. Jan 2007 17:16


solange taste gedrücktt tue! ???
 
Hi leute..

hab mal ne kleine frage:
wie kann ich das machen, dass solange eine taste (pfeiltasten) gedrückt wird etwas gemacht wird?
z.B. solange die Pfeiltaste nach links gedrückt wird soll eine figut (TImage ) nach links laufen.

habs schon mit keydown und ner while-do-schleife probiert nud das hat nicht geklapt.

bin gespannt auf euere Antworten.
schon mal danke!
grüße flo

Klaus01 22. Jan 2007 17:19

Re: solange taste gedrücktt tue! ???
 
Hallo,

Du könntest in dem OnKeyDown Ereignis der Form einen Thread starten und in dem OnKeyUp Ereignis
den Thread wieder stoppen.

Grüße
Klaus

sirius 22. Jan 2007 17:20

Re: solange taste gedrücktt tue! ???
 
Fürs erste setzt du die Bewegung in einen TTimer.
Wenn die Taste gedrückt wird (KeyDown) setzt du TTimer.enabled auf true. Wenn KEyUp kommt auf false

flori-da 22. Jan 2007 17:31

Re: solange taste gedrücktt tue! ???
 
das mit dem Timer hört sich gut an.
Doch wie kann ich dem Timer sagen , welche Taste ich drücke.
Also zum Beispiel: falls die linke Pfeiltaste gerade gedrückt wird dann tue das ... usw.
grüße der flo

flori-da 22. Jan 2007 17:34

Re: solange taste gedrücktt tue! ???
 
P.S. außerdem weiß ich nicht , was ein thread ist > deswegen fand ich die version mit dem timer besser

inherited 22. Jan 2007 17:35

Re: solange taste gedrücktt tue! ???
 
Oder du setzt das gesamte Spiel (ich nehme mal an so twas in der Arte ist es) gleich mit einem Main-Loop um (zB Timer), das ist eh besser. Dann kannst du regelmäßig mit GetAsyncKeyState die Tasten überprüfen
Diese könnte dann pseudocodemäßig so aussehen:
Delphi-Quellcode:
procedure CheckKeys;
begin
  if GetAsnycKeyState(vk_left)<0 then
    Player.MoveLeft;
  if GetAsyncKeyState(vk_right)<0 then
    Player.MoveRight
end;

procedure MainLoop;
begin
  CheckKeys;
  Render;
end;

flori-da 22. Jan 2007 17:43

Re: solange taste gedrücktt tue! ???
 
kann ich das nicht in meinen timer einbauen?
zum beispiel so, wenn der timer "startet", enabled also true ist, dann soll er nach den key fragen der gerade gedrückt ist und in eine entsprechende richtung laufen.

Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
 if GetAsnycKeyState(vk_left)<0 then
    Player.MoveLeft;
  if GetAsyncKeyState(vk_right)<0 then
    Player.MoveRight
  ...
end;

inherited 22. Jan 2007 17:45

Re: solange taste gedrücktt tue! ???
 
dito

flori-da 22. Jan 2007 17:49

Re: solange taste gedrücktt tue! ???
 
ok :?
das scheint doch nicht zu klappen.
er sagt, dass GetAsnycKeyState ein undefinierter bezeichner ist.
kann das auch an meiner delphi version liegen ( Delphi 3)??

Blackheart 22. Jan 2007 18:05

Re: solange taste gedrücktt tue! ???
 
Zitat:

Zitat von flori-da
ok :?
das scheint doch nicht zu klappen.
er sagt, dass GetAsnycKeyState ein undefinierter bezeichner ist.
kann das auch an meiner delphi version liegen ( Delphi 3)??

GetAsyncKeyState

inherited 22. Jan 2007 18:11

Re: solange taste gedrücktt tue! ???
 
Ja, Sorry, ich hab mich da in der Schnelle vertippt.

flori-da 22. Jan 2007 18:14

Re: solange taste gedrücktt tue! ???
 
:wall: ich dummerchen. trotzdem geht es auch richtig geschrieben nicht.
und ich hab es doch so gemacht, wie ihr es mir gesagt habt.

Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  if GetAsyncKeyState(vk_left)<0 then
    walk(1)
  if GetAsyncKeyState(vk_right)<0 then
    walk(3);
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  Timer1.Enabled:=true;
end;

procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  Timer1.Enabled:=false;
end;
:gruebel:

sirius 22. Jan 2007 18:17

Re: solange taste gedrücktt tue! ???
 
wegen getasync... kannst du das KEyDown und KeyUp weglassen und einfach den Timerenabled auf true setzen solange das Image sich bewegen soll.

1ceman 22. Jan 2007 18:20

Re: solange taste gedrücktt tue! ???
 
mach doch einfach 2 timer, einen für links und einen für rechts.
dann überprüfst du im FormKeyDown ob die linke oder die rechte pfeiltaste gedrückt wird und startest
dann den timer für links oder rechts.

Klaus01 22. Jan 2007 18:33

Re: solange taste gedrücktt tue! ???
 
- war mumpitz -> gelöscht

Grüße
Klaus

inherited 22. Jan 2007 19:16

Re: solange taste gedrücktt tue! ???
 
Zitat:

Zitat von 1ceman
mach doch einfach 2 timer, einen für links und einen für rechts.
dann überprüfst du im FormKeyDown ob die linke oder die rechte pfeiltaste gedrückt wird und startest
dann den timer für links oder rechts.

Und was soll das bringen?

flori-da 22. Jan 2007 19:37

Re: solange taste gedrücktt tue! ???
 
Ich hab jetzt 2 Timer eingebaut. Also zumindestens bewegt sich die Figur!
Aber ohne das ich eine Taste drücke und nur nach rechts.
Ich hab auch das Intervall des Timers auf 200 gestellt , damit es flüssig wirkt und dafür die Schrittgröße verkleinert.
(Schrittgröße = Pixelzahl die das bild bei der procedure walk verschoben wird)

also hier ist der neue Quelltext, der mir neue rätsel aufweißt.

Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  walk(1);
end;

procedure TForm1.Timer2Timer(Sender: TObject);
begin
  walk(3)
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if GetAsyncKeyState(vk_left)<0 then
    Timer1.Enabled:=true;
  if GetAsyncKeyState(vk_right)<0 then
    Timer2.enabled:=true;
end;

procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if GetAsyncKeyState(vk_left)<0 then
    Timer1.Enabled:=false;
  if GetAsyncKeyState(vk_right)<0 then
    Timer2.Enabled:=false;
end;
bei der gelegenheit könnte mir vllt auch jemand erklären, was die function getasynckeystate bewirkt.
das raffe ich nicht so ganz? :gruebel:

aber schon mal danke für euere unterstützung
grüße der flo

zecke 22. Jan 2007 19:40

Re: solange taste gedrücktt tue! ???
 
Wenn sie sich bewegt bevor Du was machst, hast du wahrscheinlich vergessen die Timer von Haus aus, auf false zu setzen ;) (im OI, Enabled:=false)

inherited 22. Jan 2007 19:44

Re: solange taste gedrücktt tue! ???
 
Nein...
So war das nicht gemeint. laso:
GetAsyncKeystate liefert dir in DEM MOMENT wo du es abfragst, ob gerade in diesem Moment die Taste gedrückt ist. Dann brauchst du also keinen Timer mehr für die Bewegung, sondern nur einen Timer in dem du mit GetAsyncKeystate abfragst, ob grad die nach-links-taste gedrückt ist oder nicht.

Um flori-da noch einmal zu zitieren:
Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  if GetAsnycKeyState(vk_left)<0 then
    Player.MoveLeft;
  if GetAsyncKeyState(vk_right)<0 then
    Player.MoveRight
  ...
end;
Das kommt in einen Timer, der ständig mit einem Interval von ca. 200 ms aktiv ist. Der überprüft dann alle 200 ms ob gerade die nach links taste oder die nach rehctsteste gedrückt ist und macht dann dies und jenes ;)

sirius 22. Jan 2007 19:47

Re: solange taste gedrücktt tue! ???
 
Zitat:

Zitat von flori-da
bei der gelegenheit könnte mir vllt auch jemand erklären, was die function getasynckeystate bewirkt.
das raffe ich nicht so ganz? :gruebel:

MSDN: GetAsyncKeyState

flori-da 22. Jan 2007 20:12

Re: solange taste gedrücktt tue! ???
 
Also so langsam versteh ich gar nix mehr..aber egal

Mein Programm sieht jetzt folgendermaßen aus:
Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  if GetAsyncKeyState(vk_left) <0 then
     walk(1);
  if GetAsyncKeyState(vk_right)<0 then
     walk(3);
end;
was für mich auch eigentlich logisch ist und eigentlich funktionieren müsste.
Ich verstehe es so:
die procedure checkt (jetzt alle 100 ms)ob eine pfeiltaste (links oder rechts) gerade gedrückt wird und wenn ja , dasnn soll sich die figur entsprechend bewegen.
Das ende vom lied ist, das die scheiß procedure gar nix macht!!
das heißt: schon wieder ein logischer fehler in meinen / unserem plan :?
enabled ist auch auf true gesetzt.
gruß der flo

bitsetter 22. Jan 2007 20:23

Re: solange taste gedrücktt tue! ???
 
Versuche mal meinen Code, er kommt auch ohne Timer aus.
Delphi-Quellcode:
var
  ImagePos: integer;
const
  verschieben= 5;//je größer um so schneller verschieben

procedure TForm1.FormCreate(Sender: TObject);
begin
  ImagePos:= Image1.Left;
  Image1.Parent.DoubleBuffered:= true;
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  case Key of
    vk_Left:
      begin
      dec(ImagePos, verschieben);
      Image1.Left:= ImagePos;
      end;
    VK_RIGHT:
      begin
      inc(ImagePos, verschieben);
      Image1.Left:= ImagePos;
      end;
  end;
end;

sirius 22. Jan 2007 20:28

Re: solange taste gedrücktt tue! ???
 
Zitat:

Zitat von bitsetter
Versuche mal meinen Code, er kommt auch ohne Timer aus.

Der dürfte nicht ganz den gewünschten Erfolg bringen, da die Tastatur nach dem ersten drücken einer Taste (wenn sie gehalten wird), erstmal eine Weile gar nix sendet und dann am Stück.

flori-da 22. Jan 2007 20:31

Re: solange taste gedrücktt tue! ???
 
die letzte version klapt auf jedenfall ganz gut.
simpel aber wirksam!
Ich weiß zwar noch nicht , ich damit auskommen (weil das alles noch viel komlepxer werden soll;
aber für den anfang reicht es aus! außerdem habe ich für heute genug von dem programm!!
Also vielen Dank für euere Hilf!
:lol:
Bye der flo

inherited 22. Jan 2007 21:47

Re: solange taste gedrücktt tue! ???
 
Außerdem hat die oben ohne Timer auskommende Funktion noch einen Nachteil: Kommt später mal Oben und Unten dazu, kann man nur in eine Richtung gleichzeitig, also zB entweder nach links, oder nach oben. Bei der Timerversion ist das nicht so.

1ceman 22. Jan 2007 23:43

Re: solange taste gedrücktt tue! ???
 
Zitat:

Zitat von inherited
Zitat:

Zitat von 1ceman
mach doch einfach 2 timer, einen für links und einen für rechts.
dann überprüfst du im FormKeyDown ob die linke oder die rechte pfeiltaste gedrückt wird und startest
dann den timer für links oder rechts.

Und was soll das bringen?

äh das die Figuren sich bewegen??? ;)
ob ich nun im Timer prüfe welche taste gedrückt wurde oder vorher ist doch eigentlich egal.
So hat man halt für jede bewegung nen eigenen timer und führt wenn die linke pfeiltaste
gedrückt wurde den timer für die bewegung nach links aus, bis die taste losgelassen wird. Bei
rechter pfeiltaste entsprechend den timer für den rechts-bewegung.
oder hab ich das problem falsch verstanden????

bitsetter 23. Jan 2007 01:19

Re: solange taste gedrücktt tue! ???
 
Inherited hatte recht, wenn man 2 Tasten bei meinem Code drückte, konnte man das Image nur in einer Richtung bewegen. Hier das ganze mit 1 Timer.
Delphi-Quellcode:
var
  ImagePosX, ImagePosY: integer;
const
  verschieben= 5;//je größer um so schneller verschieben

procedure TForm1.FormCreate(Sender: TObject);
begin
  ImagePosX:= Image1.Left;
  ImagePosY:= Image1.Top;
  Image1.Parent.DoubleBuffered:= true;
  Timer1.Interval:= 100;
  Timer1.Enabled:= false;
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Timer1.Enabled= false then
  Timer1.Enabled:= true;
  //Timer1Timer(Sender);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
 if GetAsyncKeyState(VK_LEFT)< 0 then
  begin
  dec(ImagePosX, verschieben);
  Image1.Left:= ImagePosX;
  end;
    if GetAsyncKeyState(VK_RIGHT)< 0 then
    begin
    inc(ImagePosX, verschieben);
    Image1.Left:= ImagePosX;
    end;
      if GetAsyncKeyState(VK_UP)< 0 then
      begin
      dec(ImagePosY, verschieben);
      Image1.Top:= ImagePosY;
      end;
        if GetAsyncKeyState(VK_DOWN)< 0 then
        begin
        inc(ImagePosY, verschieben);
        Image1.Top:= ImagePosY;
        end;
end;

procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  Timer1.Enabled:= false;
end;

flori-da 23. Jan 2007 16:41

Re: solange taste gedrücktt tue! ???
 
moin leute

also ich hab heut den vorschlag von bitsetter in die tat umgesetzt.
Und es funktioniert nicht.
Da hab ich mal mit F7 immer nur die einzelnen Anweisungen durchlaufen lassen und hab festgestellt, dass der Timer bei einen Tastendruck nicht angeht.Wenn ich eine Pfeiltaste drücke meldet sich die procedure keydown aber der Timer nicht. genausowenig die procedure KeyUp. Was ist da nur los?

gruß der flo

xZise 23. Jan 2007 17:07

Re: solange taste gedrücktt tue! ???
 
Lass den Timer immer laufen!
Also nicht erst starten o.s.ä. ;)

und dann im Intervall überprüfen ob sich eine Taste gedrückt hat.

inherited 23. Jan 2007 17:21

Re: solange taste gedrücktt tue! ???
 
Genau. Das mit dem OnKeyDown und OnKeyUp ist sinnlos, da im Timer ja eh überprüft wird, ob die Taste gedrückt ist.

flori-da 23. Jan 2007 17:31

Re: solange taste gedrücktt tue! ???
 
danke..es funktioniert. :lol:
ich hab festgestell, das mein erster Timer eine Macke hatte..
Hab es einfach mal in einen neuen eingebaut > und siehe da es funzt.
damit ist das problem gelöst.
Also vielen dank für euere Unterstützung
der flo

Namenloser 23. Jan 2007 17:33

Re: solange taste gedrücktt tue! ???
 
könnte an dem "timer.enabled = false" liegen, probier mal "not timer.enabled".

Aber wieso nicht einfach so:
Delphi-Quellcode:
var
  ImagePosX, ImagePosY: integer;
const
  verschieben= 5;//je größer um so schneller verschieben

procedure TForm1.FormCreate(Sender: TObject);
begin
  ImagePosX:= Image1.Left;
  ImagePosY:= Image1.Top;
  Image1.Parent.DoubleBuffered:= true;
  Timer1.Interval:= 100;
  Timer1.Enabled:= true;
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  // nixtun
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  if GetAsyncKeyState(VK_LEFT)< 0 then
  begin
    dec(ImagePosX, verschieben);
    Image1.Left:= ImagePosX;
  end;
  if GetAsyncKeyState(VK_RIGHT)< 0 then
  begin
    inc(ImagePosX, verschieben);
    Image1.Left:= ImagePosX;
  end;
  if GetAsyncKeyState(VK_UP)< 0 then
  begin
    dec(ImagePosY, verschieben);
    Image1.Top:= ImagePosY;
  end;
  if GetAsyncKeyState(VK_DOWN)< 0 then
  begin
    inc(ImagePosY, verschieben);
    Image1.Top:= ImagePosY;
  end;
end;

procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  // Nix tun
end;
edit: doofer kasten :(

inherited 23. Jan 2007 19:44

Re: solange taste gedrücktt tue! ???
 
Ääääääääh. Nimm mir das jetzt nich Übel, NamenLozer, aber warum postest du das?
Ziemlich genau so macht er es jetzt. Außerdem kannst du dir die beiden Variablen in den A... sparen, genauso wie du das Image1.Parent weglassen kannst

xZise 23. Jan 2007 21:56

Re: solange taste gedrücktt tue! ???
 
Auch wenn es inherited auf den Punkt gebracht hat:
Er brauch an sich nicht so viel Code ;)
Es reicht nur zu sagen, dass man ein Timer brauch, und im OnTimer das überprüft (GetAsyncKeyState). ggf. die Überprüfung mit Code.
Aber dein Beitrag ist ggf. kontraproduktiv dadurch, dass man, wenn man kein Bild bewegen will sondern z.B. eine Zahl, man die ganzen Sachen drum herum wieder entfernen muss...
Abgesehen davon wurde (Pseudo)Code schon 2 mal (o.s.ä.) genannt. Es happerte nur am Verständnis...

PS: Der erste Satz ist an sich falsch.
Weil der Aufruf
Delphi-Quellcode:
not Timer.Enabled
nichts macht außer den anderen Booleanwert zurückzuegeben ;)


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:55 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