diff --git a/lib/app/pages/home/widgets/board/board_widget.dart b/lib/app/pages/home/widgets/board/board_widget.dart index dfc8af3..6be680e 100644 --- a/lib/app/pages/home/widgets/board/board_widget.dart +++ b/lib/app/pages/home/widgets/board/board_widget.dart @@ -17,40 +17,49 @@ class _BoardWidgetState extends State { @override Widget build(BuildContext context) { - return Container( - width: 400, - height: 400, - color: Colors.green, - child: Stack( - children: [ - Center( - child: StreamBuilder>( - stream: bloc.foodOut, - builder: (context, snapshot) { - if (snapshot.hasData) { - return FoodWidget( - foods: snapshot.data, - ); - } else { - return CircularProgressIndicator(); - } - }), - ), - Center( - child: StreamBuilder>( - stream: bloc.positionOut, - builder: (context, snapshot) { - if (snapshot.hasData) { - return SnakeWidget( - snake: SnakeModel(body: snapshot.data), - ); - } else { - return CircularProgressIndicator(); - } - }), - ), - ], + return GestureDetector( + onTapDown: (TapDownDetails details) => onBoardTapDown(context, details), + child: Container( + width: 400, + height: 400, + color: Colors.green, + child: Stack( + children: [ + Center( + child: StreamBuilder>( + stream: bloc.foodOut, + builder: (context, snapshot) { + if (snapshot.hasData) { + return FoodWidget( + foods: snapshot.data, + ); + } else { + return CircularProgressIndicator(); + } + }), + ), + Center( + child: StreamBuilder>( + stream: bloc.positionOut, + builder: (context, snapshot) { + if (snapshot.hasData) { + return SnakeWidget( + snake: SnakeModel(body: snapshot.data), + ); + } else { + return CircularProgressIndicator(); + } + }), + ), + ], + ), ), ); } + + void onBoardTapDown(BuildContext context, TapDownDetails details) { + final RenderBox box = context.findRenderObject(); + final Offset localOffset = box.globalToLocal(details.globalPosition); + bloc.walkByTouchPosition(localOffset.dx, 400 - localOffset.dy); + } } diff --git a/lib/app/pages/home/widgets/snake/snake_bloc.dart b/lib/app/pages/home/widgets/snake/snake_bloc.dart index cc8d41c..dd668fd 100644 --- a/lib/app/pages/home/widgets/snake/snake_bloc.dart +++ b/lib/app/pages/home/widgets/snake/snake_bloc.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'dart:math'; import 'package:bloc_pattern/bloc_pattern.dart'; @@ -13,6 +14,8 @@ class SnakeBloc extends BlocBase { Direction lastDirection; + Timer walkingTimer; + SnakeBloc(this.snake) { positionOut = position.stream; positionIn = position.sink; @@ -119,35 +122,75 @@ class SnakeBloc extends BlocBase { switch (direction) { case Direction.up: { - lastDirection = Direction.up; - updatePosition(PositionModel(0.0, snake.height)); + if (lastDirection != Direction.down) { + lastDirection = Direction.up; + updatePosition(PositionModel(0.0, snake.height)); + resetWalkingTimer(); + } } break; case Direction.down: { - lastDirection = Direction.down; - updatePosition(PositionModel( - 0.0, - -snake.height, - )); + if (lastDirection != Direction.up) { + lastDirection = Direction.down; + updatePosition(PositionModel(0.0, -snake.height)); + resetWalkingTimer(); + } } break; case Direction.left: { - lastDirection = Direction.left; - updatePosition(PositionModel(-snake.height, 0.0)); + if (lastDirection != Direction.right) { + lastDirection = Direction.left; + updatePosition(PositionModel(-snake.height, 0.0)); + resetWalkingTimer(); + } + } + break; + case Direction.right: + { + if (lastDirection != Direction.left) { + lastDirection = Direction.right; + updatePosition(PositionModel(snake.height, 0.0)); + resetWalkingTimer(); + } + } + break; + default: + } + } + + void walkByTouchPosition(double touchX, double touchY) { + switch (lastDirection) { + case Direction.up: + case Direction.down: + { + if (touchX < position.value.first.x) + walking(Direction.left); + else if (touchX > position.value.first.x) + walking(Direction.right); } break; + case Direction.left: case Direction.right: { - if (lastDirection == null) lastDirection = Direction.right; - updatePosition(PositionModel(snake.height, 0.0)); + if (touchY < position.value.first.y) + walking(Direction.down); + else if (touchY > position.value.first.y) + walking(Direction.up); } break; default: } } + void resetWalkingTimer() { + if (walkingTimer != null) + walkingTimer.cancel(); + + walkingTimer = Timer.periodic(Duration(seconds: 1), (_) => walking(lastDirection)); + } + @override void dispose() { position.close();