Sprint 2: gameplay — achievements, score popups, new enemy, polish
- AchievementsManager with 10 unlockables and toast popups (Genesis Block, Chain Reaction x3, Bug Hunter, First Flight, Liftoff, Power Trip, Survivor 500, Skyscraper 1000, Speedrun 100/60s, Gas Baron 50k) - Score popups: +N text floats above player on every landing (gold and larger for genesis platforms) - Powerup duration bar in HUD bottom, color-coded per power-up, uses scaleX for smooth depletion animation - New enemy: Failed Tx, falls from above with sine drift, unlocks at difficulty > 800, can be stomped, tinted red - Dynamic background: dark cosmic overlay alpha scales with height (max 0.5 at very high altitudes) - Achievement hooks integrated into ScoreManager, GameScene - Combo no longer resets if combo was already 0 (was triggering log spam)
This commit is contained in:
@@ -8,29 +8,46 @@ export class Enemy extends Physics.Arcade.Sprite {
|
||||
scene.physics.add.existing(this);
|
||||
|
||||
this.enemyType = type;
|
||||
this.setScale(0.7);
|
||||
this.body.allowGravity = false;
|
||||
this.body.setSize(90, 80);
|
||||
this.body.setOffset(35, 30);
|
||||
|
||||
if (type === 'bug') {
|
||||
this.setScale(0.7);
|
||||
this.body.setSize(this.width * 0.7, this.height * 0.7);
|
||||
this.body.setOffset(this.width * 0.15, this.height * 0.15);
|
||||
this.speed = Phaser.Math.Between(60, 140) * (Math.random() < 0.5 ? 1 : -1);
|
||||
this.startX = x;
|
||||
this.patrolRange = Phaser.Math.Between(80, 200);
|
||||
} else if (type === 'failed_tx') {
|
||||
this.setScale(0.55);
|
||||
this.setTint(0xef4444);
|
||||
this.body.setSize(this.width * 0.6, this.height * 0.6);
|
||||
this.body.setOffset(this.width * 0.2, this.height * 0.2);
|
||||
this.fallSpeed = Phaser.Math.Between(80, 140);
|
||||
this.driftAmplitude = Phaser.Math.Between(20, 60);
|
||||
this.driftFreq = Phaser.Math.FloatBetween(0.001, 0.003);
|
||||
this.spawnTime = scene.time.now;
|
||||
this.spawnX = x;
|
||||
}
|
||||
}
|
||||
|
||||
preUpdate(time, delta) {
|
||||
super.preUpdate(time, delta);
|
||||
|
||||
if (this.enemyType === 'bug') {
|
||||
this.x += this.speed * (delta / 1000);
|
||||
if (Math.abs(this.x - this.startX) > this.patrolRange) {
|
||||
this.speed *= -1;
|
||||
this.setFlipX(this.speed < 0);
|
||||
}
|
||||
// Wrap
|
||||
if (this.x < -60) this.x = GAME_WIDTH + 60;
|
||||
if (this.x > GAME_WIDTH + 60) this.x = -60;
|
||||
} else if (this.enemyType === 'failed_tx') {
|
||||
const dt = delta / 1000;
|
||||
this.y += this.fallSpeed * dt;
|
||||
const t = time - this.spawnTime;
|
||||
this.x = this.spawnX + Math.sin(t * this.driftFreq) * this.driftAmplitude;
|
||||
this.x = Phaser.Math.Clamp(this.x, 30, GAME_WIDTH - 30);
|
||||
this.setAngle(Math.sin(t * 0.005) * 15);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user