• SilverXna初体验:通用键盘输入设备


    继承上一节的设计思路,本节我们来补全SilverXna键盘输入设备的实现。

    首先依然是常量和枚举定义:

    InputTypes.cs
    /*-------------------------------------

    代码清单:InputTypes.cs
    来自:
    http://www.cnblogs.com/kenkao

    -------------------------------------
    */

    using System;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;

    namespace Microsoft.Xna.Framework.Input
    {
        // 鼠标设备动作
        public enum MouseAction
        {
            None,

            MouseLeftButtonDown,
            MouseLeftButtonUp,
            MouseRightButtonDown,
            MouseRightButtonUp,

            LostMouseCapture,
            MouseEnter,
            MouseLeave,
            MouseMove,

            MouseWheel
        }

        // 键盘设备动作
        public enum KeyboardAction
        {
            None,

            KeyDown,
            KeyUp
        }

        // 鼠标键状态
        public enum ButtonState
        {
            Released = 0,
            Pressed = 1
        }

        // 键盘键状态
        public enum KeyState
        {
            Up = 0,
            Down = 1
        }

        // 鼠标设备委托定义
        public delegate void MouseButtonHandler(MouseAction act, MouseButtonEventArgs e);
        public delegate void MouseCommonHandler(MouseAction act, MouseEventArgs e);
        public delegate void MouseWheelHandler(MouseAction act, MouseWheelEventArgs e);

        // 键盘设备委托定义
        public delegate void KeyboardHandler(KeyboardAction act, KeyEventArgs e);
    }

    接下来是键盘设备状态的定义,思路仿前一节的MouseState,参看Xna内部的定义亦可:

    KeyboardState.cs
    /*-------------------------------------

    代码清单:KeyboardState.cs
    来自:
    http://www.cnblogs.com/kenkao

    -------------------------------------
    */

    using System;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;

    namespace Microsoft.Xna.Framework.Input
    {
        /// <summary>
        
    /// 键盘设备状态
        
    /// </summary>
        public class KeyboardState
        {
            // 键位状态缓冲数组
            KeyState[] _KeyStateBuffer;

            // 构造函数
            public KeyboardState(KeyState[] KeyStateBuffer)
            {
                _KeyStateBuffer = KeyStateBuffer;
            }

            // 获得单键状态
            public KeyState this[Key key]
            {
                get
                {
                    return _KeyStateBuffer[(int)key];
                }
            }

            // 检测单键是否按下
            public bool IsKeyDown(Key key)
            {
                return _KeyStateBuffer[(int)key] == KeyState.Down;
            }

            // 检测单键是否弹起
            public bool IsKeyUp(Key key)
            {
                return _KeyStateBuffer[(int)key] == KeyState.Up;
            }

            // 重载 != 运算符
            public static bool operator !=(KeyboardState a, KeyboardState b)
            {
                return !(a == b);
            }

            // 重载 == 运算符
            public static bool operator ==(KeyboardState a, KeyboardState b)
            {
                return a._KeyStateBuffer == b._KeyStateBuffer;
            }
        }
    }

    之后我们收集Silverlight控件的键盘响应事件,还原键盘设备输入状态即可。

    Silverlight控件通用的键盘事件只有键位按下与弹起两种,因此实现起来相对简单。我们只需侦听并存储256个键位全部的按下和弹起状态即可。

    KeyboardInput.cs
    /*-------------------------------------

    代码清单:KeyboardInput.cs
    来自:
    http://www.cnblogs.com/kenkao

    -------------------------------------
    */

    using System;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;

    namespace Microsoft.Xna.Framework.Input
    {
        public class KeyboardInput
        {
            // 256个键位状态
            static KeyState[] _KeyStateBuffer = new KeyState[256];

            // 监听根容器
            static UIElement _Handle;
            static public UIElement Handle
            { get { return _Handle; } }

            // 键盘事件定义
            static public event KeyboardHandler KeyboardEvent;

            // 初始化键盘输入设备
            static public void InitDevice(UIElement handle)
            {
                _Handle = handle;
                _Handle.KeyDown += new KeyEventHandler(_Handle_KeyDown);
                _Handle.KeyUp += new KeyEventHandler(_Handle_KeyUp);
            }

            // 获得键盘设备状态
            static public KeyboardState GetState()
            {
                return new KeyboardState((KeyState[])_KeyStateBuffer.Clone());
            }

            // 设备内置键位按下事件处理
            static void _Handle_KeyDown(object sender, KeyEventArgs e)
            {
                // 重置键位状态
                int KeyIndex = (int)e.Key;
                _KeyStateBuffer[KeyIndex] = KeyState.Down;
                // 支持外链键位按下事件
                if (KeyboardEvent != null)
                    KeyboardEvent.Invoke(KeyboardAction.KeyDown, e);
            }

            // 设备内置键位弹起事件
            static void _Handle_KeyUp(object sender, KeyEventArgs e)
            {
                // 重置键位状态
                int KeyIndex = (int)e.Key;
                _KeyStateBuffer[KeyIndex] = KeyState.Up;
                // 支持外链键位弹起事件
                if (KeyboardEvent != null)
                    KeyboardEvent.Invoke(KeyboardAction.KeyUp, e);
            }
        }
    }

    思路上完全仿上一节的MouseInput。然后我们将Silverlight默认根容器捆绑给构建好的键盘输入设备。

    /*-------------------------------------

    代码清单:MainPage.xaml.cs
    来自:
    http://www.cnblogs.com/kenkao

    -------------------------------------
    */

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media.Animation;
    using System.Windows.Media.Imaging;
    using System.Windows.Shapes;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;

    namespace SilverXna
    {
        public partial class MainPage : UserControl
        {
            Game _Game;
            public MainPage()
            {
                InitializeComponent();
                _Game = new Game(_GameSurface);
                // 初始化键盘、鼠标输入设备
                KeyboardInput.InitDevice(this);
                MouseInput.InitDevice(this);
            }
        }
    }

    最后是我们的主体代码:

    Game.cs
    /*-------------------------------------

    代码清单:Game.cs
    来自:
    http://www.cnblogs.com/kenkao

    -------------------------------------
    */

    using System;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media.Imaging;
    using System.Windows.Media.Animation;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;
    using System.IO;

    namespace SilverXna
    {
        public class Game : SilverGame
        {
            SpriteBatch _SpriteBatch;
            Texture2D texture;

            public Game(DrawingSurface GameSurface)
                : base(GameSurface)
            { }

            public override void Initialize()
            {
                base.Initialize();
            }

            public override void LoadContent()
            {
                _SpriteBatch = new SpriteBatch(this);

                Stream imageStream = Content.OpenResourceStream("SilverXna","Content/SLXNA.png");
                texture = Content.LoadTexture2D(imageStream);
                base.LoadContent();
            }

            public override void UnloadContent()
            {
                base.UnloadContent();
            }

            Vector2 pos = new Vector2(100100);
            public override void Update(TimeSpan DeltaTime, TimeSpan TotalTime)
            {
                // 获得鼠标设备状态
                MouseState mouseState = MouseInput.GetState();
                // 更新纹理位置到鼠标左键单击点
                if (mouseState.LeftButton == ButtonState.Pressed)
                {
                    pos = new Vector2((float)mouseState.X, (float)mouseState.Y);
                }
                // 获得键盘设备状态
                KeyboardState keyboardState = KeyboardInput.GetState();
                // 如果D键按下,则纹理向右移动一个像素
                if (keyboardState.IsKeyDown(Key.D))
                {
                    pos = new Vector2(pos.X+1, pos.Y);
                }
                base.Update(DeltaTime, TotalTime);
            }

            public override void Draw(TimeSpan DeltaTime, TimeSpan TotalTime)
            {
                GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, new Color(100149237255), 1.0f0);

                _SpriteBatch.Begin(BlendState.AlphaBlend);
                _SpriteBatch.Draw(texture, pos, new Color(255255255255));
                _SpriteBatch.End();

                base.Draw(DeltaTime, TotalTime);
            }
        }
    }

    D键按下时,纹理会缓慢右移。当然,如果大家高兴的话,还可以自行实现W、A、S键的位移效果。

    以上两节没有太多的难点,但却充当着重要的基础作用,建议大家自行理解并掌握。

    以上,谢谢 ^ ^





  • 相关阅读:
    linux内核同步机制相关收集
    【转载】关于终端和控制台的一些解释
    【转】linux内核调试方法总结
    misc汇总
    关于proc的介绍,比较详细
    linux内核启动流程分析
    linux通用中断子系统介绍
    ftrace在mips上的验证
    线程死锁demo
    BeanFactory与FactoryBean
  • 原文地址:https://www.cnblogs.com/kenkao/p/2286742.html
Copyright © 2020-2023  润新知