Flutter游戏手柄输入插件xinput_gamepad的使用

发布于 1周前 作者 yibo5220 来自 Flutter

Flutter游戏手柄输入插件xinput_gamepad的使用

简介

xinput_gamepad 是一个用于在Flutter应用中支持XInput控制器(如Xbox手柄)的插件。它通过Win32 API与Windows系统进行交互,提供了对游戏手柄输入的处理、控制器信息获取、振动等功能。

依赖项

  • win32: 用于与Windows系统的API进行交互。
  • ffi: 用于调用C语言库,实现与Win32 API的通信。

功能

  • 轻松处理控制器输入:可以为每个按钮设置回调函数,当按钮被按下时执行相应的操作。
  • 获取控制器信息:包括电池类型、电池电量、控制器类型等。
  • 获取已连接的控制器:可以获取当前连接的手柄列表。
  • 自定义按钮映射:可以为每个控制器设置多个按钮映射。
  • 设置输入延迟和死区:可以根据需要调整输入的响应时间和灵敏度。
  • 使用振动功能:可以控制手柄的振动马达。

安装

使用Dart安装

dart pub add xinput_gamepad

使用Flutter安装

flutter pub add xinput_gamepad

示例代码

以下是一个完整的示例代码,展示了如何使用 xinput_gamepad 插件来处理游戏手柄的输入,并获取控制器信息。

import 'dart:io';
import 'package:xinput_gamepad/xinput_gamepad.dart';

void main(List<String> arguments) {
  // 启用XInput
  XInputManager.enableXInput();

  // 创建一个空的控制器列表,用于存储所有可用的控制器
  List<Controller> availableControllers = List.empty(growable: true);

  // 获取所有已连接的控制器索引
  for (int controllerIndex in ControllersManager.getIndexConnectedControllers()) {
    // 初始化控制器,并设置按钮模式为按下模式
    final Controller controller = Controller(
      index: controllerIndex, 
      buttonMode: ButtonMode.PRESS
    );

    // 为每个按钮设置回调函数
    controller.buttonsMapping = {
      ControllerButton.A_BUTTON: () => print("Controller $controllerIndex - Button A"),
      ControllerButton.B_BUTTON: () => print("Controller $controllerIndex - Button B"),
      ControllerButton.X_BUTTON: () => print("Controller $controllerIndex - Button X"),
      ControllerButton.Y_BUTTON: () => print("Controller $controllerIndex - Button Y"),
      ControllerButton.DPAD_UP: () => print("Controller $controllerIndex - DPAD UP"),
      ControllerButton.DPAD_DOWN: () => print("Controller $controllerIndex - DPAD DOWN"),
      ControllerButton.DPAD_LEFT: () => print("Controller $controllerIndex - DPAD LEFT"),
      ControllerButton.DPAD_RIGHT: () => print("Controller $controllerIndex - DPAD RIGHT"),
      ControllerButton.LEFT_SHOULDER: () => print("Controller $controllerIndex - LEFT SHOULDER"),
      ControllerButton.RIGHT_SHOULDER: () => print("Controller $controllerIndex - RIGHT SHOULDER"),
      ControllerButton.LEFT_THUMB: () {
        print("Controller $controllerIndex - LEFT THUMB");
        // 触发左摇杆时,使手柄振动3秒
        controller.vibrate(Duration(seconds: 3));
      },
      ControllerButton.RIGHT_THUMB: () => print("Controller $controllerIndex - RIGHT THUMB"),
      ControllerButton.START: () {
        // 更新并打印控制器的电池信息
        controller.updateBatteryInfo();
        print("Controller $controllerIndex informations:");
        print("Type: ${controller.capababilities.type}");
        print("Subtype: ${controller.capabilities.subType}");
        print("Flags: ${controller.capabilities.flags}");
        print("Battery type: ${controller.batteryInformation.batteryType}");
        print("Battery level: ${controller.batteryInformation.batteryLevel}");
        print("============================================================");
      },
      ControllerButton.BACK: () => exit(0)  // 按下BACK按钮退出程序
    };

    // 设置按钮组合的回调函数
    controller.buttonsCombination = {
      {ControllerButton.LEFT_SHOULDER, ControllerButton.RIGHT_SHOULDER}: () => 
        print("Controller $controllerIndex - Combination [LEFT_SHOULDER; RIGHT_SHOULDER]"),
      {ControllerButton.LEFT_THUMB, ControllerButton.RIGHT_THUMB}: () => 
        print("Controller $controllerIndex - Combination [LEFT_THUMB; RIGHT_THUMB]"),
      {ControllerButton.LEFT_SHOULDER, ControllerButton.RIGHT_SHOULDER, ControllerButton.A_BUTTON}: () => 
        print("Controller $controllerIndex - Combination [LEFT_SHOULDER; RIGHT_SHOULDER; A_BUTTON]"),
    };

    // 设置可变按键(如扳机键、摇杆)的回调函数
    controller.variableKeysMapping = {
      VariableControllerKey.LEFT_TRIGGER: (value) => print("Controller $controllerIndex - LEFT TRIGGER - $value"),
      VariableControllerKey.RIGHT_TRIGGER: (value) => print("Controller $controllerIndex - RIGHT TRIGGER - $value"),
      VariableControllerKey.THUMB_LX: (value) => print("Controller $controllerIndex - THUMB LX - $value"),
      VariableControllerKey.THUMB_LY: (value) => print("Controller $controllerIndex - THUMB LY - $value"),
      VariableControllerKey.THUMB_RX: (value) => print("Controller $controllerIndex - THUMB RX - $value"),
      VariableControllerKey.THUMB_RY: (value) => print("Controller $controllerIndex - THUMB RY - $value")
    };

    // 设置按钮释放时的回调函数
    controller.onReleaseButton = (button) => print("$button has been released");

    // 将初始化好的控制器添加到列表中
    availableControllers.add(controller);
  }

  // 打印所有可用的控制器
  print("Available controllers:");
  for (Controller controller in availableControllers) {
    print("Controller ${controller.index}");
  }

  // 开始监听所有控制器的输入
  for (Controller controller in availableControllers) {
    controller.listen();
  }
}

