Avatar billede noxiaz Nybegynder
31. januar 2007 - 19:12 Der er 18 kommentarer og
1 løsning

Reager på flere taste på en gang.

Har koden:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            bool blnSpecialKeys = true;
            switch (keyData)
            {
                case Keys.Up:
                    if (GlobalVariables.Instance.gamemode == 1)
                    {
                        movebar(1, this.pictureBox3.Location.Y - movespeed);
                    }
                    else if (GlobalVariables.Instance.gamemode == 2)
                    {
                        movebar(2, this.pictureBox2.Location.Y - movespeed);
                    }
                    break;


Har flere taster der ned af.. men problemet er den kun kan reagere på en tast af gangen. Hvis man holde en tast i bund og trykker på en anden, så stopper den tasten som man holdte i bund.. Hvad kan jeg gøre ved det?
Avatar billede mcgoat Nybegynder
31. januar 2007 - 19:20 #1
kigger lige med
Avatar billede noxiaz Nybegynder
31. januar 2007 - 20:22 #2
Btw nogen taste fejl i hvad jeg har skrevet, mangler et "r" et par stedet. så som holder* :) Håber ik det skader så meget :)
Avatar billede hmortensen Nybegynder
31. januar 2007 - 21:04 #3
F.eks. sådan her for Ctrl+C

case Keys.Control | Keys.C:
Avatar billede noxiaz Nybegynder
31. januar 2007 - 21:27 #4
hmortensen, jeg er ved at lave et pingpong spil, hvor man kan spille i multi, og bliver styret efter tastaturet.. tasterne der bruges: W/S og Pil.op/pil.ned

Men når W bliver holdt i bund og der trykkes Pil.Op så stopper W med at virke, og omvendt. Og man skal jo gerne kunne flytte på samme tid, og begge skulle gerne kunne holde tasten i bund uden problemer. :)
Avatar billede bulgroz Nybegynder
31. januar 2007 - 21:30 #5
Ovenstående giver kun mulighed for at lytte til én key + eventuelle modifiers (ctrl, alt osv.)

Hvis du skal lytte til flere keys skal du have fat i GetAsyncKeyState.
Jeg har brygget nedenstående eksempel som reagerer på navigationstasterne, men du kan naturligvis udvide efter behov.
Eksemplet skriver til fire labels som ikke er med her (dem må du selv tilføje til din form).

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            // Dette eksempel ignorerer keys i modsatte retning! (men man kan naturligvis gøre hvad man har lyst til)
           
            bool left = GetAsyncKeyState((int)System.Windows.Forms.Keys.Left) < 0;
            bool right = GetAsyncKeyState((int)System.Windows.Forms.Keys.Right) < 0;
            bool up = GetAsyncKeyState((int)System.Windows.Forms.Keys.Up) < 0;
            bool down = GetAsyncKeyState((int)System.Windows.Forms.Keys.Down) < 0;

            this.Update(left, right, up, down);
        }

        [DllImport("user32.dll")]
        public static extern int GetAsyncKeyState(int vkey);

        private void Update(bool left, bool right, bool up, bool down)
        {
            this.labelLeft.Enabled = left;
            this.labelRight.Enabled = right;
            this.labelUp.Enabled = up;
            this.labelDown.Enabled = down;
        }

        private void Form1_KeyUp(object sender, KeyEventArgs e)
        {
            this.Update(false, false, false, false);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.Update(false, false, false, false);
        }
    }
Avatar billede bulgroz Nybegynder
31. januar 2007 - 21:32 #6
du skal naturligvis også binde Form1_KeyUp & Load til de respektive events på din form. (står i designer filen som jeg har udeladt her)
Avatar billede noxiaz Nybegynder
31. januar 2007 - 22:23 #7
Den brokker sig over [DllImport("user32.dll")] ? Skal jeg "using" noget?
Avatar billede noxiaz Nybegynder
31. januar 2007 - 22:29 #8
bulgroz, forstår slet ikke scriptet? Kan ikke se hvordan jeg skal se hvornår tasterne er trykket ned? :S Er total last. Kunne du evt. lave noget så den skriver med messegebox når en tast bliver trykket ned? så jeg ved hvor jeg skal sætte det ind til at flytte bar'en. :D

