Flutter棋类游戏控制插件chessnutdriver的使用
Flutter棋类游戏控制插件chessnutdriver的使用
chessnutdriver
是一个用于在 Flutter 应用程序中快速连接 chessnut-board
的插件。它允许开发者通过蓝牙与棋盘进行通信,并接收其事件。
截图
开始使用 chessnutdriver
添加依赖
在 pubspec.yaml
文件中添加以下依赖:
dependencies:
chessnutdriver: ^0.0.1
然后运行 flutter pub get
来获取依赖。
导入包
在 Dart 文件中导入 chessnutdriver
包:
import 'package:chessnutdriver/chessnutdriver.dart';
连接到棋盘并监听事件
以下是一个完整的示例代码,展示了如何连接到棋盘并通过蓝牙与其通信:
// 初始化蓝牙通信客户端
ChessnutCommunicationClient chessnutCommuniChessnutCommunicationClient = ChessnutCommunicationClient(
ChessnutCommunicationType.bluetooth,
(v) => flutterReactiveBle.writeCharacteristicWithResponse(write, value: v),
waitForAck: ackEnabled
);
// 订阅蓝牙读取流 A 和 B
boardBtInputStreamA = flutterReactiveBle
.subscribeToCharacteristic(readA)
.listen((list) {
chessnutCommuniChessnutCommunicationClient.handleReceive(Uint8List.fromList(list));
});
boardBtInputStreamB = flutterReactiveBle
.subscribeToCharacteristic(readB)
.listen((list) {
chessnutCommuniChessnutCommunicationClient.handleAckReceive(Uint8List.fromList(list));
});
// 初始化棋盘
ChessnutBoard nBoard = new ChessnutBoard();
await nBoard.init(chessnutCommuniChessnutCommunicationClient);
print("chessnutBoard connected");
实际操作
为了快速了解如何使用该插件,可以在以下项目中查看其实现,该项目目前尚未开源。
完整示例代码
以下是完整的示例代码,展示如何在 Flutter 中使用 chessnutdriver
插件:
import 'dart:async';
import 'dart:typed_data';
import 'package:chessnutdriver/chessnutdriver.dart';
import 'package:flutter/material.dart';
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
final _ble = FlutterReactiveBle();
final _scanner = BleScanner(ble: _ble, logMessage: print);
runApp(
MultiProvider(
providers: [
Provider.value(value: _scanner),
StreamProvider<BleScannerState>(
create: (_) => _scanner.state,
initialData: const BleScannerState(
discoveredDevices: [],
scanIsInProgress: false,
),
),
],
child: MaterialApp(
title: 'Flutter example',
home: MyApp(),
),
),
);
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key}) : super(key: key);
[@override](/user/override)
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final flutterReactiveBle = FlutterReactiveBle();
final bleReadCharacteristicA = Uuid.parse("1B7E8262-2877-41C3-B46E-CF057C562023");
final bleReadCharacteristicB = Uuid.parse("1B7E8273-2877-41C3-B46E-CF057C562023");
final bleWriteCharacteristic = Uuid.parse("1B7E8272-2877-41C3-B46E-CF057C562023");
ChessnutBoard connectedBoard;
StreamSubscription<ConnectionStateUpdate> boardBtStream;
StreamSubscription<List<int>> boardBtInputStreamA;
StreamSubscription<List<int>> boardBtInputStreamB;
bool loading = false;
bool ackEnabled = true;
void connectBle() async {
await Permission.bluetoothScan.request();
await Permission.bluetoothConnect.request();
String deviceId = await Navigator.of(context).push(MaterialPageRoute(builder: (context) => DeviceListScreen()));
setState(() {
loading = true;
});
boardBtStream = flutterReactiveBle.connectToDevice(
id: deviceId,
connectionTimeout: const Duration(seconds: 5),
).listen((e) async {
if (e.connectionState == DeviceConnectionState.connected) {
List<DiscoveredService> services = await flutterReactiveBle.discoverServices(e.deviceId);
await flutterReactiveBle.requestMtu(deviceId: deviceId, mtu: 247); // Important: Increase MTU
QualifiedCharacteristic readA;
QualifiedCharacteristic readB;
QualifiedCharacteristic write;
for (var service in services) {
for (var characteristicId in service.characteristicIds) {
if (characteristicId == bleReadCharacteristicA) {
readA = QualifiedCharacteristic(
serviceId: service.serviceId,
characteristicId: bleReadCharacteristicA,
deviceId: e.deviceId
);
}
if (characteristicId == bleReadCharacteristicB) {
readB = QualifiedCharacteristic(
serviceId: service.serviceId,
characteristicId: bleReadCharacteristicB,
deviceId: e.deviceId
);
}
if (characteristicId == bleWriteCharacteristic) {
write = QualifiedCharacteristic(
serviceId: service.serviceId,
characteristicId: bleWriteCharacteristic,
deviceId: e.deviceId
);
}
}
}
ChessnutCommunicationClient chessnutCommuniChessnutCommunicationClient = ChessnutCommunicationClient(
ChessnutCommunicationType.bluetooth,
(v) => flutterReactiveBle.writeCharacteristicWithResponse(write, value: v),
waitForAck: ackEnabled
);
boardBtInputStreamA = flutterReactiveBle
.subscribeToCharacteristic(readA)
.listen((list) {
chessnutCommuniChessnutCommunicationClient.handleReceive(Uint8List.fromList(list));
});
boardBtInputStreamB = flutterReactiveBle
.subscribeToCharacteristic(readB)
.listen((list) {
chessnutCommuniChessnutCommunicationClient.handleAckReceive(Uint8List.fromList(list));
});
// connect to board and initialize
ChessnutBoard nBoard = new ChessnutBoard();
await nBoard.init(chessnutCommuniChessnutCommunicationClient);
print("chessnutBoard connected");
// set connected board
setState(() {
connectedBoard = nBoard;
loading = false;
});
}
});
}
Map<String, String> lastData;
LEDPattern ledpattern = LEDPattern();
void toggleLed(String square) {
ledpattern.setSquare(square, !ledpattern.getSquare(square));
connectedBoard.setLEDs(ledpattern);
setState(() {});
}
void disconnectBle() {
boardBtInputStreamA.cancel();
boardBtInputStreamB.cancel();
boardBtStream.cancel();
setState(() {
boardBtInputStreamA = null;
boardBtInputStreamB = null;
boardBtStream = null;
connectedBoard = null;
});
}
void testLeds() async {
LEDPattern pattern;
for (var square in ChessnutProtocol.squares) {
pattern = LEDPattern();
pattern.setSquare(square, true);
await connectedBoard.setLEDs(pattern);
}
}
[@override](/user/override)
Widget build(BuildContext context) {
double width = MediaQuery.of(context).size.width;
return Scaffold(
appBar: AppBar(
title: Text("chessnutdriver example"),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Checkbox(value: ackEnabled, onChanged: connectedBoard == null ? (state) => setState(() => ackEnabled = state) : null),
SizedBox(width: 4),
Text("Enable Acks"),
],
),
Center(child: TextButton(
child: Text(connectedBoard == null ? "Try to connect to board (BLE)" : (boardBtStream != null ? "Disconnect" : "")),
onPressed: !loading && connectedBoard == null ? connectBle : (boardBtStream != null && !loading ? disconnectBle : null),
)),
Center(child: TextButton(
child: Text("Test LEDS"),
onPressed: !loading && connectedBoard != null ? testLeds : null,
)),
Center(
child: StreamBuilder(
stream: connectedBoard?.getBoardUpdateStream(),
builder: (context, AsyncSnapshot<Map<String, String>> snapshot) {
if (!snapshot.hasData && lastData == null) return Text("- no data -");
Map<String, String> fieldUpdate = snapshot.data ?? lastData;
lastData = fieldUpdate;
List<Widget> rows = [];
for (var i = 0; i < 8; i++) {
List<Widget> cells = [];
for (var j = 0; j < 8; j++) {
MapEntry<String, String> entry = fieldUpdate.entries.toList()[i * 8 + j];
cells.add(
TextButton(
onPressed: () => toggleLed(entry.key),
style: TextButton.styleFrom(
padding: EdgeInsets.zero,
minimumSize: Size(width / 8 - 4, width / 8 - 4),
alignment: Alignment.centerLeft
),
child: Container(
padding: EdgeInsets.only(bottom: 2),
width: width / 8 - 4,
height: width / 8 - 4,
child: DecoratedBox(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(2),
color: ledpattern.getSquare(entry.key) ? Colors.blueAccent : Colors.black54,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(entry.key, style: TextStyle(color: Colors.white)),
Text(entry.value ?? ".", style: TextStyle(color: Colors.white, fontSize: 8)),
],
)
),
),
)
);
}
rows.add(Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: cells,
));
}
return Column(
children: rows,
);
}
),
),
],
),
);
}
}
更多关于Flutter棋类游戏控制插件chessnutdriver的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter棋类游戏控制插件chessnutdriver的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
chessnut_driver
是一个用于在 Flutter 应用中控制棋类游戏的插件,特别是针对 Chessnut 智能棋盘。它允许开发者通过蓝牙与 Chessnut 棋盘进行通信,获取棋子的移动信息并发送反馈。以下是如何使用 chessnut_driver
插件的基本步骤:
1. 添加依赖
首先,在 pubspec.yaml
文件中添加 chessnut_driver
依赖:
dependencies:
flutter:
sdk: flutter
chessnut_driver: ^1.0.0 # 请确保使用最新版本
然后运行 flutter pub get
来安装依赖。
2. 初始化 ChessnutDriver
在你的 Flutter 应用中,首先需要初始化 ChessnutDriver
:
import 'package:chessnut_driver/chessnut_driver.dart';
ChessnutDriver chessnutDriver = ChessnutDriver();
3. 扫描并连接设备
使用 chessnutDriver
扫描附近的 Chessnut 设备并连接:
void scanAndConnect() async {
// 扫描设备
List<BluetoothDevice> devices = await chessnutDriver.scanDevices();
// 假设我们选择第一个设备
if (devices.isNotEmpty) {
BluetoothDevice device = devices.first;
// 连接设备
bool isConnected = await chessnutDriver.connect(device);
if (isConnected) {
print("Connected to ${device.name}");
} else {
print("Failed to connect");
}
}
}
4. 监听棋子移动
连接成功后,你可以监听棋子的移动事件:
void listenToMoves() {
chessnutDriver.onMove.listen((move) {
print("Move detected: ${move.from} to ${move.to}");
// 在这里处理移动逻辑,例如更新棋盘状态
});
}
5. 发送反馈
你可以通过 chessnutDriver
向 Chessnut 棋盘发送反馈,例如点亮 LED 灯:
void sendFeedback() async {
// 例如,点亮 A1 位置的 LED
bool success = await chessnutDriver.sendFeedback('A1', LedColor.red);
if (success) {
print("Feedback sent successfully");
} else {
print("Failed to send feedback");
}
}
6. 断开连接
当不再需要连接时,记得断开连接:
void disconnect() async {
await chessnutDriver.disconnect();
print("Disconnected");
}
7. 处理错误
在使用过程中,可能会遇到一些错误,例如连接失败或通信中断。你可以通过监听错误流来处理这些情况:
void handleErrors() {
chessnutDriver.onError.listen((error) {
print("Error occurred: $error");
// 在这里处理错误逻辑
});
}
8. 完整示例
以下是一个简单的完整示例,展示了如何扫描、连接、监听移动并发送反馈:
import 'package:flutter/material.dart';
import 'package:chessnut_driver/chessnut_driver.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: ChessnutExample(),
);
}
}
class ChessnutExample extends StatefulWidget {
[@override](/user/override)
_ChessnutExampleState createState() => _ChessnutExampleState();
}
class _ChessnutExampleState extends State<ChessnutExample> {
ChessnutDriver chessnutDriver = ChessnutDriver();
[@override](/user/override)
void initState() {
super.initState();
scanAndConnect();
listenToMoves();
handleErrors();
}
void scanAndConnect() async {
List<BluetoothDevice> devices = await chessnutDriver.scanDevices();
if (devices.isNotEmpty) {
BluetoothDevice device = devices.first;
bool isConnected = await chessnutDriver.connect(device);
if (isConnected) {
print("Connected to ${device.name}");
} else {
print("Failed to connect");
}
}
}
void listenToMoves() {
chessnutDriver.onMove.listen((move) {
print("Move detected: ${move.from} to ${move.to}");
// 在这里处理移动逻辑
});
}
void sendFeedback() async {
bool success = await chessnutDriver.sendFeedback('A1', LedColor.red);
if (success) {
print("Feedback sent successfully");
} else {
print("Failed to send feedback");
}
}
void handleErrors() {
chessnutDriver.onError.listen((error) {
print("Error occurred: $error");
// 在这里处理错误逻辑
});
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Chessnut Example"),
),
body: Center(
child: ElevatedButton(
onPressed: sendFeedback,
child: Text("Send Feedback"),
),
),
);
}
}