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

Fully draw board, without asset images

parent d0d75680
No related branches found
No related tags found
1 merge request!8Resolve "Remove border on same colored adjacent cells"
Pipeline #3821 passed
<?xml version="1.0" encoding="UTF-8"?>
<svg enable-background="new 0 0 100 100" version="1.1" viewBox="0 0 100 100" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><rect width="100" height="100" ry="2" fill="none"/><rect width="100" height="100" fill="#A13CB1" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width="2.6"/></svg>
<?xml version="1.0" encoding="UTF-8"?>
<svg enable-background="new 0 0 100 100" version="1.1" viewBox="0 0 100 100" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><rect width="100" height="100" ry="2" fill="none"/><rect width="100" height="100" fill="#38FFFF" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width="2.6"/></svg>
<?xml version="1.0" encoding="UTF-8"?>
<svg enable-background="new 0 0 100 100" version="1.1" viewBox="0 0 100 100" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><rect width="100" height="100" ry="2" fill="none"/><rect width="100" height="100" fill="#F2739D" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width="2.6"/></svg>
import 'package:flutter/material.dart';
import 'package:jeweled_game/provider/data.dart';
import 'package:jeweled_game/utils/board_utils.dart';
class Cell {
String value = '0';
Cell(
this.value,
);
/*
* Build widget for board cell, with interactions
* @TODO: remove parameters
*/
Container widget(Data myProvider, int row, int col) {
String imageAsset = this.getImageAssetName(myProvider);
return Container(
child: GestureDetector(
child: AnimatedSwitcher(
duration: const Duration(milliseconds: 100),
transitionBuilder: (Widget child, Animation<double> animation) {
return ScaleTransition(child: child, scale: animation);
},
child: Image(
image: AssetImage(imageAsset),
fit: BoxFit.fill,
key: ValueKey<int>(imageAsset.hashCode),
),
),
onTap: () {
if (!myProvider.isGameFinished) {
BoardUtils.tapOnCell(myProvider, row, col);
}
},
),
);
}
/*
* Compute image asset name, from skin and cell value/state
*/
String getImageAssetName(Data myProvider) {
String imageAsset = 'assets/skins/' + myProvider.parameterSkin + '_' + this.value + '.png';
return imageAsset;
}
}
import 'package:flutter/material.dart';
import 'package:jeweled_game/layout/board_painter.dart';
import 'package:jeweled_game/provider/data.dart';
import 'package:jeweled_game/utils/board_utils.dart';
class Board {
static Container buildGameBoard(Data myProvider) {
static Container buildGameBoard(Data myProvider, double boardWidth) {
return Container(
margin: EdgeInsets.all(4),
padding: EdgeInsets.all(4),
child: Column(
children: [
buildGameTileset(myProvider),
],
Container(
child: Center(
child: GestureDetector(
onTapUp: (details) {
double xTap = details.localPosition.dx;
double yTap = details.localPosition.dy;
int col = xTap ~/ (boardWidth / myProvider.sizeHorizontal);
int row = yTap ~/ (boardWidth / myProvider.sizeVertical);
BoardUtils.tapOnCell(myProvider, row, col);
},
child: Container(
child: CustomPaint(
size: Size(boardWidth, boardWidth),
willChange: false,
painter: BoardPainter(myProvider),
isComplex: true,
),
),
);
}
static Table buildGameTileset(Data myProvider) {
int boardSizeHorizontal = myProvider.sizeHorizontal;
int boardSizeVertical = myProvider.sizeVertical;
return Table(
defaultColumnWidth: IntrinsicColumnWidth(),
children: [
for (var row = 0; row < boardSizeVertical; row++)
TableRow(
children: [
for (var col = 0; col < boardSizeHorizontal; col++)
Column(
children: [
myProvider.getCell(row, col).widget(myProvider, row, col),
],
),
],
),
)
],
),
);
}
}
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:jeweled_game/entities/cell.dart';
import 'package:jeweled_game/layout/color_theme.dart';
import 'package:jeweled_game/provider/data.dart';
class BoardPainter extends CustomPainter {
const BoardPainter(this.myProvider);
final Data myProvider;
@override
void paint(Canvas canvas, Size size) {
int sizeHorizontal = myProvider.sizeHorizontal;
int sizeVertical = myProvider.sizeVertical;
List cells = myProvider.cells;
double cellSize = size.width / (max(sizeHorizontal, sizeVertical));
// background
for (var row = 0; row < sizeVertical; row++) {
double y = cellSize * row;
for (var col = 0; col < sizeHorizontal; col++) {
double x = cellSize * col;
final Cell cell = cells[row][col];
final String cellValue = cell.value;
final int colorCode = ColorTheme.getColorCode(myProvider.parameterSkin, cellValue);
final cellPaintBackground = Paint();
cellPaintBackground.color = Color(colorCode);
cellPaintBackground.style = PaintingStyle.fill;
final Rect cellBackground =
Rect.fromPoints(Offset(x - 1, y - 1), Offset(x + cellSize + 2, y + cellSize + 2));
canvas.drawRect(cellBackground, cellPaintBackground);
}
}
// borders
double borderSize = 4;
final cellPaintBorder = Paint();
cellPaintBorder.color = Colors.black;
cellPaintBorder.strokeWidth = borderSize;
cellPaintBorder.strokeCap = StrokeCap.round;
for (var row = 0; row < sizeVertical; row++) {
double y = cellSize * row;
for (var col = 0; col < sizeHorizontal; col++) {
double x = cellSize * col;
final Cell cell = cells[row][col];
final String cellValue = cell.value;
if ((row == 0) || (row > 1 && cellValue != myProvider.getCellValue(row - 1, col))) {
Offset borderStart = Offset(x, y);
Offset borderStop = Offset(x + cellSize, y);
canvas.drawLine(borderStart, borderStop, cellPaintBorder);
}
if ((row == sizeVertical - 1) ||
((row + 1) < sizeVertical && cellValue != myProvider.getCellValue(row + 1, col))) {
Offset borderStart = Offset(x, y + cellSize);
Offset borderStop = Offset(x + cellSize, y + cellSize);
canvas.drawLine(borderStart, borderStop, cellPaintBorder);
}
if ((col == 0) || (col > 1 && cellValue != myProvider.getCellValue(row, col - 1))) {
Offset borderStart = Offset(x, y);
Offset borderStop = Offset(x, y + cellSize);
canvas.drawLine(borderStart, borderStop, cellPaintBorder);
}
if ((col == sizeHorizontal - 1) ||
((col + 1) < sizeHorizontal &&
cellValue != myProvider.getCellValue(row, col + 1))) {
Offset borderStart = Offset(x + cellSize, y);
Offset borderStop = Offset(x + cellSize, y + cellSize);
canvas.drawLine(borderStart, borderStop, cellPaintBorder);
}
}
}
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return false;
}
}
class ColorTheme {
static Map<String, Map<String, int>> borderColors = {
'default': {
'0': 0xffffff,
'1': 0xe63a3f,
'2': 0x708cfd,
'3': 0x359c35,
'4': 0xffce2c,
'5': 0xff6f43,
'6': 0xa13cb1,
'7': 0x38ffff,
'8': 0xf2739d,
},
};
static int defaultBorderColor = 0x808080;
static int getColorCode(String skin, String value) {
if (borderColors.containsKey(skin) && null != borderColors[skin]) {
Map<String, int>? skinColors = borderColors[skin];
if (null != skinColors && skinColors.containsKey(value) && null != skinColors[value]) {
return (skinColors[value] ?? defaultBorderColor) | 0xFF000000;
}
}
return defaultBorderColor | 0xFF000000;
}
}
......@@ -4,7 +4,7 @@ import 'package:jeweled_game/provider/data.dart';
import 'package:jeweled_game/utils/game_utils.dart';
class Game {
static Container buildGameWidget(Data myProvider) {
static Container buildGameWidget(Data myProvider, double boardWidth) {
bool gameIsFinished = myProvider.isGameFinished;
return Container(
......@@ -16,7 +16,7 @@ class Game {
Game.buildTopIndicatorWidget(myProvider),
SizedBox(height: 2),
Expanded(
child: Board.buildGameBoard(myProvider),
child: Board.buildGameBoard(myProvider, boardWidth),
),
SizedBox(height: 2),
Container(
......
......@@ -34,7 +34,6 @@ class Data extends ChangeNotifier {
String get parameterSkin => _parameterSkin;
// Game data
bool _assetsPreloaded = false;
bool _gameIsRunning = false;
bool _gameIsFinished = false;
int _sizeVertical = 0;
......@@ -261,11 +260,6 @@ class Data extends ChangeNotifier {
return {};
}
bool get assetsPreloaded => _assetsPreloaded;
void updateAssetsPreloaded(bool assetsPreloaded) {
_assetsPreloaded = assetsPreloaded;
}
List<List<Cell>> get cells => _cells;
void updateCells(List<List<Cell>> cells) {
_cells = cells;
......
......@@ -23,51 +23,10 @@ class _HomeState extends State<Home> {
myProvider.loadCurrentSavedState();
}
List getImagesAssets(Data myProvider) {
List assets = [];
List gameImages = [
'button_back',
'button_delete_saved_game',
'button_resume_game',
'button_start',
'game_fail',
'game_win',
'placeholder',
];
myProvider.availableLevelValues.forEach((level) => gameImages.add('level_' + level));
myProvider.availableSizeValues.forEach((size) => gameImages.add('size_' + size));
myProvider.availableSkinValues.forEach((skin) => gameImages.add('skin_' + skin));
gameImages.forEach((image) => assets.add('assets/icons/' + image + '.png'));
List skinImages = [
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
];
myProvider.availableSkinValues.forEach((skin) => skinImages
.forEach((image) => assets.add('assets/skins/' + skin + '_' + image + '.png')));
return assets;
}
@override
Widget build(BuildContext context) {
Data myProvider = Provider.of<Data>(context);
if (!myProvider.assetsPreloaded) {
List assets = getImagesAssets(myProvider);
assets.forEach((asset) => precacheImage(AssetImage(asset), context));
myProvider.updateAssetsPreloaded(true);
}
double boardWidth = MediaQuery.of(context).size.width;
List<Widget> menuActions = [];
......@@ -100,7 +59,7 @@ class _HomeState extends State<Home> {
body: SafeArea(
child: Center(
child: myProvider.isGameRunning
? Game.buildGameWidget(myProvider)
? Game.buildGameWidget(myProvider, boardWidth)
: Parameters.buildParametersSelector(myProvider),
),
),
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment