Reglike: A simple roguelike written in Regex!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>Reglike</title> | |
<style> | |
*, *::before, *::after { | |
margin: 0; | |
padding: 0; | |
box-sizing: border-box; | |
} | |
html, body { | |
width: 100%; | |
height: 100%; | |
background: #333; | |
color: #bbb; | |
font-family: sans-serif; | |
} | |
.game > .display { | |
white-space: pre; | |
font-family: monospace; | |
font-size: 2rem; | |
} | |
.instructions { | |
font-size: 1.2rem; | |
padding: 0.5em; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="game"> | |
<div class="display"></div> | |
<form action="#" data-controls> | |
<input type="text" name="action" /> | |
<button type="submit">Submit</button> | |
</form> | |
</div> | |
<div class="instructions"> | |
Use the R, L, U, and D commands to move yourself (@) and attack monsters (1 and 2). | |
</div> | |
<script> | |
"use strict"; | |
var gameEl = document.querySelector(".game"); | |
var display = document.querySelector(".display"); | |
var controls = gameEl.querySelector("form[data-controls]"); | |
var input = controls.querySelector("input[name=\"action\"]"); | |
var BASE_BOARD = ` | |
████████████████ | |
█.2..1112..██.1█ | |
█.@.████2████2.█ | |
█1.████1.2.1...█ | |
████████████████ | |
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ | |
▌HP:3 │ LV:1▐ | |
▌XP: <▐ | |
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ | |
`.trim(); | |
var state = { | |
board: BASE_BOARD | |
}; | |
var code = [ | |
[/@\.((?:.|\n)+)R$/gi, "\.@$1"], // move right | |
[/\.@((?:.|\n)+)L$/gi, "@\.$1"], // move left | |
[/\.((?:.|\n){16})@((?:.|\n)+)U$/gi, "@$1\.$2"], // move up | |
[/@((?:.|\n){16})\.((?:.|\n)+)D$/gi, "\.$1@$2"], // move down | |
[/@2((?:.|\n)+)R$/gi, "@1$1"], // attack right, 2 -> 1 | |
[/@1((?:.|\n)+?)XP:(\|*) ((?:.|\n)+)R$/gi, "\.@$1XP:$2|$3"], // kill monster R, add XP | |
[/2@((?:.|\n)+)L$/gi, "1@$1"], // attack left, 2 -> 1 | |
[/1@((?:.|\n)+?)XP:(\|*) ((?:.|\n)+)L$/gi, "@\.$1XP:$2|$3"], // kill monster L, add XP | |
[/2((?:.|\n){16})@((?:.|\n)+)U$/gi, "1$1@$2"], // attack up, 2 -> 1 | |
[/1((?:.|\n){16})@((?:.|\n)+?)XP:(\|*) ((?:.|\n)+)U$/gi, "@$1\.$2XP:$3|$4"], // kill monster U, add XP | |
[/@((?:.|\n){16})2((?:.|\n)+)D$/gi, "@$11$2"], // attack down, 2 -> 1 | |
[/@((?:.|\n){16})1((?:.|\n)+?)XP:(\|*) ((?:.|\n)+)D$/gi, "\.$1@$2XP:$3|$4"], // kill monster D, add XP | |
[/LV:1((?:.|\n)+?)XP:\|{10}/, "LV:2$1XP: "], // level up (1 -> 2) | |
[/LV:2((?:.|\n)+?)XP:\|{10}/, "LV:3$1XP: "], // level up (1 -> 2) | |
[/[^\n]+$/, ""] // remove command from buffer | |
]; | |
var colors = [ | |
[/[▄▐▌▀│<]+|█/g, "#fff"], | |
[/HP:(\d)/, "#0d0"], | |
[/LV:(\d)/, "#77e"], | |
[/@/, "#ddf"], | |
]; | |
function harvest() { | |
return state.board + "\n" + input.value; | |
} | |
function step() { | |
var value = harvest(); | |
code.forEach(function(pair) { | |
value = value.replace(pair[0], pair[1]); | |
}); | |
state.board = value.trim(); | |
show(); | |
} | |
function colorize(board) { | |
colors.forEach(function(pair) { | |
var a = pair[0]; | |
var b = pair[1]; | |
board = board.replace(a, `<span style="color: ${ b }">$&</span>`); | |
}); | |
return board; | |
} | |
function show() { | |
display.innerHTML = colorize(state.board); | |
input.value = ""; | |
} | |
controls.addEventListener("submit", function(e) { | |
e.preventDefault(); | |
step(); | |
return false; | |
}); | |
show(); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You should implement a WASD option for movement...