homepage/glow.js
2026-05-17 22:57:30 +02:00

369 lines
9.4 KiB
JavaScript

/**
* This script handles all the background "Easter egg" action.
*
* The great rogue-like game engine ROT.js was taken (stolen) from:
* Ondrej Zara, http://ondras.zarovi.cz/
*
* -- Dejvino, 2013
*/
function initBackground()
{
$(document).ready(function() {
enableDungeon($("#glow-holder"));
$("#activators").show();
$("#stop").hide();
$("#play").click(function() {
$("#play").hide();
$("#stop").show();
$("#main-content").hide();
$("#overlay-one").hide();
});
$("#stop").click(function() {
$("#stop").hide();
$("#play").show();
$("#main-content").show();
$("#overlay-one").show();
});
});
}
function enableDungeon(holder)
{
window._reloadLock = 0;
$(window).resize(function () {
makeFullscreen('#rogue-canvas');
makeFullscreen('#overlay-one');
makeFullscreen('#overlay-two');
window._reloadLock += 1;
setTimeout("deferedInit(" + window._reloadLock + ")", 500);
}).resize();
}
function deferedInit(lock)
{
if (window._reloadLock != lock || lock == 1) {
return;
}
if (Math.abs(Game.width * Game.cellWidth - $(window).width()
+ Game.height * Game.cellHeight - $(window).height()) < 60) {
return;
}
Game.init();
makeFullscreen('#rogue-canvas');
}
function makeFullscreen(elem)
{
$(elem).css({
'width': $(window).width(),
'height': $(window).height(),
'left': '0px',
'top':'0px'
});
}
/******************************************************************************
*
* Game
*
*****************************************************************************/
var Game = {
width: null,
height: null,
cellWidth: 15,
cellHeight: 24,
display: null,
map: {},
mapColor: {},
freeCells: [],
engine: null,
player: null,
goblins: {},
imgFloor: '.',
colorWall: "#530",
colorFloor: "#444",
inited: false,
scheduler: null,
init: function() {
this.map = {};
this.freeCells = [];
this.goblins = {};
this.width = $(window).width() / Game.cellWidth;
this.height = $(window).height() / Game.cellHeight;
var fontSize = 64;
// (re)create canvas
$("canvas").remove();
this.display = new ROT.Display({width:this.width, height:this.height, spacing:1.0, fontSize:fontSize});
document.body.appendChild(this.display.getContainer());
$("canvas").attr("id", "rogue-canvas");
$("#rogue-canvas").appendTo("#glow-holder").show();
if (this.inited) {
this.scheduler.clear();
}
this._generateMap();
this.scheduler = new ROT.Scheduler.Simple();
this.engine = new ROT.Engine(this.scheduler);
this.scheduler.add(this.player, true);
for (var i in this.goblins) {
this.scheduler.add(this.goblins[i], true);
}
if (!this.inited) {
this.engine.start();
}
this.inited = true;
},
makeKey: function(x,y) {
return x+","+y;
},
parseKey: function(key) {
var parts = key.split(",");
var x = parseInt(parts[0]);
var y = parseInt(parts[1]);
return {x: x, y: y};
},
getRandomFreeCell: function() {
var dests = this.freeCells;
return dests[Math.floor(dests.length * Math.random())];
},
_generateMap: function() {
var digger = new ROT.Map.Digger();
var tryMakeWall = function(x,y, img) {
var key = x+","+y;
if (Game.map[key]) {
if (img != '-' && img != '|') {
return;
} else if (Game.map[key] == Game.imgFloor) {
return;
}
}
Game.map[key] = img;
Game.mapColor[key] = Game.colorWall;
};
var digCallback = function(x, y, value) {
if (value) { return; }
var key = x+","+y;
Game.map[key] = Game.imgFloor;
Game.mapColor[key] = Game.colorFloor;
Game.freeCells.push(key);
tryMakeWall(x-1, y-1, "+");
tryMakeWall(x+1, y-1, "+");
tryMakeWall(x-1, y+1, "+");
tryMakeWall(x+1, y+1, "+");
tryMakeWall(x-1, y, "|");
tryMakeWall(x+1, y, "|");
tryMakeWall(x, y-1, "-");
tryMakeWall(x, y+1, "-");
}
digger.create(digCallback.bind(this));
this._generateBoxes(Game.freeCells);
this._drawWholeMap();
this.player = this._createBeing(Player, Game.freeCells);
for (var i = 0; i < 10; i++) {
this.goblins[i] = this._createBeing(Goblin, Game.freeCells);
}
},
_createBeing: function(what, freeCells) {
var index = Math.floor(ROT.RNG.getUniform() * freeCells.length);
var key = freeCells.splice(index, 1)[0];
var parts = key.split(",");
var x = parseInt(parts[0]);
var y = parseInt(parts[1]);
return new what(x, y);
},
_generateBoxes: function(freeCells) {
for (var i=0;i<10;i++) {
var index = Math.floor(ROT.RNG.getUniform() * freeCells.length);
var key = freeCells.splice(index, 1)[0];
}
},
_drawMapCell: function(x,y) {
var key = x+","+y;
if (key in this.map) {
this.display.draw(x, y, this.map[key], this.mapColor[key]);
}
},
_drawWholeMap: function() {
this.display.clear();
for (var key in this.map) {
var parts = key.split(",");
var x = parseInt(parts[0]);
var y = parseInt(parts[1]);
this._drawMapCell(x,y);
}
},
passableCallback: function(x, y) {
var key = x+","+y;
return (key in Game.map && Game.map[key] == Game.imgFloor);
}
};
/******************************************************************************
*
* Player
*
*****************************************************************************/
var Player = function(x, y) {
this._dest = null;
this._x = x;
this._y = y;
this._draw();
}
Player.prototype.getSpeed = function() { return 100; }
Player.prototype.getX = function() { return this._x; }
Player.prototype.getY = function() { return this._y; }
Player.prototype.act = function() {
Game.engine.lock();
this._move();
setTimeout("Game.engine.unlock();", 1000);
}
Player.prototype._draw = function() {
Game.display.draw(this._x, this._y, "@", "#ff0");
}
Player.prototype._move = function() {
// generate a new quest if needed
if (!this._dest) {
this._dest = Game.getRandomFreeCell();
}
var destPos = Game.parseKey(this._dest);
var astar = new ROT.Path.AStar(destPos.x, destPos.y, Game.passableCallback, {topology:4});
var path = [];
var pathCallback = function(x, y) {
path.push([x, y]);
}
astar.compute(this._x, this._y, pathCallback);
path.shift();
if (!path || path.length <= 1) {
// new quest!
this._dest = null;
} else {
x = path[0][0];
y = path[0][1];
Game._drawMapCell(this._x, this._y);
this._x = x;
this._y = y;
this._draw();
}
}
/******************************************************************************
*
* Goblins
*
*****************************************************************************/
var Goblin = function(x, y) {
this._x = x;
this._y = y;
this._draw();
this._dead = 0;
var icons = ['g', 'z', 'k', 'd', 's'];
this._icon = icons[Math.floor(icons.length * Math.random())];
}
Goblin.prototype.getSpeed = function() { return 100; }
Goblin.prototype.act = function() {
if (this._dead > 0) {
this._dead -= 1;
if (this._dead <= 0) {
// teleport!
Game._drawMapCell(this._x, this._y);
var tel = Game.parseKey(Game.getRandomFreeCell());
this._x = tel.x;
this._y = tel.y;
this._draw();
}
this._draw();
return;
}
var x = Game.player.getX();
var y = Game.player.getY();
var astar = new ROT.Path.AStar(x, y, Game.passableCallback, {topology:4});
var path = [];
var pathCallback = function(x, y) {
path.push([x, y]);
}
astar.compute(this._x, this._y, pathCallback);
path.shift();
if (!path || path.length <= 1) {
this._dead = 10;
} else if (path.length > 7) {
// screw this
if (Math.random() <= 0.5) {
var x = this._x + Math.round(Math.random()*2 - 1);
var y = this._y + Math.round(Math.random()*2 - 1);
Game._drawMapCell(this._x, this._y);
if (Game.passableCallback(x,y)) {
this._x = x;
this._y = y;
}
}
} else {
x = path[0][0];
y = path[0][1];
Game._drawMapCell(this._x, this._y);
this._x = x;
this._y = y;
}
this._draw();
}
Goblin.prototype._draw = function() {
var icon = this._icon;
var colFg = "red";
var colBg = "black";
if (this._dead > 0) {
colFg = "white";
colBg = "red";
}
Game.display.draw(this._x, this._y, icon, colFg, colBg);
}
// ====================
Game.init();