Sprite moves indefinitely in a direction or gets stuck in diagonals - c#

I am working on a gaming project with a base to help get me started. The base is overall extremely helpful, however there is a part of the code that confuses me as to how to manipulate correctly.
When this code is run, the player sprite will indefinitely move in a direction until the other key press is used. If a playerMoveY is added, it will get stuck moving in diagonals.
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Left)
{
playerMoveX = -1;
}
else if (e.KeyCode == Keys.Right)
{
playerMoveX = 1;
}

Without seeing your full code, it's going to be hard to say for sure, but it is probably because you don't have a KeyUp event to reset the move value.
Similarly to how you created a KeyDown event to use the Form1_KeyDown method, try something like this for KeyUp
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Left)
{
playerMoveX = 0;
}
else if (e.KeyCode == Keys.Right)
{
playerMoveX = 0;
}
}

Related

C# If more keys are pressed at once how to not stop functions of others?

I know the title was little unclear but i will explain.
My Example:
when i press 'D' my object will move to right,
same for 'A' just move to left,
but when i press 'Space' while holding 'A'/'D',the object will just o the function of the 'Space'.
if (e.KeyCode == Keys.A)
{
ply.Left -= 3;
}
if (e.KeyCode == Keys.D)
{
ply.Left += 3;
}
if (e.KeyCode == Keys.Space) {
ply.Top -= 100;
}
You can track the state of multiple keys through the use of both KeyUp and KeyDown by use of a HashSet<Keys>:
private HashSet<Keys> _keys = new HashSet<Keys>();
public void Control_KeyDown(object sender, KeyEventArgs e)
{
_keys.Add(e.KeyCode);
}
public void Control_KeyUp(object sender, KeyEventArgs e)
{
_keys.Remove(e.KeyCode);
}
public bool IsKeyDown(Keys keyCode)
{
return _keys.Contains(keyCode);
}
Now, whenever you want to check to see if a key is down, just do:
if(IsKeyDown(Keys.A))
{
ply.Left -= 3;
}
Keep in mind that if you just check key states in one of the key events, you will probably have issues with not detecting repeats properly. If you really want to handle this properly, you should use a Timer with a fairly small Interval that periodically polls with IsKeyDown and handles all your input.
With a Timer named timer1 that has an interval of 100, you can handle all your input like this, and have fairly responsive input to the full range of keys supported by your hardware.
private void timer1_Tick(object sender, EventArgs e)
{
if (IsKeyDown(Keys.A))
{
ply.Left -= 3;
}
if (IsKeyDown(Keys.S))
{
ply.Top += 3;
}
if (IsKeyDown(Keys.D))
{
ply.Left += 3;
}
if (IsKeyDown(Keys.W))
{
ply.Top -= 3;
}
}
As Bradley said, you could save all key events to a keystate cache.
This could look something like this pseudo code:
Event KeyDown(e) -> keystate[e.KeyCode] = true
Event KeyUp(e) -> keystate[e.KeyCode] = false
That way, you should always know every state.

How to make a picturebox rotate only once in c#?

I'm making a mini game. I want to rotate my player with this code when I turn left and right picPlayer.Image.RotateFlip(RotateFlipType.RotateNoneFlipX) My moving code is:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
//when one of the movement keys are pressed,
//makes it's variable true.
if (e.KeyCode == Keys.Right || e.KeyCode == Keys.D)
{
moveRight = true;
}
}
Also, my timer's program is:
private void tmrMovementPlayer_Tick(object sender, EventArgs e)
{
//whenever right arrow is pressed,
if (moveRight == true)
{
//decrease the x variable by 5 (moves right)
x = x + PLAYER_SPEED;
//check for boundaries (if the player is out of the screen)
if (x >= this.ClientSize.Width - picPlayer.Width)
{
//if yes, set it back to the boundary.
x = this.ClientSize.Width - picPlayer.Width;
}
//check the subprogram for info
MovePlayer();
}
}
What should I do at this point? Thanks.
So thanks to the other answer, I found the solution. It was a little bit different. I created another boolean called "goingRight" just for the rotation.
if (e.KeyCode == Keys.Right || e.KeyCode == Keys.D)
{
//make move right true
moveRight = true;
//if i was going left,
if (goingRight == false)
{
//say it im going right
goingRight = true;
//and flip it (only if i was going left before)
picPlayer.Image.RotateFlip(RotateFlipType.RotateNoneFlipX);
}
}
Again, thanks for all the help.
Try something like...
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
//when one of the movement keys are pressed,
//makes it's variable true.
if (e.KeyCode == Keys.Right || e.KeyCode == Keys.D)
{
if (!moveRight)
{
picPlayer.Image.RotateFlip(RotateFlipType.RotateNoneFlipX)
moveRight = true;
}
}
}

Save a text string to textbox with keyboard shortcut

