2017-02-01 7 views
3

Ich mache ein kleines Programm, bei dem zwei Rechtecke um eine Rennwagenspur fahren. Wenn ich das Programm laufe, läuft alles wie geplant und ich kann die Rechtecke mit den Pfeiltasten für die eine und A, S, D, W für die andere um die Spur bewegen. Das Problem ist, dass wenn ich eins mit den Pfeiltasten bewege und ich versuche, D zu drücken, um das andere Rechteck gleichzeitig nach rechts zu bewegen, stoppt dasjenige, das mit den Pfeiltasten bewegt wird. Ziel ist es, dass sie sich gleichzeitig bewegen können. Was soll ich machen?C#: Zwei Rechtecke gleichzeitig mit verschiedenen Tasten bewegen

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Threading; 
using System.Windows.Forms; 

namespace Race_Game 
{ 
     public partial class Form1 : Form 
     { 
      private int x1 = 24; 
      private int y1 = 16; 
      private int size1 = 115; 
      private int size2 = 50; 
      private Rectangle _rect1; 
      private int x2 = 24; 
      private int y2 = 74; 
      private int size3 = 115; 
      private int size4 = 50; 
      private Rectangle _rect2; 

     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void pictureBox1_Paint_1(object sender, PaintEventArgs e) 
     { 
      _rect1 = new Rectangle(x1, y1, size1, size2); 
      e.Graphics.FillRectangle(Brushes.Red, _rect1); 
      _rect2 = new Rectangle(x2, y2, size3, size4); 
      e.Graphics.FillRectangle(Brushes.Black, _rect2); 
     } 

     private void pictureBox1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) 
     { 
      this.KeyPreview = true; 

      this.KeyDown += new KeyEventHandler(Form1_KeyDown); 
     } 

     private void Form1_KeyDown(object sender, KeyEventArgs e) 
     { 
      if (e.KeyData == Keys.Right) 
      { 
       x1 += 15; 
      } 
      if (e.KeyData == Keys.Left) 
      { 
       x1 -= 15; 
      } 
      if (e.KeyData == Keys.Up) 
      { 
       y1 -= 15; 
      } 
      if (e.KeyData == Keys.Down) 
      { 
       y1 += 15; 
      } 
      if (e.KeyData == Keys.D) 
      { 
       x2 += 15; 
      } 
      if (e.KeyData == Keys.A) 
      { 
       x2 -= 15; 
      } 
      if (e.KeyData == Keys.W) 
      { 
       y2 -= 15; 
      } 
      if (e.KeyData == Keys.S) 
      { 
       y2 += 15; 
      } 
     } 

     private void timer1_Tick(object sender, EventArgs e) 
     { 
      pictureBox1.Invalidate(); 
     } 
    } 
} 

Visual Studio generiert, Design, Code:

namespace Race_Game 
{ 
    partial class Form1 
    { 
    /// <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.components = new System.ComponentModel.Container(); 
     System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1)); 
     this.timer1 = new System.Windows.Forms.Timer(this.components); 
     this.pictureBox1 = new System.Windows.Forms.PictureBox(); 
     ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); 
     this.SuspendLayout(); 
     // 
     // timer1 
     // 
     this.timer1.Enabled = true; 
     this.timer1.Interval = 1; 
     this.timer1.Tick += new System.EventHandler(this.timer1_Tick); 
     // 
     // pictureBox1 
     // 
     this.pictureBox1.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("pictureBox1.BackgroundImage"))); 
     this.pictureBox1.Location = new System.Drawing.Point(0, 0); 
     this.pictureBox1.Name = "pictureBox1"; 
     this.pictureBox1.Size = new System.Drawing.Size(1944, 1066); 
     this.pictureBox1.TabIndex = 0; 
     this.pictureBox1.TabStop = false; 
     this.pictureBox1.Paint += new System.Windows.Forms.PaintEventHandler(this.pictureBox1_Paint_1); 
     this.pictureBox1.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler(this.pictureBox1_PreviewKeyDown); 
     // 
     // Form1 
     // 
     this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 
     this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 
     this.ClientSize = new System.Drawing.Size(1916, 1053); 
     this.Controls.Add(this.pictureBox1); 
     this.Name = "Form1"; 
     this.Text = "Form1"; 
     this.WindowState = System.Windows.Forms.FormWindowState.Maximized; 
     this.Paint += new System.Windows.Forms.PaintEventHandler(this.pictureBox1_Paint_1); 
     this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown); 
     ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); 
     this.ResumeLayout(false); 

    } 

    #endregion 

    private System.Windows.Forms.Timer timer1; 
    private System.Windows.Forms.PictureBox pictureBox1; 
} 

}

