This is probably a trivial question, however, i have yet to find an answer. I'm trying to improve my winforms application by adding the possibility of key navigation (arrow keys). The problem is I have a number of buttons arranged in rows and columns and it has proven troublesome to navigate. The UP/RIGHT and DOWN/LEFT arrows only increment and decrement the index rather than move in the specified direction. So far my only idea was to map the button indexes to a 2d array and use that as reference to the buttons, however, i have been unsuccessful. Anyone have some ideas or suggestions on how i could implement this?
I'm using C# on Visual studio 2008 and .NET3.5
Control[,] MyButtons = new Control[4,3] { {b1,b2,b3},{b4,b5,b6},{b7,b8,b9},{btn_Clear,b0,btn_Cancel}};
for(int i=0;i<4;i++)
for (int j = 0; j < 3; j++)
{
switch (e.KeyValue)
{
case 13: //return
{ e.Handled = false; break; }
case 39: //Right
{
j++;
break;
}
case 38: //Up
{
i++;
break;
}
case 37: //Left
{
j--;
break;
}
case 40: //Down
{
i--;
break;
}
}
if (e.KeyValue != 13)
{
e.Handled = true; //Don't pass on the keystroke
MyButtons[i,j].Focus(); // Set the focus to the selected control
Application.DoEvents();
}
}
With this code i keep getting this error for each element of the array
Invalid rank specifier: expected ',' or ']'
I'll give you a full example and you can extrapolate to your project/code.
The form itself:
Here's that form's code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class frmButtons : Form
{
private Int32 _selectedButton = 1;
private Dictionary<Int32, Button> _buttonDict = new Dictionary<Int32, Button>();
public frmButtons()
{
InitializeComponent();
foreach (Button b in this.Controls.OfType<Button>().Where(x => x.Tag != null))
{
Int32 i;
if (Int32.TryParse(b.Tag.ToString(), out i))
_buttonDict.Add(i, b);
}
if (_buttonDict.Count > 0)
_buttonDict[_selectedButton].Focus();
}
private void frmButtons_KeyUp(Object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.Up:
_selectedButton -= 3;
e.Handled = true;
break;
case Keys.Down:
_selectedButton += 3;
e.Handled = true;
break;
case Keys.Left:
_selectedButton -= 1;
e.Handled = true;
break;
case Keys.Right:
_selectedButton += 1;
e.Handled = true;
break;
case Keys.Enter:
break;
}
if (_selectedButton < 1)
_selectedButton += 12;
else if (_selectedButton > 12)
_selectedButton -= 12;
_buttonDict[_selectedButton].Focus();
}
}
}
I notice a hitch when you hit a key...there's a default behavior in the form where it attempts to handle the arrow key to move to the next in the Tab Order. Solve that and you've got it. Sorry, but I'm out of time to work on this.
Related
I'm working on a speech recognizer but every time I say a word it puts it in a loop and keeps saying:
hi my name is Jarvis how can I help you?
What should I do?
I've also tried RecognizeAsyncCancel() but it didn't work!
My code is below:
using System;
using System.IO;
using System.Speech.Recognition;
using System.Speech.Synthesis;
using System.Windows.Forms;
namespace Jarvis
{
public partial class Form1 : Form
{
SpeechRecognitionEngine RecEngine = new SpeechRecognitionEngine();
SpeechSynthesizer speech = new SpeechSynthesizer();
public Form1()
{
InitializeComponent();
Choices choices = new Choices();
string[] text = File.ReadAllLines(Environment.CurrentDirectory + "//grammer.txt");
choices.Add(text);
Grammar grammar = new Grammar(new GrammarBuilder(choices));
RecEngine.LoadGrammar(grammar);
RecEngine.SetInputToDefaultAudioDevice();
RecEngine.RecognizeAsync(RecognizeMode.Multiple);
RecEngine.SpeechRecognized += new EventHandler<SpeechRecognizedEventArgs>(RecEngine_SpeechRecognized);
speech.SelectVoiceByHints(VoiceGender.Male);
}
private void RecEngine_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
string result = e.Result.Text;
if (result == "Hello")
{
result = "";
result = "Hi, my name is Jarvis, how can I help you";
}
if (result == "Hi")
{
result = "";
result = "It is currently " + DateTime.Now.ToLongTimeString();
}
speech.SpeakAsync(result);
lblresult.Text = result;
result = "";
MessageBox.Show("a");
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
}
For starters, the setup you are using, is creating your problems, due mostly from arrangement of your code. You should also be incorporating a switch case statement in your recEngine Sub. Also, you are using SpeechSynthesizer speech in your declaration and your SpeechSynthesizer should compliment that and be: speech.Speak("Hi, my name is Jarvis, how can I help you") NOT result = "Hi, my name is Jarvis, how can I help you";.
You don't need this either: result = ""; You can still use If Statements within Case Statements if you want. With that said, here is an example from one of my old projects. I am leaving you with a link to the full project of the code. It will get you on the right path: Just scroll down to the Form1.cs at my repository.
https://github.com/DeadReport77/Scarlett-Speech-Recognition-Final-Production/commit/20f4db5d3b75b03d601d39c6fe54e8261c7976f0
I am the creator of Scarlett Witch Speech Recognition surfacing the net on YouTube and other places. This is the YouTube link: https://www.youtube.com/watch?v=39S10FoCbIA
The code will solve all your problems as well (switch case example):
private void RecEngine_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
switch (e.Result.Text)
{
case "scarlett mute volume":
SendMessageW(this.Handle, WM_APPCOMMAND, this.Handle,
(IntPtr)APPCOMMAND_VOLUME_MUTE);
break;
case "scarlett volume up":
int repeat = 10;
for (int i = 0; i < repeat; i++)
SendMessageW(this.Handle, WM_APPCOMMAND, this.Handle,
(IntPtr)APPCOMMAND_VOLUME_UP);
break;
case "scarlett volume down":
for (int iter = 0; iter < 10; iter++)
SendMessageW(this.Handle, WM_APPCOMMAND, this.Handle,
(IntPtr)APPCOMMAND_VOLUME_DOWN);
break;
case "show commands":
new SoundPlayer(#"C:\Users\Leeraoy.Jenkins\source\repos\Scarlett\Resources\list.wav").Play();
Process.Start(#"C:\\Users\Leeraoy.Jenkins\source\repos\Scarlett\Resources\Commands.txt");
break;
case "tell me who you are":
new SoundPlayer(#"C:\Users\Leeraoy.Jenkins\source\repos\Scarlett\Resources\info.wav").Play();
break;
case "scarlett open youtube":
new SoundPlayer(#"C:\Users\Leeraoy.Jenkins\source\repos\Scarlett\Resources\youtube.wav").Play();
Process.Start("chrome", "Http://www.youtube.com");
break;
case "scarlett movies":
new SoundPlayer(#"C:\Users\Leeraoy.Jenkins\source\repos\Scarlett\Resources\movie.wav").Play();
Process.Start("chrome", "http://www.tubitv.com");
break;
case "scarlett open github":
new SoundPlayer(#"C:\Users\Leeraoy.Jenkins\source\repos\Scarlett\Resources\github.wav").Play();
Process.Start("chrome", "Http://www.github.com");
break;
case "open wiki":
new SoundPlayer(#"C:\Users\Leeraoy.Jenkins\source\repos\Scarlett\Resources\wiki.wav").Play();
Process.Start("http://www.wikipedia.org/");
break;
case "scarlett microsoft office":
new SoundPlayer(#"C:\Users\Leeraoy.Jenkins\source\repos\Scarlett\Resources\word.wav").Play();
Process.Start("winword");
break;
case "stop listening":
recEngine.RecognizeAsyncStop();
new SoundPlayer(#"C:\Users\Leeraoy.Jenkins\source\repos\Scarlett\Resources\mic.wav").Play();
break;
case "open command":
new SoundPlayer(#"C:\Users\Leeraoy.Jenkins\source\repos\Scarlett\Resources\prompt.wav").Play();
System.Diagnostics.Process.Start("cmd");
break;
case "scarlett run system scan":
Scanning f = new Scanning();
f.Show();
break;
case "commit to memory":
new SoundPlayer(#"C:\Users\Leeraoy.Jenkins\source\repos\Scarlett\Resources\storing.wav").Play();
break;
case "scarlett close":
new SoundPlayer(#"C:\Users\Leeraoy.Jenkins\source\repos\Scarlett\Resources\shuttingdown.wav").Play();
Sleep(TimeSpan.FromSeconds(2));
Application.Exit();
break;
case "scarlett what day is it":
Scarlett.Speak(DateTime.Today.ToString("dd-MM-yyyy"));
break;
case "scarlett out of the way":
if (WindowState == FormWindowState.Normal)
{
WindowState = FormWindowState.Minimized;
new SoundPlayer(#"C:\Users\Leeraoy.Jenkins\source\repos\Scarlett\Resources\standby.wav").Play();
}
break;
case "scarlett come back":
if (WindowState == FormWindowState.Minimized)
{
WindowState = FormWindowState.Normal;
new SoundPlayer(#"C:\Users\Leeraoy.Jenkins\source\repos\Scarlett\Resources\comeback.wav").Play();
}
break;
case "disparta":
new SoundPlayer(#"C:\Users\Leeraoy.Jenkins\source\repos\Scarlett\Resources\closingapp.wav").Play();
SendKeys.Send("%{F4}");
break;
case "scarlett play rammstein":
new SoundPlayer(#"C:\Users\Leeraoy.Jenkins\source\repos\Scarlett\Resources\video.wav").Play();
Process.Start("chrome", "https://www.youtube.com/watch?v=3b4szXcRFcs?autoplay=1&mute=1");
break;
case "page up":
SendKeys.Send("{PGUP}");
break;
case "page down":
SendKeys.Send("{PGDN}");
break;
case "new tab":
SendKeys.Send("^{t}");
break;
case "switch tab":
SendKeys.Send("^{TAB}");
break;
case "magnify":
SendKeys.Send("^{+}");
break;
case "less":
SendKeys.Send("^{-}");
break;
case "scarlett notepad":
new SoundPlayer(#"C:\Users\Leeraoy.Jenkins\source\repos\Scarlett\Resources\notepad.wav").Play();
Process.Start("notepad");
break;
case "scarlett visual studios":
new SoundPlayer(#"C:\Users\Leeraoy.Jenkins\source\repos\Scarlett\Resources\visual.wav").Play();
Process.Start("devenv.exe");
break;
default:
new SoundPlayer(#"C:\Users\Leeraoy.Jenkins\source\repos\Scarlett\Resources\unknown.wav").Play();
break;
}
}
I am making a snake game as my homework assignment , I've already added a code for making the snake head move depending on the user input (left , right , down , up)
But I am stuck with the timing of it , I used Thread.Sleep in order for the game not to crash and get an exception , but my instructor told me that Thread.Sleep is a horrible idea in programming because it literally adds a delay to your game.
So, I need to somehow make it that there won't be a delay in my game while avoiding Thread.Sleep
class Program
{
static void Main(string[] args)
{
Direction direction = Direction.Down;
Console.CursorVisible = false;
int x=0 , y=0 ;
int xprev = 2, yprev = 2;
char shape = 'o';
x = xprev;
y = yprev;
Console.SetCursorPosition(xprev, yprev);
Console.Write(shape);
UserInput input = new UserInput();
ConsoleKeyInfo? info;
while (true)
{
info = input.GetKey();
if (info.HasValue)
{
switch (info.Value.Key)
{
case ConsoleKey.RightArrow:
direction = Direction.Right;
break;
case ConsoleKey.LeftArrow:
direction = Direction.Left;
break;
case ConsoleKey.UpArrow:
direction = Direction.Up;
break;
case ConsoleKey.DownArrow:
direction = Direction.Down;
break;
}
}
Thread.Sleep(100);
switch (direction)
{
case Direction.Up:
y--;
break;
case Direction.Down:
y++;
break;
case Direction.Left:
x--;
break;
case Direction.Right:
x++;
break;
}
Console.MoveBufferArea(xprev, yprev, 1, 1, x, y);
xprev = x;
yprev = y;
}
As Sohaib Jundi suggests, a timer of some description is a reasonable solution here. Your objective is:
Every 100ms, update where the snake is
Rather than solve this by saying make the application pause for 100ms, then update the snake, using a timer changes it to Have something that triggers every 100ms to update the snake.
For example:
using System;
using System.Threading;
namespace Snake
{
class Program
{
static void Main(string[] args)
{
var snakeTimer = new Timer(updateTheSnake, null, 0, 100);
while(true)
{
var keypress = Console.ReadKey();
if (keypress.Key == ConsoleKey.Escape)
{
break;
}
}
}
static void updateTheSnake(object state)
{
Console.Write("#");
}
}
}
This is a very simple example that just draws a line of # across the screen until the user presses the escape key. In your code, you'd likely want to move everything below the Thread.Sleep into the updateTheSnake method. direction will probably need to be stored into shared state so that you can refer to it from the updateTheSnake method.
I am making a game in C# and the game will not end once the Life has hit 0. The game however does show the ending MessageBox alerting the User that they have no live remaining which by pressing OK the game should close and the Gameover Dialog Form should show. However the game just restarts again from scratch while the Gameover form shows. Can anyone help me as this project has all the elements of a small indie side scroll game which I will be using this Game as an introduction to the components within my next project.
This is the code which I have used, if you can help me it would be greatly appreciated. Bear in mind this is my first question posted and having searched extensively for the solution which I have not been able to find.
using System; //--->
using System.Collections.Generic; //--->
using System.ComponentModel; //--->
using System.Data; //--->
using System.Drawing; //--->
using System.Linq; //--->
using System.Text; //--->
using System.Threading.Tasks; //--->
using System.Windows.Forms; //------>
namespace BouningBall
{
public partial class EasyGame : Form
{
public int speed_Left = 5;
public int speed_Top = 3;
public int Lifes = 3;
int Points = 0;
public EasyGame()
{
InitializeComponent();
EasyTimer.Enabled = true;
EasyLife.Text = Lifes.ToString();
this.FormBorderStyle = FormBorderStyle.Sizable;
this.TopMost = true;
this.Bounds = Screen.PrimaryScreen.Bounds;
Cursor.Hide();
Bar.Top = Playground.Bottom - (Playground.Bottom / 10);
}
private void EasyTimer_Tick(object sender, EventArgs e)
{
Bar.Left = Cursor.Position.X - (Bar.Width / 2);
Ball.Left += speed_Left;
Ball.Top += speed_Top;
if (EasyLife.Text == "0")
{
EasyTimer.Stop();
if (Lifes == 0)
EasyTimer.Stop();
this.Hide();
Cursor.Show();
string info = "lost ...";
string snippet = "all lifes have been used...";
MessageBoxButtons digits = MessageBoxButtons.OK;
DialogResult ending;
ending = MessageBox.Show(info, snippet, digits);
if (ending == System.Windows.Forms.DialogResult.OK)
{
EasyTimer.Stop();
EndLife Final = new EndLife();
Final.Show();
}
}
if (Ball.Bottom >= Bar.Top && Ball.Bottom <= Bar.Bottom && Ball.Left >= Bar.Left && Ball.Right <= Bar.Right)
{
speed_Top += 3;
speed_Left += 3;
speed_Top = -speed_Top;
Points += 1;
Easygamepoints.Text = Points.ToString();
}
if (Ball.Left <= Playground.Left)
{
speed_Left = -speed_Left;
}
if (Ball.Right >= Playground.Right)
{
speed_Left = -speed_Left;
}
if (Ball.Top <= Playground.Top)
{
speed_Top = -speed_Top;
}
if (Ball.Bottom >= Playground.Bottom)
{
EasyTimer.Stop();
Cursor.Show();
Lifes -= 1;
string message = "You have lost one of your lives...";
string caption = "You died, Life Lost...";
MessageBoxButtons buttons = MessageBoxButtons.OK;
DialogResult result;
result = MessageBox.Show(message, caption, buttons);
if (result == System.Windows.Forms.DialogResult.OK)
{
EasyTimer.Enabled = false;
Cursor.Hide();
EasyLife.Text = Lifes.ToString();
EasyTimer.Start();
speed_Left = 5;
speed_Top = 3;
Ball.Top = 69;
Ball.Left = 128;
}
}
}
}
}
Due to Confusion, this body has been edited to allow better understanding of the objective that needs to be met.`enter code here`
NB: Potentially not the answer, but I can only post so many characters in the comments section, so it's here instead.
private void EasyTimer_Tick(object sender, EventArgs e)
{
Bar.Left = Cursor.Position.X - (Bar.Width / 2);
Ball.Left += speed_Left;
Ball.Top += speed_Top;
if (Ball.Bottom >= Bar.Top && Ball.Bottom <= Bar.Bottom && Ball.Left >= Bar.Left && Ball.Right <= Bar.Right)
{
speed_Top += 3;
speed_Left += 3;
speed_Top = -speed_Top;
Points += 1;
Easygamepoints.Text = Points.ToString();
}
if (Ball.Left <= Playground.Left)
...
...
if (Ball.Bottom >= Playground.Bottom)
{
EasyTimer.Stop();
Cursor.Show();
Lifes -= 1;
if (Lifes == 0)
{
DialogResult ending;
MessageBox.Show("all lifes have been used...", "lost ...", MessageBoxButtons.OK);
EndLife Final = new EndLife();
Final.Show();
// You need to return whether or not the user wants to play another game from this form
// See http://stackoverflow.com/questions/280579/how-do-i-pass-a-value-from-a-child-back-to-the-parent-form
if (Final.NewGame == true)
{
speed_Left = 5;
speed_Top = 3;
Ball.Top = 69;
Ball.Left = 128;
Lifes = 3;
EasyTimer.Start();
}
else
Close();
}
else
{
DialogResult result = MessageBox.Show("You have lost one of your lives...", "You died, Life Lost...", MessageBoxButtons.OK);
if (result == DialogResult.OK)
{
EasyTimer.Start();
Cursor.Hide();
EasyLife.Text = Lifes.ToString();
speed_Left = 5;
speed_Top = 3;
Ball.Top = 69;
Ball.Left = 128;
}
else
Close();
}
}
}
The important thing to notice here, is that you must check if the user wants to play another game or not, from the Final form. If they don't, then Close the main form. The game will never end if you don't close the form.
I'm trying to make a single game, but I got a little problem here...
I'm moving a picturebox with the arrow keys, to avoid other pictureboxes... The problem is, that my picturebox moves out of the form when I press the left key too many times... I succeeded in solving this problem with the right side(by blocking the picturebox with an another), but the left side version still doesn't works, and I don't know why...
Here is the code:
if (pictureBox7.Bounds.IntersectsWith(pictureBox1.Bounds))
switch (e.KeyCode)
{
case Keys.Escape: Application.Exit(); break;
case Keys.P: timerkunai1.Enabled = false;
timerkunai2.Enabled = false; timerkunai3.Enabled = false;
timerkunai4.Enabled = false; timerninja.Enabled = false;
timerlife.Enabled = false;
button3.Show(); break;
case Keys.Right: i = 6; dx = 25; press = true; break;
}
if (pictureBox8.Bounds.IntersectsWith(pictureBox1.Bounds))
switch (e.KeyCode)
{
case Keys.Escape: Application.Exit(); break;
case Keys.P: timerkunai1.Enabled = false;
timerkunai2.Enabled = false; timerkunai3.Enabled = false;
timerkunai4.Enabled = false; timerninja.Enabled = false;
timerlife.Enabled = false;
button3.Show(); break;
case Keys.Left: i = 0; dx = -25; press = true; break;
}
else
switch (e.KeyCode)
{
case Keys.Escape: Application.Exit(); break;
case Keys.P: timerkunai1.Enabled = false;
timerkunai2.Enabled = false; timerkunai3.Enabled = false;
timerkunai4.Enabled = false; timerninja.Enabled = false;
timerlife.Enabled = false;
button3.Show(); break;
case Keys.Left: i = 0; dx = -25; press = true; break;
case Keys.Right: i = 6; dx = 25; press = true; break;
}
You need code to check if the picturebox's bounds are outside of the form. If the picturebox movement will cause it to be outside the bounds then prevent the motion.
Something like this pseudocode:
if (pictureBoxZ + dx < 0 || pictureBoxZ + dx > pictureBoxZ.Parent.Width) { //Deny Motion }
Is your dx variable an offset to the new Location of the PictureBox?
Then limit the Location.x to 0:
if (pictureBox1.Location.x + dx > 0)
pictureBox1.Location += dx;
If you want to limit to left and right size, to the width of the Form use this code:
if ((pictureBox1.Location.x + dx > 0) && (pictureBox1.Location.x + dx < this.Size.Width - pictureBox1.Size.Width))
pictureBox1.Location += dx;
I'm kinda new to both Keys event and timers in my code but for some reason there is this weird bug. (read the last edit)
public partial class Form1 : Form
{
bool start = false;
Snake ormen = new Snake(10);
short direction = 3;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
button1.Hide();
timer1.Enabled = true;
start = true;
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics g = e.Graphics;
if (start)
{
ormen.rita(g);
}
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.Up:
direction = 3;
break;
case Keys.Down:
direction = 1;
break;
case Keys.Left:
direction = 2;
break;
case Keys.Right:
direction = 0;
break;
default:
break;
}
}
private void timer1_Tick(object sender, EventArgs e)
{
ormen.flytta(direction);
Invalidate();
}
}
}
I also tried to use debug at the key event but it does not even activate until after the time period. Can anyone please tell me why? Also if there are any obvious mistakes i would appreciate it if you could mention them. I have also tried to make the timer interval higher to check if the program can't keep up but it can. (read the last edit)
[EDIT] I don't think it will help but here is the code for the class "Snake". I doubt it's a problem in there but anyways.
private short diameter = 0;
//0 = Right, 1 = Down, 2 = Left, 3 = Up
public Snake(short diameter)
{
this.diameter = diameter;
ormensPlatser.Enqueue(new Point(0, 0));
ormensPlatser.Enqueue(new Point(0 + diameter, 0));
ormensPlatser.Enqueue(new Point(0 + diameter + diameter, 0));
}
Queue<Point> ormensPlatser = new Queue<Point>();
public void rita(Graphics g)
{
Point temp;
for (int i = 0; i < ormensPlatser.Count; i++)
{
temp = ormensPlatser.Dequeue();
g.FillEllipse(new SolidBrush(Color.Red), temp.X, temp.Y, diameter, diameter);
ormensPlatser.Enqueue(temp);
}
}
private void ormNäraKant(short direction,ref Point ormBit)
{
switch (direction)
{
case 0:
ormBit.X = ormBit.X + diameter >= 380 ? 0 : ormBit.X + diameter;
break;
case 1:
ormBit.Y = ormBit.Y + diameter >= 360 ? 0 : ormBit.Y + diameter;
break;
case 2:
ormBit.X = ormBit.X - diameter < 0 ? 370 : ormBit.X - diameter;
break;
case 3:
ormBit.Y = ormBit.Y - diameter < 0 ? 350 : ormBit.Y - diameter;
break;
}
}
public void flytta(short direction)
{
Point temp;
int temp1 = ormensPlatser.Count - 1;
for (int i = 0; i < ormensPlatser.Count; i++)
{
if (i == temp1)
{
switch(direction)
{
case 0:
temp = ormensPlatser.Dequeue();
ormNäraKant(0, ref temp);
ormensPlatser.Enqueue(temp);
break;
case 1:
temp = ormensPlatser.Dequeue();
ormNäraKant(1, ref temp);
ormensPlatser.Enqueue(temp);
break;
case 2:
temp = ormensPlatser.Dequeue();
ormNäraKant(2, ref temp);
ormensPlatser.Enqueue(temp);
break;
case 3:
temp = ormensPlatser.Dequeue();
ormNäraKant(3, ref temp);
ormensPlatser.Enqueue(temp);
break;
}
}
else
{
ormensPlatser.Dequeue();
temp = ormensPlatser.Peek();
ormensPlatser.Enqueue(temp);
}
}
}
}
}
[EDIT2] Okey, apparently it wasn't about the time or anything like that, the code worked but i think it has something to do with what slawekwin said in the comments about the focus when the program starts. So the problem is still the same but if I ALT+tab to a another program then back to the snake program it works.
SO i finally figure it out, i thought that the problem was with the timer event and the key input event when they worked together but my assumption was wrong. So what i did is that i went through all the properties that the form has and i found a setting called "KeyPrevied" and it was false so i tried to set it to true and it worked :).