262 lines
12 KiB
HTML
262 lines
12 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="fr">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<meta name="description" content="Tutoriel interactif de Mahjong Riichi - Apprenez à jouer au Mahjong japonais">
|
|
<meta name="theme-color" content="#1a7f4b">
|
|
<title>Mahjong Riichi - Tutoriel Interactif</title>
|
|
|
|
<!-- Preload fonts -->
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Poppins:wght@500;600;700&display=swap" rel="stylesheet">
|
|
|
|
<!-- Main stylesheet -->
|
|
<link rel="stylesheet" href="src/styles/main.css">
|
|
</head>
|
|
<body>
|
|
<!-- Navigation -->
|
|
<nav class="navbar" role="navigation" aria-label="Navigation principale">
|
|
<ul class="navbar__container">
|
|
<!-- GitHub Link -->
|
|
<li class="navbar__item">
|
|
<a href="https://github.com/Didictateur/Riichi"
|
|
class="navbar__link"
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
aria-label="Voir le code source sur GitHub">
|
|
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
|
|
<path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z"/>
|
|
</svg>
|
|
GitHub
|
|
</a>
|
|
</li>
|
|
|
|
<!-- Introduction -->
|
|
<li class="navbar__item">
|
|
<a href="#" class="navbar__link" onclick="loadScript('dp0.js'); return false;">
|
|
Introduction
|
|
</a>
|
|
</li>
|
|
|
|
<!-- Riichi Mahjong -->
|
|
<li class="navbar__item">
|
|
<a href="#" class="navbar__link navbar__link--dropdown">
|
|
Riichi Mahjong
|
|
</a>
|
|
<div class="dropdown" role="menu">
|
|
<a href="#" class="dropdown__link dropdown__link--chapter" onclick="loadScript('dp1.js'); return false;" role="menuitem">
|
|
Chap 1: Présentation des tuiles
|
|
</a>
|
|
<a href="#" class="dropdown__link dropdown__link--chapter" onclick="loadScript('dp2.js'); return false;" role="menuitem">
|
|
Chap 2: La main
|
|
</a>
|
|
<a href="#" class="dropdown__link dropdown__link--chapter" onclick="loadScript('dp3.js'); return false;" role="menuitem">
|
|
Chap 3: Les groupes
|
|
</a>
|
|
<a href="#" class="dropdown__link dropdown__link--chapter" onclick="loadScript('dp4.js'); return false;" role="menuitem">
|
|
Chap 4: Avoir une main valide en jeu
|
|
</a>
|
|
<a href="#" class="dropdown__link dropdown__link--chapter" onclick="loadScript('dp5.js'); return false;" role="menuitem">
|
|
Chap 5: Annoncer la victoire
|
|
</a>
|
|
<a href="#" class="dropdown__link dropdown__link--chapter" onclick="loadScript('dp6.js'); return false;" role="menuitem">
|
|
Chap 6: Le vent du joueur
|
|
</a>
|
|
<a href="#" class="dropdown__link dropdown__link--chapter" onclick="loadScript('dp7.js'); return false;" role="menuitem">
|
|
Chap 7: Les yakus
|
|
</a>
|
|
<a href="#" class="dropdown__link dropdown__link--chapter" onclick="loadScript('dp8.js'); return false;" role="menuitem">
|
|
Chap 8: Le riichi
|
|
</a>
|
|
<a href="#" class="dropdown__link dropdown__link--chapter" onclick="loadScript('dp9.js'); return false;" role="menuitem">
|
|
Chap 9: Le furiten
|
|
</a>
|
|
<a href="#" class="dropdown__link dropdown__link--chapter" onclick="loadScript('dp10.js'); return false;" role="menuitem">
|
|
Chap 10: Première partie complète
|
|
</a>
|
|
<a href="#" class="dropdown__link dropdown__link--chapter" onclick="loadScript('dp11.js'); return false;" role="menuitem">
|
|
Chap 11: Score: les Hans
|
|
</a>
|
|
<a href="#" class="dropdown__link dropdown__link--chapter" onclick="loadScript('dp12.js'); return false;" role="menuitem">
|
|
Chap 12: Score: les doras
|
|
</a>
|
|
<a href="#" class="dropdown__link dropdown__link--chapter" onclick="loadScript('dp13.js'); return false;" role="menuitem">
|
|
Chap 13: Score: les Fus
|
|
</a>
|
|
<a href="#" class="dropdown__link dropdown__link--chapter" onclick="loadScript('dp14.js'); return false;" role="menuitem">
|
|
Chap 14: Score: le calcul des points
|
|
</a>
|
|
<a href="#" class="dropdown__link dropdown__link--chapter" onclick="loadScript('dp15.js'); return false;" role="menuitem">
|
|
Chap 15: Partie avec les scores
|
|
</a>
|
|
</div>
|
|
</li>
|
|
|
|
<!-- Partie réelle -->
|
|
<li class="navbar__item">
|
|
<a href="#" class="navbar__link navbar__link--dropdown">
|
|
Partie réelle
|
|
</a>
|
|
<div class="dropdown" role="menu">
|
|
<a href="#" class="dropdown__link dropdown__link--chapter" onclick="loadScript('dp16.js'); return false;" role="menuitem">
|
|
Chap 1: Placement des joueurs
|
|
</a>
|
|
<a href="#" class="dropdown__link dropdown__link--chapter" onclick="loadScript('dp17.js'); return false;" role="menuitem">
|
|
Chap 2: Construction des murs
|
|
</a>
|
|
<a href="#" class="dropdown__link dropdown__link--chapter" onclick="loadScript('dp18.js'); return false;" role="menuitem">
|
|
Chap 3: Désigner la pioche
|
|
</a>
|
|
<a href="#" class="dropdown__link dropdown__link--chapter" onclick="loadScript('dp19.js'); return false;" role="menuitem">
|
|
Chap 4: Le mur mort
|
|
</a>
|
|
</div>
|
|
</li>
|
|
|
|
<!-- Riichi à trois -->
|
|
<li class="navbar__item">
|
|
<a href="#" class="navbar__link" onclick="loadScript('dp20.js'); return false;">
|
|
Riichi à 3
|
|
</a>
|
|
</li>
|
|
|
|
<!-- Yaku trainer -->
|
|
<li class="navbar__item">
|
|
<a href="#" class="navbar__link navbar__link--dropdown">
|
|
Yaku Trainer
|
|
</a>
|
|
<div class="dropdown" role="menu">
|
|
<a href="#" class="dropdown__link dropdown__link--chapter" onclick="loadScript('dp21.js'); return false;" role="menuitem">
|
|
Entraînement Yaku 1
|
|
</a>
|
|
</div>
|
|
</li>
|
|
|
|
<!-- MCR -->
|
|
<li class="navbar__item">
|
|
<a href="#" class="navbar__link navbar__link--dropdown">
|
|
MCR
|
|
</a>
|
|
<div class="dropdown" role="menu">
|
|
<a href="#" class="dropdown__link dropdown__link--chapter" onclick="loadScript('dp22.js'); return false;" role="menuitem">
|
|
Chapitre 1
|
|
</a>
|
|
<a href="#" class="dropdown__link dropdown__link--chapter" onclick="loadScript('dp23.js'); return false;" role="menuitem">
|
|
Chapitre 2
|
|
</a>
|
|
</div>
|
|
</li>
|
|
</ul>
|
|
</nav>
|
|
|
|
<!-- Main Content -->
|
|
<main class="main-container">
|
|
<div id="canvasContainer" class="canvas-wrapper animate-fadeIn">
|
|
<canvas id="myCanvas" width="1000" height="1000"></canvas>
|
|
</div>
|
|
<div id="anotherCanvasContainer" class="canvas-wrapper animate-fadeIn">
|
|
<canvas id="myTextCanvas" width="1000" height="1000"></canvas>
|
|
</div>
|
|
</main>
|
|
|
|
<!-- Application Script -->
|
|
<script type="module">
|
|
// State management
|
|
const AppState = {
|
|
currentScript: null,
|
|
lastLoadedScript: 'dp0.js',
|
|
lastTextMode: true
|
|
};
|
|
|
|
// Utility functions
|
|
function removePlayButton() {
|
|
const btn = document.getElementById("playButton");
|
|
if (btn) btn.remove();
|
|
}
|
|
|
|
function generateTimestamp() {
|
|
return Date.now();
|
|
}
|
|
|
|
function cleanupPreviousState() {
|
|
if (window.cleanup) {
|
|
window.cleanup();
|
|
}
|
|
removePlayButton();
|
|
}
|
|
|
|
// Load text content
|
|
function loadText(scriptName, nb) {
|
|
cleanupPreviousState();
|
|
window.txtNumber = nb;
|
|
|
|
const container = document.getElementById("anotherCanvasContainer");
|
|
container.innerHTML = `
|
|
<canvas id="myTextCanvas" width="1000" height="1000"></canvas>
|
|
`;
|
|
|
|
const script = document.createElement("script");
|
|
script.type = "module";
|
|
script.src = `build/${scriptName}?t=${generateTimestamp()}`;
|
|
document.body.appendChild(script);
|
|
|
|
AppState.currentScript = script;
|
|
}
|
|
|
|
// Load main script
|
|
function loadScript(scriptName, txt = true) {
|
|
cleanupPreviousState();
|
|
|
|
const mainContainer = document.querySelector('.main-container');
|
|
const container = document.getElementById("canvasContainer");
|
|
const textContainer = document.getElementById("anotherCanvasContainer");
|
|
|
|
// Mode introduction (dp0) : canvas plus grand
|
|
const isIntro = scriptName === 'dp0.js';
|
|
|
|
if (isIntro) {
|
|
mainContainer.classList.add('intro-mode');
|
|
container.innerHTML = `
|
|
<canvas id="myCanvas" width="1000" height="1000"></canvas>
|
|
`;
|
|
} else {
|
|
mainContainer.classList.remove('intro-mode');
|
|
container.innerHTML = `
|
|
<canvas id="myCanvas" width="1000" height="1000"></canvas>
|
|
`;
|
|
}
|
|
|
|
const script = document.createElement("script");
|
|
script.type = "module";
|
|
script.src = `build/${scriptName}?t=${generateTimestamp()}`;
|
|
document.body.appendChild(script);
|
|
|
|
AppState.lastLoadedScript = scriptName;
|
|
AppState.lastTextMode = txt;
|
|
AppState.currentScript = script;
|
|
|
|
if (txt) {
|
|
const number = scriptName.substring(2, scriptName.length - 3);
|
|
loadText("txt.js", number);
|
|
}
|
|
}
|
|
|
|
// Keyboard navigation
|
|
document.addEventListener('keydown', (event) => {
|
|
if (event.key === 'Enter') {
|
|
loadScript(AppState.lastLoadedScript, AppState.lastTextMode);
|
|
}
|
|
});
|
|
|
|
// Expose to global scope for onclick handlers
|
|
window.loadScript = loadScript;
|
|
window.loadText = loadText;
|
|
|
|
// Initialize
|
|
loadScript('dp0.js');
|
|
</script>
|
|
</body>
|
|
</html>
|
|
|