Skip to content

Instantly share code, notes, and snippets.

@adam-singer
Created October 4, 2013 16:38
Show Gist options
  • Save adam-singer/6828861 to your computer and use it in GitHub Desktop.
Save adam-singer/6828861 to your computer and use it in GitHub Desktop.
library heatequation;
import 'dart:html';
import 'dart:async';
import 'dart:collection';
CanvasElement canvas;
CanvasRenderingContext2D context;
List<List<Tile>> world;
Timer running;
Vector mouse, currentTilePosition, previousTilePosition;
int width = 480, height = 480, FPS = 60, heatCounter = 0;
void main() {
mouse = new Vector.zero();
previousTilePosition = new Vector.zero();
canvas = new CanvasElement(width: width, height: height);
query('body').children.add(canvas);
context = canvas.getContext("2d");
canvas
..onMouseMove.listen((event) => onMouseMove(event))
..onMouseDown.listen((event) => onMouseDown(event))
..onMouseUp.listen((event) => onMouseUp(event))
..onContextMenu.listen((event) => event.preventDefault());
world = new List<List<Tile>>(30);
for (var y = 0; y < 30; y++) {
world[y] = new List<Tile>(30);
for (var x = 0; x < 30; x++) {
world[y][x] = new Tile(0);
}
}
running = new Timer.periodic(new Duration(milliseconds: 1000 ~/ FPS), (Timer timer) => update());
window.requestAnimationFrame(draw);
}
void update() {
heatEquation();
}
void draw(num _) {
context.clearRect(0, 0, width, height);
for (var y = 0; y < 30; y++) {
for (var x = 0; x < 30; x++) {
// draw gray background tile
context
..fillStyle = 'rgb(125, 125, 125)'
..beginPath()
..rect(x * 16, y * 16, 16, 16)
..fill()
..lineWidth = 1
..strokeStyle = '#333'
..stroke();
// draw heat
if (world[x][y].heat > 0) {
context
..save()
..globalAlpha = world[x][y].heat //((world[x][y].heat * 10).toInt() / 10).toDouble()
..fillStyle = 'rgb(255, 0, 0)'
..beginPath()
..rect(x * 16, y * 16, 16, 16)
..fill()
..restore();
}
}
}
window.requestAnimationFrame(draw);
}
void updateMouse(MouseEvent evt) {
mouse.x = evt.client.x - canvas.getBoundingClientRect().left;
mouse.y = evt.client.y - canvas.getBoundingClientRect().top;
currentTilePosition = getHoveredTilePosition();
}
void onMouseMove(MouseEvent evt) {
updateMouse(evt);
setTile(evt);
}
void onMouseDown(MouseEvent evt) {
// prevent the mouse cursor from changing
evt.preventDefault();
}
void onMouseUp(MouseEvent evt) {
setTile(evt);
}
void setTile(MouseEvent evt) {
if (evt.which == 1) {
world[currentTilePosition.x][currentTilePosition.y].type = 1;
}
else if (evt.which == 3) {
if (currentTilePosition.x != previousTilePosition.x || currentTilePosition.y != previousTilePosition.y) {
if (world[currentTilePosition.x][currentTilePosition.y].type != 0)
world[currentTilePosition.x][currentTilePosition.y].type = 0;
}
}
}
/**
* Main function of the heat simulation.
*/
void heatEquation() {
heatCounter++;
if (heatCounter == 1) {
heatCounter = 0;
// reset heat sources
for (int y = 1; y < 29; y++) {
for (int x = 1; x < 29; x++) {
if (world[x][y].type == 1)
world[x][y].heat = 1.0;
}
}
//heat equation
for (int y = 1; y < 29; y++) {
for (int x = 1; x < 29; x++) {
if (world[x][y].type != 1)
world[x][y].heat_temp = ((world[x + 1][y ].heat + world[x - 1][y ].heat + world[x ][y + 1].heat + world[x ][y - 1].heat) * 4 +
world[x + 1][y - 1].heat + world[x + 1][y + 1].heat + world[x - 1][y - 1].heat + world[x - 1][y + 1].heat) / 20;
else
world[x][y].heat_temp = 1.0;
}
}
// clamp and copy values
for (int y = 0; y < 30; y++) {
for (int x = 0; x < 30; x++) {
if (world[x][y].heat_temp > 1.0)
world[x][y].heat_temp = 1.0;
if (world[x][y].heat_temp < .01)
world[x][y].heat_temp = 0.0;
world[x][y].heat = world[x][y].heat_temp;
}
}
}
}
Vector getHoveredTilePosition() {
return new Vector(
mouse.x ~/ 16,
mouse.y ~/ 16);
}
class Vector {
num x, y;
Vector(this.x, this.y);
Vector.zero() : x = 0, y = 0;
Vector operator +(Vector other) => new Vector(x + other.x, y + other.y);
String toString() {
return "$x/$y";
}
}
class Tile {
int type;
double heat, heat_temp;
Tile(this.type) {
heat = 0.0;
heat_temp = 0.0;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment