114 lines
3.5 KiB
JavaScript
114 lines
3.5 KiB
JavaScript
/**
|
|
* Coin class - manages collectible coins with enhanced visuals
|
|
*/
|
|
class Coin {
|
|
constructor(scene, lane) {
|
|
this.scene = scene;
|
|
this.mesh = null;
|
|
this.glowMesh = null;
|
|
|
|
this.createMesh(lane);
|
|
}
|
|
|
|
createMesh(lane) {
|
|
// Create procedural texture for coin
|
|
const canvas = document.createElement('canvas');
|
|
canvas.width = 128;
|
|
canvas.height = 64;
|
|
const ctx = canvas.getContext('2d');
|
|
|
|
// Gold gradient background
|
|
const gradient = ctx.createLinearGradient(0, 0, 128, 64);
|
|
gradient.addColorStop(0, '#ffd700');
|
|
gradient.addColorStop(0.3, '#ffec8b');
|
|
gradient.addColorStop(0.5, '#ffd700');
|
|
gradient.addColorStop(0.7, '#ffec8b');
|
|
gradient.addColorStop(1, '#daa520');
|
|
|
|
ctx.fillStyle = gradient;
|
|
ctx.fillRect(0, 0, 128, 64);
|
|
|
|
// Inner ring
|
|
ctx.strokeStyle = '#b8860b';
|
|
ctx.lineWidth = 3;
|
|
ctx.beginPath();
|
|
ctx.ellipse(64, 32, 45, 20, 0, 0, Math.PI * 2);
|
|
ctx.stroke();
|
|
|
|
// Star symbol in center
|
|
ctx.fillStyle = '#b8860b';
|
|
ctx.beginPath();
|
|
const cx = 64, cy = 32;
|
|
for (let i = 0; i < 5; i++) {
|
|
const angle = (i * 4 * Math.PI / 5) - Math.PI / 2;
|
|
const x = cx + Math.cos(angle) * 15;
|
|
const y = cy + Math.sin(angle) * 15;
|
|
if (i === 0) ctx.moveTo(x, y);
|
|
else ctx.lineTo(x, y);
|
|
}
|
|
ctx.closePath();
|
|
ctx.fill();
|
|
|
|
const texture = new THREE.CanvasTexture(canvas);
|
|
|
|
const geometry = new THREE.CylinderGeometry(0.5, 0.5, 0.15, 24);
|
|
const material = new THREE.MeshStandardMaterial({
|
|
map: texture,
|
|
color: 0xffd700,
|
|
emissive: 0xffd700,
|
|
emissiveIntensity: 0.6,
|
|
metalness: 0.9,
|
|
roughness: 0.1
|
|
});
|
|
|
|
const LANE_WIDTH = 3.5;
|
|
|
|
this.mesh = new THREE.Mesh(geometry, material);
|
|
this.mesh.position.set(lane * LANE_WIDTH, 1, -60);
|
|
this.mesh.rotation.x = Math.PI / 2;
|
|
|
|
// Outer glow ring
|
|
const glowGeometry = new THREE.TorusGeometry(0.6, 0.12, 8, 32);
|
|
const glowMaterial = new THREE.MeshBasicMaterial({
|
|
color: 0xffd700,
|
|
transparent: true,
|
|
opacity: 0.4
|
|
});
|
|
this.glowMesh = new THREE.Mesh(glowGeometry, glowMaterial);
|
|
this.glowMesh.rotation.x = Math.PI / 2;
|
|
this.mesh.add(this.glowMesh);
|
|
|
|
// Add point light for glow
|
|
const coinLight = new THREE.PointLight(0xffd700, 0.4, 3);
|
|
this.mesh.add(coinLight);
|
|
|
|
this.scene.add(this.mesh);
|
|
}
|
|
|
|
update(gameSpeed) {
|
|
this.mesh.position.z += gameSpeed;
|
|
|
|
// Rotate coin
|
|
this.mesh.rotation.z += 0.05;
|
|
this.glowMesh.rotation.z -= 0.03;
|
|
|
|
// Bobbing motion
|
|
this.mesh.position.y = 1 + Math.sin(Date.now() * 0.005) * 0.15;
|
|
}
|
|
|
|
isPastCamera() {
|
|
return this.mesh.position.z > 15;
|
|
}
|
|
|
|
checkCollection(playerPosition) {
|
|
const dx = Math.abs(this.mesh.position.x - playerPosition.x);
|
|
const dz = Math.abs(this.mesh.position.z - playerPosition.z);
|
|
|
|
return dx < 1 && dz < 1;
|
|
}
|
|
|
|
dispose() {
|
|
this.scene.remove(this.mesh);
|
|
}
|
|
}
|