texture triangle ameliorer
This commit is contained in:
180
game.js
180
game.js
@ -38,6 +38,7 @@ const closeCustomizeBtn = document.getElementById('closeCustomizeBtn');
|
||||
const saveCustomizeBtn = document.getElementById('saveCustomizeBtn');
|
||||
const playerPreviewCanvas = document.getElementById('playerPreviewCanvas');
|
||||
const colorOptions = document.querySelectorAll('.color-option');
|
||||
const shapeOptions = document.querySelectorAll('.shape-option');
|
||||
|
||||
// Fonction pour vérifier si on est en mode plein écran
|
||||
function isFullscreen() {
|
||||
@ -50,6 +51,7 @@ let gameOverUsername = null;
|
||||
|
||||
// Personnalisation du joueur
|
||||
let playerColor = localStorage.getItem('playerColor') || 'rainbow';
|
||||
let playerShape = localStorage.getItem('playerShape') || 'round';
|
||||
|
||||
const CELL_SIZE = 25;
|
||||
const COLS = 30;
|
||||
@ -253,7 +255,7 @@ let traps = [];
|
||||
let specialZones = [];
|
||||
|
||||
class Pacman {
|
||||
constructor(color = null) {
|
||||
constructor(color = null, shape = null) {
|
||||
this.x = 14;
|
||||
this.y = 23;
|
||||
this.direction = 0;
|
||||
@ -266,6 +268,7 @@ class Pacman {
|
||||
this.pixelY = this.y * CELL_SIZE + CELL_SIZE / 2;
|
||||
this.colorAnimation = 0;
|
||||
this.color = color || playerColor;
|
||||
this.shape = shape || playerShape;
|
||||
}
|
||||
|
||||
update() {
|
||||
@ -471,9 +474,11 @@ class Pacman {
|
||||
ctx.rotate(rotation[this.direction]);
|
||||
|
||||
// Utiliser la couleur personnalisée
|
||||
let baseFillColor;
|
||||
if (this.color === 'rainbow') {
|
||||
const hue = (this.colorAnimation * 180 / Math.PI) % 360;
|
||||
ctx.fillStyle = `hsl(${hue}, 100%, 50%)`;
|
||||
baseFillColor = `hsl(${hue}, 100%, 50%)`;
|
||||
ctx.fillStyle = baseFillColor;
|
||||
} else {
|
||||
const colorMap = {
|
||||
'yellow': '#ffd700',
|
||||
@ -484,19 +489,77 @@ class Pacman {
|
||||
'orange': '#ff8844',
|
||||
'pink': '#ff44aa'
|
||||
};
|
||||
ctx.fillStyle = colorMap[this.color] || '#ffd700';
|
||||
baseFillColor = colorMap[this.color] || '#ffd700';
|
||||
ctx.fillStyle = baseFillColor;
|
||||
}
|
||||
|
||||
const size = CELL_SIZE * 0.4;
|
||||
|
||||
ctx.beginPath();
|
||||
|
||||
if (this.shape === 'triangle') {
|
||||
const triangleSize = size * 1.5; // Plus grand pour une meilleure visibilité
|
||||
|
||||
// Dessiner le triangle avec contour et yeux
|
||||
ctx.beginPath();
|
||||
if (this.mouthOpen) {
|
||||
ctx.arc(0, 0, CELL_SIZE * 0.4, 0.2, Math.PI * 2 - 0.2);
|
||||
// Triangle avec bouche ouverte - ouverture plus grande et visible
|
||||
ctx.moveTo(0, -triangleSize * 0.9);
|
||||
ctx.lineTo(-triangleSize * 0.85, triangleSize * 0.7);
|
||||
ctx.lineTo(-triangleSize * 0.4, triangleSize * 0.4);
|
||||
ctx.lineTo(0, triangleSize * 0.2);
|
||||
ctx.lineTo(triangleSize * 0.4, triangleSize * 0.4);
|
||||
ctx.lineTo(triangleSize * 0.85, triangleSize * 0.7);
|
||||
ctx.closePath();
|
||||
} else {
|
||||
ctx.arc(0, 0, CELL_SIZE * 0.4, 0, Math.PI * 2);
|
||||
// Triangle équilatéral complet
|
||||
ctx.moveTo(0, -triangleSize);
|
||||
ctx.lineTo(-triangleSize * 0.866, triangleSize * 0.5); // cos(30°) ≈ 0.866
|
||||
ctx.lineTo(triangleSize * 0.866, triangleSize * 0.5);
|
||||
ctx.closePath();
|
||||
}
|
||||
|
||||
// Remplir le triangle
|
||||
ctx.fill();
|
||||
|
||||
// Contour noir épais pour plus de définition
|
||||
ctx.strokeStyle = '#000000';
|
||||
ctx.lineWidth = 2.5;
|
||||
ctx.stroke();
|
||||
|
||||
// Dessiner les yeux
|
||||
ctx.fillStyle = '#ffffff';
|
||||
ctx.beginPath();
|
||||
ctx.arc(-triangleSize * 0.2, -triangleSize * 0.15, triangleSize * 0.12, 0, Math.PI * 2);
|
||||
ctx.arc(triangleSize * 0.2, -triangleSize * 0.15, triangleSize * 0.12, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
|
||||
// Pupilles
|
||||
ctx.fillStyle = '#000000';
|
||||
ctx.beginPath();
|
||||
ctx.arc(-triangleSize * 0.2, -triangleSize * 0.15, triangleSize * 0.06, 0, Math.PI * 2);
|
||||
ctx.arc(triangleSize * 0.2, -triangleSize * 0.15, triangleSize * 0.06, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
|
||||
// Reflets dans les yeux pour plus de vie
|
||||
ctx.fillStyle = '#ffffff';
|
||||
ctx.beginPath();
|
||||
ctx.arc(-triangleSize * 0.22, -triangleSize * 0.17, triangleSize * 0.03, 0, Math.PI * 2);
|
||||
ctx.arc(triangleSize * 0.18, -triangleSize * 0.17, triangleSize * 0.03, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
|
||||
// Restaurer la couleur originale
|
||||
ctx.fillStyle = baseFillColor;
|
||||
} else {
|
||||
// Forme ronde (par défaut)
|
||||
if (this.mouthOpen) {
|
||||
ctx.arc(0, 0, size, 0.2, Math.PI * 2 - 0.2);
|
||||
} else {
|
||||
ctx.arc(0, 0, size, 0, Math.PI * 2);
|
||||
}
|
||||
ctx.lineTo(0, 0);
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
ctx.restore();
|
||||
}
|
||||
@ -2487,6 +2550,7 @@ if (rulesModal) {
|
||||
|
||||
// === GESTION DU MODAL DE PERSONNALISATION ===
|
||||
let selectedColor = playerColor;
|
||||
let selectedShape = playerShape;
|
||||
|
||||
// Ouvrir le modal de personnalisation
|
||||
if (customizeBtn) {
|
||||
@ -2494,7 +2558,9 @@ if (customizeBtn) {
|
||||
if (customizeModal) {
|
||||
customizeModal.style.display = 'flex';
|
||||
selectedColor = playerColor;
|
||||
selectedShape = playerShape;
|
||||
updateColorSelection();
|
||||
updateShapeSelection();
|
||||
updatePlayerPreview();
|
||||
startPreviewAnimation();
|
||||
}
|
||||
@ -2532,6 +2598,17 @@ if (colorOptions) {
|
||||
});
|
||||
}
|
||||
|
||||
// Gérer la sélection de forme
|
||||
if (shapeOptions) {
|
||||
shapeOptions.forEach(option => {
|
||||
option.addEventListener('click', () => {
|
||||
selectedShape = option.getAttribute('data-shape');
|
||||
updateShapeSelection();
|
||||
updatePlayerPreview();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Mettre à jour la sélection visuelle
|
||||
function updateColorSelection() {
|
||||
if (colorOptions) {
|
||||
@ -2545,6 +2622,18 @@ function updateColorSelection() {
|
||||
}
|
||||
}
|
||||
|
||||
function updateShapeSelection() {
|
||||
if (shapeOptions) {
|
||||
shapeOptions.forEach(option => {
|
||||
if (option.getAttribute('data-shape') === selectedShape) {
|
||||
option.classList.add('active');
|
||||
} else {
|
||||
option.classList.remove('active');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Prévisualisation du joueur
|
||||
let previewAnimationId = null;
|
||||
function startPreviewAnimation() {
|
||||
@ -2589,14 +2678,86 @@ function startPreviewAnimation() {
|
||||
mouthOpen = !mouthOpen;
|
||||
}
|
||||
|
||||
const size = 40;
|
||||
ctx.beginPath();
|
||||
|
||||
if (selectedShape === 'triangle') {
|
||||
const triangleSize = size * 1.5; // Plus grand pour une meilleure visibilité
|
||||
|
||||
// Dessiner le triangle avec contour et yeux
|
||||
ctx.beginPath();
|
||||
const radius = 40;
|
||||
if (mouthOpen) {
|
||||
ctx.arc(0, 0, radius, 0.2, Math.PI * 2 - 0.2);
|
||||
// Triangle avec bouche ouverte
|
||||
ctx.moveTo(0, -triangleSize * 0.9);
|
||||
ctx.lineTo(-triangleSize * 0.85, triangleSize * 0.7);
|
||||
ctx.lineTo(-triangleSize * 0.4, triangleSize * 0.4);
|
||||
ctx.lineTo(0, triangleSize * 0.2);
|
||||
ctx.lineTo(triangleSize * 0.4, triangleSize * 0.4);
|
||||
ctx.lineTo(triangleSize * 0.85, triangleSize * 0.7);
|
||||
ctx.closePath();
|
||||
} else {
|
||||
ctx.arc(0, 0, radius, 0, Math.PI * 2);
|
||||
// Triangle équilatéral complet
|
||||
ctx.moveTo(0, -triangleSize);
|
||||
ctx.lineTo(-triangleSize * 0.866, triangleSize * 0.5);
|
||||
ctx.lineTo(triangleSize * 0.866, triangleSize * 0.5);
|
||||
ctx.closePath();
|
||||
}
|
||||
|
||||
// Remplir le triangle
|
||||
ctx.fill();
|
||||
|
||||
// Contour noir épais
|
||||
ctx.strokeStyle = '#000000';
|
||||
ctx.lineWidth = 2.5;
|
||||
ctx.stroke();
|
||||
|
||||
// Dessiner les yeux
|
||||
ctx.fillStyle = '#ffffff';
|
||||
ctx.beginPath();
|
||||
ctx.arc(-triangleSize * 0.2, -triangleSize * 0.15, triangleSize * 0.12, 0, Math.PI * 2);
|
||||
ctx.arc(triangleSize * 0.2, -triangleSize * 0.15, triangleSize * 0.12, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
|
||||
// Pupilles
|
||||
ctx.fillStyle = '#000000';
|
||||
ctx.beginPath();
|
||||
ctx.arc(-triangleSize * 0.2, -triangleSize * 0.15, triangleSize * 0.06, 0, Math.PI * 2);
|
||||
ctx.arc(triangleSize * 0.2, -triangleSize * 0.15, triangleSize * 0.06, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
|
||||
// Reflets dans les yeux
|
||||
ctx.fillStyle = '#ffffff';
|
||||
ctx.beginPath();
|
||||
ctx.arc(-triangleSize * 0.22, -triangleSize * 0.17, triangleSize * 0.03, 0, Math.PI * 2);
|
||||
ctx.arc(triangleSize * 0.18, -triangleSize * 0.17, triangleSize * 0.03, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
|
||||
// Restaurer la couleur originale
|
||||
if (selectedColor === 'rainbow') {
|
||||
const hue = (angle * 180 / Math.PI) % 360;
|
||||
ctx.fillStyle = `hsl(${hue}, 100%, 50%)`;
|
||||
} else {
|
||||
const colorMap = {
|
||||
'yellow': '#ffd700',
|
||||
'red': '#ff4444',
|
||||
'blue': '#4444ff',
|
||||
'green': '#44ff44',
|
||||
'purple': '#aa44ff',
|
||||
'orange': '#ff8844',
|
||||
'pink': '#ff44aa'
|
||||
};
|
||||
ctx.fillStyle = colorMap[selectedColor] || '#ffd700';
|
||||
}
|
||||
} else {
|
||||
// Dessiner un cercle
|
||||
if (mouthOpen) {
|
||||
ctx.arc(0, 0, size, 0.2, Math.PI * 2 - 0.2);
|
||||
} else {
|
||||
ctx.arc(0, 0, size, 0, Math.PI * 2);
|
||||
}
|
||||
ctx.lineTo(0, 0);
|
||||
}
|
||||
|
||||
ctx.fill();
|
||||
|
||||
ctx.restore();
|
||||
@ -2622,11 +2783,14 @@ function updatePlayerPreview() {
|
||||
if (saveCustomizeBtn) {
|
||||
saveCustomizeBtn.addEventListener('click', () => {
|
||||
playerColor = selectedColor;
|
||||
playerShape = selectedShape;
|
||||
localStorage.setItem('playerColor', playerColor);
|
||||
localStorage.setItem('playerShape', playerShape);
|
||||
|
||||
// Mettre à jour le joueur actuel si le jeu est en cours
|
||||
if (pacman) {
|
||||
pacman.color = playerColor;
|
||||
pacman.shape = playerShape;
|
||||
}
|
||||
|
||||
// Fermer le modal
|
||||
|
||||
13
index.html
13
index.html
@ -276,6 +276,19 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="customize-section">
|
||||
<h3>Forme du joueur</h3>
|
||||
<div class="shape-options">
|
||||
<div class="shape-option active" data-shape="round" data-name="Rond">
|
||||
<div class="shape-preview round-preview"></div>
|
||||
<span>Rond (Classique)</span>
|
||||
</div>
|
||||
<div class="shape-option" data-shape="triangle" data-name="Triangle">
|
||||
<div class="shape-preview triangle-preview"></div>
|
||||
<span>Triangle</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="customize-preview">
|
||||
<h3>Aperçu</h3>
|
||||
<canvas id="playerPreviewCanvas" width="200" height="200"></canvas>
|
||||
|
||||
65
style.css
65
style.css
@ -1479,3 +1479,68 @@ footer {
|
||||
.save-customize-btn:active {
|
||||
transform: translateY(0) scale(0.98);
|
||||
}
|
||||
|
||||
.shape-options {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
||||
gap: 15px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.shape-option {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 15px;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border: 2px solid rgba(255, 215, 0, 0.3);
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.shape-option:hover {
|
||||
background: rgba(255, 215, 0, 0.1);
|
||||
border-color: #ffd700;
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.shape-option.active {
|
||||
background: rgba(255, 215, 0, 0.2);
|
||||
border-color: #ffd700;
|
||||
box-shadow: 0 0 15px rgba(255, 215, 0, 0.5);
|
||||
}
|
||||
|
||||
.shape-preview {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.round-preview {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border-radius: 50%;
|
||||
background: #ffd700;
|
||||
border: 3px solid #fff;
|
||||
box-shadow: 0 0 10px rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
.triangle-preview {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 25px solid transparent;
|
||||
border-right: 25px solid transparent;
|
||||
border-bottom: 45px solid #ffd700;
|
||||
border-top: none;
|
||||
filter: drop-shadow(0 0 5px rgba(255, 255, 255, 0.3));
|
||||
}
|
||||
|
||||
.shape-option span {
|
||||
font-size: 0.7em;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user