12. oktober 2007 - 14:45Der er
12 kommentarer og 1 løsning
2 taster på samme tid
Hej ! jeg sidder med scriptet som jeg bruger til at få min figur til at gøre nogle forskellige ting efter hvad jeg trykker på, men når jeg holder "pil op" i bund, og efter trykker "pil venstre" så stopper op funktionen? Hvordan kan jeg fixe det?
Scriptet jeg bruger:
[DllImport("user32.dll")] public static extern int GetAsyncKeyState(int vkey); private void kupdate(bool up, bool down, bool right, bool left) { if (left == true) { movefuntion("left"); } if (right == true) { movefuntion("right"); } if (up == true && checkair() == false) { int i = 1; while (i <= 10) { movefuntion("up"); i++; } } if (down == true) { movefuntion("down"); } update(); } private void Form1_KeyDown(object sender, KeyEventArgs e) { bool left = e.KeyData == Keys.Left; bool right = e.KeyData == Keys.Right; bool up = e.KeyData == Keys.Up; bool down = e.KeyData == Keys.Down; this.kupdate(up, down, right, left); } private void Form1_KeyUp(object sender, KeyEventArgs e) { this.kupdate(false, false, false, false); }
Hvis det skulle have nogen betydning? :) - Da jeg gjorde som du sagde, virkede min "right" ikke rigtig længere :S så ændrede tilbage igen til det normale, da det heller ikke gav nogen ændring med pil op og til venstre på samme tid :(
private void key_change(Keys key, bool state) { switch (key) { case Keys.Left: left = state; break; case Keys.Right: right = state; break; case Keys.Up: up = state; break; case Keys.Down: down = state; break; } this.kupdate(up, down, right, left); }
Lige fundet ud af det ikke virker helt rigtigt endnu :/
Holder jeg "venstre" i bund, og der efter trykker en gang på "op" så stopper den med at gå til venstre, men holder jeg der imod op i bund gør den begge ting? Men den må ikke stoppe med at holde "venstre" i bund, fordi jeg trykker "op" engang.
Prøv at smutte en tur i Notepad og brug f.eks. A, S, D og W, istedet for piletasterne. Så vil du opleve det samme fænomen som driller dig nu. Holder du A nede skriver du en masse af dem, men... Det øjeblik du trykker bare en enkelt gang på W kommer der ikke flere A'er før du slipper knappen og holder den nede igen.
"Problemet" ligger i den måde input fra tastaturet håndteres. Trykker du på en knap og holder den inde aktiveres en auto-repeat funktion, som svarer til at du trykker meget hurtigt på knappen. Den funktion afbrydes så snart du trykker på en anden knap.
Sådan som du lige nu "bevæger" din figur udnytter du netop auto-repeat. Holder du f.eks. "venstre" nede, kaldes din Form1_KeyDown en masse gange lige efter hinanden. Hvilket er helt fint lige indtil du trykker en enkelt gang på en anden tast og afbryder auto-repeat.
Indrømmet... Det tog også mig et øjeblik at finde en løsning på det her problem, men sjovt nok er det dig selv som ledte mig på vej.
Jeg har nemlig løst det ved hjælp af GetAsyncKeyState :)
Istedet for at reagere på hvert enkelt tastetryk, har jeg løst problemet ved selv at undersøge om de enkelte taster er trykket ned (100 gange i sekundet)
Jeg har oprettet en "timer" i min "form". Timeren er sat til 10ms.
Hver gang timer1_Tick bliver kaldt bruger jeg GetAsyncKeyState til at undersøge om de enkelte taster er trykket ned og flytte min figur tilsvarende.
Jeg bliver nødt til at smutte i seng nu. Skal møde på arbejdet kl 5:15, så må lige have lidt søvn...
Her er det eksempel jeg selv har lavet:
Håber det kan lede dig på rette vej.
For at kunne bruge koden skal du have en form (Form1) med en timer (timer1) og en kontrol (crosshair) som du kan flytte rundt på.
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices;
namespace Eksperten800714 { public partial class Form1 : Form { public Form1() { InitializeComponent(); }
[DllImport("User32.dll")] public static extern short GetAsyncKeyState(Keys vkey);
//Timerens eventhandler private void timer1_Tick(object sender, EventArgs e) { //Aflæs figurens position Point loc = crosshair.Location;
//Juster X og Y afhængig af hvilke taster der bliver holdt nede if ((GetAsyncKeyState(Keys.Right) >> 15) != 0) loc.X++;
if ((GetAsyncKeyState(Keys.Left) >> 15) != 0) loc.X--;
if ((GetAsyncKeyState(Keys.Up) >> 15) != 0) loc.Y--;
if ((GetAsyncKeyState(Keys.Down) >> 15) != 0) loc.Y++;
//Sæt figurens nye position crosshair.Location = loc; }
//GetAsyncKeyState virker selvom formen ikke har fokus. //Husk derfor at aktivere og deaktivere timeren sammen med formen, //så GetAsyncKeyState ikke bliver kaldt
Tak for dit indlæg, lærte mig en hel del, troede problemet lå i at den læste begge keys da man løftede den ene og der ved satte false på dem begge :S
Men til et andet problem tror ikke at
[DllImport("User32.dll")] public static extern short GetAsyncKeyState(Keys vkey);
er understøttet i windows vista 64bit - Dette brugte jeg før i tiden da jeg havde windows xp og der virkede det, men efter jeg fik vista ville den ikke længere flytte rundt på min "brik". der for jeg begyndet at lave noget andet som kunne reager på key taster..
Jamen det er jo kun godt når du også lære lidt ! og det samme gjorde jeg - vidste ikke at den autofunktion stoppede når en tast blev trykket ned og slippet igen :/ Noget mærkeligt noget !! :D
Men sjov det er det at lege med !
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.