Skip to content
Snippets Groups Projects
Commit d073b6ad authored by Benoît Harrault's avatar Benoît Harrault
Browse files

Merge branch '76-normalize-activity-application-architecture' into 'master'

Resolve "Normalize Activity application architecture"

Closes #76

See merge request !72
parents e80df8de 5d04b26c
No related branches found
No related tags found
1 merge request!72Resolve "Normalize Activity application architecture"
Pipeline #6774 passed
Showing
with 692 additions and 47 deletions
{
"app_name": "Jigsaw puzzle",
"page_home": "Home",
"page_game": "Game",
"settings_title": "Settings",
"settings_label_theme": "Theme mode",
......
......
{
"app_name": "Puzzle",
"page_home": "Accueil",
"page_game": "Jeu",
"settings_title": "Réglages",
"settings_label_theme": "Thème de couleurs",
......
......
Normalize Activity application architecture.
Harmonisation des applications en Activity.
import 'package:flutter/material.dart';
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:puzzlegame/ui/screens/page_about.dart';
import 'package:puzzlegame/ui/screens/page_game.dart';
import 'package:puzzlegame/ui/screens/page_settings.dart';
import 'package:puzzlegame/common/ui/pages/game.dart';
import 'package:puzzlegame/common/ui/pages/parameters.dart';
class MenuItem {
class ActivityPageItem {
final String code;
final Icon icon;
final Widget page;
const MenuItem({
const ActivityPageItem({
required this.code,
required this.icon,
required this.page,
});
}
class Menu {
static const indexGame = 0;
static const menuItemGame = MenuItem(
icon: Icon(UniconsLine.home),
page: PageGame(),
);
class ActivityPage {
static const bool displayBottomNavBar = false;
static const indexSettings = 1;
static const menuItemSettings = MenuItem(
icon: Icon(UniconsLine.setting),
page: PageSettings(),
static const indexHome = 0;
static const pageHome = ActivityPageItem(
code: 'page_home',
icon: Icon(UniconsLine.home),
page: PageParameters(),
);
static const indexAbout = 2;
static const menuItemAbout = MenuItem(
icon: Icon(UniconsLine.info_circle),
page: PageAbout(),
static const indexGame = 1;
static const pageGame = ActivityPageItem(
code: 'page_game',
icon: Icon(UniconsLine.star),
page: PageGame(),
);
static Map<int, MenuItem> items = {
indexGame: menuItemGame,
indexSettings: menuItemSettings,
indexAbout: menuItemAbout,
static const Map<int, ActivityPageItem> items = {
indexHome: pageHome,
indexGame: pageGame,
};
static int defaultPageIndex = indexHome;
static bool isIndexAllowed(int pageIndex) {
return items.keys.contains(pageIndex);
}
static Widget getPageWidget(int pageIndex) {
return items[pageIndex]?.page ?? menuItemGame.page;
static Widget getWidget(int pageIndex) {
return items[pageIndex]?.page ?? pageHome.page;
}
static int itemsCount = Menu.items.length;
}
import 'package:flutter/material.dart';
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:puzzlegame/common/ui/screens/about.dart';
import 'package:puzzlegame/common/ui/screens/activity.dart';
import 'package:puzzlegame/common/ui/screens/settings.dart';
class ScreenItem {
final String code;
final Icon icon;
final Widget screen;
const ScreenItem({
required this.code,
required this.icon,
required this.screen,
});
}
class Screen {
static const indexActivity = 0;
static const screenActivity = ScreenItem(
code: 'screen_activity',
icon: Icon(UniconsLine.home),
screen: ScreenActivity(),
);
static const indexSettings = 1;
static const screenSettings = ScreenItem(
code: 'screen_settings',
icon: Icon(UniconsLine.setting),
screen: ScreenSettings(),
);
static const indexAbout = 2;
static const screenAbout = ScreenItem(
code: 'screen_about',
icon: Icon(UniconsLine.info_circle),
screen: ScreenAbout(),
);
static Map<int, ScreenItem> items = {
indexActivity: screenActivity,
indexSettings: screenSettings,
indexAbout: screenAbout,
};
static bool isIndexAllowed(int screenIndex) {
return items.keys.contains(screenIndex);
}
static Widget getWidget(int screenIndex) {
return items[screenIndex]?.screen ?? screenActivity.screen;
}
}
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:puzzlegame/config/menu.dart';
import 'package:puzzlegame/common/config/activity_page.dart';
class NavCubit extends HydratedCubit<int> {
NavCubit() : super(0);
class NavCubitPage extends HydratedCubit<int> {
NavCubitPage() : super(0);
void updateIndex(int index) {
if (Menu.isIndexAllowed(index)) {
if (ActivityPage.isIndexAllowed(index)) {
emit(index);
} else {
goToGamePage();
emit(ActivityPage.indexHome);
}
}
void goToGamePage() {
emit(Menu.indexGame);
void goToPageHome() {
updateIndex(ActivityPage.indexHome);
}
void goToSettingsPage() {
emit(Menu.indexSettings);
}
void goToAboutPage() {
emit(Menu.indexAbout);
void goToPageGame() {
updateIndex(ActivityPage.indexGame);
}
@override
int fromJson(Map<String, dynamic> json) {
return Menu.indexGame;
return ActivityPage.indexHome;
}
@override
Map<String, dynamic>? toJson(int state) {
return <String, int>{'pageIndex': state};
return <String, int>{'index': state};
}
}
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:puzzlegame/common/config/screen.dart';
class NavCubitScreen extends HydratedCubit<int> {
NavCubitScreen() : super(0);
void updateIndex(int index) {
if (Screen.isIndexAllowed(index)) {
emit(index);
} else {
goToScreenActivity();
}
}
void goToScreenActivity() {
emit(Screen.indexActivity);
}
void goToScreenSettings() {
emit(Screen.indexSettings);
}
void goToScreenAbout() {
emit(Screen.indexAbout);
}
@override
int fromJson(Map<String, dynamic> json) {
return Screen.indexActivity;
}
@override
Map<String, dynamic>? toJson(int state) {
return <String, int>{'index': state};
}
}
import 'package:flutter/material.dart';
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:puzzlegame/common/config/activity_page.dart';
import 'package:puzzlegame/common/cubit/nav/nav_cubit_pages.dart';
class BottomNavBar extends StatelessWidget {
const BottomNavBar({super.key});
@override
Widget build(BuildContext context) {
return Card(
margin: const EdgeInsets.only(top: 1, right: 4, left: 4),
elevation: 4,
shadowColor: Theme.of(context).colorScheme.shadow,
color: Theme.of(context).colorScheme.surfaceContainerHighest,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16),
),
),
child: BlocBuilder<NavCubitPage, int>(builder: (BuildContext context, int state) {
final List<BottomNavigationBarItem> items = [];
ActivityPage.items.forEach((int pageIndex, ActivityPageItem item) {
items.add(BottomNavigationBarItem(
icon: item.icon,
label: tr(item.code),
));
});
return BottomNavigationBar(
currentIndex: state,
onTap: (int index) => BlocProvider.of<NavCubitPage>(context).updateIndex(index),
type: BottomNavigationBarType.fixed,
elevation: 0,
backgroundColor: Colors.transparent,
selectedItemColor: Theme.of(context).colorScheme.primary,
unselectedItemColor: Theme.of(context).textTheme.bodySmall!.color,
items: items,
);
}),
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:puzzlegame/config/menu.dart';
import 'package:puzzlegame/cubit/game_cubit.dart';
import 'package:puzzlegame/cubit/nav_cubit.dart';
import 'package:puzzlegame/models/game/game.dart';
import 'package:puzzlegame/common/config/screen.dart';
import 'package:puzzlegame/common/cubit/nav/nav_cubit_pages.dart';
import 'package:puzzlegame/common/cubit/nav/nav_cubit_screens.dart';
import 'package:puzzlegame/cubit/activity/activity_cubit.dart';
import 'package:puzzlegame/models/activity/activity.dart';
class GlobalAppBar extends StatelessWidget implements PreferredSizeWidget {
const GlobalAppBar({super.key});
@override
Widget build(BuildContext context) {
return BlocBuilder<GameCubit, GameState>(
builder: (BuildContext context, GameState gameState) {
return BlocBuilder<NavCubit, int>(
return BlocBuilder<ActivityCubit, ActivityState>(
builder: (BuildContext context, ActivityState activityState) {
return BlocBuilder<NavCubitScreen, int>(
builder: (BuildContext context, int pageIndex) {
final Game currentGame = gameState.currentGame;
final Activity currentActivity = activityState.currentActivity;
final List<Widget> menuActions = [];
if (currentGame.isRunning && !currentGame.isFinished) {
if (currentActivity.isRunning && !currentActivity.isFinished) {
menuActions.add(StyledButton(
color: Colors.red,
onPressed: () {},
onLongPress: () {
BlocProvider.of<GameCubit>(context).quitGame();
BlocProvider.of<ActivityCubit>(context).quitActivity();
BlocProvider.of<NavCubitPage>(context).goToPageHome();
},
child: const Image(
image: AssetImage('assets/ui/button_back.png'),
......@@ -32,38 +35,38 @@ class GlobalAppBar extends StatelessWidget implements PreferredSizeWidget {
),
));
} else {
if (pageIndex == Menu.indexGame) {
if (pageIndex == Screen.indexActivity) {
// go to Settings page
menuActions.add(ElevatedButton(
onPressed: () {
BlocProvider.of<NavCubit>(context).goToSettingsPage();
BlocProvider.of<NavCubitScreen>(context).goToScreenSettings();
},
style: ElevatedButton.styleFrom(
shape: const CircleBorder(),
),
child: Menu.menuItemSettings.icon,
child: Screen.screenSettings.icon,
));
// go to About page
menuActions.add(ElevatedButton(
onPressed: () {
BlocProvider.of<NavCubit>(context).goToAboutPage();
BlocProvider.of<NavCubitScreen>(context).goToScreenAbout();
},
style: ElevatedButton.styleFrom(
shape: const CircleBorder(),
),
child: Menu.menuItemAbout.icon,
child: Screen.screenAbout.icon,
));
} else {
// back to Home page
menuActions.add(ElevatedButton(
onPressed: () {
BlocProvider.of<NavCubit>(context).goToGamePage();
BlocProvider.of<NavCubitScreen>(context).goToScreenActivity();
},
style: ElevatedButton.styleFrom(
shape: const CircleBorder(),
),
child: Menu.menuItemGame.icon,
child: Screen.screenActivity.icon,
));
}
}
......
......
import 'package:flutter/material.dart';
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:puzzlegame/cubit/game_cubit.dart';
import 'package:puzzlegame/models/game/game.dart';
import 'package:puzzlegame/cubit/activity/activity_cubit.dart';
import 'package:puzzlegame/models/activity/activity.dart';
import 'package:puzzlegame/ui/game/game_bottom.dart';
import 'package:puzzlegame/ui/game/game_end.dart';
import 'package:puzzlegame/ui/game/game_top.dart';
import 'package:puzzlegame/ui/widgets/game/game_board.dart';
class GameLayout extends StatelessWidget {
const GameLayout({super.key});
class PageGame extends StatelessWidget {
const PageGame({super.key});
@override
Widget build(BuildContext context) {
return BlocBuilder<GameCubit, GameState>(
builder: (BuildContext context, GameState gameState) {
final Game currentGame = gameState.currentGame;
return BlocBuilder<ActivityCubit, ActivityState>(
builder: (BuildContext context, ActivityState activityState) {
final Activity currentActivity = activityState.currentActivity;
return Container(
alignment: AlignmentDirectional.topCenter,
......@@ -30,7 +30,7 @@ class GameLayout extends StatelessWidget {
const SizedBox(height: 8),
const GameBottomWidget(),
const Expanded(child: SizedBox.shrink()),
currentGame.isFinished ? const GameEndWidget() : const SizedBox.shrink(),
currentActivity.isFinished ? const GameEndWidget() : const SizedBox.shrink(),
],
),
);
......
......
import 'package:flutter/material.dart';
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:puzzlegame/config/default_game_settings.dart';
import 'package:puzzlegame/common/ui/parameters/parameter_widget.dart';
import 'package:puzzlegame/config/default_activity_settings.dart';
import 'package:puzzlegame/config/default_global_settings.dart';
import 'package:puzzlegame/cubit/settings_game_cubit.dart';
import 'package:puzzlegame/cubit/settings_global_cubit.dart';
import 'package:puzzlegame/ui/parameters/parameter_widget.dart';
import 'package:puzzlegame/cubit/activity/activity_cubit.dart';
import 'package:puzzlegame/cubit/settings/settings_activity_cubit.dart';
import 'package:puzzlegame/cubit/settings/settings_global_cubit.dart';
import 'package:puzzlegame/models/activity/activity.dart';
import 'package:puzzlegame/ui/widgets/actions/button_delete_saved_game.dart';
import 'package:puzzlegame/ui/widgets/actions/button_game_start_new.dart';
import 'package:puzzlegame/ui/widgets/actions/button_resume_saved_game.dart';
class ParametersLayout extends StatelessWidget {
const ParametersLayout({super.key, required this.canResume});
final bool canResume;
class PageParameters extends StatelessWidget {
const PageParameters({super.key});
final double separatorHeight = 8.0;
@override
Widget build(BuildContext context) {
return BlocBuilder<ActivityCubit, ActivityState>(
builder: (BuildContext context, ActivityState activityState) {
final Activity currentActivity = activityState.currentActivity;
final List<Widget> lines = [];
// Game settings
for (String code in DefaultGameSettings.availableParameters) {
for (String code in DefaultActivitySettings.availableParameters) {
lines.add(Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: buildParametersLine(
......@@ -38,7 +43,7 @@ class ParametersLayout extends StatelessWidget {
child: SizedBox(height: separatorHeight),
));
if (canResume == false) {
if (currentActivity.canBeResumed == false) {
// Start new game
lines.add(
const AspectRatio(
......@@ -77,6 +82,8 @@ class ParametersLayout extends StatelessWidget {
return Column(
children: lines,
);
},
);
}
List<Widget> buildParametersLine({
......@@ -87,25 +94,25 @@ class ParametersLayout extends StatelessWidget {
final List<String> availableValues = isGlobal
? DefaultGlobalSettings.getAvailableValues(code)
: DefaultGameSettings.getAvailableValues(code);
: DefaultActivitySettings.getAvailableValues(code);
if (availableValues.length <= 1) {
return [];
}
for (String value in availableValues) {
final Widget parameterButton = BlocBuilder<GameSettingsCubit, GameSettingsState>(
builder: (BuildContext context, GameSettingsState gameSettingsState) {
final Widget parameterButton = BlocBuilder<ActivitySettingsCubit, ActivitySettingsState>(
builder: (BuildContext context, ActivitySettingsState activitySettingsState) {
return BlocBuilder<GlobalSettingsCubit, GlobalSettingsState>(
builder: (BuildContext context, GlobalSettingsState globalSettingsState) {
final GameSettingsCubit gameSettingsCubit =
BlocProvider.of<GameSettingsCubit>(context);
final ActivitySettingsCubit activitySettingsCubit =
BlocProvider.of<ActivitySettingsCubit>(context);
final GlobalSettingsCubit globalSettingsCubit =
BlocProvider.of<GlobalSettingsCubit>(context);
final String currentValue = isGlobal
? globalSettingsCubit.getParameterValue(code)
: gameSettingsCubit.getParameterValue(code);
: activitySettingsCubit.getParameterValue(code);
final bool isSelected = (value == currentValue);
......@@ -119,12 +126,12 @@ class ParametersLayout extends StatelessWidget {
value: value,
isSelected: isSelected,
size: itemWidth,
gameSettings: gameSettingsState.settings,
activitySettings: activitySettingsState.settings,
globalSettings: globalSettingsState.settings,
onPressed: () {
isGlobal
? globalSettingsCubit.setParameterValue(code, value)
: gameSettingsCubit.setParameterValue(code, value);
: activitySettingsCubit.setParameterValue(code, value);
},
),
);
......
......
......@@ -3,21 +3,21 @@ import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:puzzlegame/config/default_game_settings.dart';
import 'package:puzzlegame/models/settings/settings_game.dart';
import 'package:puzzlegame/config/default_activity_settings.dart';
import 'package:puzzlegame/models/settings/settings_activity.dart';
import 'package:puzzlegame/models/settings/settings_global.dart';
class ParameterPainter extends CustomPainter {
const ParameterPainter({
required this.code,
required this.value,
required this.gameSettings,
required this.activitySettings,
required this.globalSettings,
});
final String code;
final String value;
final GameSettings gameSettings;
final ActivitySettings activitySettings;
final GlobalSettings globalSettings;
@override
......@@ -27,7 +27,7 @@ class ParameterPainter extends CustomPainter {
// content
switch (code) {
case DefaultGameSettings.parameterCodeTilesetSize:
case DefaultActivitySettings.parameterCodeTilesetSize:
paintTilesetSizeParameterItem(canvas, canvasSize);
break;
default:
......
......
import 'package:flutter/material.dart';
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:puzzlegame/config/default_game_settings.dart';
import 'package:puzzlegame/common/ui/parameters/parameter_painter.dart';
import 'package:puzzlegame/config/default_activity_settings.dart';
import 'package:puzzlegame/config/default_global_settings.dart';
import 'package:puzzlegame/models/settings/settings_game.dart';
import 'package:puzzlegame/models/settings/settings_activity.dart';
import 'package:puzzlegame/models/settings/settings_global.dart';
import 'package:puzzlegame/ui/parameters/parameter_painter.dart';
class ParameterWidget extends StatelessWidget {
const ParameterWidget({
......@@ -14,7 +15,7 @@ class ParameterWidget extends StatelessWidget {
required this.value,
required this.isSelected,
required this.size,
required this.gameSettings,
required this.activitySettings,
required this.globalSettings,
required this.onPressed,
});
......@@ -23,7 +24,7 @@ class ParameterWidget extends StatelessWidget {
final String value;
final bool isSelected;
final double size;
final GameSettings gameSettings;
final ActivitySettings activitySettings;
final GlobalSettings globalSettings;
final VoidCallback onPressed;
......@@ -37,7 +38,7 @@ class ParameterWidget extends StatelessWidget {
Widget content = const SizedBox.shrink();
switch (code) {
case DefaultGameSettings.parameterCodeTilesetSize:
case DefaultActivitySettings.parameterCodeTilesetSize:
content = getTilesetSizeParameterItem();
break;
case DefaultGlobalSettings.parameterCodeSkin:
......@@ -76,13 +77,13 @@ class ParameterWidget extends StatelessWidget {
Color backgroundColor = Colors.grey;
switch (value) {
case DefaultGameSettings.tilesetSizeValueSmall:
case DefaultActivitySettings.tilesetSizeValueSmall:
backgroundColor = Colors.green;
break;
case DefaultGameSettings.tilesetSizeValueMedium:
case DefaultActivitySettings.tilesetSizeValueMedium:
backgroundColor = Colors.orange;
break;
case DefaultGameSettings.tilesetSizeValueLarge:
case DefaultActivitySettings.tilesetSizeValueLarge:
backgroundColor = Colors.red;
break;
default:
......@@ -98,7 +99,7 @@ class ParameterWidget extends StatelessWidget {
painter: ParameterPainter(
code: code,
value: value,
gameSettings: gameSettings,
activitySettings: activitySettings,
globalSettings: globalSettings,
),
isComplex: true,
......
......
import 'package:flutter/material.dart';
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
class PageAbout extends StatelessWidget {
const PageAbout({super.key});
class ScreenAbout extends StatelessWidget {
const ScreenAbout({super.key});
@override
Widget build(BuildContext context) {
......
......
import 'package:flutter/material.dart';
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:puzzlegame/common/config/activity_page.dart';
import 'package:puzzlegame/common/cubit/nav/nav_cubit_pages.dart';
class ScreenActivity extends StatelessWidget {
const ScreenActivity({super.key});
@override
Widget build(BuildContext context) {
return BlocBuilder<NavCubitPage, int>(
builder: (BuildContext context, int pageIndex) {
return ActivityPage.getWidget(pageIndex);
},
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
class PageSettings extends StatelessWidget {
const PageSettings({super.key});
class ScreenSettings extends StatelessWidget {
const ScreenSettings({super.key});
@override
Widget build(BuildContext context) {
......
......
class ApplicationConfig {
static const String appTitle = 'Puzzle';
}
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
class DefaultGameSettings {
class DefaultActivitySettings {
// available game parameters codes
static const String parameterCodeTilesetSize = 'tilesetSize';
static const String parameterCodeImageName = 'imageName';
......@@ -33,9 +33,9 @@ class DefaultGameSettings {
static List<String> getAvailableValues(String parameterCode) {
switch (parameterCode) {
case parameterCodeTilesetSize:
return DefaultGameSettings.allowedTilesetSizeValues;
return DefaultActivitySettings.allowedTilesetSizeValues;
case parameterCodeImageName:
return DefaultGameSettings.allowedImageNameS;
return DefaultActivitySettings.allowedImageNameS;
}
printlog('Did not find any available value for game parameter "$parameterCode".');
......
......
......@@ -7,66 +7,66 @@ import 'package:flutter/services.dart' show rootBundle;
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:image/image.dart' as imglib;
import 'package:puzzlegame/models/game/game.dart';
import 'package:puzzlegame/models/game/moving_tile.dart';
import 'package:puzzlegame/models/settings/settings_game.dart';
import 'package:puzzlegame/models/activity/activity.dart';
import 'package:puzzlegame/models/activity/moving_tile.dart';
import 'package:puzzlegame/models/settings/settings_activity.dart';
import 'package:puzzlegame/models/settings/settings_global.dart';
part 'game_state.dart';
part 'activity_state.dart';
class GameCubit extends HydratedCubit<GameState> {
GameCubit()
: super(GameState(
currentGame: Game.createEmpty(),
class ActivityCubit extends HydratedCubit<ActivityState> {
ActivityCubit()
: super(ActivityState(
currentActivity: Activity.createEmpty(),
));
void updateState(Game game) {
emit(GameState(
currentGame: game,
void updateState(Activity activity) {
emit(ActivityState(
currentActivity: activity,
));
}
void refresh() {
final Game game = Game(
final Activity activity = Activity(
// Settings
gameSettings: state.currentGame.gameSettings,
globalSettings: state.currentGame.globalSettings,
activitySettings: state.currentActivity.activitySettings,
globalSettings: state.currentActivity.globalSettings,
// State
isRunning: state.currentGame.isRunning,
isStarted: state.currentGame.isStarted,
isFinished: state.currentGame.isFinished,
animationInProgress: state.currentGame.animationInProgress,
shufflingInProgress: state.currentGame.shufflingInProgress,
isRunning: state.currentActivity.isRunning,
isStarted: state.currentActivity.isStarted,
isFinished: state.currentActivity.isFinished,
animationInProgress: state.currentActivity.animationInProgress,
shufflingInProgress: state.currentActivity.shufflingInProgress,
// Base data
image: state.currentGame.image,
tiles: state.currentGame.tiles,
image: state.currentActivity.image,
tiles: state.currentActivity.tiles,
// Game data
movesCount: state.currentGame.movesCount,
displayTip: state.currentGame.displayTip,
tileSize: state.currentGame.tileSize,
movesCount: state.currentActivity.movesCount,
displayTip: state.currentActivity.displayTip,
tileSize: state.currentActivity.tileSize,
);
// game.dump();
updateState(game);
updateState(activity);
}
void startNewGame({
required GameSettings gameSettings,
void startNewActivity({
required ActivitySettings activitySettings,
required GlobalSettings globalSettings,
}) {
final Game newGame = Game.createNew(
final Activity newActivity = Activity.createNew(
// Settings
gameSettings: gameSettings,
activitySettings: activitySettings,
globalSettings: globalSettings,
);
newGame.dump();
newActivity.dump();
updateState(newGame);
updateState(newActivity);
refresh();
state.currentGame.isRunning = true;
state.currentGame.shufflingInProgress = true;
state.currentActivity.isRunning = true;
state.currentActivity.shufflingInProgress = true;
refresh();
Timer(const Duration(seconds: 1), () {
......@@ -74,44 +74,44 @@ class GameCubit extends HydratedCubit<GameState> {
});
}
void quitGame() {
state.currentGame.isRunning = false;
void quitActivity() {
state.currentActivity.isRunning = false;
refresh();
}
void resumeSavedGame() {
state.currentGame.isRunning = true;
void resumeSavedActivity() {
state.currentActivity.isRunning = true;
refresh();
}
void deleteSavedGame() {
state.currentGame.isRunning = false;
state.currentGame.isFinished = true;
void deleteSavedActivity() {
state.currentActivity.isRunning = false;
state.currentActivity.isFinished = true;
refresh();
}
void updateTileSize(double tileSize) {
if (tileSize != state.currentGame.tileSize) {
state.currentGame.tileSize = tileSize;
for (var i = 0; i < state.currentGame.tiles.length; i++) {
state.currentGame.tiles[i].size = tileSize;
if (tileSize != state.currentActivity.tileSize) {
state.currentActivity.tileSize = tileSize;
for (var i = 0; i < state.currentActivity.tiles.length; i++) {
state.currentActivity.tiles[i].size = tileSize;
}
refresh();
}
}
void toggleDisplayTipImage() {
state.currentGame.displayTip = !state.currentGame.displayTip;
state.currentActivity.displayTip = !state.currentActivity.displayTip;
refresh();
}
void incrementMovesCount() {
state.currentGame.movesCount++;
state.currentActivity.movesCount++;
refresh();
}
bool checkTilesetIsCleared() {
for (MovingTile tile in state.currentGame.tiles) {
for (MovingTile tile in state.currentActivity.tiles) {
if (!tile.isCorrect()) {
return false;
}
......@@ -120,40 +120,40 @@ class GameCubit extends HydratedCubit<GameState> {
}
void swapTiles(List<int> tile1, List<int> tile2) {
state.currentGame.isStarted = true;
state.currentActivity.isStarted = true;
final int indexTile1 = state.currentGame.tiles.indexWhere(
final int indexTile1 = state.currentActivity.tiles.indexWhere(
(tile) => ((tile.currentCol == tile1[0]) && (tile.currentRow == tile1[1])));
final int indexTile2 = state.currentGame.tiles.indexWhere(
final int indexTile2 = state.currentActivity.tiles.indexWhere(
(tile) => ((tile.currentCol == tile2[0]) && (tile.currentRow == tile2[1])));
final MovingTile swap = state.currentGame.tiles[indexTile1];
state.currentGame.tiles[indexTile1] = state.currentGame.tiles[indexTile2];
state.currentGame.tiles[indexTile2] = swap;
final MovingTile swap = state.currentActivity.tiles[indexTile1];
state.currentActivity.tiles[indexTile1] = state.currentActivity.tiles[indexTile2];
state.currentActivity.tiles[indexTile2] = swap;
final int swapCol = state.currentGame.tiles[indexTile1].currentCol;
state.currentGame.tiles[indexTile1].currentCol =
state.currentGame.tiles[indexTile2].currentCol;
state.currentGame.tiles[indexTile2].currentCol = swapCol;
final int swapCol = state.currentActivity.tiles[indexTile1].currentCol;
state.currentActivity.tiles[indexTile1].currentCol =
state.currentActivity.tiles[indexTile2].currentCol;
state.currentActivity.tiles[indexTile2].currentCol = swapCol;
final int swapRow = state.currentGame.tiles[indexTile1].currentRow;
state.currentGame.tiles[indexTile1].currentRow =
state.currentGame.tiles[indexTile2].currentRow;
state.currentGame.tiles[indexTile2].currentRow = swapRow;
final int swapRow = state.currentActivity.tiles[indexTile1].currentRow;
state.currentActivity.tiles[indexTile1].currentRow =
state.currentActivity.tiles[indexTile2].currentRow;
state.currentActivity.tiles[indexTile2].currentRow = swapRow;
incrementMovesCount();
if (checkTilesetIsCleared()) {
state.currentGame.isFinished = true;
state.currentActivity.isFinished = true;
}
refresh();
}
Future<void> splitImageInTiles() async {
final String imageAsset = 'assets/images/${state.currentGame.image}.png';
final String imageAsset = 'assets/images/${state.currentActivity.image}.png';
final Uint8List imageData = (await rootBundle.load(imageAsset)).buffer.asUint8List();
final int tilesCount = state.currentGame.gameSettings.tilesetSizeValue;
final int tilesCount = state.currentActivity.activitySettings.tilesetSizeValue;
final imglib.Image image = imglib.decodeImage(imageData) ??
imglib.Image.fromBytes(
......@@ -181,7 +181,7 @@ class GameCubit extends HydratedCubit<GameState> {
currentCol: j,
currentRow: i,
image: Image.memory(tileData),
size: state.currentGame.tileSize,
size: state.currentActivity.tileSize,
originalCol: j,
originalRow: i,
));
......@@ -192,17 +192,17 @@ class GameCubit extends HydratedCubit<GameState> {
y += height;
}
state.currentGame.tiles = tiles;
state.currentActivity.tiles = tiles;
shuffleTiles();
state.currentGame.shufflingInProgress = false;
state.currentActivity.shufflingInProgress = false;
refresh();
}
void shuffleTiles() {
final Random random = Random();
final List<MovingTile> tiles = state.currentGame.tiles;
final List<MovingTile> tiles = state.currentActivity.tiles;
final int tilesCount = tiles.length;
for (int i = 0; i < (10 * tilesCount); i++) {
......@@ -222,22 +222,22 @@ class GameCubit extends HydratedCubit<GameState> {
tiles[indexTile2].currentRow = swapRow;
}
state.currentGame.tiles = tiles;
state.currentActivity.tiles = tiles;
}
@override
GameState? fromJson(Map<String, dynamic> json) {
final Game currentGame = json['currentGame'] as Game;
ActivityState? fromJson(Map<String, dynamic> json) {
final Activity currentActivity = json['currentActivity'] as Activity;
return GameState(
currentGame: currentGame,
return ActivityState(
currentActivity: currentActivity,
);
}
@override
Map<String, dynamic>? toJson(GameState state) {
Map<String, dynamic>? toJson(ActivityState state) {
return <String, dynamic>{
'currentGame': state.currentGame.toJson(),
'currentActivity': state.currentActivity.toJson(),
};
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment