Skip to content

Commit

Permalink
ui: Implement piece animations
Browse files Browse the repository at this point in the history
  • Loading branch information
calcitem committed Oct 1, 2024
1 parent 633edae commit 5675a2c
Show file tree
Hide file tree
Showing 14 changed files with 434 additions and 150 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class DisplaySettings {
this.fontScale = 1.0,
this.boardTop = kToolbarHeight,
this.animationDuration = 0.0,
this.aiResponseDelayTime = 0.0,
@Deprecated("Deprecated.") this.aiResponseDelayTime = 0.0,
this.isPositionalAdvantageIndicatorShown = false,
this.backgroundImagePath = '',
this.isNumbersOnPiecesShown = false,
Expand Down Expand Up @@ -119,7 +119,7 @@ class DisplaySettings {
@HiveField(11)
final double boardTop;

@HiveField(12)
@HiveField(12, defaultValue: 1.0)
final double animationDuration;

@HiveField(13)
Expand All @@ -141,6 +141,7 @@ class DisplaySettings {
@HiveField(17, defaultValue: false)
final bool isFullScreen;

@Deprecated("Deprecated.")
@HiveField(18, defaultValue: 0.0)
final double aiResponseDelayTime;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ part 'package:sanmill/appearance_settings/widgets/modals/point_painting_style_mo
part 'package:sanmill/appearance_settings/widgets/pickers/background_image_picker.dart';
part 'package:sanmill/appearance_settings/widgets/pickers/piece_image_picker.dart';
part 'package:sanmill/appearance_settings/widgets/pickers/language_picker.dart';
part 'package:sanmill/appearance_settings/widgets/sliders/ai_response_delay_time_slider.dart';
part 'package:sanmill/appearance_settings/widgets/sliders/animation_duration_slider.dart';
part 'package:sanmill/appearance_settings/widgets/sliders/board_boarder_line_width_slider.dart';
part 'package:sanmill/appearance_settings/widgets/sliders/board_inner_line_width_slider.dart';
Expand Down Expand Up @@ -106,11 +105,6 @@ class AppearanceSettingsPage extends StatelessWidget {
builder: (_) => const _AnimationDurationSlider(),
);

void setAiResponseDelayTime(BuildContext context) => showModalBottomSheet(
context: context,
builder: (_) => const _AiResponseDelayTimeSlider(),
);

void setBackgroundImage(BuildContext context) => showModalBottomSheet(
context: context,
builder: (_) => const _BackgroundImagePicker(),
Expand Down Expand Up @@ -428,10 +422,6 @@ class AppearanceSettingsPage extends StatelessWidget {
titleString: S.of(context).animationDuration,
onTap: () => setAnimationDuration(context),
),
SettingsListTile(
titleString: S.of(context).aiResponseDelayTime,
onTap: () => setAiResponseDelayTime(context),
),
],
);
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -17,46 +17,165 @@
import 'package:flutter/material.dart';

import '../../../shared/database/database.dart';
import '../mill.dart';

class AnimationManager {
AnimationManager(this.vsync) {
_initAnimation();
_initPlaceAnimation();
_initMoveAnimation();
_initRemoveAnimation();
}

final TickerProvider vsync;

late final AnimationController _animationController;
late final Animation<double> _animation;
bool allowAnimations = true;

AnimationController get animationController => _animationController;
Animation<double> get animation => _animation;
// Place Animation
late final AnimationController _placeAnimationController;
late final Animation<double> _placeAnimation;

void _initAnimation() {
// TODO: Check _initAnimation on branch master
_animationController = AnimationController(
AnimationController get placeAnimationController => _placeAnimationController;
Animation<double> get placeAnimation => _placeAnimation;

// Move Animation
late final AnimationController _moveAnimationController;
late final Animation<double> _moveAnimation;

AnimationController get moveAnimationController => _moveAnimationController;
Animation<double> get moveAnimation => _moveAnimation;

// Remove Animation
late final AnimationController _removeAnimationController;
late final Animation<double> _removeAnimation;

AnimationController get removeAnimationController =>
_removeAnimationController;
Animation<double> get removeAnimation => _removeAnimation;

void _initPlaceAnimation() {
_placeAnimationController = AnimationController(
vsync: vsync,
duration: Duration(
milliseconds: (DB().displaySettings.animationDuration * 1000).toInt(),
),
);

_placeAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
CurvedAnimation(
parent: _placeAnimationController,
curve: Curves.easeOutCubic,
),
);
}

void _initMoveAnimation() {
_moveAnimationController = AnimationController(
vsync: vsync,
duration: Duration(
seconds: DB().displaySettings.animationDuration.toInt(),
milliseconds: (DB().displaySettings.animationDuration * 1000).toInt(),
),
);

_animation =
Tween<double>(begin: 1.27, end: 1.0).animate(_animationController);
_moveAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
CurvedAnimation(
parent: _moveAnimationController,
curve: Curves.easeOutCubic,
),
);
}

void _initRemoveAnimation() {
_removeAnimationController = AnimationController(
vsync: vsync,
duration: Duration(
milliseconds: (DB().displaySettings.animationDuration * 1000).toInt(),
),
);

_removeAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
CurvedAnimation(
parent: _removeAnimationController,
curve: Curves.easeOutCubic,
),
);
}

void dispose() {
_animationController.dispose();
_placeAnimationController.dispose();
_moveAnimationController.dispose();
_removeAnimationController.dispose();
}

void resetPlaceAnimation() {
_placeAnimationController.reset();
}

void forwardPlaceAnimation() {
_placeAnimationController.forward();
}

void resetMoveAnimation() {
_moveAnimationController.reset();
}

void forwardMoveAnimation() {
_moveAnimationController.forward();
}

void resetAnimation() {
_animationController.reset();
void resetRemoveAnimation() {
_removeAnimationController.reset();
}

void forwardAnimation() {
_animationController.forward();
void forwardRemoveAnimation() {
_removeAnimationController.forward();
}

void animateToEnd() {
_animationController.animateTo(1.0);
void animatePlace() {
if (GameController().isDisposed == true) {
// TODO: See f0c1f3d5df544e5910b194b8479d956dd10fe527
//return;
}

if (allowAnimations) {
resetPlaceAnimation();
forwardPlaceAnimation();
}
}

bool isRemoveAnimationAnimating() {
if (_removeAnimationController.isAnimating) {
return true;
}
return false;
}

void animateMove() {
if (GameController().isDisposed == true) {
// TODO: See f0c1f3d5df544e5910b194b8479d956dd10fe527
//return;
}

if (allowAnimations) {
resetMoveAnimation();
forwardMoveAnimation();
}
}

void animateRemove() {
if (GameController().isDisposed == true) {
// TODO: See f0c1f3d5df544e5910b194b8479d956dd10fe527
//return;
}
if (allowAnimations) {
resetRemoveAnimation();

_removeAnimationController.addStatusListener((AnimationStatus status) {
if (status == AnimationStatus.completed) {
GameController().gameInstance.removeIndex = null;
}
});

forwardRemoveAnimation();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,9 @@ class GameController {
0) {
isEngineInDelay = true;
await Future<void>.delayed(Duration(
seconds: DB().displaySettings.aiResponseDelayTime.toInt()));
milliseconds:
(DB().displaySettings.animationDuration * 1000).toInt(),
));
isEngineInDelay = false;
}

Expand All @@ -269,11 +271,6 @@ class GameController {
loopIsFirst = false;
searched = true;

if (GameController().isDisposed == false) {
GameController().animationManager.resetAnimation();
GameController().animationManager.animateToEnd();
}

// TODO: Do not use BuildContexts across async gaps.
if (DB().generalSettings.screenReaderSupport) {
rootScaffoldMessengerKey.currentState!.showSnackBar(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,17 @@ class HistoryNavigator {

SoundManager().mute();

if (navMode == HistoryNavMode.takeBackAll ||
navMode == HistoryNavMode.takeBackN ||
navMode == HistoryNavMode.takeBack) {
GameController().animationManager.allowAnimations = false;
}

final HistoryResponse resp =
await doEachMove(navMode, number); // doMove() to index

GameController().animationManager.allowAnimations = true;

switch (resp) {
case HistoryOK():
final ExtMove? lastEffectiveMove = controller.gameRecorder.current;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,6 @@ class TapHandler {
switch (GameController().position.action) {
case Act.place:
if (GameController().position._putPiece(sq)) {
GameController().animationManager.resetAnimation();
GameController().animationManager.animateToEnd();
if (GameController().position.action == Act.remove) {
if (GameController()
.position
Expand Down Expand Up @@ -391,9 +389,6 @@ class TapHandler {
final GameResponse removeRet =
GameController().position._removePiece(sq);

//GameController().animationManager.resetAnimation();
//GameController().animationManager.animateToEnd();

switch (removeRet) {
case GameResponseOK():
ret = true;
Expand Down
1 change: 1 addition & 0 deletions src/ui/flutter_app/lib/game_page/services/engine/game.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class Game {

int? focusIndex;
int? blurIndex;
int? removeIndex;

final List<Player> players = <Player>[
Player(color: PieceColor.white, isAi: false),
Expand Down
Loading

0 comments on commit 5675a2c

Please sign in to comment.