I'm creating ping pong game. I managed to move both lines (picture box) at same time if keys for movement are pressed down. Problem is that if control for one player is pressed down and then other player JUST clicks (1 time) it breaks movement of other player,so that he needs to press key again. I tried to fix it with keypress and Keyboard.IsKeyDownbut no luck.
Here is my code:
public void Form1_KeyDown(object sender, KeyEventArgs e)
{
Keys up1 = (Keys)Enum.Parse(typeof(Keys), form1.p5_text_kontrole_gor1.Text , true);
Keys down1 = (Keys)Enum.Parse(typeof(Keys), form1.p5_text_kontrole_dol1.Text , true);
Keys up2 = (Keys)Enum.Parse(typeof(Keys), form1.p5_text_kontrole_gor2.Text, true);
Keys down2 = (Keys)Enum.Parse(typeof(Keys), form1.p5_text_kontrole_dol2.Text, true);
if (e.KeyCode == Keys.Escape)
Application.Exit();
if(e.KeyCode == up1)
{
goup1 = true;
}
if (e.KeyCode == down1)
{
godown1 = true;
}
if (e.KeyCode == up2)
{
goup2 = true;
}
if (e.KeyCode == down2)
{
godown2 = true;
}
igra1();
}
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
Keys up1 = (Keys)Enum.Parse(typeof(Keys), form1.p5_text_kontrole_gor1.Text, true);
Keys down1 = (Keys)Enum.Parse(typeof(Keys), form1.p5_text_kontrole_dol1.Text, true);
Keys up2 = (Keys)Enum.Parse(typeof(Keys), form1.p5_text_kontrole_gor2.Text, true);
Keys down2 = (Keys)Enum.Parse(typeof(Keys), form1.p5_text_kontrole_dol2.Text, true);
if (e.KeyCode == up1)
{
goup1 = false;
}
if (e.KeyCode == down1)
{
godown1 = false;
}
if (e.KeyCode == up2)
{
goup2 = false;
}
if (e.KeyCode == down2)
{
godown2 = false;
}
igra1();
}
public void igra1()
{
if (goup1)
{
if (form1.p6_ploscek1.Top > form1.panel6_pongIgra.Top)
form1.p6_ploscek1.Top -= 15;
}
if (goup2)
{
if (form1.p6_ploscek2.Top > form1.panel6_pongIgra.Top)
form1.p6_ploscek2.Top -= 15;
}
if (godown1)
{
if (form1.p6_ploscek1.Bottom < form1.panel6_pongIgra.Bottom)
form1.p6_ploscek1.Top += 15;
}
if (godown2)
{
if (form1.p6_ploscek2.Bottom < form1.panel6_pongIgra.Bottom)
form1.p6_ploscek2.Top += 15;
}
}
I believe you're relying on the fact that keys get repeated by Windows while you hold them down to make your game pieces move. The first key being held down will stop repeating because the new key being held down is repeating instead.
To fix this move the pieces in the Tick() event of a Timer control. In the KeyDown/KeyUp events simply change the state of a variable that represents whether the associated piece should be moving (and what direction it should go). The Timer code will look at the state variables and act accordingly...
Related
I have a class that catches keyboard keys and I want to catch a specific combination:
Alt + 1
And in case this combination is detected to do my stuff.
This is what I have try:
private bool isAltPressed;
private bool isOnePressed;
private bool bothPressed;
private void HookManager_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
if (e.KeyCode == Keys.LMenu)
isAltPressed = true;
if (e.KeyCode == Keys.D1)
isOnePressed = true;
if (isAltPressed & isOnePressed)
bothPressed = true;
}
private void HookManager_KeyUp(object sender, System.Windows.Forms.KeyEventArgs e)
{
if (bothPressed)
// Do something...
if (e.KeyCode == Keys.LMenu)
{
isAltPressed = false;
bothPressed = false;
}
if (e.KeyCode == Keys.D1)
{
isOnePressed = false;
bothPressed = false;
}
}
So where do I need to verify that both keys are pressed and released and then do my stuff?
Try this:
if ( e.KeyData == (Keys.Alt | Keys.D1) )
Keys is a struct having a flag attribute.
It means that several key codes can be combinated with the logic or operator to form the result.
[Flags]
public enum Keys ...
You should not wait for alt key to be released to perform your action. Unless you can explain why you need to make sure both the alt key and the key pressed must be released before 'doing something', the following code should suffice in either your KeyUp or KeyDown event.
if (e.Modifiers == Keys.Alt && e.KeyCode == Keys.D1)
{
// Do Something
}
I've started creating a game and i ran into a problem:
I cant place check boxes because it somehow stops the "players" movement.
I'm moving my "player" using arrow keys.
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Left)
{
left = true;
}
if (e.KeyCode == Keys.Right)
{
right = true;
}
if (e.KeyCode == Keys.Up)
{
up = true;
}
if (e.KeyCode == Keys.Down)
{
down = true;
}
}
And to reset the controls:
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Left)
{
left = false;
}
if (e.KeyCode == Keys.Right)
{
right = false;
}
if (e.KeyCode == Keys.Up)
{
up = false;
}
if (e.KeyCode == Keys.Down)
{
down = false;
}
}
So how can i place a check box and still control my "player"?
The game working without the check box:
https://i.imgur.com/oJmn2uD.gifv
Then i put the check box and not being able to move the "player":
https://i.imgur.com/53WOGjW.gifv
What are other ways to add a checkbox sort of control that i could use for settings tab that would work?
The answer was that i cant use arrows keys because they act as input keys so i replaced them with WASD and it works like a charm!
I have a picturebox that I want to relocate when a key is pressed.
I'm making a game of pong. With the code below I want to make the paddle of player 1, which is a picturebox that should move up and down while a key is pressed. The following code doesn't seem to work:
public partial class Form1 : Form
{
bool upPressed, downPressed;
public Form1()
{
InitializeComponent();
}
private void PongTimer_Tick(object sender, EventArgs e)
{
if(upPressed){
paddlePlayer1.Location = new Point(paddlePlayer1.Location.X, paddlePlayer1.Location.Y + 5);
}
if (downPressed)
{
MessageBox.Show("Numlock");
}
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Up){
upPressed = true;
}
if (e.KeyCode == Keys.NumLock)
{
downPressed = true;
}
}
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Up){
upPressed = false;
}
}
}
I used the Numlock to see if the problem was in the picture, this isn't the case. I've put the KeyPreview propery to true but this didnt solve it either. The timer does work properly.
I hope somebody here can tell me what I'm doing wrong.
This is a code example to move a PictureBox:
Drag/drop a PictureBox on a form (in this case Form1).
Change the Background color of the PictureBox to e.g. red. (This way it is visible during runtime).
Implement the KeyDown event of Form1 (in this case Form1_KeyDown).
Run the application.
Start pressing an arrow key and the PictureBox will move.
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
int x = pictureBox1.Location.X;
int y = pictureBox1.Location.Y;
if (e.KeyCode == Keys.Right) { x += 1; }
else if (e.KeyCode == Keys.Left) { x -= 1; }
else if (e.KeyCode == Keys.Up) { y -= 1; }
else if (e.KeyCode == Keys.Down) { y += 1; }
pictureBox1.Location = new Point(x, y);
}
I have started to learn some Microsoft.DirectX 3D basic techniques, and bumped to this problem that is too dificult for me. I have created 3D Scene, Camera, Light's etc, with some simple 3D objects drawn. What I want to do now is simple 3D rotation of that objects around all three axes. For that I want to use Arrow and ASWD keyboard keys as in manner in computer games are used. For that I have used OnKeyDown and OnKeyUp event handlers :
#region - Event handler -
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
#region - speed -
if(e.KeyValue == (char)Keys.Add || e.KeyValue == (char)Keys.Oemplus)
step_p = true;
if(e.KeyValue == (char)Keys.Subtract || e.KeyValue == (char)Keys.OemMinus)
step_m = true;
if(step_p)
step++;
if(step_m)
step--;
if(step==0)
step = 1;
#endregion
#region - rotation -
if(e.KeyCode == Keys.Left)
{
left = true;
}
if(e.KeyCode == Keys.Right)
{
right = true;
}
if(e.KeyCode == Keys.Up)
{
up = true;
}
if(e.KeyCode == Keys.Down)
{
down = true;
}
if(e.KeyCode == Keys.A)
{
a = true;
}
if(e.KeyCode == Keys.D)
{
d = true;
}
if(left)
angleZ_D+=step;
if(right)
angleZ_D-=step;
if(up)
angleX_D-=step;
if(down)
angleX_D+=step;
if(a)
angleY_D+=step;
if(d)
angleY_D-=step;
//
//
//
if(angleX_D == 360)
angleX_D = 0;
if(angleY_D >= 360)
angleY_D = 0;
if(angleZ_D >= 360)
angleZ_D = 0;
angleX_R = angleX_D * rad;
angleY_R = angleY_D * rad;
angleZ_R = angleZ_D * rad;
//
//
//
#endregion
#region - zoom -
if(e.KeyValue == (char)Keys.W)
{
w = true;
}
if(e.KeyValue == (char)Keys.S)
{
s = true;
}
if(w)
{
zoom+=0.1f * step;
if(zoom>10.0f) zoom=10.0f;
}
if(s)
{
zoom-=0.1f * step;
if(zoom<1.0f) zoom=1.0f;
}
#endregion
Draw();
}
protected override void OnKeyUp(KeyEventArgs e)
{
base.OnKeyUp(e);
#region - speed -
if(e.KeyValue == (char)Keys.Add || e.KeyValue == (char)Keys.Oemplus)
step_p = false;
if(e.KeyValue == (char)Keys.Subtract || e.KeyValue == (char)Keys.OemMinus)
step_m = false;
#endregion
#region - rotation -
if(e.KeyCode == Keys.Left)
{
left = false;
}
if(e.KeyCode == Keys.Right)
{
right = false;
}
if(e.KeyCode == Keys.Up)
{
up = false;
}
if(e.KeyCode == Keys.Down)
{
down = false;
}
if(e.KeyCode == Keys.A)
{
a = false;
}
if(e.KeyCode == Keys.D)
{
d = false;
}
#endregion
#region - zoom -
if(e.KeyValue == (char)Keys.W)
{
w = false;
}
if(e.KeyValue == (char)Keys.S)
{
s = false;
}
#endregion
Draw();
}
This is the problem :
When I press key A and while holding it down I press key W, program works perfectly but when I release key W the event handler do not recognize that key A is still pressed.
Is there solution for such problem in C# 4.0 and .Net framework 2.0
All the best,
Željko Perić
According to
Quote:
You are depending on the keyboard repeating a key when held down.
That stops working as soon as you press another key.
You instead need to use a Timer and in the Tick event handler
check which way you want to move. Now key-repeat no longer matters.
Set the timer's Interval property to 15 or 31 to get good consistency. – Hans Passant
this is problem solution :
using System;
using System.Windows.Forms;
namespace WASD_keyboard_game_control
{
public partial class MainForm : Form
{
//
// Global variables declaration
//
//
// Timer
//
// Implements a timer that
// raises event at user defined interval
//
Timer Clock;
//
// Set Timer tick Interval in miliseconds
//
// By changing value of Interval,
// we control how often the timer tick event handler is raised
// and eventually the call frequency of Main_Function()
//
const int Interval = 15;
//
// Variables for counting the number
// of times that program has confirmed
// the key down state of AWSD keys
//
int W = 0;
int A = 0;
int S = 0;
int D = 0;
//
// Variables ( flags ) for memorizing
// the key down state of AWSD keys
//
// true - key is down ( pressed )
//
// false - key is up ( released )
//
//
bool w = false;
bool a = false;
bool s = false;
bool d = false;
//
//
//
public MainForm()
{
//
// The InitializeComponent() call is required
// for Windows Forms designer support.
//
InitializeComponent();
//
// Call Initialize_Timer() function
//
Initialize_Timer();
}
void Initialize_Timer()
{
// Create new timer
Clock = new Timer();
// Set timer tick interval in miliseconds
//
// By changing value of interval,
// we control how often the timer tick event handler is raised
// and eventually the call frequency of Main_Function()
//
Clock.Interval = Interval;
//
// Add timer tick event handler
//
// This event handler is raised
// every time timer make tick
//
// The smaler value for timer interval,
// more often the event handler is raised
//
Clock.Tick += new System.EventHandler(this.ClockTick);
//
// Start timer
//
Clock.Start();
}
void ClockTick(object sender, EventArgs e)
{
//
// Timer tick event handler
//
//
// Call Main_Function()
//
Main_Function();
//
//
//
}
protected override void OnKeyDown(KeyEventArgs e)
{
//
// This event handler is raised every time
// some key on the keyboard is first pressed
//
base.OnKeyDown(e);
//
// Set corresponding key down flag state to true
//
if(e.KeyCode == Keys.W)
w = true;
if(e.KeyCode == Keys.A)
a = true;
if(e.KeyCode == Keys.S)
s = true;
if(e.KeyCode == Keys.D)
d = true;
}
protected override void OnKeyUp(KeyEventArgs e)
{
//
// This event handler is raised every time
// some key on the keyboard is released
//
base.OnKeyUp(e);
//
// Set corresponding key down flag state to false
//
if(e.KeyCode == Keys.W)
w = false;
if(e.KeyCode == Keys.A)
a = false;
if(e.KeyCode == Keys.S)
s = false;
if(e.KeyCode == Keys.D)
d = false;
}
void Main_Function()
{
//
// Main function
//
//
// This function is called every time the
// timer tick event handler is raised
//
//
// This function determines wich key is pressed
// upon key down flag value and updates correspondig counter value
//
// Counter value shows how many times program has confirmed the
// key down state and not how many times user has pressed the key
//
//
// Increase counter value if key is down
//
if(a)
A++;
if(s)
S++;
if(w)
W++;
if(d)
D++;
//
// Show values of counters
//
Label_A.Text = "A = " + A.ToString();
Label_S.Text = "S = " + S.ToString();
Label_W.Text = "W = " + W.ToString();
Label_D.Text = "D = " + D.ToString();
}
}
}
If you press and hold the 5 key on the numpad it will continue to execute a statement in the KeyDown event handler. How can i ensure the statement is executed only once, even if i hold the key down?
Thanks for your attention.
private void form_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
if (e.KeyCode == Keys.NumPad5)
{
dados.enviar("f"); //I want this to run only once!
}
}
You can set flag on key down and reset it on key up.
private bool isPressed = false;
public Form1()
{
InitializeComponent();
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.B && !isPressed )
{
isPressed = true;
// do work
}
}
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
if (isPressed )
isPressed = false;
}
bool alreadyPressed = false;
...
if (e.KeyCode == Keys.NumPad5 && ! alreadyPressed)
{
alreadyPressed = true;
...
You should use IsRepeat flag to check if it's the first time key is pressed.
if (e.KeyCode == Keys.NumPad5 && !e.IsRepeat)