Im a beginner in C# and im trying to create a windows form application that save a copied text to a textbox when you execute a command with the keyboard. I know there is mouch more to do but where do i start? I suceed to make someting happening with the code below a start at least..
And another question.. is it possible to create more than 2 commands. It doesn't work if i add for example : " && KeyCode.ToString() == "B") "
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode.ToString() == "C")
{
MessageBox.Show("CTRL+C");
}
}
Cheers
You would manage this by calling keyDown/Up events. Keep track of each event and which key went down. Then using the Clipboard.GetText() function to copy/paste the text from clipboard into your textbox once both keys are down.
Example,
bool keyup = false;
bool keyleft = false;
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Up)
{
keyup = true;
}
else if (e.KeyCode == Keys.Left)
{
keyleft = true;
}
if (keyleft && keyup)
{
textboxOne.Text = Clipboard.GetText(TextDataFormat.Html);
}
}
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Up)
{
keyup = false;
}
else if (e.KeyCode == Keys.Left)
{
keyleft = false;
}
}
Used both these as my resources.
Resource One: Detect when two keys are pressed at the same time
Resource Two: http://msdn.microsoft.com/en-us/library/c2thcsx4%28v=vs.110%29.aspx

Why is my object not moving?

I have a program where I want to move a Graphic with the keyboard keys. I originally had a function to move the graphic whenever pressed a button, but I abandoned that method to get around the keyboard repeat delay. Instead, I decided I would use a timer, which I would enable upon the KeyPess event, and disable on the KeyUp event. At first, I used 4 different timers for each different direction, and although it worked I noticed my program had begun to freeze quite often. I decided to use a single timer for all movements, and use if statements to determine the direction. Now, it seems that my Graphic doesn't move at all, even though all I did was copy and paste code.
enum Direction
{
Left, Right, Up, Down
}
private Direction _objectDirection;
int _x = 100, _y = 100;
private void Form1_Paint(object sender, PaintEventArgs e)
{
Picture.MakeTransparent(Color.Transparent);
e.Graphics.DrawImage(Picture, _x, _y);
}
void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.W)
{
if (timerAnimation.Enabled == false)
{
AnimationMaxFrame = 3;
timerAnimation.Enabled = true;
}
_objectDirection = Direction.Up;
timerMovement.Enabled = true;
}
//The rest of this code is omitted to save space, it is repeated 4 times with the only
//changes being the key pressed, and the object direction.
Invalidate();
}
void Form1_KeyUp(object sender, KeyEventArgs e)
{
timerAnimation.Enabled = false;
timerMovement.Enabled = false;
Picture = Idle;
this.Refresh();
}
private void timerMovement_Tick(object sender, EventArgs e)
{
if (_objectDirection == Direction.Up)
{
if (_y > 24)
{ _y = _y - 2; }
else
{ timerMovement.Enabled = false; }
//This if statement is to ensure that the object doesn't leave the form.
//I have tried removing them already, they're not the problem.
}
//Again, this is shortened to save space, it is repeated for each direction.
Invalidate();
}
What is preventing my graphic from moving, and is there a better way to do this? There is still a lot of functionality I want to add to this, but it's already freezing.
Not sure you are making a game with WinForms, but to the point...
You need to handle key pressed events, when a key pressed event fires set a boolean flag in your code depending on if the event was a press or release. Then in your update code check the flag and do your movement accordingly.
It would be something like this (example code):
bool moveup = false;
void KeyPressed(object sender, KeyEventArgs e)
{
// check for keys that trigger starting of movement
if (e.KeyCode == Keys.W) moveup = true;
}
void KeyReleased(object sender, EventEventArgs e)
{
// check for keys that trigger stopping of movement
if (e.KeyCode == Keys.W) moveup = false;
}
void TimerTick(obect sender, EventArgs e)
{
if (moveup)
{
// move your object
}
}

Trying to detect keypress

I made a method that detects when a key is pressed, but its not working! Heres my code
void KeyDetect(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.W && firstload == true)
{
MessageBox.Show("Good, now move to that box over to your left");
firstload = false;
}
}
I also tried to make a keyeventhandler but, it sais "cannot assign to key detect because it is a method group"
public Gwindow()
{
this.KeyDetect += new KeyEventHandler(KeyDetect);
InitializeComponent();
}
Use keypress event like this:
private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyCode == Keys.F1 && e.Alt)
{
//do something
}
}
1) Go to your form's Properties
2) Look for the "Misc" section and make sure "KeyPreview" is set to "True"
3) Go to your form's Events
4) Look for the "Key" section and double click "KeyDown" to generate a function to handle key down events
Here is some example code:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
Console.WriteLine("You pressed " + e.KeyCode);
if (e.KeyCode == Keys.D0 || e.KeyCode == Keys.NumPad0)
{
//Do Something if the 0 key is pressed (includes Num Pad 0)
}
}
You are looking for this.KeyPress. See How to Handle Keypress Events on MSDN.
Try to use the KeyDown event.
Just see KeyDown in MSDN
Just do
if (Input.GetKeyDown("/* KEYCODE HERE */"))
{
/* CODE HERE */
}

Categories