JoyStick(游戏手柄)与C#

CH58x开发板插上电脑秒变游戏手柄?聊聊USB HID协议JoyStick描述符配置 本文详细介绍了如何利用CH58x开发板通过USB HID协议实现游戏手柄功能,包括JoyStick描述符的配置实战指南。从USB HID协议的核心要素到CH58x开发板的USB功能实战,帮助开发者快速掌握HID报告描述符编写调试技巧,实现低成本开发板变身专业游戏控制器的创新应用。 阅读详情

前言

这是我的第一篇技术博客,希望能为大家提供些有用信息。

 

概述

       前段时间有一项工作是通过游戏手柄控制云台,通过google和msdn搞定了,在这吧就总结一下吧。

问题

        对于手柄控制主要有以下几个问题

  1. 在合适的时机获取游戏手柄的输入?
  2. 一般游戏手柄都是有n个方向键和n个功能键控制的,要确认各个键的状态?

解决方案

  1. 通过windows API 中与游戏手柄相关的函数进行控制,主要是joystick系统函数,这一问题的关键点是P/Invoke调用。优点是不需要directx 支持,缺点是调用如果要想让多个窗口接受手柄输入有点麻烦(后边会详细描述)。
  2. 通过directx的directx input,Microsoft.DirectX.DirectInput命名空间下的类对joystick进行了很好的封装,在.net中用时很方便。优点使用方便,缺点需要directx支持不过这点应该不用担心,现在大部分系统安装完后应该都安装了directx

在本篇中将先介绍通过directxinput进行控制,这篇文章有些地方借鉴了codepoject上的文章点击这里可以看到

程序最终运行效果

运行效果

1.获取系统中已经连接成功的游戏手柄列表,代码如下

        public static string[] FindJoysticks(IntPtr hWnd)

        {

            string[] systemJoysticks = null;



            try

            {

                // 查找连接成功的游戏设备

                DeviceList gameControllerList = Manager.GetDevices(DeviceClass.GameControl, EnumDevicesFlags.AttachedOnly);



                // 遍历列表并获取设备名称

                if (gameControllerList.Count > 0)

                {

                    systemJoysticks = new string[gameControllerList.Count];

                    int i = 0;

                   

                    foreach (DeviceInstance deviceInstance in gameControllerList)

                    {

                        // 创建一个Device对像并获取

                        Device joystickDevice = new Device(deviceInstance.InstanceGuid);

                        joystickDevice.SetCooperativeLevel(hWnd,

                            CooperativeLevelFlags.Background |

                            CooperativeLevelFlags.NonExclusive);



                        systemJoysticks[i] = joystickDevice.DeviceInformation.InstanceName;



                        i++;

                    }

                }

            }

            catch (Exception err)

            {

                Debug.WriteLine("FindJoysticks()");

                Debug.WriteLine(err.Message);

                Debug.WriteLine(err.StackTrace);

            }



            return systemJoysticks;

        }
 
2.连接到手柄设备开始获取手柄输入
public bool AcquireJoystick(string name)

        {

            try

            {

                DeviceList gameControllerList = Manager.GetDevices(DeviceClass.GameControl, EnumDevicesFlags.AttachedOnly);

                int i = 0;

                bool found = false;

                // 查找指定名称的设备并连接到指定的窗口

                foreach (DeviceInstance deviceInstance in gameControllerList)

                {

                    if (deviceInstance.InstanceName == name)

                    {

                        found = true;

                        // 创建一个Device对象用来管理一个joystick

                        joystickDevice = new Device(deviceInstance.InstanceGuid);

                        joystickDevice.SetCooperativeLevel(hWnd,

                            CooperativeLevelFlags.Background |

                            CooperativeLevelFlags.NonExclusive);

                        break;

                    }



                    i++;

                }



                if (!found)

                    return false;



        

                //告诉directx要控制的是一个Joystick

                joystickDevice.SetDataFormat(DeviceDataFormat.Joystick);



                joystickDevice.Acquire();

             



                DeviceCaps cps = joystickDevice.Caps;

                Debug.WriteLine("Joystick Axis: " + cps.NumberAxes);

                Debug.WriteLine("Joystick Buttons: " + cps.NumberButtons);





                UpdateStatus();

            }

            catch (Exception err)

            {

                Debug.WriteLine("FindJoysticks()");

                Debug.WriteLine(err.Message);

                Debug.WriteLine(err.StackTrace);

                return false;

            }



            return true;

        }

