Icône + Texte WIP et message fin du jeu sur curseur

This commit is contained in:
2024-10-28 00:53:00 +01:00
parent b41d82b5cd
commit 8b7fe06b37
6 changed files with 146 additions and 94 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 56 KiB

View File

@@ -24,42 +24,3 @@
</transition> </transition>
</router-view> </router-view>
</template> </template>
<style scoped>
header {
position: fixed;
z-index: 2;
height: 40px;
width: 100%;
padding: 10px;
background-color: #333;
color: #fff;
}
header * {
display: inline-block;
vertical-align: middle;
}
h1 {
text-align: center;
left: 0;
width: 200px;
font-size: 22px;
}
h2 {
text-align: left;
left: 220px;
font-size: medium;
}
nav {
right: 100px;
font-size: 20px;
}
nav * {
margin-left: 20px;
}
</style>

View File

@@ -45,24 +45,64 @@ a,
} }
} }
/* APP HEADER */
header {
position: fixed;
z-index: 2;
height: 40px;
width: 100%;
padding: 10px;
background-color: #333;
color: #fff;
* {
display: inline-block;
vertical-align: middle;
}
h1 {
text-align: center;
left: 0;
width: 200px;
font-size: 22px;
}
h2 {
text-align: left;
left: 220px;
font-size: medium;
}
nav {
right: 100px;
font-size: 20px;
}
nav * {
margin-left: 20px;
}
}
/* SIDEBAR NAVIGATION */ /* SIDEBAR NAVIGATION */
.sidenav { .sidenav {
position: fixed; position: absolute;
z-index: 1; z-index: 1;
width: 203px; /* 200px is the width of the header vl position + half the bar */ width: 203px; /* 200px is the width of the header vl position + half the bar */
background-color: #111; background-color: #111;
}
.sidenav a { a {
padding: 6px 8px 6px 16px; padding: 6px 8px 6px 16px;
text-decoration: none; text-decoration: none;
font-size: 25px; font-size: 25px;
color: #818181; color: #818181;
display: block; display: block;
}
.sidenav a:hover { }
color: #f1f1f1;
a:hover {
color: #f1f1f1;
}
} }
/* PAGE CONTENT */ /* PAGE CONTENT */
@@ -85,11 +125,11 @@ a,
justify-content: end; /* Centre les deux éléments horizontalement */ justify-content: end; /* Centre les deux éléments horizontalement */
width: 100%; width: 100%;
gap: 20px; /* Ajoute un espacement entre le h1 et le timer */ gap: 20px; /* Ajoute un espacement entre le h1 et le timer */
}
.space h1 { h1 {
font-weight: bold; font-weight: bold;
font-size: 20px; font-size: 20px;
}
} }
.timer { .timer {
@@ -109,14 +149,14 @@ a,
width: 100%; /* Prend toute la largeur disponible */ width: 100%; /* Prend toute la largeur disponible */
margin-top: -5px; margin-top: -5px;
margin-bottom: 10px; margin-bottom: 10px;
}
.menu button { button {
cursor: pointer; cursor: pointer;
height: 36px; height: 36px;
color: white; color: white;
border-radius: 10px; border-radius: 10px;
font-size: 16px; font-size: 16px;
}
} }
.presets { .presets {
@@ -124,17 +164,17 @@ a,
display: flex; display: flex;
align-items: center; align-items: center;
gap: 10px; /* Ajoute un espacement entre les boutons */ gap: 10px; /* Ajoute un espacement entre les boutons */
}
.presets button { button {
width: 75px; width: 75px;
height: 50px; height: 50px;
background-color: #3f77ff; background-color: #3f77ff;
border: 2px solid #7aa0ff; border: 2px solid #7aa0ff;
}
.presets button:hover { }
background-color: #1c5dff; button:hover {
background-color: #1c5dff;
}
} }
.inputs { .inputs {
@@ -142,25 +182,25 @@ a,
align-items: center; align-items: center;
gap: 10px; /* Ajoute un espacement entre les inputs */ gap: 10px; /* Ajoute un espacement entre les inputs */
margin-right: 20px; margin-right: 20px;
}
.inputs div { div {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
} }
.inputs label { label {
font-weight: bold; font-weight: bold;
font-size: 14px; font-size: 14px;
} }
.inputs input { input {
text-align: center; text-align: center;
width: 80px; width: 80px;
padding: 5px; padding: 5px;
border: 1px solid #ccc; border: 1px solid #ccc;
border-radius: 5px; border-radius: 5px;
}
} }
.newgame { .newgame {
@@ -177,6 +217,9 @@ a,
.grid { .grid {
display: grid; display: grid;
border: 4px solid rgb(65, 65, 65); border: 4px solid rgb(65, 65, 65);
margin: 0 auto; /* Centre la grille horizontalement */
overflow-x: auto; /* Active le défilement horizontal si nécessaire */
max-width: 100%; /* Empêche la grille de déborder trop */
} }
.row { .row {
@@ -215,6 +258,20 @@ a,
border-left: 6px solid rgb(0, 255, 140); border-left: 6px solid rgb(0, 255, 140);
} }
.message {
position: absolute;
z-index: 1000;
color: white;
background-color: rgba(0, 0, 0, 0.7);
border-radius: 8px;
padding: 10px;
transform: translate(-50%, 50%);
pointer-events: none;
white-space: nowrap;
font-weight: bold;
font-size: 18px;
}
/* ROUTE HIGHLIGHT */ /* ROUTE HIGHLIGHT */
.router-link-exact-active { .router-link-exact-active {
border-left: 5px solid rgb(0, 255, 140); border-left: 5px solid rgb(0, 255, 140);

View File

@@ -1,5 +1,13 @@
<template> <template>
<div class="main"> <div class="main">
<h1>Multijoueur</h1> <h1>Multijoueur</h1>
<p>Work in progress...</p>
<p>Vous pouvez jouer en solo pour l'instant !</p>
</div> </div>
</template> </template>
<style scoped>
p {
margin: 0;
}
</style>

View File

@@ -35,8 +35,8 @@ const formatTime = (seconds: number) => {
// Si les heures sont 0, ne pas les afficher // Si les heures sont 0, ne pas les afficher
const hoursDisplay = hours > 0 ? `${hours}:` : '' const hoursDisplay = hours > 0 ? `${hours}:` : ''
// Afficher les minutes sans padding de 0 // Afficher les minutes avec un padding de 0 si elles sont inférieures à 10
const minutesDisplay = `${minutes}:` const minutesDisplay = `${hours > 0 ? String(minutes).padStart(2, '0') : minutes}:`
// Toujours afficher les secondes avec un padding de 0 // Toujours afficher les secondes avec un padding de 0
const secondsDisplay = String(secs).padStart(2, '0') const secondsDisplay = String(secs).padStart(2, '0')
@@ -53,6 +53,10 @@ watch(gameStatus, async (status) => {
else if (timerInterval) clearInterval(timerInterval) else if (timerInterval) clearInterval(timerInterval)
}) })
// Variables pour stocker la position du curseur
const mouseX = ref(0)
const mouseY = ref(0)
// État pour gérer le clic et la position de la cellule // État pour gérer le clic et la position de la cellule
const isMouseDown = ref(false) const isMouseDown = ref(false)
const currentCell = ref<{ rowIndex: number, cellIndex: number } | null>(null) const currentCell = ref<{ rowIndex: number, cellIndex: number } | null>(null)
@@ -114,6 +118,9 @@ const handleMouseMove = (rowIndex: number, cellIndex: number) => {
// Gestion des événements de déplacement de la souris et de la position de la cellule // Gestion des événements de déplacement de la souris et de la position de la cellule
const handleGlobalMouseMove = (event: MouseEvent) => { const handleGlobalMouseMove = (event: MouseEvent) => {
mouseX.value = event.clientX
mouseY.value = event.clientY
if (isMouseDown.value && currentCell.value) { if (isMouseDown.value && currentCell.value) {
const target = event.target as HTMLElement const target = event.target as HTMLElement
@@ -153,6 +160,12 @@ onUnmounted(() => document.removeEventListener('mousemove', handleGlobalMouseMov
<div class="timer" :gameStatus>{{ formatTime(timer) }}</div> <div class="timer" :gameStatus>{{ formatTime(timer) }}</div>
</div> </div>
<transition name="fade">
<div v-if="gameStatus === 2 || gameStatus === 3" class="message" :style="{ top: mouseY + 'px', left: mouseX + 'px' }">
{{ gameStatus === 2 ? 'Vous avez gagné !' : 'Vous avez perdu !' }}
</div>
</transition>
<div class="menu"> <div class="menu">
<div class="presets"> <div class="presets">
<button class="rounded" @click="width = 10; length = 15; nbMines = 20">Facile</button> <button class="rounded" @click="width = 10; length = 15; nbMines = 20">Facile</button>
@@ -179,6 +192,7 @@ onUnmounted(() => document.removeEventListener('mousemove', handleGlobalMouseMov
<button class="rounded newgame" @click="startNewGame">Nouvelle partie</button> <button class="rounded newgame" @click="startNewGame">Nouvelle partie</button>
</div> </div>
<div class="grid"> <div class="grid">
<div v-for="(row, rowIndex) in cellGrid" :key="rowIndex" class="row"> <div v-for="(row, rowIndex) in cellGrid" :key="rowIndex" class="row">
<img v-for="(cell, cellIndex) in row" :key="cellIndex" class="cell" :src="cell" <img v-for="(cell, cellIndex) in row" :key="cellIndex" class="cell" :src="cell"
@@ -192,11 +206,6 @@ onUnmounted(() => document.removeEventListener('mousemove', handleGlobalMouseMov
/> />
</div> </div>
</div> </div>
<transition name="fade">
<div v-if="gameStatus === 2" class="message">Vous avez gagné !</div>
<div v-else-if="gameStatus === 3" class="message">Vous avez perdu !</div>
</transition>
</div> </div>
</template> </template>

View File

@@ -1,11 +1,18 @@
<template> <template>
<div class="main"> <div class="main">
<p class="wip">
Le jeu est actuellement en cours de développement.
<br>
Le mode multijoueur n'est pas implémenté et l'affichage est encore en cours de finalisation.
</p>
<h1>MultiMinesweeper</h1> <h1>MultiMinesweeper</h1>
<p> <p>
Bienvenue sur notre jeu de démineur en ligne ! Bienvenue sur notre jeu de démineur en ligne !
<br> <br>
Pour jouer, il vous suffit de sélectionner le mode de jeu que vous souhaitez dans le menu ci-dessous. Pour jouer, il vous suffit de sélectionner le mode de jeu que vous souhaitez dans le menu ci-dessous.
</p> </p>
<div class="buttons"> <div class="buttons">
<router-link to="/game/solo" v-slot="{ navigate }"> <router-link to="/game/solo" v-slot="{ navigate }">
<button @click="navigate">Solo</button> <button @click="navigate">Solo</button>
@@ -22,6 +29,16 @@
text-align: center; text-align: center;
} }
.wip {
position: absolute;
bottom: 60px;
right: 40px;
text-align: right;
font-style: italic;
font-weight: bold;
font-size: 20px;
}
.buttons { .buttons {
display: flex; display: flex;
gap: 10px; gap: 10px;