From 2a7c17aad301e2b0f94c59129ef4bdfc781ed4c1 Mon Sep 17 00:00:00 2001 From: Dobz Date: Tue, 22 May 2012 19:25:03 +1000 Subject: [PATCH] alter grid to better match mockup, fix some broken code --- combat/Arena.js | 36 +++++----- combat/CanvasRenderer.js | 4 +- combat/Creature.js | 144 ++++++++++++++++++------------------- combat/Renderer.js | 2 +- combat/Tile.js | 32 ++++----- combat/TileMap.js | 151 ++++++++++++++++++++------------------- 6 files changed, 184 insertions(+), 185 deletions(-) diff --git a/combat/Arena.js b/combat/Arena.js index f3a83f2d8..627b7c84f 100644 --- a/combat/Arena.js +++ b/combat/Arena.js @@ -15,14 +15,14 @@ Arena.prototype.init = function() { this.arenaRenderer = new CanvasRenderer($("#arena")[0], 17); this.tilesRenderer.resizeToWindow(); this.arenaRenderer.resizeToWindow(); - - this.testCreature = new Creature(this.tileMap.getTileAtIndex(23), this.tilesRenderer); - + + this.testCreature = new Creature(this.tileMap.getTileAtIndex2D(new Vector2D(10, 2)), this.tilesRenderer); + // TODO use callback to do a loading screen this.arenaRenderer.fetchTexture("../locations/forest/bg.jpg", function() { - _this.drawBackground(); + _this.drawBackground(); }); - + // resize events $(window).resize(function () { clearTimeout(_this.windowResizeTimeout); @@ -30,32 +30,32 @@ Arena.prototype.init = function() { _this.onResize(); }, 100); }); - + // Mouse events $(window).on("click", function(e) { _this.mouse = new Vector2D(e.offsetX, e.offsetY); _this.mouse = _this.mouse.toUnitSpace(_this.tilesRenderer); console.log(_this.mouse); if (_this.tileMap.activeTile != null) { - if (_this.selectedCreature == null) { - _this.selectedCreature = _this.tileMap.activeTile.creature; - } else { - _this.selectedCreature.setAtTile(_this.tileMap.activeTile); - } + if (_this.selectedCreature == null) { + _this.selectedCreature = _this.tileMap.activeTile.creature; + } else { + _this.selectedCreature.setAtTile(_this.tileMap.activeTile); + } } }) - + $(window).on("mousemove", function(e){ - _this.mouse = new Vector2D(e.pageX - $(_this.tilesRenderer.canvas).offset().left, - e.pageY - $(_this.tilesRenderer.canvas).offset().top); + _this.mouse = new Vector2D(e.pageX - $(_this.tilesRenderer.canvas).offset().left, + e.pageY - $(_this.tilesRenderer.canvas).offset().top); _this.mouse = _this.mouse.toUnitSpace(_this.tilesRenderer); _this.tileMap.onMouseMove(_this.tilesRenderer, _this.mouse); }); - + window.requestAnimFrame(function () { _this.drawAll(_this.drawTiles, _this.tilesRenderer.canvas); }, _this.tilesRenderer.canvas); - + return true; } @@ -68,7 +68,7 @@ Arena.prototype.onResize = function() { Arena.prototype.drawAll = function(f, element) { var _this = this; - + f.call(this); window.requestAnimFrame(function () { _this.drawAll(f); @@ -89,5 +89,5 @@ Arena.prototype.drawTiles = function() { } Arena.prototype.draw = function() { - + } diff --git a/combat/CanvasRenderer.js b/combat/CanvasRenderer.js index 5702f23ec..9940cf395 100644 --- a/combat/CanvasRenderer.js +++ b/combat/CanvasRenderer.js @@ -26,7 +26,7 @@ CanvasRenderer.prototype.drawLine = function(vertices) { var v = vertices[0].toScreenSpace(this); this.context.moveTo(v.x, v.y); - + for (var i = 1; i < vertices.length; i++) { v = vertices[i].toScreenSpace(this); this.context.lineTo(v.x, v.y); @@ -80,7 +80,7 @@ CanvasRenderer.prototype.resizeCanvas = function(size, isWidth) { } this.unitsPerColumn = this.unitsPerRow / this.gameWidth * this.gameHeight; this.pixelsPerUnit = this.gameWidth / this.unitsPerRow; - + $(this.canvas).parent().css({ "width": (this.gameWidth + 64) + "px", "height": (this.gameHeight + 64) + "px", diff --git a/combat/Creature.js b/combat/Creature.js index ded6e139c..c58adaf98 100644 --- a/combat/Creature.js +++ b/combat/Creature.js @@ -1,92 +1,90 @@ function Creature(centerTile, renderer) { + this.name = "Magma Spwan"; + // collision map: + // 0 does not collide on this tile + // 1 collides on this tile + // 2 blocks tile for creatures, but does not collide with terrain (flying) + this.collisionMap = [ + [1,1,1] + ]; - this.name = "Magma Spwan"; - // collision map: - // 0 does not collide on this tile - // 1 collides on this tile - // 2 blocks tile for creatures, but does not collide with terrain (flying) - this.collisionMap = [ - [0,1,1], - [1,1,1] - ]; - - // TODO move into Sprite class - this.position = Vector2D(0,0); - this.size = new Vector2D(3,2.3); //TODO set size relative to tileSize - this.texturePosition = new Vector2D(0,0); - this.textureSize = new Vector2D(275, 211); - this.footOffset = new Vector2D(0.8, 0); //TODO set as pixel and convert -// this.footPosition.toUnitSpace(renderer); - - this.image = "../bestiary/Magma Spawn/cardboard.png"; - renderer.fetchTexture("../bestiary/Magma Spawn/cardboard.png", this.onReady); - - this.setAtTile(centerTile); //TODO add a check if is free + // TODO move into Sprite class + this.position = Vector2D(0,0); + this.size = new Vector2D(3,2.3); //TODO set size relative to tileSize + this.texturePosition = new Vector2D(0,0); + this.textureSize = new Vector2D(275, 211); + this.footOffset = new Vector2D(1, 1.7); //TODO set as pixel and convert +// this.footPosition.toUnitSpace(renderer); + + this.image = "../bestiary/Magma Spawn/cardboard.png"; + renderer.fetchTexture("../bestiary/Magma Spawn/cardboard.png", this.onReady); + + this.setAtTile(centerTile); //TODO add a check if is free } // TODO extend from sprite Creature.prototype = new Drawable(); Creature.prototype.draw = function(renderer) { - renderer.bindTexture("../bestiary/Magma Spawn/cardboard.png"); - renderer.drawImage(this.position, this.size, this.texturePosition, this.textureSize); + renderer.bindTexture("../bestiary/Magma Spawn/cardboard.png"); + renderer.drawImage(this.position, this.size, this.texturePosition, this.textureSize); } // call when all textures are loaded and the Creature is ready to be displayed Creature.prototype.onReady = function() { - if (this.onReadyCallback) { - this.onReadyCallback(); - } + if (this.onReadyCallback) { + this.onReadyCallback(); + } } //TODO shift offset rows Creature.prototype.setAtTile = function(tile) { - var tileMap = tile.tileMap; - //TODO use a footPosition Vector2D - this.position = tileMap.getTilePosition(tile); - this.position = this.position.substract(this.footOffset); - - // clear old surrounding collision tiles - if (this.centerTile) { - for (var y=0; y < this.collisionMap.length; ++y) { - for (var x=0; x < this.collisionMap[y].length; ++x) { - if (this.collisionMap[y][x] > 0) { - var t = tileMap.getTileRelativeTo(this.centerTile, Math.floor(-(this.collisionMap[y].length/2)+x+1), - Math.floor(-(this.collisionMap.length/2)+y+1)); - t.creature = null; - t.filled = false; - } - } - } - } - - // occupy surrounding collision tiles - for (var y=0; y < this.collisionMap.length; ++y) { - for (var x=0; x < this.collisionMap[y].length; ++x) { - if (this.collisionMap[y][x] > 0) { - var t = tileMap.getTileRelativeTo(tile, Math.floor(-(this.collisionMap[y].length/2)+x+1), - Math.floor(-(this.collisionMap.length/2)+y+1)); - t.creature = this; - t.filled = true; - } - } - } - this.centerTile = tile; + var tileMap = tile.tileMap; + //TODO use a footPosition Vector2D + this.position = tileMap.getTilePosition(tile); + this.position = this.position.substract(this.footOffset); + + // clear old surrounding collision tiles + if (this.centerTile) { + for (var y=0; y < this.collisionMap.length; ++y) { + for (var x=0; x < this.collisionMap[y].length; ++x) { + if (this.collisionMap[y][x] > 0) { + var t = tileMap.getTileRelativeTo(this.centerTile, Math.floor(-(this.collisionMap[y].length/2)+x+1), + Math.floor(-(this.collisionMap.length/2)+y+1)); + t.creature = null; + t.filled = false; + } + } + } + } + + // occupy surrounding collision tiles + for (var y=0; y < this.collisionMap.length; ++y) { + for (var x=0; x < this.collisionMap[y].length; ++x) { + if (this.collisionMap[y][x] > 0) { + var t = tileMap.getTileRelativeTo(tile, Math.floor(-(this.collisionMap[y].length/2)+x+1), + Math.floor(-(this.collisionMap.length/2)+y+1)); + t.creature = this; + t.filled = true; + } + } + } + this.centerTile = tile; } Creature.prototype.setTileStyle = function(filled, fillColor, color) { - //TODO write foreachTile funciton to avoid the same for loop over and over again - var tileMap = this.centerTile.tileMap; - if (this.centerTile) { - for (var y=0; y < this.collisionMap.length; ++y) { - for (var x=0; x < this.collisionMap[y].length; ++x) { - if (this.collisionMap[y][x] > 0) { - var t = tileMap.getTileRelativeTo(this.centerTile, Math.floor(-(this.collisionMap[y].length/2)+x+1), - Math.floor(-(this.collisionMap.length/2)+y+1)); - filled != null ? t.filled = filled : 0; - fillColor != null ? t.fillColor = fillColor : 0; - color != null ? t.color = color : 0; - } - } - } - } + //TODO write foreachTile funciton to avoid the same for loop over and over again + var tileMap = this.centerTile.tileMap; + if (this.centerTile) { + for (var y=0; y < this.collisionMap.length; ++y) { + for (var x=0; x < this.collisionMap[y].length; ++x) { + if (this.collisionMap[y][x] > 0) { + var t = tileMap.getTileRelativeTo(this.centerTile, Math.floor(-(this.collisionMap[y].length/2)+x+1), + Math.floor(-(this.collisionMap.length/2)+y+1)); + filled != null ? t.filled = filled : 0; + fillColor != null ? t.fillColor = fillColor : 0; + color != null ? t.color = color : 0; + } + } + } + } } diff --git a/combat/Renderer.js b/combat/Renderer.js index 4e817bcf8..6e148fc10 100644 --- a/combat/Renderer.js +++ b/combat/Renderer.js @@ -6,7 +6,7 @@ function Renderer(unitsPerRow) { this.gameWidth = 16; this.gameHeight = 9; this.unitsPerRow = unitsPerRow || 20; - this.unitsPerColumn = this.unitsPerRow / this.gameWidth * this.gameHeight; + this.unitsPerColumn = this.unitsPerRow / this.aspectRatio; this.pixelsPerUnit = this.gameWidth / this.unitsPerRow; } diff --git a/combat/Tile.js b/combat/Tile.js index 304dd28ca..37408d5e5 100644 --- a/combat/Tile.js +++ b/combat/Tile.js @@ -1,26 +1,26 @@ function Tile(shape, color) { - this.shape = shape; - this.color = color || "#739141"; - this.fillColor = "rgba(250, 145, 65, 0.2)"; + this.shape = shape; + this.color = color || "#739141"; + this.fillColor = "rgba(250, 145, 65, 0.2)"; - this.creature = null; - this.trap = null; - this.terrain = 1; // TODO create Enum 0:default 1:walkable 2:blocked. - this.terrainType = 0; // Elemental type, water, lava, aso - this.lineWidth = 0.04; + this.creature = null; + this.trap = null; + this.terrain = 1; // TODO create Enum 0:default 1:walkable 2:blocked. + this.terrainType = 0; // Elemental type, water, lava, aso + this.lineWidth = 0.04; } Tile.prototype = new Drawable(); Tile.prototype.draw = function(renderer) { - if (this.filled) { - renderer.setColor(this.fillColor); - renderer.setLineWidth(this.lineWidth); - renderer.drawPolygon(this.shape); - } - renderer.setColor(this.color); - renderer.setLineWidth(this.lineWidth); - renderer.drawLine(this.shape); + if (this.filled) { + renderer.setColor(this.fillColor); + renderer.setLineWidth(this.lineWidth); + renderer.drawPolygon(this.shape); + } + renderer.setColor(this.color); + renderer.setLineWidth(this.lineWidth); + renderer.drawLine(this.shape); } // TODO apply effects like water, lava, traps to creature on tile diff --git a/combat/TileMap.js b/combat/TileMap.js index 7fc0f93f3..bc21af323 100644 --- a/combat/TileMap.js +++ b/combat/TileMap.js @@ -4,20 +4,21 @@ function TileMap(columns, rows) { // Location of TileMap this.tilesTranslation = new Vector2D(0.25, 3.5); - this.columns = columns || 2; - this.rows = rows || 2; - this.activeTile = null; - - var hexagon = MathUtils.generateTessellatingHexagon(); - this.tileSeparation = hexagon.tile; - this.tileShape = hexagon.vertices; - - var size = this.rows*this.columns; - this.tiles = new Array(); - for (var i=0; i < size; ++i) { - this.tiles.push(new Tile(this.tileShape)); - this.tiles[i].tileMap = this; - } + this.columns = columns || 2; + this.rows = rows || 2; + this.activeTile = null; + + var hexagon = MathUtils.generateTessellatingHexagon(); + this.tileSeparation = hexagon.tile; + console.log(this.tileSeparation); + this.tileShape = hexagon.vertices; + + var size = this.rows*this.columns; + this.tiles = new Array(); + for (var i=0; i < size; ++i) { + this.tiles.push(new Tile(this.tileShape)); + this.tiles[i].tileMap = this; + } } TileMap.prototype.draw = function(renderer) { @@ -27,11 +28,11 @@ TileMap.prototype.draw = function(renderer) { for (var y=0; y < this.rows; ++y) { for (var x=0; x < this.columns; ++x) { renderer.save(); - var offset = new Vector2D(y % 2 == 0 ? this.tilesSize.x * 0.5 : 0, 0); + var offset = new Vector2D(y % 2 == 0 ? 0 : this.tilesSize.x * 0.5, 0); var translate = new Vector2D(offset.x + x * this.tileSeparation.x, offset.y + y * this.tileSeparation.y); renderer.translate(translate); - this.tiles[y*this.columns + x].draw(renderer); + this.tiles[y*this.columns + x].draw(renderer); renderer.restore(); } @@ -41,91 +42,90 @@ TileMap.prototype.draw = function(renderer) { /// @return Vector2D the actual x,y position the tile has on the renderer target. TileMap.prototype.getTilePosition = function(tile) { - var rowHeight = (this.tilesSize.y*this.tileSeparation.y); - var columnWidth = (this.tilesSize.x*this.tileSeparation.x); - var tileIndex2D = this.getTileIndex2D(tile); - var position = new Vector2D(tileIndex2D.x * columnWidth, tileIndex2D.y * rowHeight); - var offsetX = tileIndex2D.y % 2 == 0 ? columnWidth * 0.5 : 0; + var tileIndex2D = this.getTileIndex2D(tile); + var position = new Vector2D(tileIndex2D.x, tileIndex2D.y); + var offsetX = tileIndex2D.y % 2 == 0 ? 0 : 0.5; position.x = position.x + offsetX; - position = position.add(this.tilesTranslation); position = position.multiply(this.tilesSize); - return position; + position = position.multiply(this.tileSeparation); + position = position.add(this.tilesTranslation); + return position; } TileMap.prototype.getTileRelativeTo = function(tile, xRelative, yRelative) { - var index = this.getTileIndex(tile); - index += xRelative; - index += yRelative*this.columns; - return this.getTileAtIndex(index); + var index = this.getTileIndex(tile); + index += xRelative; + index += yRelative*this.columns; + return this.getTileAtIndex(index); } TileMap.prototype.getTileIndex = function(tile) { - for (var i=0; i < ++this.tiles.length; ++i) { - if (tile == this.tiles[i]) { - return i; - } - } - console.log("Warning: trying to find a tile that's not on this tilemap:" + tile) - return -1; + for (var i=0; i < this.tiles.length; ++i) { + if (tile == this.tiles[i]) { + return i; + } + } + console.log("Warning: trying to find a tile that's not on this tilemap:" + tile) + return -1; } TileMap.prototype.getTileIndex2D = function(tile) { - var index = this.getTileIndex(tile); - if (index > -1) { - return new Vector2D(index % this.columns, (index - (index % this.columns))/ this.rows); - } else { - return null; - } + var index = this.getTileIndex(tile); + if (index > -1) { + return new Vector2D(index % this.columns, (index - (index % this.columns)) / this.columns); + } else { + return null; + } } TileMap.prototype.getTileAtIndex = function(index) { - if (this.isValidIndex(index)) { - return this.tiles[index]; - } else { - console.log("Warning: trying to access invalid index of Tilemap: " + index); - return null; - } + if (this.isValidIndex(index)) { + return this.tiles[index]; + } else { + console.log("Warning: trying to access invalid index of Tilemap: " + index); + return null; + } } TileMap.prototype.getTileAtIndex2D = function(index) { - return getTileIndex(index.y*this.columns+index.x); + return this.getTileAtIndex(index.y*this.columns+index.x); } TileMap.prototype.isValidIndex = function(index) { - return index >= 0 && index < this.columns*this.rows; + return index >= 0 && index < this.columns*this.rows; } TileMap.prototype.isValidIndex2D = function(index2D) { - return index.x >= 0 && index.y >= 0 && index.x < this.columns && index.y < this.rows; + return index.x >= 0 && index.y >= 0 && index.x < this.columns && index.y < this.rows; } // TODO move into a child class so that this one stays more independent form logic TileMap.prototype.onMouseMove = function(renderer, mouse) { - this.mouse = mouse; + this.mouse = mouse; - var newActiveTile = this.getActiveTile(renderer, mouse); - //TODO group if blocks - + var newActiveTile = this.getActiveTile(renderer, mouse); + //TODO group if blocks + if (this.activeTile != null) { - this.activeTile.filled = false; + this.activeTile.filled = false; + } + + // Highlight selected Creature's tiles + if (this.activeTile != null && this.activeTile.creature == this.activeCreature && this.activeCreature != null) { + this.activeTile.creature.setTileStyle(false, "rgba(65, 145, 250, 0.2)"); + } + + if (newActiveTile != null && newActiveTile.creature != null) { + newActiveTile.creature.setTileStyle(true, "rgba(65, 145, 250, 0.2)"); + this.activeCreature = newActiveTile.creature; } - - // Highlight selected Creature's tiles - if (this.activeTile != null && this.activeTile.creature == this.activeCreature && this.activeCreature != null) { - this.activeTile.creature.setTileStyle(false, "rgba(65, 145, 250, 0.2)"); - } - - if (newActiveTile != null && newActiveTile.creature != null) { - newActiveTile.creature.setTileStyle(true, "rgba(65, 145, 250, 0.2)"); - this.activeCreature = newActiveTile.creature; - } if (newActiveTile != null) { - newActiveTile.filled = true; - newActiveTile.fillColor = "rgba(250, 145, 65, 0.2)"; - this.activeTile = newActiveTile; + newActiveTile.filled = true; + newActiveTile.fillColor = "rgba(250, 145, 65, 0.2)"; + this.activeTile = newActiveTile; } else { - this.activeTile = null; + this.activeTile = null; } } @@ -133,25 +133,26 @@ TileMap.prototype.onMouseMove = function(renderer, mouse) { TileMap.prototype.getActiveTile = function(renderer, mouse) { var rowHeight = (this.tilesSize.y*this.tileSeparation.y); var columnWidth = (this.tilesSize.x*this.tileSeparation.x); + var halfColumnWidth = columnWidth * 0.5; var activeTile = null; if (mouse.x > this.tilesTranslation.x && mouse.y > this.tilesTranslation.y && - mouse.x < this.tilesTranslation.x + columnWidth*(this.columns+1) && - mouse.y < this.tilesTranslation.y + rowHeight*this.rows ) { + mouse.x < this.tilesTranslation.x + columnWidth * this.columns + halfColumnWidth && + mouse.y < this.tilesTranslation.y + rowHeight * this.rows) { var translatedMouse = mouse.substract(this.tilesTranslation); var activeRow = Math.floor(translatedMouse.y / rowHeight) % this.rows; - var offsetX = activeRow % 2 == 0 ? columnWidth * 0.5 : 0; - var activeColumn = Math.floor((translatedMouse.x-offsetX) / columnWidth) % this.columns; + var isOddRow = (activeRow % 2) == 0; + var activeColumn = Math.floor((translatedMouse.x - (isOddRow ? 0 : halfColumnWidth)) / columnWidth) % this.columns; // ignore if past the offset - if ((activeRow % 2 == 0 && translatedMouse.x < columnWidth) || - (activeRow % 2 != 0 && translatedMouse.x-offsetX > columnWidth*this.columns || activeColumn == -1)) { + if ((!isOddRow && translatedMouse.x < halfColumnWidth) || + (isOddRow && translatedMouse.x > columnWidth * this.columns || activeColumn == -1)) { activeTile = null; $(renderer.canvas).removeClass("cursorPointer"); } else { - activeTile = this.tiles[activeRow* this.columns + activeColumn]; + activeTile = this.tiles[activeRow * this.columns + activeColumn]; $(renderer.canvas).addClass("cursorPointer"); }