3.获取手柄状态并管理按键的状态上放开还是按下等信息,由于从手柄获取到的信息只含方向和那个键是按下的所以要想获取某个键是否按下或弹起要进行一些处理,下面的程序逻缉大家看下应该会懂的。
  public void UpdateStatus()

        {

            Poll();

            

            int[] extraAxis = state.GetSlider();



            //获取方向键的状态,并区分左右上下以及按键的按下与放开

            if (state.X == 0)

            {

                m_joyMove.Direction = JoyDirection.LEFT;

                m_joyMove.Event = JoyEvent.WM_DOWN;

            }

            else if (state.Y == 0)

            {

                m_joyMove.Direction = JoyDirection.UP;

                m_joyMove.Event = JoyEvent.WM_DOWN;

            }

            else if (state.X == 65535)

            {

                m_joyMove.Direction = JoyDirection.RIGHT;

                m_joyMove.Event = JoyEvent.WM_DOWN;

            }

            else if (state.Y == 65535)

            {

                m_joyMove.Direction = JoyDirection.DOWN;

                m_joyMove.Event = JoyEvent.WM_DOWN;

            }

            else if (state.X == 32511 && (m_joyMove.Direction == JoyDirection.LEFT || m_joyMove.Direction == JoyDirection.RIGHT)

            && m_joyMove.Event == JoyEvent.WM_DOWN)

            {

                m_joyMove.Event = JoyEvent.WM_UP;

            }

            else if (state.Y == 32511 && (m_joyMove.Direction == JoyDirection.UP || m_joyMove.Direction == JoyDirection.DOWN)

            && m_joyMove.Event == JoyEvent.WM_DOWN)

            {

                m_joyMove.Event = JoyEvent.WM_UP;

            }

            else

            {

                m_joyMove.Direction = JoyDirection.NONE;

                m_joyMove.Event = JoyEvent.NONE;

            }

            

            // 获取按键的状态

            byte[] jsButtons = state.GetButtons();

            if (jsButtons != null)

            {

                if (m_JoyButtons == null)

                    m_JoyButtons = new JoyEvent[jsButtons.Length];



                for (int i = 0; i < jsButtons.Length; i++)

                {

                    if (jsButtons[i] >= 128)

                    {

                        m_JoyButtons[i] = JoyEvent.WM_DOWN;

                    }

                    else

                    {

                        if (m_JoyButtons[i] == JoyEvent.WM_DOWN)

                            m_JoyButtons[i] = JoyEvent.WM_UP;

                        else

                            m_JoyButtons[i] = JoyEvent.NONE;

                    }



                }

            }

        }
 
最后我想上传整个工程但找不到从哪儿上传的.
C#调用WinMM实现游戏手柄输入捕获键盘映射 游戏手柄输入是Windows桌面应用中常见的外设交互需求,其底层依赖于操作系统提供的多媒体输入API。WinMM.dll作为Windows原生支持的轻量级手柄接口,无需DirectX运行时,兼容Win7至Win11,具备低开销、高稳定、易部署的技术优势。其核心机制基于消息驱动的被动捕获模式(joySetCapture),通过窗口消息(如MM_JOY1MOVE)实时接收手柄状态,避免轮询带来的CPU占用漏帧风险。在工程实践中,需结合结构体内存布局控制、ANSI字符串编码适配、WParam/LParam二进制 阅读详情

