ä¸æ¶å ´èµ·åäºä¸ä¸ªè´ªåèï¼åé´äºä¸é¢å¤§ç¥çç´ æï¼è§£å³äºå¤§ç¥æ²¡ææ¹åé®çé®é¢
 from1
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 è´ªåè
{
  public partial class Form1 : Form
  {
    static int score;
    static int foodx, foody;
    KeyEventHandler myKeyEventHandeler;
    KeyboardHook k_hook = new KeyboardHook();
    int lastKey = 0;
    public Form1()
    {
      InitializeComponent();
    }
    private void timer1_Tick(object sender, EventArgs e)
    {
      DrawSnake();
      DrawFood();
    }
    public void DrawFood()
    {
      Graphics f = this.CreateGraphics();
      SolidBrush mybrush = new SolidBrush(Color.Red);
      f.FillRectangle(mybrush, foodx, foody, 10, 10);
    }
    public void DrawSnake()
    {
      RectangleF[] rectangles = new RectangleF[Snake.realsnake.Count];
      int num;
      for (num = 0; num < Snake.realsnake.Count; num++)
      {
        rectangles[num] = new RectangleF(Snake.realsnake[num].Location_x,
          Snake.realsnake[num].Location_y, Snake.width, Snake.height);
      }
      this.Refresh();
      Graphics g = this.CreateGraphics();
      SolidBrush myBrush = new SolidBrush(Color.Black);
      g.FillRectangles(myBrush, rectangles);
    }
    private void timer2_Tick(object sender, EventArgs e)
    {
      Snake.SnakeMove(Snake.wasd);
      EatFood();
      TobeOrNotTobe();
      label2.Text = score.ToString();
    }
    public void TobeOrNotTobe()
    {
      int x = Snake.realsnake[Snake.realsnake.Count - 1].Location_x;
      int y = Snake.realsnake[Snake.realsnake.Count - 1].Location_y;
      if (!(x <= 500 && x >= 0 && y <= 500 && y >= 0))
      {
        GameOver();
        timer2.Enabled = false;
      }
    }
    public void GameOver()
    {
      label3.Visible = true;
      label4.Visible = true;
      label5.Text = score.ToString();
      label5.Visible = true;
      button1.Text = "éæ°å¼å§";
      button1.Visible = true;
      stopListen();
    }
    public void EatFood()
    {
      if (Snake.realsnake[Snake.realsnake.Count - 1].Location_x == foodx
        && Snake.realsnake[Snake.realsnake.Count - 1].Location_y == foody)
      {
        newfood();
        Snake.EatLong();
        score += 1;
      }
    }
    public void newfood()
    {
      Food food = new Food();
      foodx = food.Location_x;
      foody = food.Location_y;
    }
    public void button1_Click(object sender, EventArgs e)
    {
      Snake.Snakestart();
      newfood();
      score = 0;
      timer1.Enabled = true;
      timer2.Enabled = true;
      button1.Visible = false;
      label3.Visible = false;
      label4.Visible = false;
      label5.Visible = false;
      startListen();
    }
    private void hook_KeyDown(object sender, KeyEventArgs e)
    {
      //  è¿éåå ·ä½å®ç°
      if (e.KeyCode.Equals(Keys.W)&&lastKey!=2)
      {
        lastKey = 8;
        Snake.wasd = 8;
      }
      if (e.KeyCode.Equals(Keys.S) && lastKey!=8)
      {
        lastKey = 2;
        Snake.wasd = 2;
      }
      if (e.KeyCode.Equals(Keys.A) && lastKey!=6)
      {
        lastKey = 4;
        Snake.wasd = 4;
      }
      if (e.KeyCode.Equals(Keys.D) && lastKey!=4)
      {
        lastKey = 6;
        Snake.wasd = 6;
      }
    }
    /// <summary>
    /// å¼å§çå¬
    /// </summary>
    public void startListen()
    {
      Â
      myKeyEventHandeler = new KeyEventHandler(hook_KeyDown);
      Â
      k_hook.KeyDownEvent += myKeyEventHandeler;//é©ä½é®æä¸
      k_hook.Start();//å®è£ é®çé©å
    }
    /// <summary>
    /// ç»æçå¬
    /// </summary>
    public void stopListen()
    {
      if (myKeyEventHandeler != null)
      {
        k_hook.KeyDownEvent -= myKeyEventHandeler;//åæ¶æé®äºä»¶
        myKeyEventHandeler = null;
        k_hook.Stop();//å ³éé®çé©å
      }
    }
  }
}
Â
Snake.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace è´ªåè
{
  public class Snake
  {
    public int Location_x;//0为xï¼1为y
    public int Location_y;
    public static int width = 10, height = 10;
    public static List<Snake> realsnake = new List<Snake>();
    //å½åæ¹å
    public static int wasd;
    public Snake()
    {
      Location_x = 250;
      Location_y = 250;
    }
    public static void Snakestart()
    {
      wasd = 6;
      realsnake.Clear();
      Snake s0 = new Snake();
      Snake s1 = new Snake();
      Snake s2 = new Snake();
      Snake s3 = new Snake();
      realsnake.Add(s0);
      s1.Location_x = s0.Location_x - 10;
      realsnake.Add(s1);
      s2.Location_x = s1.Location_x - 10;
      realsnake.Add(s2);
      s3.Location_x = s2.Location_x - 10;
      realsnake.Add(s3);
      //æ·»å å个é¿åº¦ï¼æ¨ªåæ·»å list åå§åå°èèå®æ
    }
    public static void SnakeMove(int x)//8426
    {
      int i = realsnake.Count - 1;
      if (x == 8)
      {
        //对listè身è¿è¡å¤ç
        Snakelist();
        realsnake[i].Location_y -= 10;
      }
      else if (x == 4)
      {
        Snakelist();
        realsnake[i].Location_x -= 10;
      }
      else if (x == 2)
      {
        Snakelist();
        realsnake[i].Location_y += 10;
      }
      else if (x == 6)
      {
        Snakelist();
        realsnake[i].Location_x += 10;
      }
    }
    public static void Snakelist()
    {
      int j = 0;
      int x, y;
      int i = realsnake.Count - 1; Â
      for (j = 0; j < i; j++)
      {
        x = realsnake[j + 1].Location_x;
        y = realsnake[j + 1].Location_y;
        realsnake[j].Location_y = y;
        realsnake[j].Location_x = x;
      }
    }
    public static void EatLong()
    {
      Snake S_eat = new Snake();
      int xx = realsnake[realsnake.Count - 1].Location_x;
      int yy = realsnake[realsnake.Count - 1].Location_y;
      if (wasd == 8)
      {
        S_eat.Location_y = yy - 10;
        S_eat.Location_x = xx;
        realsnake.Add(S_eat);
      }
      else if (wasd == 4)
      {
        S_eat.Location_x = xx - 10;
        S_eat.Location_y = yy;
        realsnake.Add(S_eat);
      }
      else if (wasd == 2)
      {
        S_eat.Location_y = yy + 10;
        S_eat.Location_x = xx;
        realsnake.Add(S_eat);
      }
      else if (wasd == 6)
      {
        S_eat.Location_y = yy;
        S_eat.Location_x = xx + 10;
        realsnake.Add(S_eat);
      }
    }
  }
}
Â
Food.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace è´ªåè
{
  public class Food
  {
    public int Location_x;
    public int Location_y;
    public Food()
    {
      Random x = new Random();
      Random y = new Random();
      Location_x = x.Next(0, 49) * 10;
      Location_y = y.Next(0, 49) * 10;
    }
  }
}
Â
KeyboardHook
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace è´ªåè
{
  class KeyboardHook
  {
    public event KeyEventHandler KeyDownEvent;
    public event KeyPressEventHandler KeyPressEvent;
    public event KeyEventHandler KeyUpEvent;
    public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
    static int hKeyboardHook = 0; //声æé®çé©åå¤ççåå§å¼
                   //å¼å¨Microsoft SDKçWinuser.héæ¥è¯¢
    public const int WH_KEYBOARD_LL = 13;  //线ç¨é®çé©åçå¬é¼ æ æ¶æ¯è®¾ä¸º2ï¼å ¨å±é®ççå¬é¼ æ æ¶æ¯è®¾ä¸º13
    HookProc KeyboardHookProcedure; //声æKeyboardHookProcedureä½ä¸ºHookProcç±»å
                    //é®çç»æ
    [StructLayout(LayoutKind.Sequential)]
    public class KeyboardHookStruct
    {
      public int vkCode;  //å®ä¸ä¸ªèæé®ç ã该代ç å¿ é¡»æä¸ä¸ªä»·å¼çèå´1è³254
      public int scanCode; // æå®ç硬件æ«æç çå ³é®
      public int flags;  // é®æ å¿
      public int time; // æå®çæ¶é´æ³è®°çè¿ä¸ªè®¯æ¯
      public int dwExtraInfo; // æå®é¢å¤ä¿¡æ¯ç¸å ³çä¿¡æ¯
    }
    //使ç¨æ¤åè½ï¼å®è£ äºä¸ä¸ªé©å
    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
    public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
    //è°ç¨æ¤å½æ°å¸è½½é©å
    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
    public static extern bool UnhookWindowsHookEx(int idHook);
    //使ç¨æ¤åè½ï¼éè¿ä¿¡æ¯é©å继ç»ä¸ä¸ä¸ªé©å
    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
    public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);
    // åå¾å½å线ç¨ç¼å·ï¼çº¿ç¨é©åéè¦ç¨å°ï¼
    [DllImport("kernel32.dll")]
    static extern int GetCurrentThreadId();
    //使ç¨WINDOWS APIå½æ°ä»£æ¿è·åå½åå®ä¾çå½æ°,é²æ¢é©å失æ
    [DllImport("kernel32.dll")]
    public static extern IntPtr GetModuleHandle(string name);
    public void Start()
    {
      // å®è£ é®çé©å
      if (hKeyboardHook == 0)
      {
        KeyboardHookProcedure = new HookProc(KeyboardHookProc);
        hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, GetModuleHandle(System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName), 0);
        //hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);
        //************************************
        //é®ç线ç¨é©å
        SetWindowsHookEx(13, KeyboardHookProcedure, IntPtr.Zero, GetCurrentThreadId());//æå®è¦çå¬ç线ç¨idGetCurrentThreadId(),
                                                //é®çå ¨å±é©å,éè¦å¼ç¨ç©ºé´(using System.Reflection;)
                                                //SetWindowsHookEx( 13,MouseHookProcedure,Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]),0);
                                                //
                                                //å ³äºSetWindowsHookEx (int idHook, HookProc lpfn, IntPtr hInstance, int threadId)å½æ°å°é©åå å ¥å°é©åé¾è¡¨ä¸ï¼è¯´æä¸ä¸å个åæ°ï¼
                                                //idHook é©åç±»åï¼å³ç¡®å®é©åçå¬ä½ç§æ¶æ¯ï¼ä¸é¢ç代ç ä¸è®¾ä¸º2ï¼å³çå¬é®çæ¶æ¯å¹¶ä¸æ¯çº¿ç¨é©åï¼å¦ææ¯å ¨å±é©åçå¬é®çæ¶æ¯åºè®¾ä¸º13ï¼
                                                //线ç¨é©åçå¬é¼ æ æ¶æ¯è®¾ä¸º7ï¼å ¨å±é©åçå¬é¼ æ æ¶æ¯è®¾ä¸º14ãlpfn é©ååç¨çå°åæéãå¦ædwThreadIdåæ°ä¸º0 ææ¯ä¸ä¸ªç±å«çè¿ç¨å建ç
                                                //线ç¨çæ è¯ï¼lpfnå¿ é¡»æåDLLä¸çé©ååç¨ã é¤æ¤ä»¥å¤ï¼lpfnå¯ä»¥æåå½åè¿ç¨çä¸æ®µé©ååç¨ä»£ç ãé©åå½æ°çå ¥å£å°åï¼å½é©åé©å°ä»»ä½
                                                //æ¶æ¯å便è°ç¨è¿ä¸ªå½æ°ãhInstanceåºç¨ç¨åºå®ä¾çå¥æãæ è¯å å«lpfnææçåç¨çDLLãå¦æthreadId æ è¯å½åè¿ç¨å建çä¸ä¸ªçº¿ç¨ï¼èä¸å
                                                //ç¨ä»£ç ä½äºå½åè¿ç¨ï¼hInstanceå¿ é¡»ä¸ºNULLãå¯ä»¥å¾ç®åç设å®å ¶ä¸ºæ¬åºç¨ç¨åºçå®ä¾å¥æãthreaded ä¸å®è£ çé©ååç¨ç¸å ³èç线ç¨çæ è¯ç¬¦
                                                //å¦æ为0ï¼é©ååç¨ä¸ææç线ç¨å ³èï¼å³ä¸ºå ¨å±é©å
                                                //************************************
                                                //å¦æSetWindowsHookEx失败
        if (hKeyboardHook == 0)
        {
          Stop();
          throw new Exception("å®è£ é®çé©å失败");
        }
      }
    }
    public void Stop()
    {
      bool retKeyboard = true;
      if (hKeyboardHook != 0)
      {
        retKeyboard = UnhookWindowsHookEx(hKeyboardHook);
        hKeyboardHook = 0;
      }
      if (!(retKeyboard)) throw new Exception("å¸è½½é©å失败ï¼");
    }
    //ToAsciièè½ç转æ¢æå®çèæé®ç åé®çç¶æçç¸åºå符æå符
    [DllImport("user32")]
    public static extern int ToAscii(int uVirtKey, //[in] æå®èæå ³é®ä»£ç è¿è¡ç¿»è¯ã
                     int uScanCode, // [in] æå®ç硬件æ«æç çå ³é®é¡»ç¿»è¯æè±æãé«é¶ä½çè¿ä¸ªå¼è®¾å®çå ³é®ï¼å¦ææ¯ï¼ä¸åï¼
                     byte[] lpbKeyState, // [in] æéï¼ä»¥256åèæ°ç»ï¼å å«å½åé®ççç¶æãæ¯ä¸ªå ç´ ï¼åèï¼çæ°ç»å å«ç¶æçä¸ä¸ªå ³é®ãå¦æé«é¶ä½çåèæ¯ä¸å¥ï¼å ³é®æ¯ä¸è·ï¼æä¸ï¼ãå¨ä½æ¯ç¹ï¼å¦æ设置表æï¼å ³é®æ¯å¯¹åæ¢ãå¨æ¤åè½ï¼åªæèä½çCAPS LOCKé®æ¯ç¸å ³çãå¨åæ¢ç¶æçNUM个éåæ»å¨éå®é®è¢«å¿½ç¥ã
                     byte[] lpwTransKey, // [out] æéçç¼å²åºæ¶å°ç¿»è¯å符æå符ã
                     int fuState); // [in] Specifies whether a menu is active. This parameter must be 1 if a menu is active, or 0 otherwise.
    //è·åæé®çç¶æ
    [DllImport("user32")]
    public static extern int GetKeyboardState(byte[] pbKeyState);
    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
    private static extern short GetKeyState(int vKey);
    private const int WM_KEYDOWN = 0x100;//KEYDOWN
    private const int WM_KEYUP = 0x101;//KEYUP
    private const int WM_SYSKEYDOWN = 0x104;//SYSKEYDOWN
    private const int WM_SYSKEYUP = 0x105;//SYSKEYUP
    private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
    {
      // 侦å¬é®çäºä»¶
      if ((nCode >= 0) && (KeyDownEvent != null || KeyUpEvent != null || KeyPressEvent != null))
      {
        KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
        // raise KeyDown
        if (KeyDownEvent != null && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN))
        {
          Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
          KeyEventArgs e = new KeyEventArgs(keyData);
          KeyDownEvent(this, e);
        }
        //é®çæä¸
        if (KeyPressEvent != null && wParam == WM_KEYDOWN)
        {
          byte[] keyState = new byte[256];
          GetKeyboardState(keyState);
          byte[] inBuffer = new byte[2];
          if (ToAscii(MyKeyboardHookStruct.vkCode, MyKeyboardHookStruct.scanCode, keyState, inBuffer, MyKeyboardHookStruct.flags) == 1)
          {
            KeyPressEventArgs e = new KeyPressEventArgs((char)inBuffer[0]);
            KeyPressEvent(this, e);
          }
        }
        // é®çæ¬èµ·
        if (KeyUpEvent != null && (wParam == WM_KEYUP || wParam == WM_SYSKEYUP))
        {
          Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
          KeyEventArgs e = new KeyEventArgs(keyData);
          KeyUpEvent(this, e);
        }
      }
      //å¦æè¿å1ï¼åç»ææ¶æ¯ï¼è¿ä¸ªæ¶æ¯å°æ¤ä¸ºæ¢ï¼ä¸åä¼ éã
      //å¦æè¿å0æè°ç¨CallNextHookExå½æ°åæ¶æ¯åºäºè¿ä¸ªé©å继ç»å¾ä¸ä¼ éï¼ä¹å°±æ¯ä¼ ç»æ¶æ¯çæ£çæ¥åè
      return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
    }
    ~KeyboardHook()
    {
      Stop();
    }
  }
}
Â
æåè¿æ¯æé¨åé®é¢æªè§£å³ï¼æ¯å¦åå°èªå·±ç尾巴ä¸ä¼æ»
å·²ç»è§£å³äºæ¹åé®é®é¢
è¿æå¸æ大家å¤å¨å¨èåèªå·±è¿è¡å¦ä¹ ã