Flere taster på en gang

Tags:    delphi

Hej

Mit spørgsmål drejer sig omkring, brugen af flere taster på engang. For det ville være rart hvis man kunne gå frem og dreje samtidig i et spil. altså bruge pil op og enten venstre og højre samtidig. Indtil vidre gøre mit program følgende, når jeg først trykker på pil op går jeg frem men når jeg så trykker en anden tast stoppes dette selv om pil stadig holdes nede. Kan dette løses ?


Jacob B. Andersen



3 svar postet i denne tråd vises herunder
1 indlæg har modtaget i alt 2 karma
Sorter efter stemmer Sorter efter dato
Hej

Mit spørgsmål drejer sig omkring, brugen af flere taster på engang. For det ville være rart hvis man kunne gå frem og dreje samtidig i et spil. altså bruge pil op og enten venstre og højre samtidig. Indtil vidre gøre mit program følgende, når jeg først trykker på pil op går jeg frem men når jeg så trykker en anden tast stoppes dette selv om pil stadig holdes nede. Kan dette løses ?


Jacob B. Andersen


Et array af taster (der er jo 256 normal koder som kan tastes).
Dvs.
boolean : keys : array 0..255;

I starten af programmet:
GetKeyboardState(keys);

Ved WM_KEYDOWN (dvs. en OnKeyDown event for vinduet):
keys[key] := true;

Ved WM_KEYUP (dvs. en OnKeyUp event for vinduet):
keys[key] := false;


Hvis du vil se om pil venstre og pil op er nede samtidig, så kan dette afprøves:
if keys[VK_LEFT] and keys[VK_UP] then
begin
// din kode
end;

Du kan kigge i Win32 hjælpen og kigge på emnet, der hedder Virtual-Key Codes. Der kan du se alle VK_ konstanterne.
De kan i øvrigt også (ligesom næsten alt andet der har med Win32 API eller Windows generelt at gøre, findes på msdn.com).

Beklager hvis der er syntaksfejl (tænker mest på den pointer i GetKeyboardState, måske skal der et ^ foran?), men det er lidt tid siden jeg har arbejdet med Object Pascal.

Denne metode forhindrer i øvrigt også det lille "hak" der forekommer før tasten, der holdes nede, registreres kontinuerligt.
Dvs. hvis man bare agerer efter WM_KEYDOWN modtages (altså OnKeyDown).

Du vil måske også tænke på at tilføje time-based movement, sådan at dit program ikke køre hurtigere, hvis der forekommer højere fps (frames per second). Hvis du vil vide hvordan, så spørg endelig ;-)

1101110100010110000101000001

[Redigeret d. 23/02-05 17:37:32 af Nicolai Lyster Fersner]



Hej

Mit spørgsmål drejer sig omkring, brugen af flere taster på engang. For det ville være rart hvis man kunne gå frem og dreje samtidig i et spil. altså bruge pil op og enten venstre og højre samtidig. Indtil vidre gøre mit program følgende, når jeg først trykker på pil op går jeg frem men når jeg så trykker en anden tast stoppes dette selv om pil stadig holdes nede. Kan dette løses ?


Jacob B. Andersen


Et array af taster (der er jo 256 normal koder som kan tastes).
Dvs.
boolean : keys : array 0..255;

I starten af programmet:
GetKeyboardState(keys);

Ved WM_KEYDOWN (dvs. en OnKeyDown event for vinduet):
keys[key] := true;

Ved WM_KEYUP (dvs. en OnKeyUp event for vinduet):
keys[key] := false;


Hvis du vil se om pil venstre og pil op er nede samtidig, så kan dette afprøves:
if keys[VK_LEFT] and keys[VK_UP] then
begin
// din kode
end;

Du kan kigge i Win32 hjælpen og kigge på emnet, der hedder Virtual-Key Codes. Der kan du se alle VK_ konstanterne.
De kan i øvrigt også (ligesom næsten alt andet der har med Win32 API eller Windows generelt at gøre, findes på msdn.com).

Beklager hvis der er syntaksfejl (tænker mest på den pointer i GetKeyboardState, måske skal der et ^ foran?), men det er lidt tid siden jeg har arbejdet med Object Pascal.

Denne metode forhindrer i øvrigt også det lille "hak" der forekommer før tasten, der holdes nede, registreres kontinuerligt.
Dvs. hvis man bare agerer efter WM_KEYDOWN modtages (altså OnKeyDown).

Du vil måske også tænke på at tilføje time-based movement, sådan at dit program ikke køre hurtigere, hvis der forekommer højere fps (frames per second). Hvis du vil vide hvordan, så spørg endelig ;-)

1101110100010110000101000001

[Redigeret d. 23/02-05 17:37:32 af Nicolai Lyster Fersner]


Det var også noget af dette jeg selv kom frem til, Men vidste ikke om der fandtes en smartere måde. Men jeg vil nu benytte mig af denne metode.
Og jo det vil jeg da mægtig gerne vide (o:

Jacob B. Andersen



timeGetTime kan bruges (inkluder mmsystem filen), endda meget effektivt med et kald til timeBeginPeriod(1); i fx OnCreate og timeEndPeriod(1); i OnDestroy.

TTimer eller GetTickCount kan også bruges, men især GetTickCount er upræcis (der kan gå helt op til 50 ms før den opdateres, men oftest ligger den på 10 - 30 ms), så den vil jeg ikke anbefale.
Senere hen kan QueryPerformanceCounter bruges, hvis du behøver mere præcision (den kan have ned til 1 mikrosekunds præcision).

timeGetTime skulle også gerne være præcis nok op til 3-500 fps, da den opdateres ca. hvert millisekund eller deromkring, pga. timeBeginPeriod og timeEndPeriod kaldene, i mit eksempel.

Dertil skal du så, før hvert billede eller opdatering (det behøver jo ikke at være samtidig), så skal du finde ændringen i tiden, fx som her:
Fold kodeboks ind/udKode 


OBJECT_VELOCITY er en konstant, som er antal enheder (fx pixels, hvis det er 2D), som objektet skal flytte sig per sekund.
Det skulle meget gerne forklare nogenlunde, hvordan man får objekter til at bevæge sig uafhængigt af fps.

Selvfølgelig er objektet object1 bare et eksempel, som skal forklare princippet, men så vidt jeg forstår har du allerede et objekt.

1101110100010110000101000001



t