+0

Dies ist ein häufiges Designproblem. Die Frage sollte offen bleiben. – ja72

+0

'private Rectangle _rect1 = new Rectangle();' wird nicht benötigt, weil 'Rectangle' ein Werttyp ist und auch beim Paint-Ereignis überschrieben wird. – ja72

+0

Danke für den Tipp, aber es hat das Problem nicht gelöst:/@ ja72 – jholsch29

Antwort

3

Was ich beschlossen, auf Schlüssel-down eine Geschwindigkeit zuweisen und auf Schlüssel bis die Geschwindigkeit auf Null. Das und die x-und y-Koordinaten in Point und Size Objekte zu kombinieren.

Sie können die Boxen unabhängig und kontinuierlich verschieben.

scr

public partial class Form1 : Form 
{ 
    const int velocity = 15; 
    Point position_A = new Point(24, 16); 
    Point position_B = new Point(24, 74); 
    Size size_A = new Size(115, 50); 
    Size size_B = new Size(115, 50); 
    Size velocity_A = new Size(0, 0); 
    Size velocity_B = new Size(0, 0); 

    public Rectangle Shape_A 
    { 
     get 
     { 
      return new Rectangle(position_A, size_A); 
     } 
    } 
    public Rectangle Shape_B 
    { 
     get 
     { 
      return new Rectangle(position_B, size_B); 
     } 
    } 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void pictureBox1_Resize(object sender, EventArgs e) 
    { 
     pictureBox1.Refresh(); 
    } 

    private void pictureBox1_Paint(object sender, PaintEventArgs e) 
    { 
     e.Graphics.FillRectangle(Brushes.Red, Shape_A); 
     e.Graphics.FillRectangle(Brushes.Black, Shape_B); 
    } 

    private void timer1_Tick(object sender, EventArgs e) 
    { 
     this.position_A+=velocity_A; 
     this.position_B+=velocity_B; 
     pictureBox1.Refresh(); 
    } 

    private void Form1_KeyDown(object sender, KeyEventArgs e) 
    { 
     Debug.WriteLine($"KeyDown Code:{e.KeyCode}"); 
     switch (e.KeyCode) 
     { 
      case Keys.Up: 
       this.velocity_A=new Size(velocity_A.Width, -velocity); 
       break; 
      case Keys.Down: 
       this.velocity_A=new Size(velocity_A.Width, +velocity); 
       break; 
      case Keys.Left: 
       this.velocity_A=new Size(-velocity, velocity_A.Height); 
       break; 
      case Keys.Right: 
       this.velocity_A=new Size(+velocity, velocity_A.Height); 
       break; 
      case Keys.W: 
       this.velocity_B=new Size(velocity_B.Width, -velocity); 
       break; 
      case Keys.S: 
       this.velocity_B=new Size(velocity_B.Width, +velocity); 
       break; 
      case Keys.A: 
       this.velocity_B=new Size(-velocity, velocity_B.Height); 
       break; 
      case Keys.D: 
       this.velocity_B=new Size(+velocity, velocity_B.Height); 
       break; 
      case Keys.Escape: 
       this.Close(); 
       break; 
     } 
     pictureBox1.Invalidate(); 
    } 