相关推荐

C#原生开发游戏手柄:Raw Input底层接入实战

游戏手柄输入是人机交互的基础技术之一,其本质依赖操作系统提供的底层HID(Human Interface Device)设备通信机制。Windows平台通过Raw Input API将符合HID规范的各类外设——包括Xbox、PS、Switch等主流手柄——统一抽象为原始字节流报告,开发者需理解WM_INPUT消息循环、RAWINPUT结构体解析及设备热插拔管理等核心原理。该方案具备零第三方依赖、高确定性延迟、全品类兼容等技术优势,广泛应用于工业HMI、医疗模拟、无障碍辅助及VR/AR交互等对输入精度稳定

ciyinzhi8788的博客 407

c#解析游戏手柄源代码Jokstick.7z

c#解析游戏手柄源代码Jokstick.7z

C#操纵杆(JoyStick)控制例子

使用C#封装了获取游戏手柄操作信息的一些方法,这可以给大家学习,了解如何使用JoyStick,可以进行相关的参考

c# 游戏手柄控制 Joystick

C#写的游戏手柄的访问程序,并封装成windows 消息,访问非常方便。 用C#写的游戏手柄的访问程序,并封装成windows 消息,访问非常方便。

C# 摇杆设备连接,获取键值

C# 摇杆设备连接类

glmushroom的专栏 2716

[DirectX][DirectInput][JoyStick]DirectInput的JoyStick创建步骤整理

简介:DirectInput和其他DirectX组成部分一样,是通过硬件抽象层(HAL)和硬件仿真层(HEL)来实现,处理的输入设备一般包括鼠标、键盘、游戏控制杆、操作杆等。而且现在的DirectInput还能够支持力反馈设备。Step 1: Creating the DirectInput Objectcreate a single DirectInput object as o

hicoder的专栏 4526

探索游戏手柄控制的无限可能:C JoyStick 控制示例

探索游戏手柄控制的无限可能:C# JoyStick 控制示例 去发现同类优质开源项目:https://gitcode.com/ 项目介绍 在游戏开发和机器人控制等领域,游戏手柄JoyStick)作为一种常见的输入设备,其控制信息的获取和处理显得尤为重要。为了帮助开发者快速掌握这一技能,我们推出了一个使用C#封装的游戏手柄操作信息的示例代码仓库。这个项目不仅提供了完整的C#代码示例,还包含了详细的...

gitblog_09784的博客 839

C 游戏手柄控制 Joystick 资源下载介绍:项目核心功能场景

C# 游戏手柄控制 Joystick 资源下载介绍:项目核心功能场景 去发现同类优质开源项目:https://gitcode.com/ 随着游戏开发的普及,C#语言成为了游戏开发者的首选语言之一。在游戏开发中,如何实现对游戏手柄的有效控制成为了一个关键问题。本文将为您介绍一款开源项目——C# 游戏手柄控制 Joystick,该项目的核心功能是方便开发者访问游戏手柄,并将其操作封装为Windows...

gitblog_06785的博客 423

C 游戏手柄控制 Joystick 资源下载介绍

C# 游戏手柄控制 Joystick 资源下载介绍 去发现同类优质开源项目:https://gitcode.com/ 此仓库提供了一个用C#语言编写的游戏手柄控制程序,该程序能够方便地访问游戏手柄,并将其封装成Windows消息,显著简化了游戏手柄C#中的应用。 功能特点 采用C#语言编写,具有良好的兼容性和易用性。 将游戏手柄操作封装为Windows消息,方便在C#程序中调用和处理。 支持多...

gitblog_06762的博客 296

c# winform 实现北通 游戏手柄 游戏摇杆二次开发 包含视觉头盔

