Styled the whole page; reimplemented pausing; implemented success, score, and time
This commit is contained in:
parent
b871181bf4
commit
0390d54909
BIN
button.png
Normal file
BIN
button.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 187 B |
205
js/main.js
205
js/main.js
@ -11,7 +11,7 @@ function mk(tag_selector, ...children) {
|
|||||||
let el = document.createElement(tag);
|
let el = document.createElement(tag);
|
||||||
el.classList = classes.join(' ');
|
el.classList = classes.join(' ');
|
||||||
if (children.length > 0) {
|
if (children.length > 0) {
|
||||||
if (!(children[0] instanceof Node) && typeof(children[0]) !== "string" && typeof(children[0]) !== "number") {
|
if (!(children[0] instanceof Node) && children[0] !== undefined && typeof(children[0]) !== "string" && typeof(children[0]) !== "number") {
|
||||||
let [attrs] = children.splice(0, 1);
|
let [attrs] = children.splice(0, 1);
|
||||||
for (let [key, value] of Object.entries(attrs)) {
|
for (let [key, value] of Object.entries(attrs)) {
|
||||||
el.setAttribute(key, value);
|
el.setAttribute(key, value);
|
||||||
@ -235,7 +235,8 @@ class Level {
|
|||||||
// playing: normal play
|
// playing: normal play
|
||||||
// success: has been won
|
// success: has been won
|
||||||
// failure: died
|
// failure: died
|
||||||
// paused: paused
|
// note that pausing is NOT handled here, but by whatever's driving our
|
||||||
|
// event loop!
|
||||||
this.state = 'playing';
|
this.state = 'playing';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,6 +245,14 @@ class Level {
|
|||||||
this.player = null;
|
this.player = null;
|
||||||
this.actors = [];
|
this.actors = [];
|
||||||
this.chips_remaining = this.stored_level.chips_required;
|
this.chips_remaining = this.stored_level.chips_required;
|
||||||
|
if (this.stored_level.time_limit === 0) {
|
||||||
|
this.time_remaining = null;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.time_remaining = this.stored_level.time_limit;
|
||||||
|
}
|
||||||
|
this.bonus_points = 0;
|
||||||
|
this.tic_counter = 0;
|
||||||
|
|
||||||
this.hint_shown = null;
|
this.hint_shown = null;
|
||||||
|
|
||||||
@ -282,9 +291,8 @@ class Level {
|
|||||||
|
|
||||||
advance_tic(player_direction) {
|
advance_tic(player_direction) {
|
||||||
if (this.state !== 'playing') {
|
if (this.state !== 'playing') {
|
||||||
// FIXME this breaks the step buttons; maybe pausing should be in game only
|
console.warn(`Level.advance_tic() called when state is ${this.state}`);
|
||||||
//console.warn(`Level.advance_tic() called when state is ${this.state}`);
|
return;
|
||||||
//return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX this entire turn order is rather different in ms rules
|
// XXX this entire turn order is rather different in ms rules
|
||||||
@ -388,6 +396,17 @@ class Level {
|
|||||||
if (this.state === 'success' || this.state === 'failure')
|
if (this.state === 'success' || this.state === 'failure')
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.time_remaining !== null) {
|
||||||
|
this.tic_counter++;
|
||||||
|
while (this.tic_counter > 20) {
|
||||||
|
this.tic_counter -= 20;
|
||||||
|
this.time_remaining -= 1;
|
||||||
|
if (this.time_remaining <= 0) {
|
||||||
|
this.fail("Time's up!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fail(message) {
|
fail(message) {
|
||||||
@ -395,6 +414,10 @@ class Level {
|
|||||||
this.fail_message = message;
|
this.fail_message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
win() {
|
||||||
|
this.state = 'success';
|
||||||
|
}
|
||||||
|
|
||||||
// Try to move the given actor one tile in the given direction and update
|
// Try to move the given actor one tile in the given direction and update
|
||||||
// their cooldown. Return true if successful.
|
// their cooldown. Return true if successful.
|
||||||
attempt_step(actor, direction) {
|
attempt_step(actor, direction) {
|
||||||
@ -526,34 +549,58 @@ class Level {
|
|||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// - some kinda visual theme i guess lol
|
// - some kinda visual theme i guess lol
|
||||||
// - level /number/
|
|
||||||
// - level password, if any
|
// - level password, if any
|
||||||
// - set name
|
// - timer!!!!!
|
||||||
// - timer!
|
// - bonus points (cc2 only, or maybe only if got any so far this level)
|
||||||
// - intro splash with list of available levels
|
// - intro splash with list of available level packs
|
||||||
// - button: quit to splash
|
// - button: quit to splash
|
||||||
// - button: options
|
// - button: options
|
||||||
// - implement winning and show score for this level
|
// - implement winning and show score for this level
|
||||||
// - show current score so far
|
// - show current score so far
|
||||||
|
// - about, help
|
||||||
const GAME_UI_HTML = `
|
const GAME_UI_HTML = `
|
||||||
|
<header>
|
||||||
|
<h1>Lexy's Labyrinth</h1>
|
||||||
|
<nav>
|
||||||
|
<button class="nav-about" type="button" disabled>about</button>
|
||||||
|
<button class="nav-help" type="button" disabled>help</button>
|
||||||
|
<button class="nav-options" type="button" disabled>options</button>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
<main>
|
<main>
|
||||||
|
<header>
|
||||||
|
<h1 class="level-set">Chip's Challenge Level Pack 1</h1>
|
||||||
|
<nav>
|
||||||
|
<button class="set-nav-return" type="button" disabled>Change pack</button>
|
||||||
|
</nav>
|
||||||
|
<h2 class="level-name">Level 1 — Key Pyramid</h2>
|
||||||
|
<nav class="nav">
|
||||||
|
<button class="nav-prev" type="button">⬅️\ufe0e</button>
|
||||||
|
<button class="nav-browse" type="button" disabled>Level select</button>
|
||||||
|
<button class="nav-next" type="button">➡️\ufe0e</button>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
<div class="level"><!-- level canvas and any overlays go here --></div>
|
<div class="level"><!-- level canvas and any overlays go here --></div>
|
||||||
<div class="bummer"></div>
|
<div class="bummer"></div>
|
||||||
<div class="meta"></div>
|
<div class="message"></div>
|
||||||
<div class="nav">
|
<div class="chips">
|
||||||
<button class="nav-prev" type="button">«</button>
|
<h3>Chips</h3>
|
||||||
<button class="nav-browse" type="button">Level select</button>
|
<output></output>
|
||||||
<button class="nav-next" type="button">»</button>
|
</div>
|
||||||
|
<div class="time">
|
||||||
|
<h3>Time</h3>
|
||||||
|
<output></output>
|
||||||
|
</div>
|
||||||
|
<div class="bonus">
|
||||||
|
<h3>Bonus</h3>
|
||||||
|
<output></output>
|
||||||
</div>
|
</div>
|
||||||
<div class="hint"></div>
|
|
||||||
<div class="chips"></div>
|
|
||||||
<div class="time"></div>
|
|
||||||
<div class="inventory"></div>
|
<div class="inventory"></div>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<button class="control-pause" type="button">Pause</button>
|
<button class="control-pause" type="button">Pause</button>
|
||||||
<button class="control-restart" type="button">Restart</button>
|
<button class="control-restart" type="button" disabled>Restart</button>
|
||||||
<button class="control-undo" type="button">Undo</button>
|
<button class="control-undo" type="button" disabled>Undo</button>
|
||||||
<button class="control-rewind" type="button">Rewind</button>
|
<button class="control-rewind" type="button" disabled>Rewind</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="demo">
|
<div class="demo">
|
||||||
<h2>Solution demo available</h2>
|
<h2>Solution demo available</h2>
|
||||||
@ -610,19 +657,20 @@ class Game {
|
|||||||
this.container.style.setProperty('--tile-width', `${this.tileset.size_x}px`);
|
this.container.style.setProperty('--tile-width', `${this.tileset.size_x}px`);
|
||||||
this.container.style.setProperty('--tile-height', `${this.tileset.size_y}px`);
|
this.container.style.setProperty('--tile-height', `${this.tileset.size_y}px`);
|
||||||
this.level_el = this.container.querySelector('.level');
|
this.level_el = this.container.querySelector('.level');
|
||||||
this.meta_el = this.container.querySelector('.meta');
|
this.level_name_el = this.container.querySelector('.level-name');
|
||||||
this.nav_el = this.container.querySelector('.nav');
|
this.message_el = this.container.querySelector('.message');
|
||||||
this.hint_el = this.container.querySelector('.hint');
|
this.chips_el = this.container.querySelector('.chips output');
|
||||||
this.chips_el = this.container.querySelector('.chips');
|
this.time_el = this.container.querySelector('.time output');
|
||||||
this.time_el = this.container.querySelector('.time');
|
this.bonus_el = this.container.querySelector('.bonus output');
|
||||||
this.inventory_el = this.container.querySelector('.inventory');
|
this.inventory_el = this.container.querySelector('.inventory');
|
||||||
this.bummer_el = this.container.querySelector('.bummer');
|
this.bummer_el = this.container.querySelector('.bummer');
|
||||||
this.input_el = this.container.querySelector('.input');
|
this.input_el = this.container.querySelector('.input');
|
||||||
this.demo_el = this.container.querySelector('.demo');
|
this.demo_el = this.container.querySelector('.demo');
|
||||||
|
|
||||||
// Populate navigation
|
// Populate navigation
|
||||||
this.nav_prev_button = this.nav_el.querySelector('.nav-prev');
|
let nav_el = this.container.querySelector('.nav');
|
||||||
this.nav_next_button = this.nav_el.querySelector('.nav-next');
|
this.nav_prev_button = nav_el.querySelector('.nav-prev');
|
||||||
|
this.nav_next_button = nav_el.querySelector('.nav-next');
|
||||||
this.nav_prev_button.addEventListener('click', ev => {
|
this.nav_prev_button.addEventListener('click', ev => {
|
||||||
// TODO confirm
|
// TODO confirm
|
||||||
if (this.level_index > 0) {
|
if (this.level_index > 0) {
|
||||||
@ -637,13 +685,9 @@ class Game {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Bind buttons
|
// Bind buttons
|
||||||
this.container.querySelector('.controls .control-pause').addEventListener('click', ev => {
|
this.pause_button = this.container.querySelector('.controls .control-pause');
|
||||||
if (this.level.state === 'playing') {
|
this.pause_button.addEventListener('click', ev => {
|
||||||
this.level.state = 'paused';
|
this.toggle_pause();
|
||||||
}
|
|
||||||
else if (this.level.state === 'paused') {
|
|
||||||
this.level.state = 'playing';
|
|
||||||
}
|
|
||||||
ev.target.blur();
|
ev.target.blur();
|
||||||
});
|
});
|
||||||
// Demo playback
|
// Demo playback
|
||||||
@ -685,10 +729,19 @@ class Game {
|
|||||||
this.current_keys = new Set; // keys that are currently held
|
this.current_keys = new Set; // keys that are currently held
|
||||||
// TODO this could all probably be more rigorous but it's fine for now
|
// TODO this could all probably be more rigorous but it's fine for now
|
||||||
key_target.addEventListener('keydown', ev => {
|
key_target.addEventListener('keydown', ev => {
|
||||||
|
if (ev.key === 'p' || ev.key === 'Pause') {
|
||||||
|
this.toggle_pause();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.key_mapping[ev.key]) {
|
if (this.key_mapping[ev.key]) {
|
||||||
this.current_keys.add(ev.key);
|
this.current_keys.add(ev.key);
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
|
|
||||||
|
if (this.state === 'waiting') {
|
||||||
|
this.set_state('playing');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
key_target.addEventListener('keyup', ev => {
|
key_target.addEventListener('keyup', ev => {
|
||||||
@ -721,7 +774,6 @@ class Game {
|
|||||||
|
|
||||||
// Done with UI, now we can load a level
|
// Done with UI, now we can load a level
|
||||||
this.load_level(0);
|
this.load_level(0);
|
||||||
this.redraw();
|
|
||||||
|
|
||||||
// Fill in the scrubber
|
// Fill in the scrubber
|
||||||
if (false && this.level.stored_level.demo) {
|
if (false && this.level.stored_level.demo) {
|
||||||
@ -763,14 +815,22 @@ class Game {
|
|||||||
load_level(level_index) {
|
load_level(level_index) {
|
||||||
this.level_index = level_index;
|
this.level_index = level_index;
|
||||||
this.level = new Level(this.stored_game.levels[level_index]);
|
this.level = new Level(this.stored_game.levels[level_index]);
|
||||||
|
// waiting: haven't yet pressed a key so the timer isn't going
|
||||||
|
// playing: playing normally
|
||||||
|
// paused: um, paused
|
||||||
|
// rewinding: playing backwards
|
||||||
|
// stopped: level has ended one way or another
|
||||||
|
this.set_state('waiting');
|
||||||
|
|
||||||
// FIXME do better
|
// FIXME do better
|
||||||
this.meta_el.textContent = this.level.stored_level.title;
|
this.level_name_el.textContent = `Level ${level_index + 1} — ${this.level.stored_level.title}`;
|
||||||
|
|
||||||
document.title = `${PAGE_TITLE} - ${this.level.stored_level.title}`;
|
document.title = `${PAGE_TITLE} - ${this.level.stored_level.title}`;
|
||||||
|
|
||||||
this.nav_prev_button.disabled = level_index <= 0;
|
this.nav_prev_button.disabled = level_index <= 0;
|
||||||
this.nav_next_button.disabled = level_index >= this.stored_game.levels.length;
|
this.nav_next_button.disabled = level_index >= this.stored_game.levels.length;
|
||||||
this.update_ui();
|
this.update_ui();
|
||||||
|
this.redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
get_input() {
|
get_input() {
|
||||||
@ -835,13 +895,19 @@ class Game {
|
|||||||
|
|
||||||
this.level.advance_tic(player_move);
|
this.level.advance_tic(player_move);
|
||||||
this.tic++;
|
this.tic++;
|
||||||
|
|
||||||
|
if (this.level.state !== 'playing') {
|
||||||
|
// We either won or lost!
|
||||||
|
this.set_state('stopped');
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this.redraw();
|
this.redraw();
|
||||||
this.update_ui();
|
this.update_ui();
|
||||||
}
|
}
|
||||||
|
|
||||||
do_frame() {
|
do_frame() {
|
||||||
if (this.level.state === 'playing') {
|
if (this.state === 'playing') {
|
||||||
this.frame++;
|
this.frame++;
|
||||||
if (this.frame % 3 === 0) {
|
if (this.frame % 3 === 0) {
|
||||||
this.advance_by(1);
|
this.advance_by(1);
|
||||||
@ -863,16 +929,18 @@ class Game {
|
|||||||
}
|
}
|
||||||
|
|
||||||
update_ui() {
|
update_ui() {
|
||||||
|
this.pause_button.disabled = !(this.state === 'playing' || this.state === 'paused');
|
||||||
|
|
||||||
// TODO can we do this only if they actually changed?
|
// TODO can we do this only if they actually changed?
|
||||||
this.chips_el.textContent = this.level.chips_remaining;
|
this.chips_el.textContent = this.level.chips_remaining;
|
||||||
this.hint_el.textContent = this.level.hint_shown ?? '';
|
if (this.level.time_remaining === null) {
|
||||||
|
this.time_el.textContent = '---';
|
||||||
if (this.level.state === 'failure') {
|
|
||||||
this.bummer_el.textContent = this.level.fail_message;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.bummer_el.textContent = '';
|
this.time_el.textContent = this.level.time_remaining;
|
||||||
}
|
}
|
||||||
|
this.bonus_el.textContent = this.level.bonus_points;
|
||||||
|
this.message_el.textContent = this.level.hint_shown ?? "";
|
||||||
|
|
||||||
this.inventory_el.textContent = '';
|
this.inventory_el.textContent = '';
|
||||||
for (let [name, count] of Object.entries(this.level.player.inventory)) {
|
for (let [name, count] of Object.entries(this.level.player.inventory)) {
|
||||||
@ -891,6 +959,59 @@ class Game {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toggle_pause() {
|
||||||
|
if (this.state === 'paused') {
|
||||||
|
this.set_state('playing');
|
||||||
|
}
|
||||||
|
else if (this.state === 'playing') {
|
||||||
|
this.set_state('paused');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set_state(new_state) {
|
||||||
|
if (new_state === this.state)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.state = new_state;
|
||||||
|
|
||||||
|
if (this.state === 'waiting') {
|
||||||
|
this.bummer_el.textContent = "Ready!";
|
||||||
|
}
|
||||||
|
else if (this.state === 'playing' || this.state === 'rewinding') {
|
||||||
|
this.bummer_el.textContent = "";
|
||||||
|
}
|
||||||
|
else if (this.state === 'paused') {
|
||||||
|
this.bummer_el.textContent = "/// paused ///";
|
||||||
|
}
|
||||||
|
else if (this.state === 'stopped') {
|
||||||
|
if (this.level.state === 'failure') {
|
||||||
|
this.bummer_el.textContent = this.level.fail_message;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.bummer_el.textContent = "";
|
||||||
|
let base = (this.level_index + 1) * 500;
|
||||||
|
let time = (this.level.time_remaining || 0) * 10;
|
||||||
|
this.bummer_el.append(
|
||||||
|
mk('p', "go bit buster!"),
|
||||||
|
mk('dl.score-chart',
|
||||||
|
mk('dt', "base score"),
|
||||||
|
mk('dd', base),
|
||||||
|
mk('dt', "time bonus"),
|
||||||
|
mk('dd', `+ ${time}`),
|
||||||
|
mk('dt', "score bonus"),
|
||||||
|
mk('dd', `+ ${this.level.bonus_points}`),
|
||||||
|
mk('dt.-sum', "level score"),
|
||||||
|
mk('dd.-sum', base + time + this.level.bonus_points),
|
||||||
|
mk('dt', "improvement"),
|
||||||
|
mk('dd', "(TODO)"),
|
||||||
|
mk('dt', "total score"),
|
||||||
|
mk('dd', "(TODO)"),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
redraw() {
|
redraw() {
|
||||||
let ctx = this.level_canvas.getContext('2d');
|
let ctx = this.level_canvas.getContext('2d');
|
||||||
ctx.clearRect(0, 0, this.level_canvas.width, this.level_canvas.height);
|
ctx.clearRect(0, 0, this.level_canvas.width, this.level_canvas.height);
|
||||||
|
|||||||
@ -332,7 +332,7 @@ const TILE_TYPES = {
|
|||||||
is_object: true,
|
is_object: true,
|
||||||
is_item: true,
|
is_item: true,
|
||||||
is_tool: true,
|
is_tool: true,
|
||||||
item_ignores: new Set(['ice']),
|
item_ignores: new Set(['ice', 'ice_nw', 'ice_ne', 'ice_sw', 'ice_se']),
|
||||||
},
|
},
|
||||||
suction_boots: {
|
suction_boots: {
|
||||||
is_object: true,
|
is_object: true,
|
||||||
@ -419,6 +419,11 @@ const TILE_TYPES = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
exit: {
|
exit: {
|
||||||
|
on_arrive(me, level, other) {
|
||||||
|
if (other.type.is_player) {
|
||||||
|
level.win();
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
176
style.css
176
style.css
@ -1,31 +1,67 @@
|
|||||||
html {
|
html {
|
||||||
|
font-size: 24px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
font-size: 24px;
|
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
flex-direction: column;
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
background: #404040;
|
background: #101214;
|
||||||
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Generic element styling */
|
||||||
|
button {
|
||||||
|
font-size: inherit;
|
||||||
|
padding: 0.125em 0.5em;
|
||||||
|
border: 1px solid black;
|
||||||
|
background: #909090;
|
||||||
|
border-image: url(button.png) 33.333% fill / auto repeat;
|
||||||
|
text-transform: lowercase;
|
||||||
|
}
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
font-weight: normal;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Main page structure */
|
||||||
|
body > header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0.5em;
|
||||||
|
background: #00080c;
|
||||||
|
}
|
||||||
|
body > header > h1 {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 1.25rem;
|
||||||
|
}
|
||||||
|
body > header > nav {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
main {
|
main {
|
||||||
|
flex: 0;
|
||||||
|
margin: auto; /* center in both directions baby */
|
||||||
display: grid;
|
display: grid;
|
||||||
|
align-items: center;
|
||||||
grid:
|
grid:
|
||||||
"level meta" min-content
|
"header header"
|
||||||
"level nav" min-content
|
"level chips"
|
||||||
"level chips" min-content
|
"level time"
|
||||||
"level time" min-content
|
"level bonus"
|
||||||
"level hint" 1fr
|
"level message" 1fr
|
||||||
"level inventory" min-content
|
"level inventory"
|
||||||
"controls controls"
|
"level controls"
|
||||||
"demo demo"
|
"demo demo"
|
||||||
/ min-content 12em
|
/* Need explicit min-content to force the hint to wrap */
|
||||||
|
/ min-content min-content
|
||||||
;
|
;
|
||||||
gap: 1em;
|
column-gap: 1em;
|
||||||
|
row-gap: 0.5em;
|
||||||
|
|
||||||
image-rendering: optimizeSpeed;
|
image-rendering: optimizeSpeed;
|
||||||
|
|
||||||
@ -34,8 +70,23 @@ main {
|
|||||||
--scale: 2;
|
--scale: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
main > header {
|
||||||
font-size: inherit;
|
grid-area: header;
|
||||||
|
display: grid;
|
||||||
|
grid-auto-columns: 1fr auto;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.25em;
|
||||||
|
}
|
||||||
|
main > header > h1,
|
||||||
|
main > header > h2 {
|
||||||
|
grid-column: 1;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
main > header > nav {
|
||||||
|
grid-column: 2;
|
||||||
|
justify-self: end;
|
||||||
|
display: flex;
|
||||||
|
gap: 0.25em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.level {
|
.level {
|
||||||
@ -49,14 +100,16 @@ button {
|
|||||||
}
|
}
|
||||||
.bummer {
|
.bummer {
|
||||||
grid-area: level;
|
grid-area: level;
|
||||||
|
place-self: stretch;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
z-index: 99;
|
z-index: 99;
|
||||||
font-size: 48px;
|
font-size: 48px;
|
||||||
padding: 25%;
|
padding: 10%;
|
||||||
background: #0009;
|
background: #0009;
|
||||||
color: white;
|
color: white;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@ -66,6 +119,29 @@ button {
|
|||||||
.bummer:empty {
|
.bummer:empty {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
.bummer p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
dl.score-chart {
|
||||||
|
display: grid;
|
||||||
|
grid-auto-columns: 1fr 1fr;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
dl.score-chart dt {
|
||||||
|
grid-column: 1;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
dl.score-chart dd {
|
||||||
|
grid-column: 2;
|
||||||
|
margin: 0;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
dl.score-chart .-sum {
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
border-top: 1px solid white;
|
||||||
|
color: hsl(40, 75%, 80%);
|
||||||
|
}
|
||||||
|
|
||||||
.meta {
|
.meta {
|
||||||
grid-area: meta;
|
grid-area: meta;
|
||||||
|
|
||||||
@ -73,30 +149,59 @@ button {
|
|||||||
background: black;
|
background: black;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
.nav {
|
|
||||||
grid-area: nav;
|
|
||||||
display: flex;
|
|
||||||
gap: 1em;
|
|
||||||
}
|
|
||||||
.nav .nav-browse {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
.chips {
|
.chips {
|
||||||
grid-area: chips;
|
grid-area: chips;
|
||||||
|
|
||||||
padding: 0 0.5em;
|
|
||||||
color: yellow;
|
|
||||||
background: black;
|
|
||||||
}
|
|
||||||
.chips::before {
|
|
||||||
content: "chips left: ";
|
|
||||||
}
|
}
|
||||||
.time {
|
.time {
|
||||||
grid-area: time;
|
grid-area: time;
|
||||||
}
|
}
|
||||||
.hint {
|
.bonus {
|
||||||
grid-area: hint;
|
grid-area: bonus;
|
||||||
}
|
}
|
||||||
|
.chips,
|
||||||
|
.time,
|
||||||
|
.bonus {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.chips h3,
|
||||||
|
.time h3,
|
||||||
|
.bonus h3 {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 1.25rem;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
.chips output,
|
||||||
|
.time output,
|
||||||
|
.bonus output {
|
||||||
|
flex: 0;
|
||||||
|
font-size: 2em;
|
||||||
|
padding: 0.125em;
|
||||||
|
min-width: 2em;
|
||||||
|
min-height: 1em;
|
||||||
|
line-height: 1;
|
||||||
|
text-align: right;
|
||||||
|
font-family: monospace;
|
||||||
|
color: hsl(45, 100%, 60%);
|
||||||
|
background: #080808;
|
||||||
|
border: 1px inset #202020;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message {
|
||||||
|
grid-area: message;
|
||||||
|
align-self: stretch;
|
||||||
|
|
||||||
|
padding: 0.5em;
|
||||||
|
font-family: serif;
|
||||||
|
font-style: italic;
|
||||||
|
color: hsl(45, 100%, 60%);
|
||||||
|
background: #080808;
|
||||||
|
border: 1px inset #202020;
|
||||||
|
}
|
||||||
|
.message:empty {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
.inventory {
|
.inventory {
|
||||||
grid-area: inventory;
|
grid-area: inventory;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -112,6 +217,11 @@ button {
|
|||||||
}
|
}
|
||||||
.controls {
|
.controls {
|
||||||
grid-area: controls;
|
grid-area: controls;
|
||||||
|
display: flex;
|
||||||
|
gap: 0.25em;
|
||||||
|
}
|
||||||
|
.controls > button {
|
||||||
|
flex: 1;
|
||||||
}
|
}
|
||||||
.demo {
|
.demo {
|
||||||
grid-area: demo;
|
grid-area: demo;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user