我试图在传感器颤振小部件的帮助下制作一个计步器,我正在查看传感器颤振包代码,但没有从哪里开始以及如何获得所需的结果。
在传感器颤振小部件的帮助下迈出一步涉及哪些事情?或者我也可以在颤振应用程序中使用 Google Fit Api 来创建自定义计步器吗?
我添加了
dependencies:
sensors: "^0.3.3"
到 pubspec.yaml
主要.dart
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:sensors/sensors.dart';
import 'snake.dart';
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Sensors Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
final String title;
MyHomePage({Key key, this.title}) : super(key: key);
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
static const int _snakeRows = 20;
static const int _snakeColumns = 20;
static const double _snakeCellSize = 10.0;
List<double> _accelerometerValues;
List<double> _userAccelerometerValues;
List<double> _gyroscopeValues;
List<StreamSubscription<dynamic>> _streamSubscriptions =
<StreamSubscription<dynamic>>[];
@override
Widget build(BuildContext context) {
final List<String> accelerometer =
_accelerometerValues?.map((double v) => v.toStringAsFixed(1))?.toList();
final List<String> gyroscope =
_gyroscopeValues?.map((double v) => v.toStringAsFixed(1))?.toList();
final List<String> userAccelerometer = _userAccelerometerValues
?.map((double v) => v.toStringAsFixed(1))
?.toList();
return new Scaffold(
appBar: new AppBar(
title: const Text('Sensor Example'),
),
body: new Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
new Center(
child: new DecoratedBox(
decoration: new BoxDecoration(
border: new Border.all(width: 1.0, color: Colors.black38),
),
child: new SizedBox(
height: _snakeRows * _snakeCellSize,
width: _snakeColumns * _snakeCellSize,
child: new Snake(
rows: _snakeRows,
columns: _snakeColumns,
cellSize: _snakeCellSize,
),
),
),
),
new Padding(
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Text('Accelerometer: $accelerometer'),
],
),
padding: const EdgeInsets.all(16.0),
),
new Padding(
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Text('UserAccelerometer: $userAccelerometer'),
],
),
padding: const EdgeInsets.all(16.0),
),
new Padding(
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Text('Gyroscope: $gyroscope'),
],
),
padding: const EdgeInsets.all(16.0),
),
],
),
);
}
@override
void dispose() {
super.dispose();
for (StreamSubscription<dynamic> subscription in _streamSubscriptions) {
subscription.cancel();
}
}
@override
void initState() {
super.initState();
_streamSubscriptions
.add(accelerometerEvents.listen((AccelerometerEvent event) {
setState(() {
_accelerometerValues = <double>[event.x, event.y, event.z];
});
}));
_streamSubscriptions.add(gyroscopeEvents.listen((GyroscopeEvent event) {
setState(() {
_gyroscopeValues = <double>[event.x, event.y, event.z];
});
}));
_streamSubscriptions
.add(userAccelerometerEvents.listen((UserAccelerometerEvent event) {
setState(() {
_userAccelerometerValues = <double>[event.x, event.y, event.z];
});
}));
}
}
蛇飞镖
import 'dart:async';
import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:sensors/sensors.dart';
class Snake extends StatefulWidget {
final int rows;
final int columns;
final double cellSize;
Snake({this.rows = 20, this.columns = 20, this.cellSize = 10.0}) {
assert(10 <= rows);
assert(10 <= columns);
assert(5.0 <= cellSize);
}
@override
State<StatefulWidget> createState() =>
new SnakeState(rows, columns, cellSize);
}
class SnakeBoardPainter extends CustomPainter {
GameState state;
double cellSize;
SnakeBoardPainter(this.state, this.cellSize);
@override
void paint(Canvas canvas, Size size) {
final Paint blackLine = new Paint()..color = Colors.black;
final Paint blackFilled = new Paint()
..color = Colors.black
..style = PaintingStyle.fill;
canvas.drawRect(
new Rect.fromPoints(Offset.zero, size.bottomLeft(Offset.zero)),
blackLine,
);
for (math.Point<int> p in state.body) {
final Offset a = new Offset(cellSize * p.x, cellSize * p.y);
final Offset b = new Offset(cellSize * (p.x + 1), cellSize * (p.y + 1));
canvas.drawRect(new Rect.fromPoints(a, b), blackFilled);
}
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
class SnakeState extends State<Snake> {
double cellSize;
GameState state;
AccelerometerEvent acceleration;
SnakeState(int rows, int columns, this.cellSize) {
state = new GameState(rows, columns);
}
@override
Widget build(BuildContext context) {
return new CustomPaint(painter: new SnakeBoardPainter(state, cellSize));
}
@override
void initState() {
super.initState();
accelerometerEvents.listen((AccelerometerEvent event) {
setState(() {
acceleration = event;
});
});
new Timer.periodic(const Duration(milliseconds: 200), (_) {
setState(() {
_step();
});
});
}
void _step() {
final math.Point<int> newDirection = acceleration == null
? null
: acceleration.x.abs() < 1.0 && acceleration.y.abs() < 1.0
? null
: (acceleration.x.abs() < acceleration.y.abs())
? new math.Point<int>(0, acceleration.y.sign.toInt())
: new math.Point<int>(-acceleration.x.sign.toInt(), 0);
state.step(newDirection);
}
}
class GameState {
int rows;
int columns;
int snakeLength;
GameState(this.rows, this.columns) {
snakeLength = math.min(rows, columns) - 5;
}
List<math.Point<int>> body = <math.Point<int>>[const math.Point<int>(0, 0)];
math.Point<int> direction = const math.Point<int>(1, 0);
void step(math.Point<int> newDirection) {
math.Point<int> next = body.last + direction;
next = new math.Point<int>(next.x % columns, next.y % rows);
body.add(next);
if (body.length > snakeLength) body.removeAt(0);
direction = newDirection ?? direction;
}
}