Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Frage zur Tastatureingabe und Kollisionsabfrage (https://www.delphipraxis.net/80027-frage-zur-tastatureingabe-und-kollisionsabfrage.html)

Jack der 3 1. Nov 2006 22:21


Frage zur Tastatureingabe und Kollisionsabfrage
 
Hallo bin neu hier da ich erst seit 2 jahren programmiere und gerade mit einem (sehr) leichtem spiel "fangen" an.

Doch schon gibts die ersten probleme:

1)

Delphi-Quellcode:
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if char (key) = 'W' then
begin
movie1.Top:= movie1.Top -10;

end;

begin
if char (key) = 'S' then
begin
movie1.Top:= movie1.Top +10;
end;

begin
if char (key) = 'A' then
begin
movie1.left:= movie1.left -10;
end;

begin
if char (key) = 'D' then
begin
movie1.left:= movie1.left +10;
end;
begin
if key = VK_UP then
begin
movie2.Top:= movie2.Top -10;

end;

begin
if key = vk_down then
begin
movie2.Top:= movie2.Top +10;
end;

begin
if key = vk_left then
begin
movie2.left:= movie2.left -10;
end;

begin
if key = vk_right then
begin
movie2.left:= movie2.left +10;


end;
end;
end;
end;
end;
end;
end;
end;
(movie is ein eiger komponent ähnlich wie Image)


das is ne teil des quelltext. Alles schön und gut aber ich kann die zwei kreise zwar mit den Pfeiltasten und W, A, S, D bewegen aber nicht gleichzeitig!

2) Das spiel soll ja ein wie fangen sein also, dass wenn der eine kreis den anderen berührt soll zBs eine messagebox aufgerufen werden.
Wie soll das gehen??

Jack der 3

[edit=Phoenix]Titel geändert. Mfg, Phoenix[/edit]

Luckie 1. Nov 2006 22:22

Re: ---------------------FRAGE------------------------------
 
Bitte halte dich an die Regeln und gib deinem Topic einen aussagekräftigen Namen. Editier dazu deinen ersten Beitrag. Danke.

Sunlight7 2. Nov 2006 05:12

-Ohne Titel-
 
Hallo!

Und willkommen in der DP :cheers:
Hier gibt es einige Regeln, die Du beachten solltest, wenn Du willst, das Dir jemand hilft.

Könntest Du bitte:
  • das was Du möchtest genauer beschreiben
  • auf Dein Deutsch achten, damit man das nicht drei mal lesen muß, und sich dann noch nicht sicher ist, ob man's richtig verstanden hat.
  • Luckie's bitte umsetzen.

Zitat:

Zitat von Jack der 3
das is ne teil des quelltext. Alles schön und gut aber ich kann die zwei kreise zwar mit den Pfeiltasten und W, A, S, D bewegen aber nicht gleichzeitig!

Das liegt sehr wahrscheinlich an den vielen unnützen begin end Blöcken.
Außerdem wäre eine Aufsplittung mit Case schneller in der Laufzeit und übersichtlicher zu lesen.

Sunlight7 2. Nov 2006 05:38

Re: ---------------------FRAGE------------------------------
 
[OT]
Aber wenn Du Pech hast, löscht er das auch wieder... :mrgreen:
[/OT]

Zitat:

Zitat von Jack der 3
2) Das spiel soll ja ein wie fangen sein also, dass wenn der eine kreis den anderen berührt soll zBs eine messagebox aufgerufen werden.
Wie soll das gehen??

Dazu mußt Du Dir eine Routine schreiben, die prüft, ob die Kreise sich berühren.
Schau dazu mal nach Hier im Forum suchenKollision

Jens Schumann 2. Nov 2006 07:08

Re: ---------------------FRAGE------------------------------
 
Hallo,
das Reagieren auf zwei (oder mehr) gedrückte Tase funktioniert mit der API-Funktionen GetKeyState und
entsprechende. Einfach mal im Plattform SDK oder msdn-Online suchen und ausprobieren.

Phoenix 2. Nov 2006 07:40

Re: ---------------------FRAGE------------------------------
 
STOP!


:warn: Jack der 3 wurde von Luckie in seiner Funktion als Moderator bereits darauf hingewiesen, dass er seinen Titel zu ändern hat. Mir persönlich geht "----------- Frage -----------" auch auf den Sack (sorry für die harten Worte), ABER: Es wurde schon gesagt und es gibt keinen Grund, das zu wiederholen.

Weder für uns Moderatoren, noch für andere User.

SubData 2. Nov 2006 07:44