btw. fandt ud af hvad jeg skulle bruge for at bruge dllimport :)
Avatar billede bulgroz Nybegynder
31. januar 2007 - 22:42 #9
Som sagt så skriver eksemplet til fire labels. For at gøre det nemmere for dig får du hermed det komplette eksempel:


namespace MultipleKeysSample
{
    using System;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;

    public partial class Form1 : Form
    {
        private System.Windows.Forms.Label labelLeft;
        private System.Windows.Forms.Label labelRight;
        private System.Windows.Forms.Label labelDown;
        private System.Windows.Forms.Label labelUp;
       
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            // Dette eksempel ignorerer keys i modsatte retning! (men man kan naturligvis gøre hvad man har lyst til)
           
            bool left = GetAsyncKeyState((int)System.Windows.Forms.Keys.Left) < 0;
            bool right = GetAsyncKeyState((int)System.Windows.Forms.Keys.Right) < 0;
            bool up = GetAsyncKeyState((int)System.Windows.Forms.Keys.Up) < 0;
            bool down = GetAsyncKeyState((int)System.Windows.Forms.Keys.Down) < 0;

            this.Update(left, right, up, down);
        }

        [DllImport("user32.dll")]
        public static extern int GetAsyncKeyState(int vkey);

        private void Update(bool left, bool right, bool up, bool down)
        {
            this.labelLeft.Enabled = left;
            this.labelRight.Enabled = right;
            this.labelUp.Enabled = up;
            this.labelDown.Enabled = down;
        }

        private void Form1_KeyUp(object sender, KeyEventArgs e)
        {
            this.Update(false, false, false, false);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.Update(false, false, false, false);
        }

        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.labelLeft = new System.Windows.Forms.Label();
            this.labelRight = new System.Windows.Forms.Label();
            this.labelDown = new System.Windows.Forms.Label();
            this.labelUp = new System.Windows.Forms.Label();
            this.SuspendLayout();
            //
            // labelLeft
            //
            this.labelLeft.AutoSize = true;
            this.labelLeft.Location = new System.Drawing.Point(48, 110);
            this.labelLeft.Name = "labelLeft";
            this.labelLeft.Size = new System.Drawing.Size(25, 13);
            this.labelLeft.TabIndex = 0;
            this.labelLeft.Text = "Left";
            //
            // labelRight
            //
            this.labelRight.AutoSize = true;
            this.labelRight.Location = new System.Drawing.Point(136, 110);
            this.labelRight.Name = "labelRight";
            this.labelRight.Size = new System.Drawing.Size(32, 13);
            this.labelRight.TabIndex = 1;
            this.labelRight.Text = "Right";
            //
            // labelDown
            //
            this.labelDown.AutoSize = true;
            this.labelDown.Location = new System.Drawing.Point(81, 143);
            this.labelDown.Name = "labelDown";
            this.labelDown.Size = new System.Drawing.Size(35, 13);
            this.labelDown.TabIndex = 2;
            this.labelDown.Text = "Down";
            //
            // labelUp
            //
            this.labelUp.AutoSize = true;
            this.labelUp.Location = new System.Drawing.Point(81, 74);
            this.labelUp.Name = "labelUp";
            this.labelUp.Size = new System.Drawing.Size(21, 13);
            this.labelUp.TabIndex = 3;
            this.labelUp.Text = "Up";
            //
            // Form1
            //
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(292, 266);
            this.Controls.Add(this.labelUp);
            this.Controls.Add(this.labelDown);
            this.Controls.Add(this.labelRight);
            this.Controls.Add(this.labelLeft);
            this.Name = "Form1";
            this.Text = "Form1";
            this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyUp);
            this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown);
            this.Load += new System.EventHandler(this.Form1_Load);
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

    }

    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }

}
Avatar billede bulgroz Nybegynder
31. januar 2007 - 22:43 #10
Kør eksemplet og tryk på dine navigationstaster (pil op, ned, højre og venstre) og gerne samtidigt. De fire labels enables/disables i henhold til dine tastetryk.
Avatar billede bulgroz Nybegynder
31. januar 2007 - 22:48 #11
Bemærk at eksemplet lytter til formens Key events