更多关于Flutter游戏手柄输入插件xinput_gamepad的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter游戏手柄输入插件xinput_gamepad的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter中使用xinput_gamepad插件来处理游戏手柄输入的示例代码。xinput_gamepad插件允许你在Flutter应用中读取Xbox 360或兼容的XInput游戏手柄的输入数据。

首先,确保你已经将xinput_gamepad插件添加到了你的pubspec.yaml文件中:

dependencies:
  flutter:
    sdk: flutter
  xinput_gamepad: ^x.y.z  # 替换为最新版本号

然后,运行flutter pub get来安装插件。

以下是一个基本的Flutter应用示例,展示如何使用xinput_gamepad插件来读取游戏手柄的输入数据:

import 'package:flutter/material.dart';
import 'package:xinput_gamepad/xinput_gamepad.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Gamepad Input',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: GamepadInputScreen(),
    );
  }
}

class GamepadInputScreen extends StatefulWidget {
  @override
  _GamepadInputScreenState createState() => _GamepadInputScreenState();
}

class _GamepadInputScreenState extends State<GamepadInputScreen> {
  XInputGamepad? _gamepad;

  @override
  void initState() {
    super.initState();
    _initGamepad();
  }

  void _initGamepad() async {
    try {
      _gamepad = await XInputGamepad.findFirstConnected();
      if (_gamepad != null) {
        _gamepad!.onButtonStateChanged = (buttonState) {
          // 处理按钮状态变化
          print('Button state changed: $buttonState');
        };

        _gamepad!.onAxisStateChanged = (axisState) {
          // 处理轴状态变化
          print('Axis state changed: $axisState');
        };

        // 开始监听手柄输入
        _gamepad!.startListening();
      } else {
        print('No connected gamepad found.');
      }
    } catch (e) {
      print('Error initializing gamepad: $e');
    }
  }

  @override
  void dispose() {
    _gamepad?.stopListening();
    _gamepad = null;
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Gamepad Input Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Connect an XInput compatible gamepad and see the console for input events.',
              style: TextStyle(fontSize: 18),
            ),
          ],
        ),
      ),
    );
  }
}

代码解释

  1. 依赖添加:在pubspec.yaml中添加xinput_gamepad插件。

  2. 初始化:在_initGamepad方法中,我们尝试找到第一个连接的游戏手柄,并设置按钮和轴状态变化的监听器。

  3. 监听器

    • onButtonStateChanged:当按钮状态发生变化时调用。
    • onAxisStateChanged:当轴状态发生变化时调用。
  4. 开始监听:通过调用_gamepad!.startListening()开始监听手柄输入。

  5. 资源释放:在dispose方法中,停止监听并释放资源。

  6. UI:一个简单的UI,提示用户连接游戏手柄并查看控制台输出。

确保你在Windows上运行此示例,因为xinput_gamepad插件目前主要支持Windows平台上的XInput设备。

这个示例代码展示了如何初始化和监听游戏手柄的输入数据,你可以根据需要在UI中展示这些数据或进行其他处理。

回到顶部