Re: ---------------------FRAGE------------------------------
 
Zitat:

Zitat von Jens Schumann
Hallo,
das Reagieren auf zwei (oder mehr) gedrückte Tase funktioniert mit der API-Funktionen GetKeyState und
entsprechende. Einfach mal im Plattform SDK oder msdn-Online suchen und ausprobieren.


Für jemanden, der gerade ganz klein anfängt, bzw. bei dem der Quellcode noch so aussieht, wie in den Kinderschuhen, der wird mit diesem Ratschlag ohne einen ggf. entsprechenden Direktverweis, auf was du meinst, nicht sonderlich viel anfangen können, denke ich...

Jack der 3 2. Nov 2006 08:20

Re: Frage
 
Ich bin erst 13...

Aber Danke an allle! :lol:

Luckie 2. Nov 2006 08:22

Re: Frage
 
@Jack der 3: Auch das Entfernen der Bindestriche macht den Titel nicht aussagekräftiger. Überleg dir um was es bei deinem Problem geht und versuch dies kurz im Topic zu beschreiben. Und das sollte man auch könne, wenn man erst dreizehn ist.

EWeiss 2. Nov 2006 18:44

Re: Frage
 
Du mußt die Keys miteinander verknüpfen.
Das Zauberwort ist 'AND'

gruß

Namenloser 2. Nov 2006 19:07

Re: Frage
 
Also erst einmal muss ich sagen, dass dieser Code sehr unübersichtlich ist, und dass man ihn sehr einfach auf diese Größe kriegen kann:

Delphi-Quellcode:
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
  if char (key) = 'W' then
    movie1.Top:= movie1.Top -10;
  if char (key) = 'S' then
    movie1.Top:= movie1.Top +10;
  if char (key) = 'A' then
    movie1.left:= movie1.left -10;
  if char (key) = 'D' then
    movie1.left:= movie1.left +10;

  if key = VK_UP then
    movie2.Top:= movie2.Top -10;
  if key = vk_down then
    movie2.Top:= movie2.Top +10;
  if key = vk_left then
    movie2.left:= movie2.left -10;
  if key = vk_right then
    movie2.left:= movie2.left +10;
end;
So finde ich das schonmal viel übersichtlicher.

Und jetzt zu deinem Problem, dass du nicht mehrere Bewegungen auf einmal ausführen kannst.
1) Nimm dir einen Timer und setze ihn auf das Formular.
2) Nimm den gleichen Code wie oben, aber ersetze
Delphi-Quellcode:
if Char(key) = 'W' then
durch
Delphi-Quellcode:
if getasynckeystate(ord('W')) < 0 then
das wiederholst du für die anderen If-Abfragen nach dem gleichen Prinzip.
3) Jetzt setze das Intervall des Timers auf eine etwas höhere Geschwindigkeit, z.b. 50 ms.

Die Bewegung sollte so funktionieren.

Zum Thema Kollision:
http://www.dsdt.info/tipps/?id=416&search=rect

Dürfte genau das richtige für dich sein ;)


@EWeiss: ich wusste gar nicht, dass man die Keys mit AND verknüpfen kann (und was gescheites dabei rauskommt) o.O
Das probier ich mal aus^^

EWeiss 2. Nov 2006 19:17

Re: Frage
 
1 Timer ist eine sehr schlechte lösung für so etwas
2 Warum sollte man keine Shortcuts mit and verknüpfen können ?
3 in VB gehts dann bei Delphi wohl auch.

Wenn ich mir aber den Quelltext ansehe komplett unformatiert
denke ich es macht keinen sinn mit KeyHooks und ähnlichen anzufangen.

Zumal man für so etwas generell eine Winproc anstelle von timern verwenden sollte.

gruß

Cöster 3. Nov 2006 20:50

Re: Frage
 
Zitat:

Zitat von EWeiss
1 Timer ist eine sehr schlechte lösung für so etwas

Warum?
Zitat:

Zitat von EWeiss
2 Warum sollte man keine Shortcuts mit and verknüpfen können ?

Kannst du ein kurzes Codebeispiel geben? Wie stellst du dir das vor?
Zitat:

Zitat von EWeiss
Wenn ich mir aber den Quelltext ansehe komplett unformatiert
denke ich es macht keinen sinn mit KeyHooks und ähnlichen anzufangen.

Wieso?
Zitat:

Zitat von EWeiss
Zumal man für so etwas generell eine Winproc anstelle von timern verwenden sollte.

Was ist eine Winproc? Windowsprocedure würde mir auch nicht mehr sagen.