this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyUp);
            this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown);
            this.Load += new System.EventHandler(this.Form1_Load);
           
...
Avatar billede bulgroz Nybegynder
31. januar 2007 - 22:52 #12
Hvis du har kontroller på din form som kan tage focus, så skal du sætte
            this.KeyPreview = true;
Ellers vil du ikke fange keystrokes 'globalt' p din form, hvis focus f.eks. er havnet på en knap etc.
Avatar billede bulgroz Nybegynder
31. januar 2007 - 23:25 #13
Her er et eksempel med en mindre rettelse. (sætter labels korrekt også når blot én tast slippes)


namespace MultipleKeysSample
{
    using System;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;

    public partial class Form1 : Form
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        private System.Windows.Forms.Label labelLeft;
        private System.Windows.Forms.Label labelRight;
        private System.Windows.Forms.Label labelDown;
        private System.Windows.Forms.Label labelUp;
       
        public Form1()
        {
            InitializeComponent();
        }

        [DllImport("user32.dll")]
        public static extern int GetAsyncKeyState(int vkey);

        private void UpdateKeys()
        {
            // Dette eksempel ignorerer keys i modsatte retning! (men man kan naturligvis gøre hvad man har lyst til)
            bool left = GetAsyncKeyState((int)System.Windows.Forms.Keys.Left) < 0;
            bool right = GetAsyncKeyState((int)System.Windows.Forms.Keys.Right) < 0;
            bool up = GetAsyncKeyState((int)System.Windows.Forms.Keys.Up) < 0;
            bool down = GetAsyncKeyState((int)System.Windows.Forms.Keys.Down) < 0;

            this.UpdateLabels(left, right, up, down);
        }

        private void UpdateLabels(bool left, bool right, bool up, bool down)
        {
            this.labelLeft.Enabled = left;
            this.labelRight.Enabled = right;
            this.labelUp.Enabled = up;
            this.labelDown.Enabled = down;
        }

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            this.UpdateKeys();
        }

        private void Form1_KeyUp(object sender, KeyEventArgs e)
        {
            this.UpdateKeys();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.UpdateKeys();
        }

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.labelLeft = new System.Windows.Forms.Label();
            this.labelRight = new System.Windows.Forms.Label();
            this.labelDown = new System.Windows.Forms.Label();
            this.labelUp = new System.Windows.Forms.Label();
            this.SuspendLayout();
            //
            // labelLeft
            //
            this.labelLeft.Dock = System.Windows.Forms.DockStyle.Left;
            this.labelLeft.Font = new System.Drawing.Font("Microsoft Sans Serif", 13.8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.labelLeft.Location = new System.Drawing.Point(0, 0);
            this.labelLeft.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
            this.labelLeft.Name = "labelLeft";
            this.labelLeft.Size = new System.Drawing.Size(73, 163);
            this.labelLeft.TabIndex = 0;
            this.labelLeft.Text = "Left";
            this.labelLeft.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            //
            // labelRight
            //
            this.labelRight.Dock = System.Windows.Forms.DockStyle.Right;
            this.labelRight.Font = new System.Drawing.Font("Microsoft Sans Serif", 13.8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.labelRight.Location = new System.Drawing.Point(190, 0);
            this.labelRight.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
            this.labelRight.Name = "labelRight";
            this.labelRight.Size = new System.Drawing.Size(83, 163);
            this.labelRight.TabIndex = 1;
            this.labelRight.Text = "Right";
            this.labelRight.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            //
            // labelDown
            //
            this.labelDown.Dock = System.Windows.Forms.DockStyle.Bottom;
            this.labelDown.Font = new System.Drawing.Font("Microsoft Sans Serif", 13.8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.labelDown.Location = new System.Drawing.Point(73, 94);
            this.labelDown.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
            this.labelDown.Name = "labelDown";
            this.labelDown.Size = new System.Drawing.Size(117, 69);
            this.labelDown.TabIndex = 2;
            this.labelDown.Text = "Down";
            this.labelDown.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            //
            // labelUp
            //
            this.labelUp.Dock = System.Windows.Forms.DockStyle.Top;
            this.labelUp.Font = new System.Drawing.Font("Microsoft Sans Serif", 13.8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.labelUp.Location = new System.Drawing.Point(73, 0);
            this.labelUp.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
            this.labelUp.Name = "labelUp";
            this.labelUp.Size = new System.Drawing.Size(117, 70);
            this.labelUp.TabIndex = 3;
            this.labelUp.Text = "Up";
            this.labelUp.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            //
            // Form1
            //
            this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(273, 163);
            this.Controls.Add(this.labelUp);
            this.Controls.Add(this.labelDown);
            this.Controls.Add(this.labelRight);
            this.Controls.Add(this.labelLeft);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
            this.KeyPreview = true;
            this.Margin = new System.Windows.Forms.Padding(4);
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.Name = "Form1";
            this.Text = "MultipleKeysSample";
            this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyUp);
            this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown);
            this.Load += new System.EventHandler(this.Form1_Load);
            this.ResumeLayout(false);

        }

        #endregion
    }

    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}
