Rebind Space to jump, gate editor behind localStorage flag
Space is now the alternate jump key (was shoot). Web shell shows game controls by default and hides editor UI unless localStorage.show_editor is set to 'true'. The E key and ?edit URL are blocked when the editor is not enabled. Also fix Makefile to track web/shell.html as a WASM link dependency so shell changes trigger a rebuild.
This commit is contained in:
@@ -203,8 +203,8 @@ Current directives: `TILESET`, `SIZE`, `SPAWN`, `GRAVITY`, `WIND`, `BG_COLOR`, `
|
|||||||
| Action | Key | Status |
|
| Action | Key | Status |
|
||||||
|-----------|--------------|---------------|
|
|-----------|--------------|---------------|
|
||||||
| Move | Arrow keys | Implemented |
|
| Move | Arrow keys | Implemented |
|
||||||
| Jump | Z | Implemented |
|
| Jump | Z / Space | Implemented |
|
||||||
| Shoot | X / Space | Implemented |
|
| Shoot | X | Implemented |
|
||||||
| Aim up | UP (+ shoot) | Implemented |
|
| Aim up | UP (+ shoot) | Implemented |
|
||||||
| Aim diag | UP+LEFT/RIGHT (+ shoot) | Implemented |
|
| Aim diag | UP+LEFT/RIGHT (+ shoot) | Implemented |
|
||||||
| Dash | C | Implemented |
|
| Dash | C | Implemented |
|
||||||
|
|||||||
8
Makefile
8
Makefile
@@ -80,7 +80,13 @@ OBJ_ALL := $(SRC_ALL:src/%.c=$(OBJ_DIR)/%.o)
|
|||||||
|
|
||||||
all: $(BIN)
|
all: $(BIN)
|
||||||
|
|
||||||
$(BIN): $(OBJ_ALL) | outdirs
|
# On WASM builds the shell template is baked into the output HTML,
|
||||||
|
# so re-link whenever it changes.
|
||||||
|
ifdef WASM
|
||||||
|
EXTRA_LINK_DEPS := web/shell.html
|
||||||
|
endif
|
||||||
|
|
||||||
|
$(BIN): $(OBJ_ALL) $(EXTRA_LINK_DEPS) | outdirs
|
||||||
$(CC) $(OBJ_ALL) -o $@ $(LDFLAGS)
|
$(CC) $(OBJ_ALL) -o $@ $(LDFLAGS)
|
||||||
|
|
||||||
outdirs:
|
outdirs:
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ static SDL_Scancode s_bindings[ACTION_COUNT] = {
|
|||||||
|
|
||||||
/* Alternate bindings (0 = no alternate) */
|
/* Alternate bindings (0 = no alternate) */
|
||||||
static SDL_Scancode s_alt_bindings[ACTION_COUNT] = {
|
static SDL_Scancode s_alt_bindings[ACTION_COUNT] = {
|
||||||
[ACTION_SHOOT] = SDL_SCANCODE_SPACE,
|
[ACTION_JUMP] = SDL_SCANCODE_SPACE,
|
||||||
};
|
};
|
||||||
|
|
||||||
void input_init(void) {
|
void input_init(void) {
|
||||||
|
|||||||
@@ -60,6 +60,17 @@
|
|||||||
max-width: 1300px;
|
max-width: 1300px;
|
||||||
}
|
}
|
||||||
#hint { color: #666; }
|
#hint { color: #666; }
|
||||||
|
#game-controls {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
margin-top: 8px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #666;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
max-width: 1300px;
|
||||||
|
}
|
||||||
.ctrl-btn {
|
.ctrl-btn {
|
||||||
color: #4ecdc4;
|
color: #4ecdc4;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
@@ -100,7 +111,7 @@
|
|||||||
<canvas class="emscripten" id="canvas" tabindex="1"
|
<canvas class="emscripten" id="canvas" tabindex="1"
|
||||||
width="640" height="360"></canvas>
|
width="640" height="360"></canvas>
|
||||||
</div>
|
</div>
|
||||||
<div id="controls">
|
<div id="controls" class="hidden">
|
||||||
<a class="ctrl-btn" id="editor-link" href="?edit">Editor</a>
|
<a class="ctrl-btn" id="editor-link" href="?edit">Editor</a>
|
||||||
<span class="ctrl-sep">|</span>
|
<span class="ctrl-sep">|</span>
|
||||||
<button class="ctrl-btn" id="btn-save" title="Save level (download .lvl)">Save</button>
|
<button class="ctrl-btn" id="btn-save" title="Save level (download .lvl)">Save</button>
|
||||||
@@ -112,10 +123,33 @@
|
|||||||
<span class="ctrl-sep">|</span>
|
<span class="ctrl-sep">|</span>
|
||||||
<span id="hint">E=editor P=test play 1-6=tools</span>
|
<span id="hint">E=editor P=test play 1-6=tools</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="game-controls">
|
||||||
|
<span>Arrows=move</span>
|
||||||
|
<span class="ctrl-sep">|</span>
|
||||||
|
<span>Z/Space=jump</span>
|
||||||
|
<span class="ctrl-sep">|</span>
|
||||||
|
<span>X=shoot</span>
|
||||||
|
<span class="ctrl-sep">|</span>
|
||||||
|
<span>C=dash</span>
|
||||||
|
<span class="ctrl-sep">|</span>
|
||||||
|
<span>Up=aim up</span>
|
||||||
|
</div>
|
||||||
<div id="status">Loading...</div>
|
<div id="status">Loading...</div>
|
||||||
<div id="progress-bar"><div id="progress-bar-inner"></div></div>
|
<div id="progress-bar"><div id="progress-bar-inner"></div></div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
/* ── Editor gate: only enable when localStorage show_editor=true ── */
|
||||||
|
var editorEnabled = false;
|
||||||
|
try { editorEnabled = (localStorage.getItem('show_editor') === 'true'); } catch(e) {}
|
||||||
|
if (editorEnabled) {
|
||||||
|
document.getElementById('controls').classList.remove('hidden');
|
||||||
|
document.getElementById('game-controls').classList.add('hidden');
|
||||||
|
}
|
||||||
|
/* Strip ?edit from URL when editor is not enabled */
|
||||||
|
if (!editorEnabled && window.location.search.indexOf('edit') !== -1) {
|
||||||
|
window.history.replaceState({}, '', window.location.pathname);
|
||||||
|
}
|
||||||
|
|
||||||
var statusEl = document.getElementById('status');
|
var statusEl = document.getElementById('status');
|
||||||
var progressEl = document.getElementById('progress-bar');
|
var progressEl = document.getElementById('progress-bar');
|
||||||
var progressIn = document.getElementById('progress-bar-inner');
|
var progressIn = document.getElementById('progress-bar-inner');
|
||||||
@@ -155,16 +189,22 @@
|
|||||||
Module.setStatus('Error - check the browser console');
|
Module.setStatus('Error - check the browser console');
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ── Keyboard shortcuts: Ctrl+S / Ctrl+O ────────── */
|
/* ── Keyboard shortcuts: Ctrl+S / Ctrl+O / E-key ── */
|
||||||
document.addEventListener('keydown', function(e) {
|
document.addEventListener('keydown', function(e) {
|
||||||
if ((e.ctrlKey || e.metaKey) && e.key === 's') {
|
/* Block E-key editor entry when editor is not enabled */
|
||||||
|
if (!editorEnabled && e.key === 'e' && !e.ctrlKey && !e.metaKey) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (editorEnabled && (e.ctrlKey || e.metaKey) && e.key === 's') {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
if (typeof _editor_save_flag_ptr === 'function') {
|
if (typeof _editor_save_flag_ptr === 'function') {
|
||||||
HEAP32[_editor_save_flag_ptr() >> 2] = 1;
|
HEAP32[_editor_save_flag_ptr() >> 2] = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((e.ctrlKey || e.metaKey) && e.key === 'o') {
|
if (editorEnabled && (e.ctrlKey || e.metaKey) && e.key === 'o') {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
if (typeof _editor_load_flag_ptr === 'function') {
|
if (typeof _editor_load_flag_ptr === 'function') {
|
||||||
@@ -173,7 +213,8 @@
|
|||||||
}
|
}
|
||||||
}, true); /* useCapture=true to intercept before SDL */
|
}, true); /* useCapture=true to intercept before SDL */
|
||||||
|
|
||||||
/* ── Button handlers ────────────────────────────── */
|
/* ── Editor-only features (button handlers, level picker) ── */
|
||||||
|
if (editorEnabled) {
|
||||||
document.getElementById('btn-save').addEventListener('click', function() {
|
document.getElementById('btn-save').addEventListener('click', function() {
|
||||||
if (typeof _editor_save_flag_ptr === 'function') {
|
if (typeof _editor_save_flag_ptr === 'function') {
|
||||||
HEAP32[_editor_save_flag_ptr() >> 2] = 1;
|
HEAP32[_editor_save_flag_ptr() >> 2] = 1;
|
||||||
@@ -240,6 +281,7 @@
|
|||||||
if (window.location.search.indexOf('edit') !== -1) {
|
if (window.location.search.indexOf('edit') !== -1) {
|
||||||
document.title = 'Jump \'n Run - Level Editor';
|
document.title = 'Jump \'n Run - Level Editor';
|
||||||
}
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
{{{ SCRIPT }}}
|
{{{ SCRIPT }}}
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
Reference in New Issue
Block a user