以下是我试图使用flutter为Android构建的游戏图像:
Male body with tags naming body parts
以下是我编写的代码,现在它已经硬编码为Google像素,用于纵向模式
Map _decoded;
List oldData=[];
int i=0;
class IdentifyGame extends StatefulWidget {
Function onScore;
Function onProgress;
Function onEnd;
int iteration;
bool isRotated;
IdentifyGame(
{key,
this.onScore,
this.onProgress,
this.onEnd,
this.iteration,
this.isRotated = false})
: super(key: key);
@override
State createState() => new _IdentifyGameState();
}
class _IdentifyGameState extends State
with SingleTickerProviderStateMixin {
double x1 = 0.0,
y1 = 0.0,
x2 = 0.0,
y2 = 0.0,
x3 = 0.0,
y3 = 0.0,
x4 = 0.0,
y4 = 0.0,
x5 = 0.0,
y5 = 0.0,
x6 = 0.0,
y6 = 0.0,
String paste1 = '',
paste2 = '',
paste3 = '',
paste4 = '',
paste5 = '',
paste6 = '',
AnimationController _imgController;
Animation animateImage;
Future _loadGameAsset() async {
return await rootBundle.loadString("assets/imageCoordinatesInfoBody.json");
}
Future _loadGameInfo() async {
String jsonGameInfo = await _loadGameAsset();
print(jsonGameInfo);
this.setState(() {
_decoded = json.decode(jsonGameInfo);
});
print((_decoded["parts"] as List));
}
@override
void initState() {
super.initState();
this._loadGameInfo();
_imgController = new AnimationController(
duration: new Duration(
milliseconds: 800,
),
vsync: this);
animateImage =
new CurvedAnimation(parent: _imgController, curve: Curves.bounceInOut);
_imgController.forward();
SystemChrome.setPreferredOrientations(
[DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
}
_renderChoice1(String text, double X, double Y) {
setState(() {
paste1 = text;
x1 = X;
y1 = Y;
});
}
_renderChoice2(String text, double X, double Y) {
setState(() {
paste2 = text;
x2 = X;
y2 = Y;
});
}
_renderChoice3(String text, double X, double Y) {
setState(() {
paste3 = text;
x3 = X;
y3 = Y;
});
}
_renderChoice4(String text, double X, double Y) {
setState(() {
paste4 = text;
x4 = X;
y4 = Y;
});
}
_renderChoice5(String text, double X, double Y) {
setState(() {
paste5 = text;
x5 = X;
y5 = Y;
});
}
_renderChoice6(String text, double X, double Y) {
setState(() {
paste6 = text;
x6 = X;
y6 = Y;
});
}
Widget _builtButton(BuildContext context, double maxHeight, double maxWidth) {
print((_decoded["parts"] as List).length);
int j = 0;
int r = ((_decoded["parts"] as List).length / 5 +
((((_decoded["parts"] as List).length % 5) == 0) ? 0 : 1))
.toInt();
print(r);
return new ResponsiveGridView(
rows: r,
cols: 5,
children: (_decoded["parts"] as List)
.map((e) => _buildItems(j++, e, maxHeight, maxWidth))
.toList(growable: false),
);
}
List _buildPartsList() {
List partsName = [];
for (var i = 0; i (i),
part: part,
);
}
_onDragStart(BuildContext context, DragStartDetails start) {
print(start.globalPosition.toString());
}
_onDragUpdate(BuildContext context, DragUpdateDetails update) {
print(update.globalPosition.toString());
}
@override
void dispose() {
_imgController.dispose();
SystemChrome.setPreferredOrientations([]);
super.dispose();
}
@override
Widget build(BuildContext context) {
print(_buildPartsList());
Size media = MediaQuery.of(context).size;
double _height = media.height;
double _width = media.width;
print("height of screen from media is $_height ");
print("width of screen from media is $_width");
return new LayoutBuilder(builder: (context, constraint) {
return new Scaffold(
body: new Flex(
direction: Axis.vertical,
children: [
new GestureDetector(
onHorizontalDragStart: (DragStartDetails start) =>
_onDragStart(context, start),
onHorizontalDragUpdate: (DragUpdateDetails update) =>
_onDragUpdate(context, update),
onVerticalDragStart: (DragStartDetails start) =>
_onDragStart(context, start),
onVerticalDragUpdate: (DragUpdateDetails update) =>
_onDragUpdate(context, update),
child: new Container(
height: (constraint.maxHeight) * 3 / 4,
width: constraint.maxWidth,
decoration: new BoxDecoration(
color: Theme.of(context).backgroundColor,
),
child: new Stack(
fit: StackFit.passthrough,
children: [
new ScaleTransition(
scale: animateImage,
child: new Image(
image: AssetImage('assets/' + _decoded["id"]),
fit: BoxFit.contain,
),
),
new RepaintBoundary(
child: new CustomPaint(
painter: new Stickers(
text: paste1,
x: x1,
y: y1,
height: _height,
width: _width),
),
),
new RepaintBoundary(
child: new CustomPaint(
painter: new Stickers(
text: paste2,
x: x2,
y: y2,
height: _height,
width: _width),
),
),
new RepaintBoundary(
child: new CustomPaint(
painter: new Stickers(
text: paste3,
x: x3,
y: y3,
height: _height,
width: _width),
),
),
new RepaintBoundary(
child: new CustomPaint(
painter: new Stickers(
text: paste4,
x: x4,
y: y4,
height: _height,
width: _width),
),
),
new RepaintBoundary(
child: new CustomPaint(
painter: new Stickers(
text: paste5,
x: x5,
y: y5,
height: _height,
width: _width),
),
),
new RepaintBoundary(
child: new CustomPaint(
painter: new Stickers(
text: paste6,
x: x6,
y: y6,
height: _height,
width: _width),
),
),
],
)),
),
new Container(
height: (constraint.maxHeight) / 4,
width: constraint.maxWidth,
decoration: new BoxDecoration(
color: Theme.of(context).scaffoldBackgroundColor),
child: _builtButton(
context, constraint.maxHeight, constraint.maxWidth)),
],
),
);
});
}
}
class DragBox extends StatefulWidget {
var part;
double maxHeight;
double maxWidth;
Function render1;
Function render2;
Function render3;
Function render4;
Function render5;
Function render6;
Function onScore;
Function onEnd;
DragBox(
{this.onEnd,
this.onScore,
this.maxHeight,
this.maxWidth,
Key key,
this.part,
this.render1,
this.render2,
this.render3,
this.render4,
this.render5,
this.render6,})
: super(key: key);
@override
DragBoxState createState() => new DragBoxState();
}
class DragBoxState extends State with TickerProviderStateMixin {
AnimationController controller, shakeController;
Animation animation, shakeAnimation, noanimation;
// Color draggableColor;
// String draggableText;
var part;
int _flag = 0;
double maxHeight;
double maxWidth;
Function render1;
Function render2;
Function render3;
Function render4;
Function render5;
Function render6;
static List _buildPartsList() {
List partsName = [];
for (var i = 0; i data = _buildPartsList();
_onDragStart(BuildContext context, DragStartDetails start) {
RenderBox getBox = context.findRenderObject();
var local = getBox.globalToLocal(start.globalPosition);
print(local.dx.toString() + "|" + local.dy.toString());
}
_onDragUpdate(BuildContext context, DragUpdateDetails update) {
RenderBox getBox = context.findRenderObject();
var local = getBox.globalToLocal(update.globalPosition);
print(local.dx.toString() + "|" + local.dy.toString());
}
void toAnimateFunction() {
animation.addStatusListener((AnimationStatus status) {
if (status == AnimationStatus.completed) {
controller.reverse();
} else if (status == AnimationStatus.dismissed) {
controller.forward();
}
});
controller.forward();
}
void toAnimateButton() {
shakeController.forward();
}
@override
void initState() {
super.initState();
shakeController = new AnimationController(
duration: new Duration(milliseconds: 800), vsync: this);
controller = new AnimationController(
duration: new Duration(milliseconds: 80), vsync: this);
animation = new Tween(begin: -3.0, end: 3.0).animate(controller);
animation.addListener(() {
setState(() {});
});
shakeAnimation =
new CurvedAnimation(parent: shakeController, curve: Curves.easeOut);
noanimation = new Tween(begin: 0.0, end: 0.0).animate(shakeController);
part = widget.part;
maxHeight = widget.maxHeight;
maxWidth = widget.maxWidth;
render1 = widget.render1;
render2 = widget.render2;
render3 = widget.render3;
render4 = widget.render4;
render5 = widget.render5;
render6 = widget.render6;
toAnimateButton();
}
@override
void dispose() {
controller.dispose();
shakeController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
Size media = MediaQuery.of(context).size;
double _height = media.height;
double _width = media.width;
return new ScaleTransition(
scale: shakeAnimation,
child: new GestureDetector(
onHorizontalDragStart: (DragStartDetails start) =>
_onDragStart(context, start),
onHorizontalDragUpdate: (DragUpdateDetails update) =>
_onDragUpdate(context, update),
onVerticalDragStart: (DragStartDetails start) =>
_onDragStart(context, start),
onVerticalDragUpdate: (DragUpdateDetails update) =>
_onDragUpdate(context, update),
child: new Draggable(
data: part["name"],
child: new AnimatedDrag(
animation: (_flag == 0) ? noanimation : animation,
draggableColor: Theme.of(context).buttonColor,
draggableText: part["name"]),
feedback: new AnimatedFeedback(
animation: animation,
draggableColor: Theme.of(context).disabledColor,
draggableText: part["name"]),
onDraggableCanceled: (velocity, offset) {
double hRatio = ((3 * maxHeight) / (4 * part["data"]["height"]));
double wRatio = (maxWidth / part["data"]["width"]);
if (part["name"] == "face" &&
(offset.dx > 360.0 && offset.dx 140.0 && offset.dy 336.0 && offset.dx 250.0 && offset.dy 260.0 && offset.dx 300.0 && offset.dy 430.0 && offset.dx 300.0 && offset.dy 392.0 && offset.dx 620.0 && offset.dy 220.0 && offset.dx 620.0 && offset.dy animation,
this.draggableColor,
this.draggableText})
: super(key: key, listenable: animation);
final Color draggableColor;
final String draggableText;
Widget build(BuildContext context) {
Size media = MediaQuery.of(context).size;
double _height = media.height;
double _width = media.width;
final Animation animation = listenable;
return new Container(
// width: _width * 0.15,
// height: _height * 0.06,
padding: new EdgeInsets.all(
(_width > _height) ? _width * 0.01 : _width * 0.015),
color: draggableColor.withOpacity(0.5),
child: new Center(
child: new Text(
draggableText,
style: new TextStyle(
color: Theme.of(context).highlightColor,
decoration: TextDecoration.none,
fontSize: (_width > _height) ? _width * 0.015 : _width * 0.03,
),
),
),
);
}
}
class AnimatedDrag extends AnimatedWidget {
AnimatedDrag(
{Key key,
Animation animation,
this.draggableColor,
this.draggableText})
: super(key: key, listenable: animation);
final Color draggableColor;
final String draggableText;
Widget build(BuildContext context) {
Size media = MediaQuery.of(context).size;
double _height = media.height;
double _width = media.width;
final Animation animation = listenable;
double translateX = animation.value;
print("value: $translateX");
return new Transform(
transform: new Matrix4.translationValues(translateX, 0.0, 0.0),
child: new Container(
// width: _width * 0.15,
// height: _height * 0.06,
padding: new EdgeInsets.all(
(_width > _height) ? _width * 0.01 : _width * 0.015),
margin: new EdgeInsets.symmetric(
vertical: (_width > _height) ? _width * 0.005 : _width * 0.005,
horizontal: (_width > _height) ? _width * 0.005 : _width * 0.005,
),
color: draggableColor,
child: new Center(
child: new Text(
draggableText,
style: new TextStyle(
color: Theme.of(context).hintColor,
decoration: TextDecoration.none,
fontSize: (_width > _height) ? _width * 0.015 : _width * 0.03,
),
),
),
),
);
}
}
class Stickers extends CustomPainter {
Stickers({this.text, this.x, this.y, this.height, this.width});
final String text;
final double x;
final double y;
final double width;
final double height;
@override
void paint(Canvas canvas, Size size) {
TextSpan span = new TextSpan(
text: text,
style: new TextStyle(
color: Colors.black,
fontSize: (width > height) ? width * 0.015 : width * 0.03,
fontWeight: FontWeight.bold));
TextPainter tp = new TextPainter(
text: span,
textAlign: TextAlign.center,
textDirection: TextDirection.ltr);
tp.layout();
tp.paint(canvas, new Offset(x, y));
//canvas.restore();
canvas.save();
// canvas.saveLayer(rect, new Paint());
}
@override
bool shouldRepaint(Stickers oldDelegate) {
// TODO: implement shouldRepaint
if (oldDelegate.text != text) {
return true;
} else {
return false;
}
}
}
我是新手,用于将标签上带有身体部位名称的标签拖放到所显示图像上的正确位置,图像将来自数据库,并且在成功完成后会发生变化提交。现在,我正在努力使其对从数据库加载的每个图像做出响应。现在它的硬编码显示图像。任何帮助将受到高度赞赏。谢谢!