Nils_13 3. Nov 2006 21:07

Re: Frage
 
@Cöster: Warum sollte man mit HotKeys nicht anfangen, wenn der Quellcode total unübersichtlich ist, so dass man nicht einmal da, bei diesem einfachen Code, durchsteigt. Erst formatieren, dann weitermachen.

Phantom1 3. Nov 2006 21:56

Re: Frage
 
Noch eine einfache möglichkeit:

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    procedure Timer1Timer(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
    procedure FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
    Keys: Array[0..255] of Boolean;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  Keys[Key]:=True;
end;

procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  Keys[Key]:=False;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  if Keys[Ord('W')] then
    movie1.Top:= movie1.Top -10;
  if Keys[Ord('S')] then
    movie1.Top:= movie1.Top +10;
  if Keys[Ord('A')] then
    movie1.left:= movie1.left -10;
  if Keys[Ord('D')] then
    movie1.left:= movie1.left +10;

  if Keys[VK_UP] then
    movie2.Top:= movie2.Top -10;
  if Keys[VK_DOWN] = then
    movie2.Top:= movie2.Top +10;
  if Keys[VK_LEFT] then
    movie2.left:= movie2.left -10;
  if Keys[VK_RIGHT] then
    movie2.left:= movie2.left +10;
end;

end.

EWeiss 4. Nov 2006 03:24

Re: Frage
 
Zitat:

Zitat von Cöster
Zitat:

Zitat von EWeiss
1 Timer ist eine sehr schlechte lösung für so etwas

Warum?
Zitat:

Zitat von EWeiss
2 Warum sollte man keine Shortcuts mit and verknüpfen können ?

Kannst du ein kurzes Codebeispiel geben? Wie stellst du dir das vor?
Zitat:

Zitat von EWeiss
Wenn ich mir aber den Quelltext ansehe komplett unformatiert
denke ich es macht keinen sinn mit KeyHooks und ähnlichen anzufangen.

Wieso?
Zitat:

Zitat von EWeiss
Zumal man für so etwas generell eine Winproc anstelle von timern verwenden sollte.

Was ist eine Winproc? Windowsprocedure würde mir auch nicht mehr sagen.

Zu 1. Weil ein Timer immer läuft und nicht nur dann wenn das Event (Druck auf x.. Taste) auftritt.
Zu 2. Könnt dir was in VB zeigen macht aber im Delphi Forum keine Sinn und zum übersetzen hab ich keinen Bock.
Zu 3. Wenn ein User nicht mal die einfachste Formatierung eines Quelltextes zustande bekommt ..
Sorry wie will er dann mit Hooks zurechtkommen.
Zu 4. Was soll das schon sein?. Abkürzung für Windowsprocedure, Callback oder wie du es sonst nennen willst.

gruß

Khabarakh 4. Nov 2006 08:59

Re: Frage
 
Zitat:

Zitat von EWeiss
1 Timer ist eine sehr schlechte lösung für so etwas

Komplett falsch.

a) Es geht hier um ein Spiel. Und jedes Spiel, in dem eine Bewegung stattfindet, benötigt eine Spielschleife. Das kann eine echte Schleife sein oder in einfacher Art ein Timer. Der Timer ist also zwingend notwendig für ein Spiel, warum ihn dann nicht auch für dieses Problem benutzen?

b) Es geht hier um ein Spiel. Und jedes Spiel, das sich an die Windowsche Tastenverzögerung hält, würde ich sofort von meiner Festplatte verbannen. Hotkeys oder Keyhooks sind das Unsinnigste für ein Spiel, weil sie keine gleichmäßige und steuerbare Bewegung ermöglichen. Es muss unbedingt in der Spielschleife auf die Tasten geprüft werden.

Ergo: GetAsyncKeyState in der Spielschleife ist der richtige Weg, wobei ein Timer eben nur bei einfacheren Spielen in Frage kommt. So wird man es auch bei vielen kommerziellen und halbwegs guten nichtkommerziellen Spielen finden.

Phantom1 4. Nov 2006 13:12

Re: Frage
 
Zitat:

Zitat von Khabarakh
Ergo: GetAsyncKeyState in der Spielschleife ist der richtige Weg, wobei ein Timer eben nur bei einfacheren Spielen in Frage kommt. So wird man es auch bei vielen kommerziellen und halbwegs guten nichtkommerziellen Spielen finden.

Auch mein Code oben löst das Problem mit der Tastenverzögerung, letzendlich ist es aber geschmackssache wie man es macht.


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