commit all archived files
This commit is contained in:
parent
254cf4c897
commit
d51db14cf1
19
README.md
Normal file
19
README.md
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# minipato
|
||||||
|
|
||||||
|
![](https://img.shields.io/badge/written%20in-Javascript-blue)
|
||||||
|
|
||||||
|
A Sokoban game with level editor.
|
||||||
|
|
||||||
|
Developed in a rather short period of time to explain certain concepts.
|
||||||
|
|
||||||
|
Tags: game
|
||||||
|
|
||||||
|
## Changelog
|
||||||
|
|
||||||
|
2016-11-23
|
||||||
|
- Initial public release
|
||||||
|
|
||||||
|
|
||||||
|
## Download
|
||||||
|
|
||||||
|
- [⬇️ minipato.html](dist-archive/minipato.html) *(4.49 KiB)*
|
214
dist-archive/minipato.html
Normal file
214
dist-archive/minipato.html
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
<!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>
|
Reference in New Issue
Block a user