    private void Form1_KeyUp(object sender, KeyEventArgs e) 
    { 
     switch (e.KeyCode) 
     { 
      case Keys.Up: 
      case Keys.Down: 
       this.velocity_A=new Size(velocity_A.Width, 0); 
       break; 
      case Keys.Right: 
      case Keys.Left: 
       this.velocity_A=new Size(0, velocity_A.Height); 
       break; 
      case Keys.W: 
      case Keys.S: 
       this.velocity_B=new Size(velocity_B.Width, 0); 
       break; 
      case Keys.A: 
      case Keys.D: 
       this.velocity_B=new Size(0, velocity_B.Height); 
       break; 
     } 
    } 
} 
+0

Ich habe versucht zu sehen, ob ich die get-Anweisungen umgehen kann, aber ich habe beschlossen, dass mein Code identisch mit deinem ist, nur um sicher zu sein. Außerdem denke ich, dass ich meine Frage komisch formuliert habe und es mögliche Fehlinterpretationen gab. Mein Ziel ist es zum Beispiel, die D-Taste gedrückt zu halten und das schwarze Rechteck nach rechts zu bewegen, während gleichzeitig die rechte Pfeiltaste gedrückt bleibt und das rote Rechteck gleichzeitig mit dem schwarzen Rechteck nach rechts bewegt wird.Ich kann wieder überprüfen, um sicherzustellen, dass ich alles wie du gesagt hast, aber im Moment schien das nicht zu funktionieren @ ja72 – jholsch29

+0

Jetzt verstehe ich, was das Problem ist. Versuchen Sie diese neue Methode aus meinem überarbeiteten Code oben. – ja72

+0

Danke! Ich verstehe das und kann es benutzen, aber wie wäre ich dazu gekommen, es so zu machen, dass die Rechtecke sich nicht diagonal bewegen, wenn der Pfeil nach oben gedrückt wird, während sich das Rechteck horizontal bewegt? @ ja72 – jholsch29

1

Statt auf Tastendruck-Ereignisse zu reagieren, einen Timer, der Umfragen, die den Zustand der einzelnen Tasten über die WinAPI Funktion GetKeyState regelmäßig verwenden.

Für die folgende Beispielkonfiguration verwende ich ein Formular mit zwei NumericUpDown-Steuerelementen ("numericUpDownA" und "numericUpDownLeft") und einem Timer "timerCheckKeyboard" mit einem Intervall von 100 ms und aktiviert. Der Timer verfügt über den OnClick-Ereignishandler "timerCheckKeyboard_Tick".

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

    [DllImport("USER32.dll")] 
    static extern short GetKeyState(int nVirtKey); 


    private const int KEY_PRESSED = 0x8000; 

    private const int VK_W = (int)'W'; 
    private const int VK_A = (int)'A'; 
    private const int VK_S = (int)'S'; 
    private const int VK_D = (int)'D'; 
    private const int VK_LEFT = 0x25; 
    private const int VK_UP = 0x26; 
    private const int VK_RIGHT = 0x27; 
    private const int VK_DOWN = 0x28; 

    private bool IsKeyPressed(int key) 
    { 
     return (GetKeyState(key) & KEY_PRESSED) != 0; 
    } 

    private void timerCheckKeyboard_Tick(object sender, EventArgs e) 
    { 
     if (IsKeyPressed(VK_A)) 
     { 
      numericUpDownA.Value++; 
     } 

     if (IsKeyPressed(VK_LEFT)) 
     { 
      numericUpDownLeft.Value++; 
     } 
    } 
} 

Der Wert in den NumericUpDownA Steuerung erhöht, während der eine Taste gedrückt wird. Der Wert im NumericUpDownLeft-Steuerelement erhöht sich, wenn die linke Pfeiltaste gedrückt wird. Sie können gleichzeitig "A" und "Cursor links" drücken und die Werte in beiden NumericUpDown-Steuerelementen erhöhen sich.

Beachten Sie, dass dies auch funktioniert, wenn die Tasten gedrückt werden, während Ihre Anwendung nicht aktiv ist. Vielleicht möchten Sie das zuerst im Timer-Tick-Event testen oder den Timer komplett deaktivieren, während das Formular nicht den Fokus hat. (Ereignisse Activate, Deactivate des Formulars).

Verwandte Themen