277 lines
7.8 KiB
Vue
277 lines
7.8 KiB
Vue
<template>
|
|
<div class="p-2 game-container">
|
|
<h1 class="text-3xl text-center text-primary-900 font-bold">Pendu</h1>
|
|
<p class="text-center mb-4">Trouve le mot du pendu - Saisi les lettres</p>
|
|
<div class="flex justify-center dic-select">
|
|
<div v-for="(dic, key) in dictionary" :key="key">
|
|
<a v-if="!selectedWord" class="btn-primary mr-1" @click="selectWord">{{ key }}</a>
|
|
</div>
|
|
</div>
|
|
<div class="flex">
|
|
<div class="game-container-box">
|
|
<svg height="250" width="200" class="figure-container">
|
|
<!-- Potence -->
|
|
<line x1="60" y1="20" x2="140" y2="20" />
|
|
<line x1="140" y1="20" x2="140" y2="50" />
|
|
<line x1="60" y1="20" x2="60" y2="230" />
|
|
<line x1="20" y1="230" x2="100" y2="230" />
|
|
|
|
<!-- Tête -->
|
|
<circle cx="140" cy="70" r="20" class="figure-part"/>
|
|
<!-- Corps -->
|
|
<line x1="140" y1="90" x2="140" y2="150" class="figure-part"/>
|
|
<line x1="140" y1="120" x2="120" y2="100" class="figure-part"/>
|
|
<line x1="140" y1="120" x2="160" y2="100" class="figure-part"/>
|
|
<line x1="140" y1="150" x2="120" y2="180" class="figure-part"/>
|
|
<line x1="140" y1="150" x2="160" y2="180" class="figure-part"/>
|
|
</svg>
|
|
</div>
|
|
<div class="game-container-box">
|
|
<div class="wrong-letters-container">
|
|
<div v-html="wrongLettersEl" class="wrong-letters"></div>
|
|
<div class="word" v-html="wordEl"></div>
|
|
</div>
|
|
|
|
<div v-if="notification" class="notification-container">
|
|
<p>Vous avez déjà saisie cette lettre.</p>
|
|
</div>
|
|
<div v-if="popup" class="popup-container">
|
|
<div class="popup">
|
|
<h2 class="py-3">{{ finalMessage }}</h2>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import json from './dict.json'
|
|
|
|
export default {
|
|
name: 'Hangman',
|
|
data: function () {
|
|
return {
|
|
dictionary: json,
|
|
letterBox: '',
|
|
figureParts: [],
|
|
correctLetters: [],
|
|
wrongLetters: [],
|
|
wrongLettersEl: '',
|
|
selectedWord: '',
|
|
wordEl: '',
|
|
finalMessage: '',
|
|
popup: false,
|
|
notification: false,
|
|
}
|
|
},
|
|
mounted() {
|
|
this.figureParts = this.$el.querySelectorAll('.figure-part')
|
|
window.addEventListener('keyup', this.keyMessage)
|
|
},
|
|
methods: {
|
|
selectWord(e) {
|
|
this.selectedWord = this.dictionary[e.target.textContent][Math.floor(Math.random() * this.dictionary[e.target.textContent].length)].toLowerCase()
|
|
this.displayWord()
|
|
this.popup = false
|
|
},
|
|
keyMessage(e) {
|
|
if(e.keyCode >= 65 && e.keyCode <= 90) {
|
|
const letter = e.key
|
|
|
|
if(this.selectedWord.includes(letter)) {
|
|
if(!this.correctLetters.includes(letter)) {
|
|
this.correctLetters.push(letter)
|
|
|
|
this.displayWord()
|
|
} else {
|
|
this.showNotification()
|
|
}
|
|
} else {
|
|
if(!this.wrongLetters.includes(letter)) {
|
|
this.wrongLetters.push(letter)
|
|
|
|
this.updateWrongLettersEl()
|
|
} else {
|
|
this.showNotification()
|
|
}
|
|
}
|
|
}
|
|
},
|
|
displayWord() {
|
|
this.wordEl =
|
|
this.selectedWord
|
|
.split('')
|
|
.map(
|
|
letter => {
|
|
let toggleLetter = this.correctLetters.includes(letter) ? letter : ''
|
|
return '<span class="letter">' + toggleLetter + '</span>'
|
|
}
|
|
).join('')
|
|
|
|
const innerWord = this.wordEl.replace(/<span class="letter">|<\/span>/g, '')
|
|
|
|
if(innerWord === this.selectedWord) {
|
|
this.finalMessage = 'Gagné! 😃'
|
|
this.popup = true
|
|
this.newGame()
|
|
}
|
|
},
|
|
updateWrongLettersEl() {
|
|
this.wrongLettersEl =
|
|
!this.wrongLetters ? '<p>Wrong</p>' : ''
|
|
+
|
|
this.wrongLetters.map(letter => `<span>${letter}</span>`)
|
|
|
|
// Display parts
|
|
this.figureParts.forEach((part, index) => {
|
|
const errors = this.wrongLetters.length
|
|
|
|
if(index < errors) {
|
|
part.style.display = 'block'
|
|
} else {
|
|
part.style.display = 'none'
|
|
}
|
|
})
|
|
|
|
// Check if lost
|
|
if(this.wrongLetters.length === this.figureParts.length) {
|
|
this.finalMessage = 'Perdu. 😕'
|
|
this.popup = true
|
|
this.newGame()
|
|
}
|
|
},
|
|
newGame: function () {
|
|
this.popup = true
|
|
this.correctLetters.splice(0)
|
|
this.wrongLetters.splice(0)
|
|
this.letterBox = ''
|
|
this.selectedWord = ''
|
|
this.wrongLettersEl = ''
|
|
},
|
|
showNotification(){
|
|
this.notification = true
|
|
|
|
setTimeout(() => {
|
|
this.notification = false
|
|
}, 2000)
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
|
|
.game-container {
|
|
max-width: 80rem;
|
|
margin: 0 auto;
|
|
}
|
|
.game-container-box {
|
|
padding: 2rem 3rem;
|
|
position: relative;
|
|
display: flex;
|
|
flex: 1;
|
|
flex-direction: column;
|
|
justify-content: space-between;
|
|
}
|
|
|
|
.dic-select {
|
|
min-height: 6rem;
|
|
}
|
|
|
|
.figure-container {
|
|
fill: transparent;
|
|
stroke: orange;
|
|
stroke-width: 4px;
|
|
stroke-linecap: round;
|
|
}
|
|
|
|
.figure-part {
|
|
display: none;
|
|
stroke: #7b341e;
|
|
}
|
|
|
|
.wrong-letters-container {
|
|
top: 4rem;
|
|
display: flex;
|
|
flex-direction: column;
|
|
text-align: right;
|
|
}
|
|
|
|
.wrong-letters-container .wrong-letters {
|
|
height: 3.5rem;
|
|
}
|
|
|
|
.wrong-letters-container p {
|
|
margin: 0 0 5px;
|
|
}
|
|
|
|
.wrong-letters-container span {
|
|
font-size: 2.4rem;
|
|
}
|
|
|
|
.word {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
bottom: 1rem;
|
|
}
|
|
|
|
.word .letter {
|
|
border-bottom: 3px solid #c05621;
|
|
display: inline-flex;
|
|
font-size: 30px;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin: 0 3px;
|
|
height: 50px;
|
|
width: 20px;
|
|
}
|
|
|
|
.popup-container {
|
|
position: absolute;
|
|
width: calc(100% - 6rem);
|
|
}
|
|
|
|
.popup-container .popup {
|
|
background-color: #c05621;
|
|
border-radius: 5px;
|
|
color: #fbd38d;
|
|
min-height: 10rem;
|
|
padding: 20px;
|
|
text-align: center;
|
|
}
|
|
|
|
.popup-container .popup button {
|
|
cursor: pointer;
|
|
background-color: #fff;
|
|
color: #7b341e;
|
|
border: 0;
|
|
margin-top: 20px;
|
|
padding: 12px 20px;
|
|
font-size: 16px;
|
|
}
|
|
|
|
.popup-container .popup button:active {
|
|
transform: scale(0.98);
|
|
}
|
|
|
|
.popup-container .popup button:focus {
|
|
outline: 0;
|
|
}
|
|
|
|
.notification-container {
|
|
background-color: #ed8936;
|
|
border-radius: 2px;
|
|
padding: 1rem;
|
|
text-align: center;
|
|
margin-bottom: 6rem;
|
|
}
|
|
|
|
.notification-container p {
|
|
margin: 0;
|
|
}
|
|
|
|
|
|
</style>
|