/**
* Represents a single Tile object to be contained within a Grid.
* @constructor
* @param {number} tileW - The width of this tile in WC.
* @param {number} tileH - The height of this tile in WC.
* @param {number} tileX - The x coordinate of this tile in WC.
* @param {number} tileY - The y coordinate of this tile in WC.
* @param {boolean} isEdge - The property determining if this tile is on the edge of the Grid its in.
*/
function Tile(tileW, tileH, tileX, tileY, isEdge) {
this.mXPos = tileX;
this.mYPos = tileY;
this.mWidth = tileW;
this.mHeight = tileH;
this.mTexture = null;
this.mRenderComponent = null;
this.mCollidable = false;
this.mVisible = false;
this.mGridLinesVisible = false;
this.mWallsVisible = false;
this.mWalls = [];
this.mMoves = [];
this.mIsEdge = isEdge;
this.mCost = 0;
this.mHCost = 0;
this.mDirection = [0, 0]; // code for stop
this.mParent = [-1, -1];
this.mWallLines = [];
// initialize moves
this.mMoves.push([1, 0]);
this.mMoves.push([-1, 0]);
this.mMoves.push([0, 1]);
this.mMoves.push([0, -1]);
// now, create the edge lines
this._createEdgeLines(tileW, tileH, tileX, tileY);
}
// Draw the tile as LineRenderables around the bounds of the tile.
/**
* Draws the tile as visible lines around its bounds. Also draws its texture if it has one and is set to visible.
* @param {Camera} cam - The Camera object to draw the tile to.
*/
Tile.prototype.draw = function(cam) {
// draw the renderable of the texture if exists and is visible
if (this.mVisible === true && this.mRenderComponent !== null) {
this.mRenderComponent.draw(cam);
}
// if we have set the edges to be visible
if (this.mGridLinesVisible === true) {
// if this is an edge tile, draw the top and left LineRenderables
if (this.mIsEdge === true) {
// draw left and top LineRenderables
this.mEdgeLines[0].draw(cam); // the left line
this.mEdgeLines[1].draw(cam); // the top line
}
// draw bottom and right LineRenderables
this.mEdgeLines[2].draw(cam); // the right line
this.mEdgeLines[3].draw(cam); // the bottom line
}
// draw wall lines
if (this.mWallsVisible) {
for (var i = 0; i < this.mWalls.length; i++) {
// if this is top or bottom
if (this.mWalls[i][0] === 0) {
if (this.mWalls[i][1] === -1) {
// bottom wall
this.mWallLines[3].draw(cam);
} else {
// top wall
this.mWallLines[1].draw(cam);
}
}
else {
// else, this is a left or right wall
if (this.mWalls[i][0] === -1) {
// left wall
this.mWallLines[0].draw(cam);
} else {
// right wall
this.mWallLines[2].draw(cam);
}
}
}
}
};
/**
* Gets the x position of the center of the tile in WC.
* @returns {number} The x position of the tile center in WC.
*/
Tile.prototype.getXPosWC = function() {
return this.mXPos;
};
/**
* Gets the y position of the center of the tile in WC.
* @returns {number} The y position of the tile center in WC.
*/
Tile.prototype.getYPosWC = function() {
return this.mYPos;
};
/**
* Gets the collision property of this tile.
* @returns {boolean} True if this tile has collision on, false otherwise.
*/
Tile.prototype.getCollision = function() {
return this.mCollidable;
};
/**
* Sets the collision property of this tile.
* @param {boolean} bool - The value to set the collision property of this tile to.
*/
Tile.prototype.setCollision = function(bool) {
this.mCollidable = bool;
};
// Push given direction to the walls array.
// Might also want a func that can remove walls.
// Return true if new wall was added, false if the wall already exists.
/**
* Adds the given direction to the walls array for this particular tile.
* @param {Direction} direction - The direction to add a wall to for this tile.
* @returns {boolean} True if the wall was able to be added, false otherwise.
*/
Tile.prototype.addWall = function(direction) {
for (var i = 0; i < this.mWalls.length; i++) {
if (direction === this.mWalls[i]) {
return false;
}
}
var temp = this.mMoves.indexOf(direction);
if (temp > -1) {
this.mMoves.splice(temp, 1); // remove the direction from moves
}
this.mWalls.push(direction);
return true;
};
/**
* Removes the given direction to the walls array for this particular tile.
* @param {Direction} direction - The direction to remove a wall to for this tile.
* @returns {boolean} True if the wall was able to be removed, false otherwise.
*/
Tile.prototype.removeWall = function(direction) {
for (var i = 0; i < this.mWalls.length; i++) {
if (direction[0] === this.mWalls[i][0] && direction[1] === this.mWalls[i][1]) {
this.mWalls.splice(i, 1);
this.mMoves.push(direction);
return true;
}
}
return false;
};
/**
* Gets all the walls currently assigned to this tile.
* @returns {array} All the directional walls assigned to this tile.
*/
Tile.prototype.getWalls = function() {
return this.mWalls;
};
/**
* Gets all the valid moves out of a particular tile. That is, any side of this tile that doesn't have a wall.
* @returns {array} All the directional movements possible out of this tile.
*/
Tile.prototype.getMoves = function() {
return this.mMoves;
};
// May modify later to support passing specific texture renderables to fill a tile with,
// rather than just a texture path corresponding to a loaded texture asset.
/**
* Sets the texture for this tile to the texture corresponding to a given filepath.
* @param {String} texture - The filepath to an already loaded texture to set the tile to contain.
*/
Tile.prototype.setTexture = function(texture) {
this.mRenderComponent = new TextureRenderable(texture);
this.mRenderComponent.setColor([1, 1, 1, 0]);
this.mRenderComponent.getXform().setPosition(this.mXPos, this.mYPos);
this.mRenderComponent.getXform().setSize(this.mWidth, this.mHeight);
this.mTexture = texture;
};
/**
* Gets the visibility property of this tile.
* @return {boolean} True if this tile is set to visible, false otherwise.
*/
Tile.prototype.isVisible = function() {
return this.mVisible;
};
/**
* Sets the visibility of the tile. Cannot set a tile to visible if it doesn't have an assigned texture.
* @param {boolean} setTo - The value to set the visibility property to.
* @returns {boolean} True if the settting was successful, false otherwise.
*/
Tile.prototype.setVisible = function(setTo) {
if (this.mTexture === null) { // No texture, so don't modify visibility.
return false;
} else {
this.mVisible = setTo;
return true;
}
};
/**
* Sets the visibility property of the grid lines around this tile.
* @param {boolean} setTo - The value to set the grid line visibility to.
*/
Tile.prototype.setGridLineVisibility = function(setTo) {
this.mGridLinesVisible = setTo;
};
/**
* Sets the visibility property of the wall lines around this tile.
* @param {boolean} setTo - The value to set the wall line visibility to.
*/
Tile.prototype.setWallVisibility = function(setTo) {
this.mWallsVisible = setTo;
};
/**
* Generates the edge line renderables around this particular tile on creation.
* @private
* @param {number} tileW - The width of this tile in WC.
* @param {number} tileH - The height of this tile in WC.
* @param {number} tileX - The x coordinate of this tile in WC.
* @param {number} tileY - The y coordinate of this tile in WC.
*/
Tile.prototype._createEdgeLines = function(tileW, tileH, tileX, tileY) {
this.mEdgeLines = [];
var leftX = tileX - (tileW / 2);
var rightX = tileX + (tileW / 2);
var topY = tileY + (tileH / 2);
var bottomY = tileY - (tileH / 2);
var leftLine = new LineRenderable(leftX, topY, leftX, bottomY);
var rightLine = new LineRenderable(rightX, topY, rightX, bottomY);
var topLine = new LineRenderable(leftX, topY, rightX, topY);
var bottomLine = new LineRenderable(leftX, bottomY, rightX, bottomY);
this.mEdgeLines.push(leftLine);
this.mEdgeLines.push(topLine);
this.mEdgeLines.push(rightLine);
this.mEdgeLines.push(bottomLine);
};
/**
* Generates the wall line renderables around this particular tile on creation.
* @private
* @param {number} tileW - The width of this tile in WC.
* @param {number} tileH - The height of this tile in WC.
* @param {number} tileX - The x coordinate of this tile in WC.
* @param {number} tileY - The y coordinate of this tile in WC.
*/
Tile.prototype._createWallLines = function(tileW, tileH, tileX, tileY) {
var leftX = tileX - (tileW / 2);
var rightX = tileX + (tileW / 2);
var topY = tileY + (tileH / 2);
var bottomY = tileY - (tileH / 2);
var leftLine = new LineRenderable(leftX, topY, leftX, bottomY);
leftLine.setColor([1, 1, 1, 1]);
var rightLine = new LineRenderable(rightX, topY, rightX, bottomY);
rightLine.setColor([1, 1, 1, 1]);
var topLine = new LineRenderable(leftX, topY, rightX, topY);
topLine.setColor([1, 1, 1, 1]);
var bottomLine = new LineRenderable(leftX, bottomY, rightX, bottomY);
bottomLine.setColor([1, 1, 1, 1]);
this.mWallLines.push(leftLine);
this.mWallLines.push(topLine);
this.mWallLines.push(rightLine);
this.mWallLines.push(bottomLine);
};
/**
* Resets any data stored from previous A* searches to their default values.
*/
Tile.prototype.readySearch = function() {
this.mCost = 0;
this.mHCost = 0;
this.mDirection = [0, 0];
this.mParent = [-1, -1];
};
/**
* Used for A* search. Sets the cost for the tile.
* @param {number} c The total cost of reaching this tile.
*/
Tile.prototype.setC = function(c) { this.mCost = c; };
/**
* Used for A* search. Retrieves the cost for the tile.
* @returns {number} The total cost of reaching this tile.
*/
Tile.prototype.getC = function() { return this.mCost; };
/**
* Used for A* search. Stores the given heuristic estimate for the tile.
* @param {number} h The estimate to the goal given by a heuristic.
*/
Tile.prototype.setH = function(h) { this.mHCost = h; };
/**
* Used for A* search. Retrieves the given heuristic estimate for the tile.
* @returns {number} The estimate to the goal given by a heuristic.
*/
Tile.prototype.getH = function() { return this.mHCost; };
/**
* Used for A* search. Returns the combined total of the tile's cost and heuristic.
* @returns {number} The combined total of the tile's cost and heuristic..
*/
Tile.prototype.getF = function() { return this.mCost + this.mHCost; };
/**
* Used for A* search. Sets the direction we took to get to this tile.
* @param {array} d Array containing a direction.
*/
Tile.prototype.setD = function(d) { this.mDirection = d; };
/**
* Used for A* search. Returns the direction we took to get to this tile.
* @returns {array} Array containing a direction.
*/
Tile.prototype.getD = function() { return this.mDirection; };
/**
* Used for A* search. Sets the predecessor to this tile.
* @param {array} p Array containing the index of the predecessor tile.
*/
Tile.prototype.setP = function(p) { this.mParent = [p[0], p[1]]; };
/**
* Used for A* search. Returns the predecessor to this tile. If no predecessor,
* returns [-1, -1].
* @returns {array} Array containing the index of the predecessor tile.
*/
Tile.prototype.getP = function() { return this.mParent; };
/**
* Method used during A* search. Determines if this tile has a predecessor tile or not.
* @returns {boolean} Whether this tile has a predecessor tile or not.
*/
Tile.prototype.hasP = function() {
return ((this.mParent[0] > -1) && (this.mParent[1] > -1));
};