Matrix4Tween 无法正常工作?
Matrix4Tween not working properly?
我正在用 flutter 制作游戏,发现了这个问题。
虽然动画正确开始和结束,但如您所见 here.
它开始下降(因为矩阵中的第一个向量)但即使我将第一个向量完全相同,矩阵动画也不会做任何事情,只会在动画结束后以新状态出现。
状态代码(我删除了我认为不必要的所有内容,但如果您需要更多信息,我可以粘贴整个 class)
class _GameState extends State<GameWindow> with TickerProviderStateMixin{
static Matrix4 originalTransformation = new Matrix4.compose(
new vector.Vector3(1.0, 1.0, 1.0),
new vector.Quaternion.euler(0.0, 0.0, 0.0),
new vector.Vector3(1.0, 1.0, 1.0));
static Matrix4 animatedTransformation = new Matrix4.compose(
new vector.Vector3(5.0, 260.0, 1.0),
new vector.Quaternion.euler(0.0, 1.0, -0.7),
new vector.Vector3(0.6, 0.6, 0.6));
Matrix4 currentMatrix = originalTransformation;
@override
Widget build(BuildContext context){
return new Scaffold(
body: new Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: [
new Container(
// Applying default transformation matrix
transform: currentMatrix,
child: _buildSquares(), // Builds GridView with custom squares
),
_getFooter(), // Footer
],
),
);
}
@override
void initState(){
// Init animation tween
animationTween = new Matrix4Tween(
begin: originalTransformation,
end: animatedTransformation
);
// Init animation controller
animationController = new AnimationController(
vsync: this,
duration: new Duration(milliseconds: 800),
)..addListener((){
this.setState((){
currentMatrix = animationTween.evaluate(animationController);
});
});
}
_clickListener(){
// Trigger animation
animationController.forward(from: 0.0);
if(_squares[_currentSquareIndex].state.isClicked()){
_increaseScore();
}else{
_showGameOver();
}
}
}
所以在点击动画之后显然开始了,矩阵正在变化但不是以平滑的方式。任何想法为什么?我错过了什么吗?
一个正方形的工作示例:
import 'package:flutter/material.dart';
import 'package:vector_math/vector_math_64.dart' as vector;
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key}) : super(key: key);
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin{
static Matrix4 originalTransformation = new Matrix4.compose(
new vector.Vector3(1.0, 1.0, 1.0),
new vector.Quaternion.euler(0.0, 0.0, 0.0),
new vector.Vector3(1.0, 1.0, 1.0));
static Matrix4 animatedTransformation = new Matrix4.compose(
new vector.Vector3(5.0, 260.0, 1.0),
new vector.Quaternion.euler(0.0, 1.0, -0.7),
new vector.Vector3(0.6, 0.6, 0.6));
Matrix4 currentMatrix = originalTransformation;
AnimationController animationController;
Matrix4Tween animationTween;
@override
Widget build(BuildContext context) {
return new Scaffold(
resizeToAvoidBottomPadding: true,
body: new Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
new AnimatedBuilder(
// Pass animation controller
animation: animationController,
builder: (BuildContext context, Widget child) => new Container(
// Apply transformation
transform: animationTween.evaluate(animationController),
child: child,
),
// Passing child argument
child: new GestureDetector(
onTap: _onClick,
child: new Container(
height: 400.0,
width: 400.0,
color: Colors.red,
),
),
),
],
),
);
}
_onClick() {
// Start animation
animationController.forward(from: 0.0);
return;
}
@override
void initState() {
super.initState();
// Init tween for matrix
animationTween = new Matrix4Tween(
begin: originalTransformation,
end: animatedTransformation
);
// Init animation controller
animationController = new AnimationController(
vsync: this,
duration: new Duration(milliseconds: 800),
);
}
}
编辑:我试过像这样删除监听器并将动画传递给 AnimatedBuilder,但这也不起作用。
编辑 2:添加了一个正方形的工作示例。
将您的 Animation
传递给 AnimatedBuilder
而不是调用 addListener
。这减少了您随身携带的私有状态的数量,并允许您将 _buildSquares()
的结果用作 child
参数,这样您就不会在动画运行时重新计算每一帧上的所有内容。它应该可以提高动画的流畅度。
编辑:在下面添加了一个工作代码示例。
编辑 2:听起来你 运行 遇到了我没有遇到的错误,所以请提出问题。
编辑 3:听起来 issue 已经在 master 上修复了。
import 'package:flutter/material.dart';
import 'package:vector_math/vector_math_64.dart' as vector;
class HomeScreen extends StatefulWidget {
HomeScreenState createState() => new HomeScreenState();
}
class HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
AnimationController _controller;
@override initState() {
_controller = new AnimationController(
vsync: this, duration: const Duration(milliseconds: 300));
}
static Matrix4 originalTransformation = new Matrix4.compose(
new vector.Vector3(1.0, 1.0, 1.0),
new vector.Quaternion.euler(0.0, 0.0, 0.0),
new vector.Vector3(1.0, 1.0, 1.0));
static Matrix4 animatedTransformation = new Matrix4.compose(
new vector.Vector3(5.0, 260.0, 1.0),
new vector.Quaternion.euler(0.0, 1.0, -0.7),
new vector.Vector3(0.6, 0.6, 0.6));
Widget build(BuildContext context) {
return new Scaffold(
floatingActionButton: new FloatingActionButton(
child: new Icon(Icons.play_arrow),
onPressed: () => _controller.forward(from: 0.0),
),
body: new Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: [
new AnimatedBuilder(
builder: (BuildContext context, Widget child) {
return new Container(
color: Colors.red,
width: 100.0,
height: 100.0,
transform: new Matrix4Tween(
begin: originalTransformation,
end: animatedTransformation
).evaluate(_controller)
);
},
animation: _controller,
),
],
),
);
}
}
class ExampleApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
theme: new ThemeData(
primarySwatch: Colors.teal,
),
home: new HomeScreen(),
debugShowCheckedModeBanner: false,
);
}
}
void main() {
runApp(new ExampleApp());
}
我正在用 flutter 制作游戏,发现了这个问题。 虽然动画正确开始和结束,但如您所见 here.
它开始下降(因为矩阵中的第一个向量)但即使我将第一个向量完全相同,矩阵动画也不会做任何事情,只会在动画结束后以新状态出现。
状态代码(我删除了我认为不必要的所有内容,但如果您需要更多信息,我可以粘贴整个 class)
class _GameState extends State<GameWindow> with TickerProviderStateMixin{
static Matrix4 originalTransformation = new Matrix4.compose(
new vector.Vector3(1.0, 1.0, 1.0),
new vector.Quaternion.euler(0.0, 0.0, 0.0),
new vector.Vector3(1.0, 1.0, 1.0));
static Matrix4 animatedTransformation = new Matrix4.compose(
new vector.Vector3(5.0, 260.0, 1.0),
new vector.Quaternion.euler(0.0, 1.0, -0.7),
new vector.Vector3(0.6, 0.6, 0.6));
Matrix4 currentMatrix = originalTransformation;
@override
Widget build(BuildContext context){
return new Scaffold(
body: new Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: [
new Container(
// Applying default transformation matrix
transform: currentMatrix,
child: _buildSquares(), // Builds GridView with custom squares
),
_getFooter(), // Footer
],
),
);
}
@override
void initState(){
// Init animation tween
animationTween = new Matrix4Tween(
begin: originalTransformation,
end: animatedTransformation
);
// Init animation controller
animationController = new AnimationController(
vsync: this,
duration: new Duration(milliseconds: 800),
)..addListener((){
this.setState((){
currentMatrix = animationTween.evaluate(animationController);
});
});
}
_clickListener(){
// Trigger animation
animationController.forward(from: 0.0);
if(_squares[_currentSquareIndex].state.isClicked()){
_increaseScore();
}else{
_showGameOver();
}
}
}
所以在点击动画之后显然开始了,矩阵正在变化但不是以平滑的方式。任何想法为什么?我错过了什么吗?
一个正方形的工作示例:
import 'package:flutter/material.dart';
import 'package:vector_math/vector_math_64.dart' as vector;
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key}) : super(key: key);
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin{
static Matrix4 originalTransformation = new Matrix4.compose(
new vector.Vector3(1.0, 1.0, 1.0),
new vector.Quaternion.euler(0.0, 0.0, 0.0),
new vector.Vector3(1.0, 1.0, 1.0));
static Matrix4 animatedTransformation = new Matrix4.compose(
new vector.Vector3(5.0, 260.0, 1.0),
new vector.Quaternion.euler(0.0, 1.0, -0.7),
new vector.Vector3(0.6, 0.6, 0.6));
Matrix4 currentMatrix = originalTransformation;
AnimationController animationController;
Matrix4Tween animationTween;
@override
Widget build(BuildContext context) {
return new Scaffold(
resizeToAvoidBottomPadding: true,
body: new Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
new AnimatedBuilder(
// Pass animation controller
animation: animationController,
builder: (BuildContext context, Widget child) => new Container(
// Apply transformation
transform: animationTween.evaluate(animationController),
child: child,
),
// Passing child argument
child: new GestureDetector(
onTap: _onClick,
child: new Container(
height: 400.0,
width: 400.0,
color: Colors.red,
),
),
),
],
),
);
}
_onClick() {
// Start animation
animationController.forward(from: 0.0);
return;
}
@override
void initState() {
super.initState();
// Init tween for matrix
animationTween = new Matrix4Tween(
begin: originalTransformation,
end: animatedTransformation
);
// Init animation controller
animationController = new AnimationController(
vsync: this,
duration: new Duration(milliseconds: 800),
);
}
}
编辑:我试过像这样删除监听器并将动画传递给 AnimatedBuilder,但这也不起作用。
编辑 2:添加了一个正方形的工作示例。
将您的 Animation
传递给 AnimatedBuilder
而不是调用 addListener
。这减少了您随身携带的私有状态的数量,并允许您将 _buildSquares()
的结果用作 child
参数,这样您就不会在动画运行时重新计算每一帧上的所有内容。它应该可以提高动画的流畅度。
编辑:在下面添加了一个工作代码示例。
编辑 2:听起来你 运行 遇到了我没有遇到的错误,所以请提出问题。
编辑 3:听起来 issue 已经在 master 上修复了。
import 'package:flutter/material.dart';
import 'package:vector_math/vector_math_64.dart' as vector;
class HomeScreen extends StatefulWidget {
HomeScreenState createState() => new HomeScreenState();
}
class HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
AnimationController _controller;
@override initState() {
_controller = new AnimationController(
vsync: this, duration: const Duration(milliseconds: 300));
}
static Matrix4 originalTransformation = new Matrix4.compose(
new vector.Vector3(1.0, 1.0, 1.0),
new vector.Quaternion.euler(0.0, 0.0, 0.0),
new vector.Vector3(1.0, 1.0, 1.0));
static Matrix4 animatedTransformation = new Matrix4.compose(
new vector.Vector3(5.0, 260.0, 1.0),
new vector.Quaternion.euler(0.0, 1.0, -0.7),
new vector.Vector3(0.6, 0.6, 0.6));
Widget build(BuildContext context) {
return new Scaffold(
floatingActionButton: new FloatingActionButton(
child: new Icon(Icons.play_arrow),
onPressed: () => _controller.forward(from: 0.0),
),
body: new Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: [
new AnimatedBuilder(
builder: (BuildContext context, Widget child) {
return new Container(
color: Colors.red,
width: 100.0,
height: 100.0,
transform: new Matrix4Tween(
begin: originalTransformation,
end: animatedTransformation
).evaluate(_controller)
);
},
animation: _controller,
),
],
),
);
}
}
class ExampleApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
theme: new ThemeData(
primarySwatch: Colors.teal,
),
home: new HomeScreen(),
debugShowCheckedModeBanner: false,
);
}
}
void main() {
runApp(new ExampleApp());
}