c# winform 实现北通 游戏手柄 游戏摇杆二次开发 包含视觉头盔基础实现视觉头盔的数据如何获取如何移植代码到自己的项目中 基础实现 在之前的文章中,描述了如何使用摇杆获取xyz轴坐标,以及游戏手柄的按键。我测试了另外两款蓝牙手柄,分别是北通游戏手柄,和某宝上找的另一个不知名的牌子。其共同特征是连接在windows10系统的电脑后,在 控制面板-硬件和声音-设备和打印机 里边会找到手柄的图标,右键点击后会有游戏控制器设置。根据测试的三款手柄来看,只要有这个游戏控制器设置,用这个程序就没问题。 如果没看

sinat_41346277的博客 3588

C#使用DirectX获取摇杆外设状态

C#监听摇杆状态 详情请看文章 https://blog.csdn.net/q771410116/article/details/136688340

C 操纵杆(JoyStick)控制例子

C# 操纵杆(JoyStick)控制例子 去发现同类优质开源项目:https://gitcode.com/ 本仓库提供了一个使用C#封装的游戏手柄JoyStick)操作信息的示例代码。通过这个例子,你可以学习如何获取游戏手柄的操作信息,并了解如何使用JoyStick进行相关开发。 资源文件描述 该资源文件名为“C#操纵杆(JoyStick)控制例子”,主要内容包括: C#代码示例:展示了如何使...

gitblog_09791的博客 561

Unity: Unity Joystick C# 源码

C# - Joystick.cs using UnityEngine; using System; using System.Collections; using System.Collections.Generic; public class Boundary { public Vector2 min = Vector2.zero; public Vector2 m

zhangbp的专栏 1506

Windows虚拟游戏手柄完全指南:vJoy从零到精通的5步配置方案

想要在Windows系统中体验专业游戏手柄的操控感,却不想购买昂贵的硬件设备?vJoy虚拟摇杆为您提供了完美的解决方案。这个开源项目让您能够在Windows 7到Windows 10系统中创建完全自定义的虚拟游戏控制器,模拟专业游戏手柄的所有功能。无论您是游戏玩家、模拟器爱好者,还是需要特殊控制方案的开发者,vJoy都能提供强大的虚拟输入支持。 ## 为什么选择vJoy虚拟游戏手柄? 在游戏

gitblog_00292的博客 215

如何在Windows上快速搭建虚拟游戏手柄系统:vJoy完整配置教程

想要在Windows系统上模拟专业游戏控制器,却不想购买昂贵的硬件设备?vJoy虚拟摇杆工具为你提供了完美的软件解决方案。这款开源工具能将你的电脑变成功能强大的虚拟游戏手柄,支持自定义按键布局、多轴控制和力反馈功能,为游戏玩家、模拟器爱好者和开发者打开了无限可能。 ## 🎯 核心功能概览:vJoy的三大技术优势 vJoy不仅仅是简单的虚拟手柄模拟器,它提供了完整的技术架构来满足不同场景的需求

gitblog_00621的博客 419

【WPF】 关于在WPF应用中使用Joystick

上个完成的项目中涉及到在WPF应用中获取到游戏摇杆的数据。本文主要针对如何在WPF应用中使用游戏摇杆做一系列介绍,以及在使用过程中可能用得到的一些小提示。 先交代一下我所使用的环境: OS: Windows 7 Ultimate。 .NET Framework 4.0。 IDE:Visual Studio 2010. 开发语言:XAML + C#; SDK:...

weixin_34407348的博客 705

C手柄编程资源下载

C#手柄编程资源下载 去发现同类优质开源项目:https://gitcode.com/ 介绍 本工程是一个针对C#手柄编程的实践项目,包含了两个项目,分别实现了对手柄按键信息的主动获取被动获取。以下是详细的资源描述: 项目一:主动获取手柄按键信息 项目利用JoyStick类,实现了对游戏手柄按键状态的主动检测。 项目二:被动获取手柄按键信息 项目通过JoyGetPos类,实现了对手...

gitblog_06796的博客 279
fedora08
博客等级 码龄19年 5粉丝 1原创
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值