feat: gauge scoring system (subtract left neighbor per attribute)
This commit is contained in:
1 parent
25ab76c4ac
commit
91a1a9f4f0
5 files changed
+297
-203
No files matched your search
@@ -17,12 +17,6 @@ const ATTR_COLORS = {
|
||||
diplo: 0x3399ee
|
||||
}
|
||||
|
||||
const ATTR_LABELS = {
|
||||
food: 'Nourriture',
|
||||
war: 'Guerre',
|
||||
health: 'Santé',
|
||||
diplo: 'Diplomatie'
|
||||
}
|
||||
|
||||
export class GameScene extends Phaser.Scene {
|
||||
constructor() {
|
||||
@@ -184,104 +178,96 @@ export class GameScene extends Phaser.Scene {
|
||||
|
||||
// ─── Résolution visuelle ─────────────────────────────────────────────────────
|
||||
|
||||
_showPlayedCards(playedCards) {
|
||||
// Nettoyer
|
||||
/**
|
||||
* Affiche les cartes jouées et les gains obtenus (soustraction voisin gauche)
|
||||
* @param {Array} playedCards - cartes jouées dans l'ordre des joueurs
|
||||
* @param {Array} gains - gains[i] = { food, war, health, diplo } pour le joueur i
|
||||
*/
|
||||
_showPlayedCards(playedCards, gains = []) {
|
||||
this.resolveObjects.forEach(o => o.destroy())
|
||||
this.resolveObjects = []
|
||||
|
||||
const ATTRS_POS = [
|
||||
{ key: 'food', label: 'NOU', dx: -28, dy: -20 },
|
||||
{ key: 'war', label: 'GUE', dx: 28, dy: -20 },
|
||||
{ key: 'health', label: 'SAN', dx: -28, dy: 30 },
|
||||
{ key: 'diplo', label: 'DIP', dx: 28, dy: 30 }
|
||||
]
|
||||
|
||||
playedCards.forEach((entry, i) => {
|
||||
const slot = this.playSlots[i]
|
||||
if (!slot) return
|
||||
|
||||
const teamColor = TEAM_COLORS[entry.teamIndex] ?? 0x888888
|
||||
const gain = gains[i] ?? {}
|
||||
|
||||
// Mini carte de résolution
|
||||
// ── Fond carte ──────────────────────────────────────────
|
||||
const g = this.add.graphics()
|
||||
g.fillStyle(this._darken(teamColor, 0.3))
|
||||
g.fillRoundedRect(-55, -85, 110, 170, 6)
|
||||
g.fillStyle(this._darken(teamColor, 0.25))
|
||||
g.fillRoundedRect(-55, -90, 110, 180, 6)
|
||||
g.lineStyle(2, teamColor)
|
||||
g.strokeRoundedRect(-55, -85, 110, 170, 6)
|
||||
g.strokeRoundedRect(-55, -90, 110, 180, 6)
|
||||
g.x = slot.x
|
||||
g.y = slot.y
|
||||
this.resolveObjects.push(g)
|
||||
|
||||
// Nom du joueur
|
||||
const pName = this.add.text(slot.x, slot.y - 72, entry.playerName, {
|
||||
fontSize: '10px', fontFamily: 'Georgia', color: '#ffffff', fontStyle: 'bold'
|
||||
}).setOrigin(0.5)
|
||||
this.resolveObjects.push(pName)
|
||||
|
||||
// Nom de la carte
|
||||
const cName = this.add.text(slot.x, slot.y - 56, entry.cardName, {
|
||||
fontSize: '13px', fontFamily: 'Georgia', color: '#d4a732', fontStyle: 'bold'
|
||||
}).setOrigin(0.5)
|
||||
this.resolveObjects.push(cName)
|
||||
|
||||
// 4 attributs
|
||||
const attrs = [
|
||||
{ key: 'food', label: 'NOU', cx: slot.x - 28, cy: slot.y - 20 },
|
||||
{ key: 'war', label: 'GUE', cx: slot.x + 28, cy: slot.y - 20 },
|
||||
{ key: 'health', label: 'SAN', cx: slot.x - 28, cy: slot.y + 40 },
|
||||
{ key: 'diplo', label: 'DIP', cx: slot.x + 28, cy: slot.y + 40 }
|
||||
]
|
||||
|
||||
attrs.forEach(({ key, label, cx, cy }) => {
|
||||
const c = this.add.graphics()
|
||||
c.fillStyle(ATTR_COLORS[key], 0.85)
|
||||
c.fillRoundedRect(-20, -18, 40, 36, 4)
|
||||
c.x = cx
|
||||
c.y = cy
|
||||
this.resolveObjects.push(c)
|
||||
|
||||
const v = this.add.text(cx, cy - 4, String(entry[key]), {
|
||||
fontSize: '14px', fontFamily: 'Georgia', fontStyle: 'bold',
|
||||
color: '#ffffff', stroke: '#000000', strokeThickness: 2
|
||||
// ── Nom du joueur ────────────────────────────────────────
|
||||
this.resolveObjects.push(
|
||||
this.add.text(slot.x, slot.y - 78, entry.playerName, {
|
||||
fontSize: '10px', fontFamily: 'Georgia', color: '#ffffff', fontStyle: 'bold'
|
||||
}).setOrigin(0.5)
|
||||
this.resolveObjects.push(v)
|
||||
)
|
||||
|
||||
const l = this.add.text(cx, cy + 10, label, {
|
||||
fontSize: '7px', fontFamily: 'Arial', color: '#ffffff'
|
||||
// ── Nom de la carte ──────────────────────────────────────
|
||||
this.resolveObjects.push(
|
||||
this.add.text(slot.x, slot.y - 62, entry.cardName, {
|
||||
fontSize: '12px', fontFamily: 'Georgia', color: '#d4a732', fontStyle: 'bold'
|
||||
}).setOrigin(0.5)
|
||||
this.resolveObjects.push(l)
|
||||
)
|
||||
|
||||
// ── 4 badges attribut + gain ─────────────────────────────
|
||||
ATTRS_POS.forEach(({ key, label, dx, dy }) => {
|
||||
const cx = slot.x + dx
|
||||
const cy = slot.y + dy
|
||||
const cardVal = entry[key] ?? 0
|
||||
const gainVal = gain[key] ?? 0
|
||||
|
||||
// Badge fond coloré
|
||||
const badge = this.add.graphics()
|
||||
badge.fillStyle(ATTR_COLORS[key], gainVal > 0 ? 1.0 : 0.45)
|
||||
badge.fillRoundedRect(-22, -20, 44, 40, 4)
|
||||
badge.x = cx
|
||||
badge.y = cy
|
||||
this.resolveObjects.push(badge)
|
||||
|
||||
// Valeur de la carte
|
||||
this.resolveObjects.push(
|
||||
this.add.text(cx, cy - 7, String(cardVal), {
|
||||
fontSize: '14px', fontFamily: 'Georgia', fontStyle: 'bold',
|
||||
color: '#ffffff', stroke: '#000000', strokeThickness: 2
|
||||
}).setOrigin(0.5)
|
||||
)
|
||||
|
||||
// Label abrégé
|
||||
this.resolveObjects.push(
|
||||
this.add.text(cx, cy + 5, label, {
|
||||
fontSize: '7px', fontFamily: 'Arial', color: '#ffffffcc'
|
||||
}).setOrigin(0.5)
|
||||
)
|
||||
|
||||
// Gain (affiché en vert si > 0)
|
||||
if (gainVal > 0) {
|
||||
this.resolveObjects.push(
|
||||
this.add.text(cx, cy + 16, `+${gainVal}`, {
|
||||
fontSize: '10px', fontFamily: 'Georgia', fontStyle: 'bold',
|
||||
color: '#ffffff', stroke: '#000000', strokeThickness: 2
|
||||
}).setOrigin(0.5)
|
||||
)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
_showAttrResults(attrResults) {
|
||||
const { width, height } = this.scale
|
||||
const attrs = ['food', 'war', 'health', 'diplo']
|
||||
const boxY = height / 2 + 80
|
||||
|
||||
attrs.forEach((attr, i) => {
|
||||
const r = attrResults[attr]
|
||||
const x = width / 2 - 300 + i * 200
|
||||
|
||||
const g = this.add.graphics()
|
||||
g.fillStyle(ATTR_COLORS[attr], 0.15)
|
||||
g.fillRoundedRect(-90, -20, 180, 40, 6)
|
||||
g.lineStyle(1, ATTR_COLORS[attr], 0.6)
|
||||
g.strokeRoundedRect(-90, -20, 180, 40, 6)
|
||||
g.x = x
|
||||
g.y = boxY
|
||||
this.resolveObjects.push(g)
|
||||
|
||||
const label = ATTR_LABELS[attr]
|
||||
const winText = r.winner === 'tie'
|
||||
? `Égalité`
|
||||
: `${r.winner} +${r.value}`
|
||||
|
||||
const t1 = this.add.text(x, boxY - 8, label, {
|
||||
fontSize: '11px', fontFamily: 'Georgia', color: '#' + ATTR_COLORS[attr].toString(16).padStart(6, '0')
|
||||
}).setOrigin(0.5)
|
||||
this.resolveObjects.push(t1)
|
||||
|
||||
const t2 = this.add.text(x, boxY + 8, winText, {
|
||||
fontSize: '12px', fontFamily: 'Georgia', color: '#ffffff', fontStyle: 'bold'
|
||||
}).setOrigin(0.5)
|
||||
this.resolveObjects.push(t2)
|
||||
})
|
||||
}
|
||||
|
||||
// ─── Socket listeners ────────────────────────────────────────────────────────
|
||||
|
||||
_setupSocketListeners() {
|
||||
@@ -307,10 +293,9 @@ export class GameScene extends Phaser.Scene {
|
||||
}
|
||||
})
|
||||
|
||||
this.socket.on('round-result', ({ playedCards, attrResults }) => {
|
||||
this.socket.on('round-result', ({ playedCards, gains }) => {
|
||||
this.phaseText.setText('Résolution du tour...')
|
||||
this._showPlayedCards(playedCards)
|
||||
this._showAttrResults(attrResults)
|
||||
this._showPlayedCards(playedCards, gains)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user