Avatar billede noxiaz Nybegynder
12. oktober 2007 - 14:45 Der 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);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.kupdate(false, false, false, false);
        }
Avatar billede bvli Praktikant
12. oktober 2007 - 14:51 #1
Hej..

Jeg tror du skal sammenligne e.KeyData med Keys enumerationen med en logisk operator. Altså:

bool left = (e.KeyData & Keys.Left) == Keys.Left;

osv.

/B :)
Avatar billede noxiaz Nybegynder
12. oktober 2007 - 14:53 #2
Jeg prøvede som du sagde :) Og det gav mig samme resultat som før :/
Avatar billede noxiaz Nybegynder
12. oktober 2007 - 14:57 #3
Min Movefunktion ser sådan ud:

private void movefuntion(string move)
        {
            int x = rx;
            int y = ry;
            int xspeed;
            int yspeed;
            switch (move)
            {
                case "left":
                    xspeed = x - 1;
                    this.tl.Text = xspeed.ToString();
                    if (sleft != "#" && tleft != "#")
                    {
                        SetMover(xspeed+"-"+y);
                    }
                    break;
                case "right":
                    xspeed = x + 1;
                    this.tr.Text = xspeed.ToString();
                    if (sright != "#" && tright != "#")
                    {
                        SetMover(xspeed + "-" + y);
                    }
                    break;
                case "up":
                    yspeed = y - 1;
                    if (sup != "#" && tup != "#")
                    {
                        SetMover(x + "-" + yspeed);
                    }
                    break;
                case "down":
                    yspeed = y + 1;
                    if (sdown != "#" && tdown != "#")
                    {
                        SetMover(x + "-" + yspeed);
                    }
                    break;
            }
            update();
        }
Avatar billede noxiaz Nybegynder
12. oktober 2007 - 14:58 #4
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 :(
Avatar billede gammelhat Nybegynder
12. oktober 2007 - 15:10 #5
prøv om dette virker efter hensigten

bool left=false, right=false, up=false, down=false;

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);
}

private void Form1_KeyDown(object sender, KeyEventArgs e)
{
    key_change(e.KeyData, true);
}

private void Form1_KeyUp(object sender, KeyEventArgs e)
{
    key_change(e.KeyData, false);
}
Avatar billede noxiaz Nybegynder
12. oktober 2007 - 15:14 #6
DET VIRKEDE !!! :D

Perfekt, smid et svar :D
Avatar billede noxiaz Nybegynder
12. oktober 2007 - 15:24 #7
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.
Avatar billede mbulow Nybegynder
15. oktober 2007 - 23:43 #8
Hejsa :)



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

        private void Form1_Activated(object sender, EventArgs e)
        {
            timer1.Enabled = true;
        }

        private void Form1_Deactivate(object sender, EventArgs e)
        {
            timer1.Enabled = false;
        }
    }
}
Avatar billede noxiaz Nybegynder
16. oktober 2007 - 11:46 #9
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..

Er brugt i scriptet som jeg senere har fået hjælp til som kan ses her: http://www.eksperten.dk/spm/759682

Hmm :/ og det script virkede jo fint, til at flytte figuren rundt, men ikke længere.. :(
Avatar billede nielle Nybegynder
16. oktober 2007 - 11:48 #10
Gad vide om der er en User64.dll som skal bruges i stedet? Kan ikke tjekke efter...
Avatar billede noxiaz Nybegynder
16. oktober 2007 - 12:08 #11
Ahh mig der havde lavet en lille fejl !! Sad og kiggede scriptet igennem igen da jeg kunne finde user32.dll windows ! - Og nu virker det !!!! :D

mbulow - Du må meget gerne sende et svar :)
Avatar billede mbulow Nybegynder
16. oktober 2007 - 15:16 #12
Glad for at kunne hjælpe :)

Faktisk meget sjovt at lege med... Lærte selv lidt af det
Avatar billede noxiaz Nybegynder
17. oktober 2007 - 00:43 #13
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 !
Avatar billede Ny bruger Nybegynder

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.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester