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
Branches
Tags
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