/** Interactive cellular automata. Michael Soukup 2014. */ function zeros(m, n) { var mat = []; for (var i=0; i 7) { return 0; } else if (dist[2] == 1 && dist[4] < 3) { return 0; } else { return 2; } } function cell_3_update(X) { // enemy cell return 3 } function cell_4_update(X) { // conway live cells var dist = _ndist(X); if (dist[2] == 3 && dist[4] > 2) { return 2 } else if (dist[2] > 0 && (dist[4] != 5 || dist[4] == 4)) { return 4 } else if (dist[4] == 2 || dist[4] == 3) { return 4 } else { return 0 } } function cell_next(c, X) { switch (c) { case 0: return cell_0_update(X); case 1: return cell_1_update(X); case 2: return cell_2_update(X); case 3: return cell_3_update(X); case 4: return cell_4_update(X); case 5: return cell_0_update(X); } } /** Board holds the world variables and a complete map over all tiles. All tiles on the board are simlulated in each step. */ function Board() { this.x = 0; this.y = 0; } Board.prototype.on_board = function(x, y) { // TODO check walls return (x >= this.x && y >= this.y && x < this.x+this.w && y < this.y+this.h); } Board.prototype.set_tile = function(val, x, y) { if (this.on_board(x, y)) { this.map[x][y] = val; } } Board.prototype.get_tile = function(x, y) { if (this.on_board(x, y)) { return this.map[x][y]; } else { return 0; } } Board.prototype.load_tileset = function(tileset, x, y) { for (var i=0; i frame.x+frame.w && this.y+this.h > frame.y+frame.h); } TileFrame.prototype.intersects = function(frame) { return (((this.x > frame.x && this.x < frame.x+frame.w) || (frame.x > this.x && frame.x < this.x+this.w)) && ((this.y > frame.y && this.y < frame.y+frame.h) || (frame.y > this.y && frame.y < this.y+this.h))); } /** Holds the canvas context and camera coordinates. Implements methods for rendering tile sets. Coordinates are continuous and in tile space. */ function Camera(canvas_id) { this.canvas = document.getElementById(canvas_id); this.ctx = this.canvas.getContext('2d'); this.width = this.canvas.width; this.height = this.canvas.height; this.tilesize = 5; // Minimum tilesize (px). this.tw = this.width/this.tilesize; this.th = this.height/this.tilesize; } Camera.prototype.zoom = function(tilesize) { var factor = tilesize/this.tilesize, _tw = this.width/tilesize, _th = this.height/tilesize, diff_x = (this.tw - _tw)/2, diff_y = (this.th - _th)/2; this.x += diff_x; this.tw = _tw; this.y += diff_y; this.th = _th; this.tilesize = tilesize; } Camera.prototype.center = function(x, y) { this.x = x - this.tw/2; this.y = y - this.th/2; } Camera.prototype.draw_grid = function() { var i = (Math.ceil(this.x) - this.x)*this.tilesize, j = (Math.ceil(this.y) - this.y)*this.tilesize; this.ctx.strokestyle = 'black'; this.ctx.lineWidth = 0.1; // Vertical lines while (i < this.width) { this.ctx.beginPath(); this.ctx.moveTo(i, 0); this.ctx.lineTo(i, this.height); this.ctx.closePath(); this.ctx.stroke(); i += this.tilesize; } // Horizontal lines while (j < this.height) { this.ctx.beginPath(); this.ctx.moveTo(0, j); this.ctx.lineTo(this.width, j); this.ctx.closePath(); this.ctx.stroke(); j += this.tilesize; } } Camera.prototype.draw_tiles = function(board) { var x, y, i, j, tile_margin = this.tilesize*0.01; x = Math.floor(this.x); i = (x - this.x) * this.tilesize; while (i < this.width) { y = Math.floor(this.y); j = (y - this.y)*this.tilesize; while (j < this.height) { if (board.get_tile(x,y) != 0) { this.ctx.fillStyle = CELLCOL[board.get_tile(x, y)]; this.ctx.beginPath(); this.ctx.rect(i+tile_margin, j+tile_margin, this.tilesize-2*tile_margin, this.tilesize-2*tile_margin); this.ctx.closePath(); this.ctx.fill(); } y++; j += this.tilesize; } x++; i += this.tilesize; } } Camera.prototype.clear = function() { this.ctx.clearRect(0, 0, this.width, this.height); } function testsim(canvas_id, world, dt) { var board = new Board(), player = new TileFrame(world.player[1], world.player[2], CELLSETS[world.player[0]][0].length, CELLSETS[world.player[0]].length), cam = new Camera(canvas_id), tilesize = 8; board.load_world(world); cam.set(world.player[1]-1.5, world.player[1]-1.5, tilesize); // cam.center(..., cam.draw_grid(); cam.draw_tiles(board); setInterval(function (){ board.simulate(); cam.clear(); cam.draw_grid(); cam.draw_tiles(board); }, dt); } function testmove(canvas_id, world, dt) { var board = new Board(), player = new TileFrame(world.player[1], world.player[2], CELLSETS[world.player[0]][0].length, CELLSETS[world.player[0]].length), cam = new Camera(canvas_id), tilesize = 8.8; board.load_world(world); cam.zoom(tilesize); cam.center(player.x, player.y); cam.draw_grid(); cam.draw_tiles(board); function expand_player() { var X; console.log('exp'); for (var x=player.x; x 0) { tilesize *= 0.9; cam.zoom(tilesize); } else { tilesize *= 1.1; cam.zoom(tilesize); } cam.clear(); cam.draw_grid(); cam.draw_tiles(board); }); } // Run //testsim("canvas", WORLD_0, 1000); testmove("canvas", WORLD_0, 1000);