318 lines
No EOL
11 KiB
HTML
318 lines
No EOL
11 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="fr">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>Tuto Riichi</title>
|
|
<link rel="stylesheet" href="/frontend/css/style.css">
|
|
<link rel="stylesheet" href="/frontend/css/text.css">
|
|
<link rel="stylesheet" href="/frontend/css/speech-bubble.css">
|
|
<link rel="stylesheet" href="/frontend/css/hand.css">
|
|
<style>
|
|
#menu {
|
|
position: relative;
|
|
z-index: 10;
|
|
}
|
|
|
|
#mascotte {
|
|
position: absolute;
|
|
top: 670px;
|
|
right: 100px;
|
|
z-index: 999;
|
|
transform: scaleX(-1);
|
|
cursor: pointer;
|
|
}
|
|
|
|
#mascotte img {
|
|
width: 250px;
|
|
height: auto;
|
|
display: block;
|
|
}
|
|
|
|
.speech-bubble {
|
|
position: absolute;
|
|
top: 250px;
|
|
right: 170px;
|
|
z-index: 1;
|
|
display: none;
|
|
}
|
|
|
|
.speech-bubble.visible {
|
|
display: flex;
|
|
}
|
|
|
|
#tiles-container {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: flex-start;
|
|
gap: 10px;
|
|
padding: 20px;
|
|
}
|
|
|
|
:root {
|
|
--game_radius: 1100px;
|
|
}
|
|
|
|
#game-center {
|
|
position: absolute;
|
|
top: 0px;
|
|
left: 350px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
min-height: 100vh;
|
|
}
|
|
#game {
|
|
position: relatives;
|
|
width: var(--game_radius);
|
|
height: var(--game_radius);
|
|
}
|
|
|
|
#hand-0 {
|
|
position: absolute;
|
|
transform: translate(-50%, 50%);
|
|
bottom: -10%;
|
|
left: 50%;
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: flex-end;
|
|
gap: 5px;
|
|
padding: 20px 0 0 20px;
|
|
}
|
|
|
|
#hand-1 {
|
|
position: absolute;
|
|
transform: translate(-50%, -400%) rotate(-90deg) translate(0%, 450%);
|
|
bottom: -10%;
|
|
left: 50%;
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: flex-end;
|
|
gap: 5px;
|
|
padding: 20px 0 0 20px;
|
|
}
|
|
|
|
#hand-2 {
|
|
position: absolute;
|
|
transform: translate(-50%, -400%) rotate(180deg) translate(0%, 450%);
|
|
bottom: -10%;
|
|
left: 50%;
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: flex-end;
|
|
gap: 5px;
|
|
padding: 20px 0 0 20px;
|
|
}
|
|
|
|
#hand-3 {
|
|
position: absolute;
|
|
transform: translate(-50%, -400%) rotate(90deg) translate(0%, 450%);
|
|
bottom: -10%;
|
|
left: 50%;
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: flex-end;
|
|
gap: 5px;
|
|
padding: 20px 0 0 20px;
|
|
}
|
|
|
|
#hand-0 div:hover {
|
|
transform: translateY(-15px);
|
|
transition: transform 0.2s;
|
|
z-index: 2;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div id="menu"></div>
|
|
<h1>Chapitre 5</h1>
|
|
<div class="speech-bubble">
|
|
<div class="speech-text" id="speech-text"></div>
|
|
</div>
|
|
<div id="mascotte"></div>
|
|
|
|
<div id="game-center">
|
|
<div id="game">
|
|
<div id="hand-0"></div>
|
|
<div id="hand-1"></div>
|
|
<div id="hand-2"></div>
|
|
<div id="hand-3"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="/frontend/js/fr/texts.js"></script>
|
|
<script src="/frontend/js/tile.js"></script>
|
|
<script src="/frontend/js/game.js"></script>
|
|
<script>
|
|
window.addEventListener('DOMContentLoaded', () => {
|
|
// Charger le menu
|
|
fetch('/components/menu.html')
|
|
.then(r => r.text())
|
|
.then(html => document.getElementById('menu').innerHTML = html);
|
|
|
|
// Afficher la mascotte et le texte
|
|
const mascotteEl = document.getElementById('mascotte');
|
|
mascotteEl.innerHTML = '<img src="/img/tilineau/idle.png" alt="Tilineau">';
|
|
document.getElementById('speech-text').innerHTML = texts.riichi.chap5;
|
|
|
|
// Toggle bulle de dialogue au clic sur la mascotte
|
|
const speechBubble = document.querySelector('.speech-bubble');
|
|
mascotteEl.addEventListener('click', () => {
|
|
speechBubble.classList.toggle('visible');
|
|
mascotteEl.innerHTML = speechBubble.classList.contains('visible')
|
|
? '<img class="explaining" src="/img/tilineau/explaining.png" alt="Tilineau">'
|
|
: '<img src="/img/tilineau/idle.png" alt="Tilineau">';
|
|
});
|
|
|
|
// Logique de jeu frontend
|
|
let game;
|
|
function renderPlayerHand(gameInstance) {
|
|
const handDiv = document.getElementById('hand-0');
|
|
handDiv.innerHTML = '';
|
|
let handTiles = gameInstance.handPlayer.tiles.slice();
|
|
sortHand(handTiles);
|
|
handTiles.forEach((tile, idx) => {
|
|
const tileDiv = document.createElement('div');
|
|
tileDiv.className = 'hand-tile-item';
|
|
tileDiv.innerHTML = tile.getSVG();
|
|
tileDiv.dataset.tileId = tile.id;
|
|
tileDiv.style.cursor = 'pointer';
|
|
tileDiv.addEventListener('click', () => discardTile(tile.id));
|
|
handDiv.appendChild(tileDiv);
|
|
});
|
|
// Pioche
|
|
if (gameInstance.handPlayer.draw) {
|
|
const drawTileDiv = document.createElement('div');
|
|
drawTileDiv.className = 'hand-tile-item draw-tile';
|
|
drawTileDiv.innerHTML = gameInstance.handPlayer.draw.getSVG();
|
|
drawTileDiv.dataset.tileId = gameInstance.handPlayer.draw.id;
|
|
drawTileDiv.style.cursor = 'pointer';
|
|
drawTileDiv.addEventListener('click', () => discardTile(gameInstance.handPlayer.draw.id));
|
|
handDiv.appendChild(drawTileDiv);
|
|
}
|
|
// Afficher les mains des bots
|
|
for (let bot = 0; bot < 3; bot++) {
|
|
const botDiv = document.getElementById('hand-' + (bot + 1));
|
|
botDiv.innerHTML = '';
|
|
let botTiles = gameInstance.handsBots[bot].tiles.slice();
|
|
botTiles.forEach(() => {
|
|
const tileDiv = document.createElement('div');
|
|
tileDiv.innerHTML = '<svg viewBox="0 0 310 410" width="60" height="80"><image href="/img/Regular/Back.svg" width="310" height="410"/></svg>';
|
|
botDiv.appendChild(tileDiv);
|
|
});
|
|
if (gameInstance.handsBots[bot].draw) {
|
|
const drawTileDiv = document.createElement('div');
|
|
drawTileDiv.innerHTML = '<svg viewBox="0 0 310 410" width="60" height="80"><image href="/img/Regular/Back.svg" width="310" height="410"/></svg>';
|
|
botDiv.appendChild(drawTileDiv);
|
|
}
|
|
}
|
|
}
|
|
|
|
game = new window.Game(renderPlayerHand);
|
|
|
|
function sortHand(hand) {
|
|
const familyOrder = { 'man': 0, 'pin': 1, 'sou': 2, 'wind': 3, 'dragon': 4 };
|
|
return hand.sort((a, b) => {
|
|
const famA = familyOrder[a.family] ?? 99;
|
|
const famB = familyOrder[b.family] ?? 99;
|
|
if (famA !== famB) return famA - famB;
|
|
if (a.value !== undefined && b.value !== undefined) return a.value - b.value;
|
|
if (a.wind !== undefined && b.wind !== undefined) return a.wind - b.wind;
|
|
if (a.dragon !== undefined && b.dragon !== undefined) return a.dragon - b.dragon;
|
|
return 0;
|
|
});
|
|
}
|
|
|
|
function renderPlayerHand() {
|
|
const handDiv = document.getElementById('hand-0');
|
|
handDiv.innerHTML = '';
|
|
let handTiles = game.handPlayer.tiles.slice();
|
|
sortHand(handTiles);
|
|
handTiles.forEach((tile, idx) => {
|
|
const tileDiv = document.createElement('div');
|
|
tileDiv.className = 'hand-tile-item';
|
|
tileDiv.innerHTML = tile.getSVG();
|
|
tileDiv.dataset.tileId = tile.id;
|
|
tileDiv.style.cursor = 'pointer';
|
|
tileDiv.addEventListener('click', () => discardTile(tile.id));
|
|
handDiv.appendChild(tileDiv);
|
|
});
|
|
// Pioche
|
|
if (game.handPlayer.draw) {
|
|
const drawTileDiv = document.createElement('div');
|
|
drawTileDiv.className = 'hand-tile-item draw-tile';
|
|
drawTileDiv.innerHTML = game.handPlayer.draw.getSVG();
|
|
drawTileDiv.dataset.tileId = game.handPlayer.draw.id;
|
|
drawTileDiv.style.cursor = 'pointer';
|
|
drawTileDiv.addEventListener('click', () => discardTile(game.handPlayer.draw.id));
|
|
handDiv.appendChild(drawTileDiv);
|
|
}
|
|
// Afficher les mains des bots
|
|
for (let bot = 0; bot < 3; bot++) {
|
|
const botDiv = document.getElementById('hand-' + (bot + 1));
|
|
botDiv.innerHTML = '';
|
|
let botTiles = game.handsBots[bot].tiles.slice();
|
|
// Affiche le dos des tuiles
|
|
botTiles.forEach(() => {
|
|
const tileDiv = document.createElement('div');
|
|
tileDiv.innerHTML = '<svg viewBox="0 0 310 410" width="60" height="80"><image href="/img/Regular/Back.svg" width="310" height="410"/></svg>';
|
|
botDiv.appendChild(tileDiv);
|
|
});
|
|
// Pioche du bot (si présente)
|
|
if (game.handsBots[bot].draw) {
|
|
const drawTileDiv = document.createElement('div');
|
|
drawTileDiv.innerHTML = '<svg viewBox="0 0 310 410" width="60" height="80"><image href="/img/Regular/Back.svg" width="310" height="410"/></svg>';
|
|
botDiv.appendChild(drawTileDiv);
|
|
}
|
|
}
|
|
}
|
|
function renderPlayerHand(gameInstance) {
|
|
const handDiv = document.getElementById('hand-0');
|
|
handDiv.innerHTML = '';
|
|
let handTiles = gameInstance.handPlayer.tiles.slice();
|
|
sortHand(handTiles);
|
|
handTiles.forEach((tile, idx) => {
|
|
const tileDiv = document.createElement('div');
|
|
tileDiv.className = 'hand-tile-item';
|
|
tileDiv.innerHTML = tile.getSVG();
|
|
tileDiv.dataset.tileId = tile.id;
|
|
tileDiv.style.cursor = 'pointer';
|
|
tileDiv.addEventListener('click', () => discardTile(tile.id));
|
|
handDiv.appendChild(tileDiv);
|
|
});
|
|
// Pioche
|
|
if (gameInstance.handPlayer.draw) {
|
|
const drawTileDiv = document.createElement('div');
|
|
drawTileDiv.className = 'hand-tile-item draw-tile';
|
|
drawTileDiv.innerHTML = gameInstance.handPlayer.draw.getSVG();
|
|
drawTileDiv.dataset.tileId = gameInstance.handPlayer.draw.id;
|
|
drawTileDiv.style.cursor = 'pointer';
|
|
drawTileDiv.addEventListener('click', () => discardTile(gameInstance.handPlayer.draw.id));
|
|
handDiv.appendChild(drawTileDiv);
|
|
}
|
|
// Afficher les mains des bots
|
|
for (let bot = 0; bot < 3; bot++) {
|
|
const botDiv = document.getElementById('hand-' + (bot + 1));
|
|
botDiv.innerHTML = '';
|
|
let botTiles = gameInstance.handsBots[bot].tiles.slice();
|
|
botTiles.forEach(() => {
|
|
const tileDiv = document.createElement('div');
|
|
tileDiv.innerHTML = '<svg viewBox="0 0 310 410" width="60" height="80"><image href="/img/Regular/Back.svg" width="310" height="410"/></svg>';
|
|
botDiv.appendChild(tileDiv);
|
|
});
|
|
if (gameInstance.handsBots[bot].draw) {
|
|
const drawTileDiv = document.createElement('div');
|
|
drawTileDiv.innerHTML = '<svg viewBox="0 0 310 410" width="60" height="80"><image href="/img/Regular/Back.svg" width="310" height="410"/></svg>';
|
|
botDiv.appendChild(drawTileDiv);
|
|
}
|
|
}
|
|
}
|
|
|
|
async function discardTile(tileId) {
|
|
await game.discardTile(tileId);
|
|
}
|
|
|
|
// renderPlayerHand(game); // Removed direct call to renderPlayerHand with game
|
|
});
|
|
</script>
|
|
</body>
|
|
</html> |