This repository has been archived on 2020-05-03. You can view files and clone it, but cannot push or open issues or pull requests.
minipato/dist-archive/minipato.html

215 lines
4.5 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<style type="text/css">
#board {
line-height:0;
}
.tile {
display:inline-block;
width:26px;
height:26px;
border:0;
background:#F8F8F8;
border:4px solid #F8F8F8;
}
.tile.wall {
background:darkred;
border:4px solid darkred;
}
.tile.block {
background:orange;
}
.tile.goal {
border:4px solid orange;
}
.tile.player {
position:relative;
}
.tile.player:after {
content:'\1F464';
font-size:12px;
position:absolute;
top:0;
right:0;
left:0;
bottom:0;
line-height:26px;
text-align:center;
}
</style>
</head>
<body>
<div id="board"></div>
<div id="total-moves"></div>
<hr>
<textarea id="custom-board">#####
#p bG#
#####</textarea><br>
<button id="custom-board-apply">Play</button>
</body>
<script type="text/javascript">
"use strict";
//
function Tile(c) {
this.isWall = (c == "#");
this.isGoal = (c == "G" || c == "B" || c == "P");
this.isBlock = (c == "b" || c == "B");
this.isPlayer = (c == "p" || c == "P");
}
Tile.prototype.div = function() {
return "<div class='tile" +
(this.isWall ? " wall" : "") +
(this.isGoal ? " goal" : "") +
(this.isBlock ? " block" : "") +
(this.isPlayer ? " player" : "") +
"'></div>";
}
//
function Board(sz) {
this.tiles = [];
this.px = 0;
this.py = 0;
var lines = ("\n"+sz+"\n").split("\n").map(function(x) { return " " + x + " "; })
var longestLine = function(lines) {
return Math.max.apply(null, lines.map(function(x) { return x.length }) );
}
var width = longestLine(lines);
for (var i = 0; i < lines.length; i++) {
var row = [];
for (var c = 0; c < lines[i].length; c++) {
var t = new Tile(lines[i][c]);
if (t.isPlayer) {
this.py = i;
this.px = c;
}
row.push( t );
}
for (var c = lines[i].length; c < width; c++) {
row.push( new Tile(" ") );
}
this.tiles.push(row);
}
}
Board.prototype.render = function(target_id) {
var html = "";
for (var y = 0; y < this.tiles.length; y++) {
html += "<div class='row'>";
for (var x = 0; x < this.tiles[y].length; x++) {
html += this.tiles[y][x].div();
}
html += "</div>";
}
document.getElementById(target_id).innerHTML = html;
}
Board.prototype.isWon = function() {
for (var y = 0; y < this.tiles.length; y++) {
for (var x = 0; x < this.tiles[y].length; x++) {
if (this.tiles[y][x].isGoal && ! this.tiles[y][x].isBlock) {
return false; // this goal is missing a block
}
}
}
return true; // didn't find any goals missing a block
}
//
function Gameplay(target_id, movecounter_id) {
this.b = null;
this.target_id = target_id;
this.movecounter_id = movecounter_id;
this.totalMoves = 0;
}
Gameplay.prototype.setBoardContent = function(sz) {
this.b = new Board(sz);
this.b.render(this.target_id);
this.setTotalMoves(0);
}
Gameplay.prototype.setTotalMoves = function(ct) {
this.totalMoves = ct;
document.getElementById(this.movecounter_id).innerHTML = this.totalMoves;
}
Gameplay.prototype.registerEvents = function() {
window.addEventListener("keydown", this.onKey.bind(this));
}
Gameplay.prototype.onKey = function(ev) {
var dx = 0, dy = 0;
switch(ev.key) {
case "ArrowUp": dy = -1; break;
case "ArrowDown": dy = 1; break;
case "ArrowLeft": dx = -1; break;
case "ArrowRight": dx = 1; break;
default: return;
}
// Target square
var target = this.b.tiles[ this.b.py + dy ][ this.b.px + dx ]
if (target.isWall) {
return; // don't allow
}
if (target.isBlock) {
var further = this.b.tiles[ this.b.py + 2*dy ][ this.b.px + 2*dx ]
if (further.isWall || further.isBlock) {
return; // don't allow
}
// Move block
this.b.tiles[this.b.py + 2*dy][this.b.px + 2*dx].isBlock = true;
this.b.tiles[this.b.py + dy][this.b.px + dx].isBlock = false;
}
// Move player
this.b.tiles[this.b.py][this.b.px].isPlayer = false;
this.b.px += dx
this.b.py += dy
this.b.tiles[this.b.py][this.b.px].isPlayer = true;
// Re-render board
this.setTotalMoves(this.totalMoves + 1);
this.b.render(this.target_id);
// Check if the game is won
if (this.b.isWon()) {
setTimeout(function() {alert("won"); }, 1);
}
ev.stopPropagation();
ev.preventDefault();
return false;
}
//
var g = new Gameplay("board", "total-moves");
g.registerEvents();
g.setBoardContent("#####\n#p bG#\n#####");
document.getElementById("custom-board").addEventListener("keydown", function(ev) {
ev.stopPropagation(); // prevent hitting game event
});
document.getElementById("custom-board-apply").addEventListener("click", function(ev) {
g.setBoardContent( document.getElementById("custom-board").value );
})
</script>
</html>