feat: confirm button with pulse animation + ready counter (X/N players)
This commit is contained in:
1 parent
91a1a9f4f0
commit
3125823f42
2 files changed
+84
-9
No files matched your search
@@ -111,18 +111,75 @@ export class GameScene extends Phaser.Scene {
|
||||
|
||||
_buildPlayButton() {
|
||||
const { width, height } = this.scale
|
||||
const btnY = height - 28
|
||||
|
||||
this.playBtn = this.add.text(width / 2, height - 18, '[ JOUER LA CARTE ]', {
|
||||
fontSize: '15px',
|
||||
// Fond du bouton (rectangle arrondi via Graphics)
|
||||
this.playBtnBg = this.add.graphics()
|
||||
this._drawBtnBg(false)
|
||||
|
||||
// Texte du bouton
|
||||
this.playBtn = this.add.text(width / 2, btnY, '✔ CONFIRMER MA CARTE', {
|
||||
fontSize: '17px',
|
||||
fontFamily: 'Georgia',
|
||||
fontStyle: 'bold',
|
||||
color: '#1a0a00',
|
||||
backgroundColor: '#d4a732',
|
||||
padding: { x: 20, y: 8 }
|
||||
padding: { x: 28, y: 10 }
|
||||
})
|
||||
.setOrigin(0.5)
|
||||
.setAlpha(0.35)
|
||||
.setAlpha(0.3)
|
||||
.setDepth(10)
|
||||
.setInteractive({ cursor: 'pointer' })
|
||||
.on('pointerdown', this._playSelectedCard, this)
|
||||
.on('pointerover', () => { if (this._canPlay && this.selectedCard) this.playBtn.setScale(1.05) })
|
||||
.on('pointerout', () => { this.playBtn.setScale(1) })
|
||||
|
||||
// Compteur de joueurs prêts (ex: "1 / 2 prêts")
|
||||
this.readyText = this.add.text(width / 2, btnY + 22, '', {
|
||||
fontSize: '12px',
|
||||
fontFamily: 'Georgia',
|
||||
color: '#a08060'
|
||||
}).setOrigin(0.5).setDepth(10)
|
||||
}
|
||||
|
||||
_drawBtnBg(active) {
|
||||
const { width, height } = this.scale
|
||||
const btnY = height - 28
|
||||
const btnW = 280
|
||||
const btnH = 42
|
||||
this.playBtnBg.clear()
|
||||
if (active) {
|
||||
this.playBtnBg.fillStyle(0xd4a732, 1)
|
||||
} else {
|
||||
this.playBtnBg.fillStyle(0x4a3010, 0.5)
|
||||
}
|
||||
this.playBtnBg.fillRoundedRect(width / 2 - btnW / 2, btnY - btnH / 2, btnW, btnH, 8)
|
||||
if (active) {
|
||||
this.playBtnBg.lineStyle(2, 0xffd700)
|
||||
this.playBtnBg.strokeRoundedRect(width / 2 - btnW / 2, btnY - btnH / 2, btnW, btnH, 8)
|
||||
}
|
||||
this.playBtnBg.setDepth(9)
|
||||
}
|
||||
|
||||
_activateBtn() {
|
||||
this._drawBtnBg(true)
|
||||
this.playBtn.setAlpha(1).setColor('#1a0a00')
|
||||
// Animation pulse
|
||||
if (this._pulseTween) this._pulseTween.stop()
|
||||
this._pulseTween = this.tweens.add({
|
||||
targets: this.playBtn,
|
||||
scaleX: 1.04,
|
||||
scaleY: 1.04,
|
||||
duration: 600,
|
||||
yoyo: true,
|
||||
repeat: -1,
|
||||
ease: 'Sine.easeInOut'
|
||||
})
|
||||
}
|
||||
|
||||
_deactivateBtn() {
|
||||
this._drawBtnBg(false)
|
||||
this.playBtn.setAlpha(0.3).setColor('#a08060').setScale(1)
|
||||
if (this._pulseTween) { this._pulseTween.stop(); this._pulseTween = null }
|
||||
}
|
||||
|
||||
// ─── Main du joueur ──────────────────────────────────────────────────────────
|
||||
@@ -149,13 +206,14 @@ export class GameScene extends Phaser.Scene {
|
||||
}
|
||||
|
||||
_onCardSelected(card) {
|
||||
if (!this._canPlay) return
|
||||
// Désélectionner l'ancienne
|
||||
if (this.selectedCard && this.selectedCard !== card) {
|
||||
this.selectedCard.deselect()
|
||||
}
|
||||
this.selectedCard = card
|
||||
this.store.selectCard(card.cardData)
|
||||
this.playBtn.setAlpha(1)
|
||||
this._activateBtn()
|
||||
}
|
||||
|
||||
_playSelectedCard() {
|
||||
@@ -163,6 +221,7 @@ export class GameScene extends Phaser.Scene {
|
||||
|
||||
// Bloquer immédiatement pour éviter le double clic
|
||||
this._canPlay = false
|
||||
this._deactivateBtn()
|
||||
|
||||
this.socket.emit('play-card', {
|
||||
roomId: this.roomId,
|
||||
@@ -172,7 +231,6 @@ export class GameScene extends Phaser.Scene {
|
||||
this.selectedCard.setAlpha(0.4)
|
||||
this.selectedCard = null
|
||||
this.store.clearSelection()
|
||||
this.playBtn.setAlpha(0.35)
|
||||
this.phaseText.setText('En attente des autres joueurs...')
|
||||
}
|
||||
|
||||
@@ -279,22 +337,33 @@ export class GameScene extends Phaser.Scene {
|
||||
this._canPlay = true
|
||||
this.resolveObjects.forEach(o => o.destroy())
|
||||
this.resolveObjects = []
|
||||
this.phaseText.setText('Sélectionnez une carte')
|
||||
this.phaseText.setText('Choisissez une carte puis confirmez')
|
||||
this.readyText.setText('')
|
||||
this._deactivateBtn()
|
||||
this._buildHand(state.hand)
|
||||
}
|
||||
|
||||
if (state.phase === 'waiting') {
|
||||
this._canPlay = false
|
||||
this.phaseText.setText('En attente des autres joueurs...')
|
||||
this._deactivateBtn()
|
||||
this.phaseText.setText('Carte confirmée — en attente des autres...')
|
||||
}
|
||||
|
||||
if (state.phase === 'resolve' || state.phase === 'end') {
|
||||
this._canPlay = false
|
||||
this._deactivateBtn()
|
||||
}
|
||||
})
|
||||
|
||||
this.socket.on('players-ready', ({ ready, total }) => {
|
||||
if (this.readyText) {
|
||||
this.readyText.setText(`${ready} / ${total} joueurs prêts`)
|
||||
}
|
||||
})
|
||||
|
||||
this.socket.on('round-result', ({ playedCards, gains }) => {
|
||||
this.phaseText.setText('Résolution du tour...')
|
||||
this.readyText.setText('')
|
||||
this._showPlayedCards(playedCards, gains)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user