feat: Introduce CoinType, ObstacleType, PowerUp components and systems
All checks were successful
Build and Publish Docker Image / Build and Validate (pull_request) Successful in 9s
All checks were successful
Build and Publish Docker Image / Build and Validate (pull_request) Successful in 9s
- Added CoinType component to define different coin types and their score values. - Implemented ObstacleType component to manage various obstacle behaviors. - Created PowerUp component to handle power-up types and durations. - Integrated ParticleSystem for visual effects upon collecting coins and power-ups. - Updated EntityFactory to create coins, obstacles, and power-ups with respective types. - Enhanced Game class to manage power-up collection and effects, including score multipliers and health restoration. This update enriches gameplay by adding collectible items with distinct behaviors and effects, enhancing player interaction and strategy.
This commit is contained in:
parent
7ea49a1c9e
commit
4220e216e1
11 changed files with 885 additions and 33 deletions
106
src/systems/ParticleSystem.js
Normal file
106
src/systems/ParticleSystem.js
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
import { System } from '../ecs/System.js';
|
||||
import { Transform } from '../components/Transform.js';
|
||||
import { ParticleEmitter } from '../components/ParticleEmitter.js';
|
||||
import { GameConfig } from '../game/GameConfig.js';
|
||||
|
||||
/**
|
||||
* ParticleSystem - manages particle effects for visual feedback
|
||||
*/
|
||||
export class ParticleSystem extends System {
|
||||
constructor(scene) {
|
||||
super();
|
||||
/** @type {import('three').Scene} */
|
||||
this.scene = scene;
|
||||
|
||||
/** @type {Array<{mesh: import('three').Mesh, velocity: import('three').Vector3, lifetime: number, maxLifetime: number}>} */
|
||||
this.particles = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create particles at a position
|
||||
* @param {import('three').Vector3} position - Position to emit from
|
||||
* @param {number} count - Number of particles
|
||||
* @param {number} color - Color (hex)
|
||||
* @param {number} [speed=5] - Particle speed
|
||||
*/
|
||||
emit(position, count, color, speed = 5) {
|
||||
for (let i = 0; i < count; i++) {
|
||||
const geometry = new window.THREE.SphereGeometry(0.1, 8, 8);
|
||||
const material = new window.THREE.MeshBasicMaterial({
|
||||
color: color,
|
||||
transparent: true,
|
||||
opacity: 1.0
|
||||
});
|
||||
const mesh = new window.THREE.Mesh(geometry, material);
|
||||
mesh.position.copy(position);
|
||||
this.scene.add(mesh);
|
||||
|
||||
// Random velocity direction
|
||||
const velocity = new window.THREE.Vector3(
|
||||
(Math.random() - 0.5) * speed,
|
||||
Math.random() * speed * 0.5 + speed * 0.5,
|
||||
(Math.random() - 0.5) * speed
|
||||
);
|
||||
|
||||
this.particles.push({
|
||||
mesh: mesh,
|
||||
velocity: velocity,
|
||||
lifetime: GameConfig.PARTICLE_LIFETIME,
|
||||
maxLifetime: GameConfig.PARTICLE_LIFETIME
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update particles
|
||||
* @param {number} deltaTime - Time since last frame in seconds
|
||||
*/
|
||||
update(deltaTime) {
|
||||
// Update existing particles
|
||||
for (let i = this.particles.length - 1; i >= 0; i--) {
|
||||
const particle = this.particles[i];
|
||||
|
||||
// Update position
|
||||
particle.mesh.position.add(
|
||||
particle.velocity.clone().multiplyScalar(deltaTime)
|
||||
);
|
||||
|
||||
// Apply gravity
|
||||
particle.velocity.y -= 9.8 * deltaTime;
|
||||
|
||||
// Update lifetime
|
||||
particle.lifetime -= deltaTime;
|
||||
|
||||
// Fade out
|
||||
const alpha = particle.lifetime / particle.maxLifetime;
|
||||
particle.mesh.material.opacity = alpha;
|
||||
|
||||
// Remove dead particles
|
||||
if (particle.lifetime <= 0) {
|
||||
this.scene.remove(particle.mesh);
|
||||
particle.mesh.geometry.dispose();
|
||||
particle.mesh.material.dispose();
|
||||
this.particles.splice(i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Process particle emitters from entities
|
||||
const entities = this.getEntities(Transform, ParticleEmitter);
|
||||
for (const entityId of entities) {
|
||||
const transform = this.getComponent(entityId, Transform);
|
||||
const emitter = this.getComponent(entityId, ParticleEmitter);
|
||||
|
||||
if (emitter && emitter.active) {
|
||||
this.emit(
|
||||
transform.position,
|
||||
emitter.count,
|
||||
emitter.color,
|
||||
emitter.speed
|
||||
);
|
||||
// Deactivate after emitting once
|
||||
emitter.active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue