Commandes personnage : détection de touche au clavier + touches d'animation supplémentaires
Deux retours utilisateur sur le panneau "Commandes" (déplacement/
animation automatiques, voir précédent commit) :
- Les champs de touche (haut/bas/gauche/droite/interagir) capturent
maintenant la touche au clavier (clic puis appui — event.key, même
valeur que heldKeys/triggers.js) au lieu d'être tapés à la main,
source d'erreurs ("Espace" vs " ", "flèche haut" vs "ArrowUp"...).
- Nouvelle section "Animations supplémentaires" : un nombre illimité de
touches, chacune liée à UNE pose au choix parmi celles réellement
disponibles pour ce personnage (sauter, attaquer, courir...) — pas
seulement les 4 touches de déplacement + interagir.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
74f7ca396f
commit
5891c82c62
@@ -145,14 +145,23 @@ function swapSceneObjectCharacter(forgeCharacter) {
|
||||
}
|
||||
|
||||
// "Commandes" (voir static/js/play/personnage-controller.js) : touches de
|
||||
// déplacement/interaction + blocage d'axe d'un personnage — un seul
|
||||
// formulaire, enregistré en AJAX à chaque changement de champ, même
|
||||
// patron que swapSceneObjectCharacter() ci-dessus (POST JSON vers
|
||||
// routes/scenes/scene_object_commands.py, aucun rechargement de page).
|
||||
// déplacement/interaction + blocage d'axe + touches supplémentaires d'un
|
||||
// personnage — un seul formulaire, enregistré en AJAX à chaque
|
||||
// changement de champ, même patron que swapSceneObjectCharacter()
|
||||
// ci-dessus (POST JSON vers routes/scenes/scene_object_commands.py,
|
||||
// aucun rechargement de page).
|
||||
function saveSceneObjectCommands() {
|
||||
var body = document.getElementById('personnageCommandsBody');
|
||||
if (!body) return;
|
||||
var objectId = parseInt(body.dataset.elementId, 10);
|
||||
var extra = [];
|
||||
document.querySelectorAll('#personnageCommandsExtra .personnageCommandExtraRow').forEach(function (row) {
|
||||
var toucheEl = row.querySelector('.personnageKeyCapture');
|
||||
var animEl = row.querySelector('.cmdExtraAnim');
|
||||
if (toucheEl && toucheEl.value && animEl && animEl.value) {
|
||||
extra.push({ touche: toucheEl.value, animation: animEl.value });
|
||||
}
|
||||
});
|
||||
fetch('/game/' + GAME_SLUG + '/scene-objects/' + objectId + '/commandes', {
|
||||
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
@@ -163,15 +172,83 @@ function saveSceneObjectCommands() {
|
||||
interagir: document.getElementById('cmd-interagir').value,
|
||||
axe: document.getElementById('cmd-axe').value,
|
||||
vitesse: document.getElementById('cmd-vitesse').value,
|
||||
extra: extra,
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
// Détection de touche (bug remonté par l'utilisateur : taper le nom d'une
|
||||
// touche à la main est source d'erreurs — "Espace" vs " ", "flèche haut"
|
||||
// vs "ArrowUp"...) : au focus, le champ (readonly, jamais tapé) affiche un
|
||||
// indice puis se remplit avec la PROCHAINE touche pressée (event.key,
|
||||
// même valeur que heldKeys/bindKeyboardTriggers, triggers.js — cohérent
|
||||
// avec ce que le moteur compare réellement au jeu). capture:true sur
|
||||
// window pour intercepter la touche avant tout autre raccourci de
|
||||
// l'éditeur (ex. Suppr qui efface l'objet sélectionné).
|
||||
function bindPersonnageKeyCapture(el) {
|
||||
if (!el || el.dataset.keyCaptureBound) return;
|
||||
el.dataset.keyCaptureBound = '1';
|
||||
el.addEventListener('focus', function () {
|
||||
var previous = el.value;
|
||||
el.value = 'Appuie sur une touche...';
|
||||
el.classList.add('is-warning');
|
||||
function onKey(ev) {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
window.removeEventListener('keydown', onKey, true);
|
||||
el.classList.remove('is-warning');
|
||||
if (ev.key === 'Escape') { el.value = previous; el.blur(); return; }
|
||||
el.value = ev.key;
|
||||
el.blur();
|
||||
el.dispatchEvent(new Event('change'));
|
||||
}
|
||||
window.addEventListener('keydown', onKey, true);
|
||||
});
|
||||
}
|
||||
|
||||
// Une ligne = une touche supplémentaire liée à UNE pose au choix parmi
|
||||
// celles RÉELLEMENT disponibles pour CE personnage (ELEMENT_ANIMATIONS_MAP,
|
||||
// déjà connu de personnage-panel.js/personnage-preview.js) — jamais un nom
|
||||
// tapé à la main, qui pourrait ne correspondre à aucune pose existante.
|
||||
function personnageCommandExtraRowEl(objectId, touche, animation) {
|
||||
var row = document.createElement('div');
|
||||
row.className = 'field is-grouped personnageCommandExtraRow';
|
||||
var animNames = Object.keys(ELEMENT_ANIMATIONS_MAP[objectId] || {});
|
||||
var options = animNames.map(function (name) {
|
||||
return '<option value="' + name + '"' + (name === animation ? ' selected' : '') + '>' + name + '</option>';
|
||||
}).join('');
|
||||
row.innerHTML =
|
||||
'<div class="control"><input class="input is-small personnageKeyCapture" readonly placeholder="Touche..." value="' + (touche || '').replace(/"/g, '"') + '"></div>' +
|
||||
'<div class="control"><div class="select is-small"><select class="cmdExtraAnim">' + options + '</select></div></div>' +
|
||||
'<div class="control"><button type="button" class="button is-small" onclick="this.closest(\'.personnageCommandExtraRow\').remove(); saveSceneObjectCommands();">×</button></div>';
|
||||
var keyInput = row.querySelector('.personnageKeyCapture');
|
||||
bindPersonnageKeyCapture(keyInput);
|
||||
keyInput.addEventListener('change', saveSceneObjectCommands);
|
||||
row.querySelector('.cmdExtraAnim').addEventListener('change', saveSceneObjectCommands);
|
||||
return row;
|
||||
}
|
||||
|
||||
function addPersonnageCommandExtraRow() {
|
||||
var body = document.getElementById('personnageCommandsBody');
|
||||
var container = document.getElementById('personnageCommandsExtra');
|
||||
if (!body || !container) return;
|
||||
var objectId = parseInt(body.dataset.elementId, 10);
|
||||
container.appendChild(personnageCommandExtraRowEl(objectId, '', ''));
|
||||
}
|
||||
|
||||
(function () {
|
||||
var body = document.getElementById('personnageCommandsBody');
|
||||
if (!body) return;
|
||||
var objectId = parseInt(body.dataset.elementId, 10);
|
||||
['cmd-haut', 'cmd-bas', 'cmd-gauche', 'cmd-droite', 'cmd-interagir'].forEach(function (id) {
|
||||
bindPersonnageKeyCapture(document.getElementById(id));
|
||||
});
|
||||
['cmd-haut', 'cmd-bas', 'cmd-gauche', 'cmd-droite', 'cmd-interagir', 'cmd-axe', 'cmd-vitesse'].forEach(function (id) {
|
||||
var el = document.getElementById(id);
|
||||
if (el) el.addEventListener('change', saveSceneObjectCommands);
|
||||
});
|
||||
var container = document.getElementById('personnageCommandsExtra');
|
||||
(window.PERSONNAGE_COMMANDS_EXTRA || []).forEach(function (e) {
|
||||
container.appendChild(personnageCommandExtraRowEl(objectId, e.touche, e.animation));
|
||||
});
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user