/* * Michael Soukup, 2014 */ //var DIM = [window.innerWidth, window.innerHeight]; function zeros(m, n) { var mat = []; for (var i=0; i 0 && this.dim.x > dx) || (dx < 0 && f.dim.x < -dx)), inter_y = ((dy > 0 && this.dim.y > dy) || (dy < 0 && f.dim.y < -dy)); return inter_x && inter_y } Frame.prototype.join = function(f) { // Expands frame to also fit f var x_min = Math.min(this.coords.x, f.coords.x), y_min = Math.min(this.coords.y, f.coords.y), x_max = Math.max(this.coords.x+this.dim.x, f.coords.x+f.dim.x), y_max = Math.max(this.coords.y+this.dim.y, f.coords.y+f.dim.y); this.coords.x = x_min; this.coords.y = y_min; this.dim.x = x_max - x_min; this.dim.y = y_max - y_min; } Frame.prototype.intersect = function(f) { // this AND f var dx = f.coords.x - this.coords.x, dy = f.coords.y - this.coords.y; if (dx > 0) { this.coords.x = f.coords.x; this.dim.x = Math.min(this.dim.x - dx, f.dim.x); } else { this.dim.x = Math.min(f.dim.x + dx, this.dim.x); } if (dy > 0) { this.coords.y = f.coords.y; this.dim.y = Math.min(this.dim.y - dy, f.dim.y); } else { this.dim.y = Math.min(f.dim.y + dy, this.dim.y); } } var CELL_COL = { 0: '#000', 1: '#222', 2: '#484', 3: '#a44', 4: '#8a8a8a' }, CELL_T = { 'empty': 0, 'wall': 1, 'player': 2, 'enemy': 3, 'conway': 4 }, CELL_CONFIGS = { 'player0': [ [0,2,2,0,0,0], [0,0,0,0,0,0], [0,0,0,0,0,0], [0,0,0,4,4,0], [0,0,4,0,4,0], [0,0,0,4,0,0] ], 'enemy0': [ [0,3,3,3,3,0], [3,4,4,0,3,3], [3,4,0,0,0,3], [3,0,0,4,4,3], [3,0,4,0,3,3], [0,3,3,3,0,0] ], 'organism0': [ [0,0,0,0,0,0,4,4], [0,0,4,4,4,4,4,4], [0,0,0,4,0,0,0,0], [0,4,0,0,0,0,0,0], [0,4,4,4,0,4,0,4], [4,4,4,0,4,4,4,4], [0,0,4,4,4,0,0,0] ], 'box': [ [0,0,0,0], [0,4,4,0], [0,4,4,0], [0,0,0,0] ], 'diamond': [ [0,4,0,0], [4,0,4,0], [0,4,0,0], [0,0,0,0] ] }; function Ndist(N, r) { var dist = [0,0,0,0,0]; for (var x=0; x 2) { return 2 } else if (dist[4] == 2 || dist[4] == 3) { return 4 } else { return 0 } } function cellNext(N) { // Size of neighbourhood N is nxn where n is (r*2 + 1), r in {1,2,3...}: // 3x3, 5x5, 7x7, ... var r = (N.length - 1) / 2, // must be int cell = N[r][r]; switch (cell) { case 0: return cell_0_update(N, r); case 1: return cell_1_update(N, r); case 2: return cell_2_update(N, r); case 3: return cell_3_update(N, r); case 4: return cell_4_update(N, r); } } // Every organism has a pointer to the environment // dim_cam, coords_cam, px_tile, dim_frame, coords_frame, tiles_frame // function Organism(configuration, x, y, tilesize) { // // Tiles can be of any size px_tile_min*n, n in N // this.p = new Vector(x, y); // continuous // this.v = new Vector(0, 0); // this.px_tile = tilesize; // this.tiles = new Vector(configuration[0].length, configuration.length); // this.config = configuration; // this.config_buf = zeros(this.tiles.x, this.tiles.y); // this.frame = new Frame(new Vector(nearestMod0(x, tilesize), nearestMod0(y, tilesize)), // new Vector(tilesize*this.tiles.x, tilesize*this.tiles.y)); // //this.coords_center = null // keep track of center for steering and battle // } // Organism.prototype.getNeighbourhood = function(cx, cy, r) { // var n = (r*2)+1, // N = zeros(n,n); // for (var x=cx-r; x<=cx+r; x++) { // for (var y=cy-r; y<=cy+r; y++) { // if ((x < 0 || x >= this.tiles.x) || (y < 0 || y >= this.tiles.y)) { // N[x+r-cx][y+r-cy] = 0; // Tiles outside constraints are 0 anyways // } // else { // N[x+r-cx][y+r-cy] = this.config[x][y]; // } // } // } // return N // } // Organism.prototype.updateCells = function() { // // find player cell center // for (var x=0; x= this.tiles.x) || (y < 0 || y >= this.tiles.y)) { N[x+r-cx][y+r-cy] = 0; // Tiles outside constraints are 0 anyways } else { N[x+r-cx][y+r-cy] = this.config[x][y]; } } } return N } Organism.prototype.updateCells = function() { var config_buf = zeros(this.tiles.x, this.tiles.y); for (var x=0; x 0 dy = y - this.frame.dim.y; this.frame.coords.x += -dx/2; this.frame.coords.y += -dy/2; this.frame.dim.x = x; this.frame.dim.y = y; this.move(dF, dt); // fit frame and simulate this.frame.align(this.px_tile); var new_tiles = new Vector(this.frame.dim.x / this.px_tile, this.frame.dim.y / this.px_tile); this.setConfig(new_tiles); this.updateCells(); } var Game = (function(canvas_id) { var canvas = document.getElementById(canvas_id), ctx = canvas.getContext('2d'), // Set up camera and simulation frame // Camera moves continuously, frame size and coords must fit tiles. dim_cam = new Vector(canvas.width, canvas.height), coords_cam = new Vector(0.0, 0.0), // Initial view: coords_cam -> coords_cam+dim_cam px_tile_min = 5, // 5x5 pixels dim_frame = new Vector(nearestMod0(2*dim_cam.x, px_tile_min), nearestMod0(2*dim_cam.y, px_tile_min)), coords_frame = new Vector(nearestMod0(coords_cam.x - 0.25*dim_frame.x, px_tile_min), nearestMod0(coords_cam.y - 0.25*dim_frame.y, px_tile_min)), tiles_frame = new Vector(dim_frame.x/px_tile_min, dim_frame.y/px_tile_min), player, enemies = [], organisms = [], level0 = [ 'player0,55,60', 'enemy0,120,24', 'organism0,-5,0', 'box,120,32', 'diamond,87,32' ]; //cells = zeros(tiles_frame.x, tiles_frame.y), //cells_buf = (tiles_frame.x, tiles_frame.y), // function detectNearbyEnemies(organism) { // // Returns a list of indices of nearby enemies // } // function _setOrganismBox(organism, nearby) { // // assume all coords are tile fitted // // pos_o = box_coord + 0.5*box // var pos_o = Vector(organism.box_coords.x + 0.5*organism.box.x, organism.box_coords.y + 0.5*organism.box.y), // old_coords = Vector(organism.box_coords.x, organism.box_coords.y), // old_box = Vector(organism.box.x, organism.box.y) // for (var i=0; i 0) { // ctx.fillStyle = cellcol[configuration[j][i]]; // ctx.beginPath(); // ctx.rect((i+x)*tilesize+0.5, (j+y)*tilesize+0.5, tilesize-0.5, tilesize-0.5); // ctx.closePath(); // ctx.fill(); // } // } // } // } // function update(vx, vy) { // updateCells(vx, vy); // } // function drawCells() { // for (var i=0; i 0) { // ctx.fillStyle = cellcol[cells[i][j]]; // ctx.beginPath(); // ctx.rect(i*tilesize+0.5, j*tilesize+0.5, tilesize-0.5, tilesize-0.5); // ctx.closePath(); // ctx.fill(); // } // } // } // } // function drawGrid() { // ctx.translate(0.5, 0.5); // Transform canvas to get sharp lines // ctx.strokeStyle = 'black'; // ctx.lineWidth = 0.1; // for (var i=1; i 0) { // ctx.fillStyle = CELL_COL[organism.config[j][i]]; // ctx.beginPath(); // // Draw every 5x5 tile at x = (i+x)*tile_min + x_t0, y = (j+y)*tile_min + y_t0 // ctx.rect((i+x)*tile_min+x_t0+0.5, (j+y)*tile_min+y_t0+0.5, tile_min-0.5, tile_min-0.5); // ctx.closePath(); // ctx.fill(); // } // } // } // } function framesOverlap(o1, o2) { } function minimumDist(o1, o2, d_gap, cell_sep) { // returns true if o1 and o2 are touching or have a layer of maximum width d_gap consisting only of celltype cell_sep. // try finding a layer. If no layer, return true // try expanding the layer. If d_layer > d_gap return false } function updatePlayer() { var new_enemies = [], new_organisms = []; // Split player? Implement later var gap = 2; for (var i=0; i