2018-07-20 09:58:11 +00:00
|
|
|
import 'dart:html';
|
2018-07-20 12:36:32 +00:00
|
|
|
import 'dart:math';
|
|
|
|
|
2018-07-20 12:05:48 +00:00
|
|
|
typedef void gridIterator(int x, int y);
|
|
|
|
|
2018-07-20 09:58:11 +00:00
|
|
|
class Game {
|
|
|
|
List<List<Color>> grid;
|
|
|
|
CanvasElement canvas;
|
2018-07-20 12:36:32 +00:00
|
|
|
Random rng = new Random();
|
2018-07-20 09:58:11 +00:00
|
|
|
|
2018-07-20 12:36:32 +00:00
|
|
|
double _oscill = 0.1;
|
|
|
|
bool _oscillDir = true; // oscillate upwards (true) or downwards (false)
|
2018-07-20 17:51:13 +00:00
|
|
|
double _OSCILLSPEED = 1.0;
|
2018-07-20 09:58:11 +00:00
|
|
|
bool _fwd = true;
|
2018-07-24 11:29:47 +00:00
|
|
|
Point _curPos = Point(-1, 0);
|
|
|
|
|
|
|
|
bool isRandom = false;
|
2018-07-20 09:58:11 +00:00
|
|
|
|
|
|
|
Game(CanvasElement this.canvas) {
|
2018-07-20 17:51:13 +00:00
|
|
|
grid = _buildGrid(5, new Color(255, 255, 255));
|
2018-07-20 09:58:11 +00:00
|
|
|
}
|
|
|
|
|
2018-07-20 14:28:12 +00:00
|
|
|
// In-World Logic Updates
|
2018-07-24 13:33:11 +00:00
|
|
|
void update([int speed]) {
|
2018-07-24 11:29:47 +00:00
|
|
|
Point next = isRandom ? nextPosRandom() : nextPosOrdered(_curPos);
|
2018-07-24 12:16:45 +00:00
|
|
|
if (_curPos.x < 0) _curPos = Point(0, _curPos.y);
|
|
|
|
Color newColor = isRandom ? randomColor() : nextColor(
|
2018-07-24 13:03:36 +00:00
|
|
|
grid[_curPos.y][_curPos.x], step: speed ?? 1);
|
2018-07-24 12:16:45 +00:00
|
|
|
grid[next.y][next.x] = newColor;
|
2018-07-24 11:29:47 +00:00
|
|
|
_curPos = next;
|
|
|
|
}
|
|
|
|
|
|
|
|
Point nextPosOrdered(Point curPos) {
|
|
|
|
Point pos = Point(curPos.x, curPos.y);
|
|
|
|
pos = Point(pos.x + 1, pos.y);
|
2018-07-24 12:16:45 +00:00
|
|
|
if (pos.x >= grid[pos.y].length) pos = Point(0, pos.y + 1);
|
|
|
|
if (pos.y >= grid.length) pos = Point(0, 0);
|
2018-07-24 11:29:47 +00:00
|
|
|
return pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
Point nextPosRandom() {
|
2018-07-20 12:36:32 +00:00
|
|
|
int ry = rng.nextInt(grid.length);
|
2018-07-24 11:29:47 +00:00
|
|
|
return Point(rng.nextInt(grid[ry].length), ry);
|
2018-07-20 12:36:32 +00:00
|
|
|
}
|
2018-07-20 09:58:11 +00:00
|
|
|
|
2018-07-24 12:16:45 +00:00
|
|
|
Color randomColor([int max = 255]) {
|
|
|
|
return new Color(rng.nextInt(max), rng.nextInt(max), rng.nextInt(max));
|
|
|
|
}
|
|
|
|
|
2018-07-24 13:03:36 +00:00
|
|
|
Color nextColor(Color col, {int step = 1}) {
|
2018-07-24 12:16:45 +00:00
|
|
|
if (col.r > 254 || col.g > 254 || col.b > 254) return randomColor(100);
|
|
|
|
if (col.r > col.g && col.r > col.b)
|
2018-07-24 13:03:36 +00:00
|
|
|
return Color(col.r + step, col.g, col.b);
|
2018-07-24 12:16:45 +00:00
|
|
|
else if (col.b > col.r && col.b > col.g)
|
2018-07-24 13:03:36 +00:00
|
|
|
return Color(col.r, col.g, col.b + step);
|
2018-07-24 12:16:45 +00:00
|
|
|
else
|
2018-07-24 13:03:36 +00:00
|
|
|
return Color(col.r, col.g + step, col.b);
|
2018-07-24 12:16:45 +00:00
|
|
|
}
|
|
|
|
|
2018-07-20 14:28:12 +00:00
|
|
|
// Render Pipeline
|
2018-07-20 09:58:11 +00:00
|
|
|
void draw([num interp]) {
|
2018-07-20 15:47:11 +00:00
|
|
|
CanvasRenderingContext2D ctx = this.canvas.context2D;
|
|
|
|
|
2018-07-20 09:58:11 +00:00
|
|
|
int brickW = (canvas.width ~/ grid[0].length);
|
|
|
|
int brickH = (canvas.height ~/ grid.length);
|
|
|
|
|
|
|
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
2018-07-20 14:28:12 +00:00
|
|
|
_grid_foreach((x, y) {
|
2018-07-24 11:29:47 +00:00
|
|
|
Color col = _getOscillatedCol(grid[y][x]);
|
|
|
|
ctx.setFillColorRgb(col.r, col.g, col.b);
|
|
|
|
ctx.fillRect(x * brickW, y * brickH, brickW, brickH);
|
2018-07-20 12:05:48 +00:00
|
|
|
});
|
2018-07-20 17:51:13 +00:00
|
|
|
|
|
|
|
// This should usually be place in update()
|
|
|
|
// Placed here to highlight render speed changes for some examples
|
2018-07-24 11:29:47 +00:00
|
|
|
// See variable timestep & dirty flag Loops for details
|
2018-07-20 17:51:13 +00:00
|
|
|
_oscillate();
|
2018-07-20 09:58:11 +00:00
|
|
|
}
|
|
|
|
|
2018-07-20 14:28:12 +00:00
|
|
|
// Slightly oscillating colors to highlight rendering updates
|
2018-07-20 17:51:13 +00:00
|
|
|
void _oscillate() {
|
2018-07-24 11:35:25 +00:00
|
|
|
if (_oscill >= 50.0 || _oscill <= -50.0) {
|
2018-07-20 12:36:32 +00:00
|
|
|
_oscillDir = !_oscillDir;
|
2018-07-24 11:35:25 +00:00
|
|
|
_oscill = max(min(_oscill, 49.0), -49.0);
|
|
|
|
} else
|
|
|
|
_oscillDir == true ? _oscill += _OSCILLSPEED : _oscill -= _OSCILLSPEED;
|
2018-07-20 17:51:13 +00:00
|
|
|
}
|
2018-07-20 12:36:32 +00:00
|
|
|
|
2018-07-20 17:51:13 +00:00
|
|
|
Color _getOscillatedCol(Color col) {
|
2018-07-20 12:36:32 +00:00
|
|
|
int o = _oscill.toInt();
|
|
|
|
return new Color(col.r + o, col.g + o, col.b + o);
|
|
|
|
}
|
2018-07-20 09:58:11 +00:00
|
|
|
|
2018-07-20 14:28:12 +00:00
|
|
|
void _grid_foreach(gridIterator fun) {
|
2018-07-20 12:05:48 +00:00
|
|
|
for (int y = 0; y < grid.length; y++) {
|
|
|
|
for (int x = 0; x < grid[y].length; x++) {
|
|
|
|
fun(x, y);
|
|
|
|
}
|
|
|
|
}
|
2018-07-20 09:58:11 +00:00
|
|
|
}
|
|
|
|
|
2018-07-20 17:51:13 +00:00
|
|
|
List<List<Color>> _buildGrid(int size, Color col) {
|
|
|
|
List<List<Color>> grid = new List(size);
|
|
|
|
for (int y = 0; y < size; y++) {
|
|
|
|
grid[y] = new List(size);
|
|
|
|
for (int x = 0; x < size; x++) {
|
2018-07-20 09:58:11 +00:00
|
|
|
grid[y][x] = col;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return grid;
|
|
|
|
}
|
2018-07-20 17:51:13 +00:00
|
|
|
|
|
|
|
// Grid Size Button Implementation
|
|
|
|
// true makes squares larger
|
|
|
|
// false makes squares smaller
|
|
|
|
void changeGridSize(bool larger) {
|
2018-07-24 11:29:47 +00:00
|
|
|
if (larger) {
|
|
|
|
if (grid.length <= 5) return;
|
2018-07-20 17:51:13 +00:00
|
|
|
this.grid = _buildGrid(grid.length - 5, Color(255, 255, 255));
|
|
|
|
} else {
|
2018-07-24 11:29:47 +00:00
|
|
|
if (grid.length >= 60) return;
|
2018-07-20 17:51:13 +00:00
|
|
|
this.grid = _buildGrid(grid.length + 5, Color(255, 255, 255));
|
|
|
|
}
|
|
|
|
}
|
2018-07-24 11:29:47 +00:00
|
|
|
|
|
|
|
void toggleRandomOrder() {
|
|
|
|
isRandom = !isRandom;
|
|
|
|
}
|
2018-07-20 09:58:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
class Color {
|
|
|
|
final int r;
|
|
|
|
final int g;
|
|
|
|
final int b;
|
|
|
|
|
|
|
|
const Color(this.r, this.g, this.b);
|
2018-07-24 12:16:45 +00:00
|
|
|
|
|
|
|
@override
|
|
|
|
String toString() {
|
|
|
|
return "Color: (r:$r, g:$g, b:$b)";
|
|
|
|
}
|
2018-07-20 09:58:11 +00:00
|
|
|
}
|