2013-09-06 3 views
2

Я кодирую свою собственную игру с помощью приложений Windows Forms. Предполагается, что это многопользовательская игра. Каждый игрок может контролировать свой кирпич, чтобы держать мяч в поле, но проблема в том, что оба игрока не могут одновременно нажимать элементы управления. Каждый раз, когда второй игрок нажимает клавишу во время движения первого, кирпич первого игрока останавливается. Но, если они нажимают клавиши в том же ручном, оба кирпича движутся. Я использовал KeyDown событие:Обработка нескольких ключей в многопользовательской игре

private void Form1_KeyDown(object sender, KeyEventArgs e) 
    { 
     if (e.KeyCode == Keys.W && one.BrickLocationY > 0) 
     { 
      one.BrickLocationY -= 17; 
     } 
     if (e.KeyCode == Keys.S && one.BrickLocationY + Brick.BrickHeight < screenHeight) 
     { 
      one.BrickLocationY += 17; 
     } 
     if (e.KeyCode == Keys.Up) 
     { 
      two.BrickLocationY -= 17; 
     } 
     if (e.KeyCode == Keys.Down && two.BrickLocationY + Brick.BrickHeight < screenHeight) 
     { 
      two.BrickLocationY += 17; 
     } 
     if (e.KeyCode == Keys.Escape) 
     { 
      Application.Exit(); 
     } 
    } 

Хорошо, это позволяет мне двигаться кирпич вверх и вниз. Если я нажимаю сразу две клавиши, оба кирпича движутся в желаемом направлении. Кирпичи нарисованы на событии краски, инициированной тик таймера, чей интервал устанавливается равным 1.

private void Form1_Paint(object sender, PaintEventArgs e) 
    { 
     e.Graphics.DrawEllipse(ellipsePen, x, y, ballSize, ballSize); 
     e.Graphics.FillEllipse(Brushes.White ,x+1, y+1, ballSize, ballSize); 

     e.Graphics.FillRectangle(Brushes.White, one.BrickLocationX+1, one.BrickLocationY+1, Brick.BrickWidth, Brick.BrickHeight); 

     e.Graphics.FillRectangle(Brushes.White, two.BrickLocationX+1, two.BrickLocationY+1, Brick.BrickWidth, Brick.BrickHeight); 
    } 

У меня также было попыток сделать это с помощью комбинации KeyUp и KeyPress, но без успеха. Единственное, что мне пришло в голову, это нарезать кирпичи, но понятия не имели, как это сделать. Я там каким-то образом могу обрабатывать многопользовательские элементы управления, такие как без потоки?

P.S. Клавиатура способна обрабатывать сразу несколько кнопок.

+0

winforms не предназначен для использования в разработке игр. используйте XNA или, по крайней мере, WPF. –

ответ

0

Я считаю, что вам нужно будет отследить это самостоятельно. В основном по клавише вниз вы распознаете w и считаете, что он удерживается до тех пор, пока клавиша не освободит w. то же самое с ключом s.

Затем в вашем рабочем цикле вы просто смотрите, какие клавиши активны, и выполняйте свою логику направления.

1

При возникновении события KeyDown вам необходимо каждый раз проверять, какие кнопки нажаты. Here - это то, что я нашел при быстром поиске по этой теме.

using System; 
using System.Windows.Forms; 
using System.Runtime.InteropServices; 
using System.Collections.Generic; 

namespace WindowsFormsApplication1 
{ 
    public partial class Form1 : Form 
    { 
    public Form1() 
    { 
     InitializeComponent(); 
     this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(Form1_FormClosing); 
     tm.Tick += new System.EventHandler(DoSomethingWithKeyboardInput); 
     this.Load += new System.EventHandler(Form1_Load); 
     textBox1.KeyDown += new System.Windows.Forms.KeyEventHandler(textbox1_KeyDown); 
     textBox1.KeyUp += new System.Windows.Forms.KeyEventHandler(textbox1_KeyDown); 
    } 

    private Timer tm = new Timer(); 
    private List<System.Windows.Forms.Keys> MovementKeys = new List<System.Windows.Forms.Keys>(); 
    private _MyInputKeys MyInputKeys = new _MyInputKeys(); 

    private struct _MyInputKeys 
    { 
     public bool Jump; 
     public bool Left; 
     public bool Right; 
    } 

    private void Form1_FormClosing(object sender, System.Windows.Forms.FormClosingEventArgs e) 
    { 
     tm.Stop(); 
    } 

    public void DoSomethingWithKeyboardInput(object sender, EventArgs e) 
    { 
     textBox1.Text = (MyInputKeys.Left ? "(left)" : "") + 
     (MyInputKeys.Right ? "(right)" : "") + (MyInputKeys.Jump ? "(jump)" : ""); 
    } 

    private void Form1_Load(object sender, System.EventArgs e) 
    { 
     //define keys used for movement 

     MovementKeys.Add(Keys.Up); //Jump ? 
     MovementKeys.Add(Keys.Left); //Left Arrow - Move Left 
     MovementKeys.Add(Keys.Right); //Rigth Arrow - Move Right 
     tm.Interval = 50; 
     tm.Start(); 
    } 

    private void textbox1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e) 
    { 
     if (MovementKeys.IndexOf(e.KeyCode) != -1) 
     { 
     e.Handled = true; 
     MyInputKeys.Jump = IsKeyDown(Keys.Up); 
     MyInputKeys.Left = IsKeyDown(Keys.Left); 
     MyInputKeys.Right = IsKeyDown(Keys.Right); 
     } 
    } 

    public static bool IsKeyDown(Keys key) 
    { 
     return (GetKeyState(Convert.ToInt16(key)) & 0X80) == 0X80; 
    } 
    /// <summary> 
    /// If the high-order bit is 1, the key is down; otherwise, it is up. 
    /// If the low-order bit is 1, the key is toggled. 
    /// A key, such as the CAPS LOCK key, is toggled if it is turned on. 
    /// The key is off and untoggled if the low-order bit is 0. 
    /// A toggle key's indicator light (if any) on the keyboard will be on when 
    /// the key is toggled, and off when the key is untoggled. 
    /// </summary> 
    /// <param name="nVirtKey"></param> 
    [DllImport("user32.dll")] 
    public extern static Int16 GetKeyState(Int16 nVirtKey); 
    } 
} 
Смежные вопросы