Skip to content

Commit

Permalink
Marty grid
Browse files Browse the repository at this point in the history
  • Loading branch information
justinmc committed Mar 15, 2021
1 parent e43d051 commit de8fe37
Show file tree
Hide file tree
Showing 8 changed files with 420 additions and 127 deletions.
14 changes: 7 additions & 7 deletions lib/iv_builder_page.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';

import 'marty.dart';
import 'table_builder.dart';

class IVBuilderPage extends StatefulWidget {
Expand All @@ -15,7 +16,9 @@ class _IVBuilderPageState extends State<IVBuilderPage> {
final TransformationController _transformationController = TransformationController();

static const double _cellWidth = 200.0;
static const double _cellHeight = 26.0;
static const double _cellHeight = 200.0;
static const int _rowCount = 60;
static const int _columnCount = 10;

// Returns true iff the given cell is currently visible. Caches viewport
// calculations.
Expand Down Expand Up @@ -71,8 +74,8 @@ class _IVBuilderPageState extends State<IVBuilderPage> {
//minScale: _minScale,
builder: (BuildContext context, Rect viewport) {
return TableBuilder(
rowCount: 60,
columnCount: 6,
rowCount: _rowCount,
columnCount: _columnCount,
cellWidth: _cellWidth,
builder: (BuildContext context, int row, int column) {
if (!_isCellVisible(row, column, viewport)) {
Expand All @@ -81,10 +84,7 @@ class _IVBuilderPageState extends State<IVBuilderPage> {
return Container(
height: _cellHeight,
color: row % 2 + column % 2 == 1 ? Colors.white : Colors.grey.withOpacity(0.1),
child: Align(
alignment: Alignment.centerLeft,
child: Text('$row x $column'),
),
child: Marty(index: row * _columnCount + column),
);
}
);
Expand Down
100 changes: 100 additions & 0 deletions lib/iv_builder_table_page.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';

import 'table_builder.dart';

class IVBuilderTablePage extends StatefulWidget {
const IVBuilderTablePage({ Key key }) : super(key: key);

static const String routeName = '/iv-builder-table';

@override _IVBuilderTablePageState createState() => _IVBuilderTablePageState();
}

class _IVBuilderTablePageState extends State<IVBuilderTablePage> {
final TransformationController _transformationController = TransformationController();

static const double _cellWidth = 200.0;
static const double _cellHeight = 26.0;

// Returns true iff the given cell is currently visible. Caches viewport
// calculations.
Rect _cachedViewport;
int _firstVisibleColumn;
int _firstVisibleRow;
int _lastVisibleColumn;
int _lastVisibleRow;
bool _isCellVisible(int row, int column, Rect viewport) {
if (viewport != _cachedViewport) {
_cachedViewport = viewport;
_firstVisibleRow = (viewport.top / _cellHeight).floor();
_firstVisibleColumn = (viewport.left / _cellWidth).floor();
_lastVisibleRow = (viewport.bottom / _cellHeight).floor();
_lastVisibleColumn = (viewport.right / _cellWidth).floor();
}
return row >= _firstVisibleRow && row <= _lastVisibleRow
&& column >= _firstVisibleColumn && column <= _lastVisibleColumn;
}

void _onChangeTransformation() {
setState(() {});
}

@override
void initState() {
super.initState();
_transformationController.addListener(_onChangeTransformation);
}

@override
void dispose() {
_transformationController.removeListener(_onChangeTransformation);
super.dispose();
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Two Dimensions'),
actions: <Widget>[
],
),
body: Center(
child: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return InteractiveViewer.builder(
alignPanAxis: true,
scaleEnabled: false,
transformationController: _transformationController,
//maxScale: _maxScale,
//minScale: _minScale,
builder: (BuildContext context, Rect viewport) {
return TableBuilder(
rowCount: 60,
columnCount: 6,
cellWidth: _cellWidth,
builder: (BuildContext context, int row, int column) {
if (!_isCellVisible(row, column, viewport)) {
return Container(height: _cellHeight);
}
return Container(
height: _cellHeight,
color: row % 2 + column % 2 == 1 ? Colors.white : Colors.grey.withOpacity(0.1),
child: Align(
alignment: Alignment.centerLeft,
child: Text('$row x $column'),
),
);
}
);
},
);
},
),
),
);
}
}


57 changes: 3 additions & 54 deletions lib/list_view_builder_page.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import 'package:rive/rive.dart';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';

import 'marty.dart';

class ListViewBuilderPage extends StatefulWidget {
const ListViewBuilderPage({ Key key }) : super(key: key);

Expand Down Expand Up @@ -33,7 +32,7 @@ class _ListViewBuilderPageState extends State<ListViewBuilderPage> {
return Container(
height: 200,
color: Colors.teal.withOpacity(index / _itemCount),
child: _Marty(
child: Marty(
index: index,
),
);
Expand All @@ -44,53 +43,3 @@ class _ListViewBuilderPageState extends State<ListViewBuilderPage> {
);
}
}

class _Marty extends StatefulWidget {
const _Marty({
Key key,
@required this.index,
}) : super(key: key);

final int index;

@override _MartyState createState() => _MartyState();
}

class _MartyState extends State<_Marty> {
Artboard _riveArtboard;
RiveAnimationController _controller;

@override
void initState() {
super.initState();

rootBundle.load('assets/marty_v6.riv').then(
(data) async {
final file = RiveFile();

if (file.import(data)) {
final artboard = file.mainArtboard;
_controller = SimpleAnimation(artboard.animations[widget.index % 2].name);
artboard.addController(_controller);
setState(() {
_riveArtboard = artboard;
_controller.isActive = true;
});
}
},
);
}

@override
void dispose() {
super.dispose();
print('justin dipose ${widget.index}');
}

@override
Widget build(BuildContext context) {
return _riveArtboard == null
? const SizedBox()
: Rive(artboard: _riveArtboard);
}
}
13 changes: 10 additions & 3 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';

import 'iv_builder_page.dart';
import 'iv_builder_table_page.dart';
import 'list_view_builder_page.dart';
import 'single_child_scroll_view_page.dart';
import 'procedural_generation_page.dart';
Expand All @@ -25,9 +26,10 @@ class MyApp extends StatelessWidget {
initialRoute: '/',
routes: <String, Widget Function(BuildContext)>{
'/': (BuildContext context) => MyHomePage(),
IVBuilderPage.routeName: (BuildContext context) => IVBuilderPage(),
SingleChildScrollViewPage.routeName: (BuildContext context) => SingleChildScrollViewPage(),
ListViewBuilderPage.routeName: (BuildContext context) => ListViewBuilderPage(),
IVBuilderPage.routeName: (BuildContext context) => IVBuilderPage(),
IVBuilderTablePage.routeName: (BuildContext context) => IVBuilderTablePage(),
ProceduralGenerationPage.routeName: (BuildContext context) => ProceduralGenerationPage(),
},
);
Expand Down Expand Up @@ -57,8 +59,13 @@ class MyHomePage extends StatelessWidget {
),
MyListItem(
route: '/iv-builder',
title: 'InteractiveViewer Builder Example',
subtitle: 'Build only the visible parts.',
title: 'InteractiveViewer Builder Grid Example',
subtitle: 'Build only the visible parts of a grid.',
),
MyListItem(
route: '/iv-builder-table',
title: 'InteractiveViewer Builder Table Example',
subtitle: 'Build only the visible parts of a table.',
),
MyListItem(
route: '/procedural-generation',
Expand Down
72 changes: 71 additions & 1 deletion lib/map_data.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'dart:math' show Random;
import 'dart:ui' show Offset;

import 'constants.dart';
import 'layer.dart';
Expand All @@ -13,6 +14,14 @@ class MapData {
TileData getTileDataAt(Location location) {
return TileData.generate(location, seed);
}

TileData getLowestTileDataAtScreenOffset(Offset offset) {
return TileData.generate(Location(
row: (offset.dy / Layer.layerScale).floor(),
column: (offset.dx / Layer.layerScale).floor(),
layerType: LayerType.local,
), seed);
}
}

class TileData {
Expand All @@ -21,10 +30,12 @@ class TileData {
this.aLocations,
this.bLocations,
this.parent,
this.seed,
this.terrain,
}) : assert(location != null),
assert(aLocations != null),
assert(bLocations != null),
assert(seed != null),
assert(terrain != null);

factory TileData.generate(Location location, int seed) {
Expand Down Expand Up @@ -60,10 +71,14 @@ class TileData {
),
];

if ( _terrainToType[terrainType] == null) {
print('justin null terrain $terrainType');
}
return TileData(
location: location,
aLocations: aLocations,
bLocations: bLocations,
seed: seed,
terrain: _terrainToType[terrainType],
parent: parent,
);
Expand All @@ -85,12 +100,31 @@ class TileData {
static final double _maxX = cellSize.width - 10.0;
static final double _maxY = cellSize.height - 10.0;

// Easy way to get a loation by row, column when stored in an iterable by a
// 1D index.
// TODO pass Location instead of row and column?
static TileData getByRowColumn(Iterable<TileData> tileDatas, int row, int column) {
return tileDatas.elementAt(row * Layer.layerScale + column);
}

final Location location;
final Iterable<Location> aLocations;
final Iterable<Location> bLocations;
final TileData parent;
final int seed;
final Terrain terrain;

Iterable<TileData> _children;
Iterable<TileData> get children {
if (_children != null) {
return _children;
}
_children = Iterable.generate(Layer.layerScale * Layer.layerScale, (int index) {
return TileData.generate(location.children.elementAt(index), seed);
});
return _children;
}

@override
String toString() {
return 'TileData with terrain $terrain';
Expand Down Expand Up @@ -213,6 +247,15 @@ const Map<TerrainType, Terrain> _terrainToType = <TerrainType, Terrain>{
],
),

TerrainType.planet: Terrain(
terrainType: TerrainType.planet,
layer: LayerType.solar,
childTerrainTypes: <TerrainType>[
TerrainType.ocean,
TerrainType.continent,
],
),

TerrainType.solarSpace: Terrain(
terrainType: TerrainType.solarSpace,
layer: LayerType.solar,
Expand Down Expand Up @@ -263,7 +306,7 @@ enum TerrainType {

// Row and column are local to the given layerType.
class Location {
const Location({
Location({
this.row,
this.column,
this.layerType,
Expand All @@ -285,6 +328,33 @@ class Location {
final int column;
final LayerType layerType;

// The index goes like this:
// 0: (0, 0)
// 1: (0, 1)
// ...
// 9: (0, 9)
// 10: (1, 0)
// 11: (1, 1)
// ...
Iterable<Location> _children;
Iterable<Location> get children {
if (_children != null) {
return _children;
}
assert(layerType != LayerType.local);

final int startingRow = row * Layer.layerScale;
final int startingColumn = column * Layer.layerScale;
_children = Iterable.generate(Layer.layerScale * Layer.layerScale, (int index) {
return Location(
row: startingRow + (index / Layer.layerScale).floor(),
column: startingColumn + index % Layer.layerScale,
layerType: layers[layerType].child,
);
});
return _children;
}

@override
String toString() {
return 'Location ($row, $column) in layer $layerType';
Expand Down
Loading

0 comments on commit de8fe37

Please sign in to comment.