Avatar billede noxiaz Nybegynder
01. februar 2007 - 09:38 #14
Det er bare perfekt ! :D kanon arbejde fra din side bulgroz! Smid et svar det fortjener du ! :)
Avatar billede bulgroz Nybegynder
01. februar 2007 - 10:11 #15
Takker...
Vær opmærksom på at hvis du har flere kontroller på din form som kan tage focus, så fejler koden pt. selvom du har sat KeyPreview til true (hvilket man normalt gør). Midlertidigt kan du dog holde ctrl knappen nede samtidigt med dine keys, hvorefter alt virker.
Jeg vil ved lejlighed undersøge hvad der går galt (for det bør virke altid). Hvis der er nogle som allerede har svaret så kom frit frem...
Avatar billede bulgroz Nybegynder
01. februar 2007 - 10:13 #16
Men normalt er det ikke et problem i spilprogrammering hvor man sjældent har almindelige knapper etc. når det sjove starter (og derfor har jeg ikke stødt på problemet før) :-)
Avatar billede bulgroz Nybegynder
01. februar 2007 - 10:22 #17
Alternativt kan du begynde at kigge på Microsoft.DirectX.DirectInput.Device...
Men det er en lidt anden historie.
Avatar billede noxiaz Nybegynder
01. februar 2007 - 14:12 #18
Bulgroz. Det vil jeg være opmærksom på, og du skal igen have tak for et utroligt godt svar og perfekt formulering.. Det har også givet mig en god forståelse for scriptet, og hvordan det virker :) Så mange tak ! :)
Avatar billede md_craig Nybegynder
03. februar 2007 - 03:16 #19
Som tilføjelse vil jeg faktisk sige du bør kigge nærmere på hele DirectX.
Et spil er jo som regel state baseret. (Brætspil mfl. danner dog gode muligheder for undtagelser).

Derudover giver det dig også et rigt sæt af muligheder i forhold til at benytte mulighederne i nutidens grafikkort.

Men men men, det kan naturligvis være lidt svært at komme i gang med, da det i sig selv kræver lidt tid bare at få den første tomme DirectX Frame :D...

Men tag et kig... det er sjovt at lege med når man kommer i gang, og vil her anbefale et nærmere kig på point sprites, de er rimelig nemme at arbejde med, og man kan hurtigt lave mange små men sjove spil med det.

At lave stører spil rent sprite baseret hører nok efterhånden fortiden til, selv om jeg stadig syntes at nogle af tidens bedste strategispil altså ligger i den kategori... (Red Alert, Age Of Empires, Dune som eksempler, Isometrisk view baseret på pointsprites)...

Et sted jeg personligt startede:
http://www.c-unit.com/tutorials/mdirectx/

Happy hunting... ;)
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

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