/** * @class Visual map display * @param {object} [options] * @param {int} [options.width=ROT.DEFAULT_WIDTH] * @param {int} [options.height=ROT.DEFAULT_HEIGHT] * @param {int} [options.fontSize=15] * @param {string} [options.fontFamily="monospace"] * @param {string} [options.fontStyle=""] bold/italic/none/both * @param {string} [options.fg="#ccc"] * @param {string} [options.bg="#000"] * @param {int} [options.fps=25] * @param {float} [options.spacing=1] * @param {float} [options.border=0] * @param {string} [options.layout="rect"] */ ROT.Display = function(options) { var canvas = document.createElement("canvas"); this._context = canvas.getContext("2d"); this._data = {}; this._dirty = false; /* false = nothing, true = all, object = dirty cells */ this._options = {}; this._backend = null; var defaultOptions = { width: ROT.DEFAULT_WIDTH, height: ROT.DEFAULT_HEIGHT, layout: "rect", fontSize: 15, fps: 25, spacing: 1, border: 0, fontFamily: "monospace", fontStyle: "", fg: "#ccc", bg: "#000" }; for (var p in options) { defaultOptions[p] = options[p]; } this.setOptions(defaultOptions); this.DEBUG = this.DEBUG.bind(this); this._interval = setInterval(this._tick.bind(this), 1000/this._options.fps); } /** * Debug helper, ideal as a map generator callback. Always bound to this. * @param {int} x * @param {int} y * @param {int} what */ ROT.Display.prototype.DEBUG = function(x, y, what) { var colors = [this._options.bg, this._options.fg]; this.draw(x, y, null, null, colors[what % colors.length]); } /** * Clear the whole display (cover it with background color) */ ROT.Display.prototype.clear = function() { this._data = {}; this._dirty = true; } /** * @see ROT.Display */ ROT.Display.prototype.setOptions = function(options) { for (var p in options) { this._options[p] = options[p]; } if (options.width || options.height || options.fontSize || options.fontFamily || options.spacing || options.layout) { if (options.layout) { this._backend = new ROT.Display[options.layout.capitalize()](this._context); } var font = (this._options.fontStyle ? this._options.fontStyle + " " : "") + this._options.fontSize + "px " + this._options.fontFamily; this._context.font = font; this._backend.compute(this._options); this._context.font = font; this._context.textAlign = "center"; this._context.textBaseline = "middle"; this._dirty = true; } return this; } /** * Returns currently set options * @returns {object} Current options object */ ROT.Display.prototype.getOptions = function() { return this._options; } /** * Returns the DOM node of this display * @returns {node} DOM node */ ROT.Display.prototype.getContainer = function() { return this._context.canvas; } /** * Compute the maximum width/height to fit into a set of given constraints * @param {int} availWidth Maximum allowed pixel width * @param {int} availHeight Maximum allowed pixel height * @returns {int[2]} cellWidth,cellHeight */ ROT.Display.prototype.computeSize = function(availWidth, availHeight) { return this._backend.computeSize(availWidth, availHeight, this._options); } /** * Compute the maximum font size to fit into a set of given constraints * @param {int} availWidth Maximum allowed pixel width * @param {int} availHeight Maximum allowed pixel height * @returns {int} fontSize */ ROT.Display.prototype.computeFontSize = function(availWidth, availHeight) { return this._backend.computeFontSize(availWidth, availHeight, this._options); } /** * @param {int} x * @param {int} y * @param {string} ch * @param {string} [fg] foreground color * @param {string} [bg] background color */ ROT.Display.prototype.draw = function(x, y, ch, fg, bg) { if (!fg) { fg = this._options.fg; } if (!bg) { bg = this._options.bg; } this._data[x+","+y] = [x, y, ch, fg, bg]; if (this._dirty === true) { return; } /* will already redraw everything */ if (!this._dirty) { this._dirty = {}; } /* first! */ this._dirty[x+","+y] = true; } /** * Draws a text at given position. Optionally wraps at a maximum length. Currently does not work with hex layout. * @param {int} x * @param {int} y * @param {string} text May contain color/background format specifiers, %c{name}/%b{name}, both optional. %c{}/%b{} resets to default. * @param {int} [maxWidth] wrap at what width? * @returns {int} lines drawn */ ROT.Display.prototype.drawText = function(x, y, text, maxWidth) { var fg = null; var bg = null; var cx = x; var cy = y; var lines = 1; if (!maxWidth) { maxWidth = this._options.width-x; } var tokens = ROT.Text.tokenize(text, maxWidth); while (tokens.length) { /* interpret tokenized opcode stream */ var token = tokens.shift(); switch (token.type) { case ROT.Text.TYPE_TEXT: for (var i=0;i