Created
August 29, 2013 23:03
-
-
Save shadda/6384479 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (function() | |
| { | |
| TILES = {}; | |
| SELECTED_TILES = []; | |
| INVALIDATED_TILES = {}; | |
| $stage = $('#stage'); | |
| $MAP_TILE_RADIUS = 22; | |
| $MAP_TILE_HEIGHT = parseInt($MAP_TILE_RADIUS * Math.sqrt(3)); | |
| $REDRAW = true; | |
| $SCALE = 1.0; | |
| $ALLOW_MULTI_SELECT = true; | |
| var NEIGHBORS_DI = [0, 1, 1, 0, -1,-1]; | |
| var NEIGHBORS_DJ = [ | |
| [-1, -1, 0, 1, 0, -1], | |
| [-1, 0, 1, 1, 1, 0] | |
| ]; | |
| var NUM_NEIGHBORS = 6; | |
| HexTile = function(radius, swatch) | |
| { | |
| this.$attributes = {}; | |
| this.$swatch = swatch; | |
| this.$image = {}; | |
| this.layers = { | |
| 'provinces': {}, | |
| 'height': {}, | |
| 'terrain': {}, | |
| 'buildings': [] | |
| }; | |
| this._x = 0; //Cell's left coordinate | |
| this._y = 0; //Cell's top coordinate | |
| this.x = 0; //Cell's horizontal grid coordinate | |
| this.y = 0; //Cell's vertical grid coordinate | |
| this.RADIUS = radius; | |
| this.WIDTH = this.RADIUS * 2; | |
| this.HEIGHT = parseInt(radius * Math.sqrt(3)); | |
| this.SIDE = this.RADIUS * 3 / 2; | |
| this.CORNERS_DX = [ | |
| this.RADIUS / 2, | |
| this.SIDE, | |
| this.WIDTH, | |
| this.SIDE, | |
| this.RADIUS / 2, | |
| 0 | |
| ]; | |
| this.CORNERS_DY = [ | |
| 0, 0, | |
| this.HEIGHT / 2, | |
| this.HEIGHT, | |
| this.HEIGHT, | |
| this.HEIGHT / 2 | |
| ]; | |
| } | |
| HexTile.prototype.init = function() | |
| { | |
| this.$image = {}; | |
| this.RADIUS = $MAP_TILE_RADIUS; | |
| this.WIDTH = this.RADIUS * 2; | |
| this.HEIGHT = parseInt(this.RADIUS * Math.sqrt(3)); | |
| this.SIDE = this.RADIUS * 3 / 2; | |
| this.CORNERS_DX = [ | |
| this.RADIUS / 2, | |
| this.SIDE, | |
| this.WIDTH, | |
| this.SIDE, | |
| this.RADIUS / 2, | |
| 0 | |
| ]; | |
| this.CORNERS_DY = [ | |
| 0, 0, | |
| this.HEIGHT / 2, | |
| this.HEIGHT, | |
| this.HEIGHT, | |
| this.HEIGHT / 2 | |
| ]; | |
| this.setCellIndex(this.x, this.y); | |
| } | |
| HexTile.prototype.fromHash = function(data) | |
| { | |
| for(var key in data) | |
| { | |
| this[key] = data[key]; | |
| this.$attributes[key] = data[key]; | |
| } | |
| this.setCellIndex(data['x'], data['y']); | |
| } | |
| HexTile.prototype.getData = function(callback) | |
| { | |
| var position = this.x + 'x' + this.y; | |
| $.getJSON('map.getTileData.ajax', {position: position}, function(result) | |
| { | |
| callback.call(this, result); | |
| }); | |
| } | |
| HexTile.prototype.invalidate = function() | |
| { | |
| this.$image = {}; | |
| this.$swatch = null; | |
| INVALIDATED_TILES[this._id] = this; | |
| } | |
| HexTile.prototype.setAttribute = function(key, val, layer) | |
| { | |
| var attribute = key; | |
| if(layer) | |
| attribute = key + ':' + layer.getLayerName(); | |
| this.$attributes[attribute] = { | |
| key: 'key', | |
| value: 'value', | |
| layer: layer | |
| }; | |
| } | |
| HexTile.prototype.removeAttribute = function(key, layer) | |
| { | |
| var attribute = key; | |
| if(layer) | |
| attribute = key + ':' + layer; | |
| if(this.$attributes[attribute]) | |
| delete this.$attributes[attribute]; | |
| } | |
| HexTile.prototype.getIdentity = function() | |
| { | |
| return this.x + 'x' + this.y; | |
| } | |
| HexTile.prototype.getLeft = function() | |
| { | |
| return this._x; | |
| } | |
| HexTile.prototype.getTop = function() | |
| { | |
| return this._y; | |
| } | |
| HexTile.prototype.getCenterX = function() | |
| { | |
| return this._x + this.RADIUS; | |
| } | |
| HexTile.prototype.getCenterY = function() | |
| { | |
| return this._y + this.HEIGHT / 2; | |
| } | |
| HexTile.prototype.getCoordinates = function() | |
| { | |
| return { | |
| 'x': this.x, | |
| 'y': this.y | |
| }; | |
| } | |
| HexTile.prototype.getIndex_X = function() | |
| { | |
| return this.x; | |
| } | |
| HexTile.prototype.getIndex_Y = function() | |
| { | |
| return this.y; | |
| } | |
| HexTile.prototype.getNeighbors = function() | |
| { | |
| } | |
| HexTile.prototype.getNeighborX = function(neighborId_x) | |
| { | |
| return this.x + NEIGHBORS_DI[neighborId_x]; | |
| } | |
| HexTile.prototype.getNeighborY = function(neighborId_x) | |
| { | |
| return this.y + NEIGHBORS_DJ[this.x % 2][neighborId_x]; | |
| } | |
| HexTile.prototype.computeCorners = function(cornersX, cornersY) | |
| { | |
| for(var k = 0; k < NUM_NEIGHBORS; k++) | |
| { | |
| cornersX[k] = mX + this.CORNERS_DX[k]; | |
| cornersY[k] = mY + this.CORNERS_DY[k]; | |
| } | |
| return [cornersX, cornersY]; | |
| } | |
| HexTile.prototype.setCellIndex = function(i, j) | |
| { | |
| this.x = i; | |
| this.y = j; | |
| this._x = i * this.SIDE; | |
| this._y = this.HEIGHT * (2 * j + (i % 2)) / 2; | |
| } | |
| HexTile.prototype.setCellByPoint = function(x, y) | |
| { | |
| this._x = x; | |
| this._y = y; | |
| var ci = parseInt(Math.floor( parseFloat(x) / parseFloat(this.SIDE) )); | |
| var cx = x - this.SIDE * ci; | |
| var ty = y - (ci % 2) * this.HEIGHT / 2; | |
| var cj = parseInt(Math.floor(parseFloat(ty) / parseFloat(this.HEIGHT))); | |
| var cy = ty - this.HEIGHT * cj; | |
| if(cx > Math.abs(this.RADIUS / 2 - this.RADIUS * cy / this.HEIGHT)) | |
| { | |
| this.setCellIndex(ci, cj); | |
| } | |
| else | |
| { | |
| this.setCellIndex(ci - 1, cj + (ci % 2) - ((cy < this.HEIGHT / 2) ? 1 : 0)); | |
| } | |
| } | |
| HexTile.prototype.equals = function(tile) | |
| { | |
| if(this.getIndex_X() == tile.getIndex_X() && | |
| this.getIndex_Y() == tile.getIndex_Y()) | |
| { | |
| return true; | |
| } | |
| return false; | |
| } | |
| HexTile.prototype.isVisible = function(x1, y1, x2, y2) | |
| { | |
| if(this._x < x1 || this._x > x2 || this._y < y1 || this._y > y2) | |
| return false; | |
| return true; | |
| } | |
| HexTile.prototype.save = function(callback) | |
| { | |
| $.ajax({ | |
| type: 'POST', | |
| url: 'map.saveTile.ajax', | |
| data: {tile: JSON.stringify(this)}, | |
| dataType: 'json', | |
| success: callback | |
| }); | |
| } | |
| HexTile.prototype.createImage = function(swatch, radius) | |
| { | |
| var key = swatch + "_" + radius; | |
| if(!this.$image[key]) | |
| { | |
| //Revaluate our tile's data | |
| this.init(); | |
| var canvas = $('<canvas></canvas>') | |
| .attr('width', this.WIDTH + 8) | |
| .attr('height', this.HEIGHT + 8); | |
| var context = canvas[0].getContext('2d'); | |
| var $swatch = SWATCHES[swatch]; | |
| if(!$swatch) console.log("Holy merciful shit, swatch not found: " + swatch); | |
| if(!$swatch) | |
| { | |
| $swatch = SWATCHES['default']; | |
| } | |
| if($swatch.image) | |
| { | |
| canvas.drawImage({ | |
| source: $swatch.image, | |
| x: this.getCenterX() - this.getLeft(), | |
| y: this.getCenterY() - this.getTop(), | |
| fromCenter: true | |
| }); | |
| } | |
| else | |
| { | |
| var defaults = { | |
| fillStyle: $swatch.fillStyle, | |
| strokeStyle: $swatch.strokeStyle, | |
| strokeWidth: $swatch.strokeWidth, | |
| x: this.getCenterX() - this.getLeft() + 4, | |
| y: this.getCenterY() - this.getTop() + 4, | |
| radius: radius, | |
| sides: 6 | |
| }; | |
| var options = $.extend(defaults, {}); | |
| canvas.drawPolygon(options); | |
| } | |
| this.$image[key] = canvas[0].toDataURL(); | |
| } | |
| return this.$image[key]; | |
| } | |
| var HexMapEvents = | |
| { | |
| 'onWindowResize': function() | |
| { | |
| this.$canvas[0].width = ($(window).innerWidth() - 32 ); | |
| this.$canvas[0].height = ($(window).innerHeight() - 32 ); | |
| }, | |
| 'onStageClick': function(game, map, tile, event) | |
| { | |
| if(map.isTileSelected(tile)) | |
| { | |
| if(keydown.alt) | |
| { | |
| var tiles = SELECTED_TILES; | |
| for(var k in tiles) | |
| { | |
| if(tiles[k].equals(tile)) | |
| { | |
| delete SELECTED_TILES[k]; | |
| return; | |
| } | |
| } | |
| } | |
| else if(keydown.shift) | |
| { | |
| return; | |
| } | |
| else | |
| { | |
| map.setSelectedTiles([tile]); | |
| return; | |
| } | |
| } | |
| if($ALLOW_MULTI_SELECT && keydown.shift) | |
| { | |
| var tiles = SELECTED_TILES.concat([tile]); | |
| map.setSelectedTiles(tiles); | |
| return; | |
| } | |
| map.setSelectedTiles([tile]); | |
| } | |
| }; | |
| HexMap = function(canvas) | |
| { | |
| this.canvas = canvas; | |
| this.context = this.canvas[0].getContext('2d'); | |
| this.radius = $MAP_TILE_RADIUS; | |
| this.tile_height = parseInt(this.radius * Math.sqrt(3)); | |
| this.rows = parseInt(canvas.innerHeight() / this.tile_height); | |
| this.columns = parseInt(canvas.innerWidth() / this.radius); | |
| this.$layers = LAYERS; | |
| this.$tiles = {}; | |
| this.$events = HexMapEvents; | |
| this.$events.clickEvents = [ | |
| HexMapEvents.onStageClick | |
| ]; | |
| this.$ui = {}; | |
| this.$ui.coordinate_x = $('.coord_x'); | |
| this.$ui.coordinate_y = $('.coord_y'); | |
| this.$cache = {}; | |
| this.$ui.swatches = { | |
| 'selected': null | |
| }; | |
| } | |
| HexMap.prototype.getTiles = function(page, callback) | |
| { | |
| var totalPages = 0; | |
| page = page ? page : 1; | |
| console.log("Fetching page " + page + " of " + totalPages); | |
| var self = this; | |
| $.getJSON('map.getTiles.ajax', {page: page}, function(result) | |
| { | |
| var len = result.data.length; | |
| totalPages = result.pages; | |
| for(var i = 0; i < len; i++) | |
| { | |
| var row = result.data[i]; | |
| var tile = new HexTile(self.radius); | |
| tile.fromHash(row); | |
| tile.setCellIndex(row.x, row.y); | |
| TILES[tile._id] = tile; | |
| INVALIDATED_TILES[tile._id] = tile; | |
| } | |
| if(page < totalPages) | |
| { | |
| self.getTiles.call(self, page + 1, callback); | |
| } | |
| if(page == totalPages) | |
| { | |
| callback(TILES); | |
| } | |
| }); | |
| } | |
| HexMap.prototype.createTile = function(position, radius) | |
| { | |
| var tile = new HexTile(radius); | |
| tile.setCellIndex(position[0], position[1]); | |
| //Shitty work around while I'm being drunk and lazy | |
| //Going to rewrite tiles anyway. | |
| tile.$attributes.layers = tile.layers; | |
| return tile; | |
| } | |
| HexMap.prototype.isTileSelected = function(tile) | |
| { | |
| for(var k in SELECTED_TILES) | |
| { | |
| var selectedTile = SELECTED_TILES[k]; | |
| if(selectedTile.equals(tile)) | |
| { | |
| return true; | |
| } | |
| } | |
| return false; | |
| } | |
| HexMap.prototype.setSelectedTiles = function(tiles) | |
| { | |
| SELECTED_TILES = tiles; | |
| } | |
| HexMap.prototype.drawGrid = function() | |
| { | |
| } | |
| HexMap.prototype.drawFromCache = function(cache_name, opts) | |
| { | |
| var cache = this.$cache[cache_name]; | |
| if(cache_name.indexOf('data:') !== -1) | |
| { | |
| cache = cache_name; | |
| } | |
| if(cache) | |
| { | |
| var defaults = { | |
| x: 0, | |
| y: 0, | |
| width: this.canvas.width(), | |
| height: this.canvas.height(), | |
| fromCenter: false | |
| }; | |
| var options = $.extend(defaults, opts); | |
| options.source = cache; | |
| this.canvas.drawImage(options); | |
| } | |
| } | |
| HexMap.prototype.findHex = function(position) | |
| { | |
| var mX = position[0]; | |
| var mY = position[1]; | |
| var swatch = null; | |
| var tile = new HexTile($MAP_TILE_RADIUS); | |
| tile.setCellByPoint(mX, mY); | |
| return [tile.x, tile.y]; | |
| } | |
| HexMap.prototype.drawTile = function(tile, layer, cache_name, options) | |
| { | |
| cache_name = null; | |
| if(cache_name && !this.$cache[cache_name]) | |
| { | |
| var canvas = $('<canvas></canvas>') | |
| .attr('width', tile.WIDTH) | |
| .attr('height', tile.HEIGHT); | |
| if(tile.$swatch) | |
| { | |
| this.$cache[cache_name] = tile.$swatch; | |
| } | |
| else | |
| { | |
| var defaults = { | |
| fillStyle: 'black', | |
| strokeStyle: 'white', | |
| strokeWidth: 2, | |
| x: (tile.getCenterX() - tile.getLeft()), | |
| y: (tile.getCenterY() - tile.getTop()), | |
| radius: tile.RADIUS, | |
| sides: 6 | |
| }; | |
| var options = $.extend(defaults, options); | |
| canvas.drawPolygon(options); | |
| this.$cache[cache_name] = canvas[0].toDataURL(); | |
| } | |
| } | |
| else if(!cache_name) | |
| { | |
| if(tile.$swatch) | |
| { | |
| layer.$canvas.drawImage({ | |
| 'source': tile.$swatch, | |
| x: tile.getCenterX(), | |
| y: tile.getCenterY(), | |
| fromCenter:true | |
| }); | |
| } | |
| else | |
| { | |
| var defaults = { | |
| fillStyle: 'black', | |
| strokeStyle: 'white', | |
| strokeWidth: 2, | |
| x: tile.getCenterX(), | |
| y: tile.getCenterY(), | |
| radius: tile.RADIUS, | |
| sides: 6 | |
| }; | |
| var options = $.extend(defaults, options); | |
| layer.$canvas.drawPolygon(options); | |
| } | |
| } | |
| return { | |
| source: this.$cache[cache_name], | |
| x: tile.getCenterX(), | |
| y: tile.getCenterY(), | |
| fromCenter: true | |
| }; | |
| } | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment