feat: add BurliKong game to the game pool
- Import BurliKong scene and add it to the Phaser game configuration - Register BurliKong in the GameManager's display name map - Include BurliKong in the game pool within game.json - Bump cache version for game config to ensure fresh load
This commit is contained in:
parent
d044b1f319
commit
afb95c91d1
Binary file not shown.
|
|
@ -12,5 +12,5 @@
|
|||
"9": { "gameCount": 5 },
|
||||
"10": { "gameCount": 5 }
|
||||
},
|
||||
"gamePool": ["ColoradoDefense", "CodeBugInvaders", "DotDude", "SmashOut", "Vortex"]
|
||||
"gamePool": ["ColoradoDefense", "CodeBugInvaders", "DotDude", "SmashOut", "Vortex", "BurliKong"]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,547 @@
|
|||
import { playMusic, stopMusic } from '../../audio.js';
|
||||
|
||||
const PLATFORMS = [
|
||||
{ y: 820, xMin: 50, xMax: 1550 }, // 0 = floor
|
||||
{ y: 660, xMin: 50, xMax: 1550 }, // 1
|
||||
{ y: 495, xMin: 50, xMax: 1550 }, // 2
|
||||
{ y: 330, xMin: 50, xMax: 1550 }, // 3
|
||||
{ y: 165, xMin: 50, xMax: 1550 }, // 4 = Kong platform (WIN)
|
||||
];
|
||||
|
||||
// Ladders: bottom connects lower platform, top connects upper platform
|
||||
// Zone: player can grab if within ±20px horizontally of center
|
||||
const LADDERS = [
|
||||
{ x: 1150, fromPlatform: 0, yBottom: 820, yTop: 660 }, // Floor → P1
|
||||
{ x: 380, fromPlatform: 1, yBottom: 660, yTop: 495 }, // P1 → P2
|
||||
{ x: 1050, fromPlatform: 2, yBottom: 495, yTop: 330 }, // P2 → P3
|
||||
{ x: 680, fromPlatform: 3, yBottom: 330, yTop: 165 }, // P3 → Kong (WIN lane)
|
||||
];
|
||||
|
||||
const PLATFORM_H = 15;
|
||||
const PLAYER_W = 28;
|
||||
const PLAYER_H = 40;
|
||||
const BARREL_R = 14;
|
||||
const LADDER_W = 36;
|
||||
const LADDER_GRAB_RANGE = 28;
|
||||
|
||||
// Initial direction for barrels per platform index
|
||||
const BARREL_DIR = [1, -1, 1, -1, 1]; // index = platformIndex
|
||||
|
||||
export default class BurliKong extends Phaser.Scene {
|
||||
constructor() {
|
||||
super({ key: 'BurliKong' });
|
||||
}
|
||||
|
||||
preload() {
|
||||
this.load.json('bkConfig', 'src/games/burli-kong/config.json');
|
||||
this.load.audio('bkMusic', 'assets/music/06-burli-kong.mp3');
|
||||
this.load.audio('bkComplete', 'assets/fx/complete.mp3');
|
||||
this.load.audio('bkJump', 'assets/fx/launch.mp3');
|
||||
this.load.audio('bkStomp', 'assets/fx/destroy.mp3');
|
||||
this.load.audio('bkHit', 'assets/fx/short_death.mp3');
|
||||
this.load.audio('bkBarrel', 'assets/fx/fireball.mp3');
|
||||
}
|
||||
|
||||
init(data) {
|
||||
this.lives = data.lives ?? 3;
|
||||
this.level = String(data.level ?? 1);
|
||||
}
|
||||
|
||||
create() {
|
||||
const all = this.cache.json.get('bkConfig');
|
||||
this.cfg = all.levels[this.level] ?? all.levels['1'];
|
||||
|
||||
this.gameActive = true;
|
||||
this.barrelsCleared = 0;
|
||||
this.spawnTimer = 0;
|
||||
this.barrels = [];
|
||||
this.kongArmRaise = 0; // seconds remaining for Kong arm-raise animation
|
||||
|
||||
this.player = {
|
||||
x: 200,
|
||||
y: PLATFORMS[0].y - PLAYER_H,
|
||||
vx: 0,
|
||||
vy: 0,
|
||||
state: 'ground', // 'ground' | 'jumping' | 'ladder'
|
||||
platformIndex: 0,
|
||||
facingDir: 1,
|
||||
ladderIndex: -1,
|
||||
jumpedOverBarrels: new Set(), // track barrels already scored as jump-overs
|
||||
};
|
||||
|
||||
this.mainGfx = this.add.graphics();
|
||||
this.cursors = this.input.keyboard.createCursorKeys();
|
||||
this.keyA = this.input.keyboard.addKey('A');
|
||||
this.keyAPressed = false;
|
||||
|
||||
this._buildHUD();
|
||||
playMusic(this, 'bkMusic');
|
||||
}
|
||||
|
||||
update(time, delta) {
|
||||
if (!this.gameActive) return;
|
||||
const dt = delta / 1000;
|
||||
|
||||
this._handleInput(dt);
|
||||
this._spawnBarrels(dt);
|
||||
this._updateBarrels(dt);
|
||||
this._checkCollisions();
|
||||
this._draw();
|
||||
this._updateHUD();
|
||||
}
|
||||
|
||||
// ─── Input ────────────────────────────────────────────────────────────────
|
||||
|
||||
_handleInput(dt) {
|
||||
const p = this.player;
|
||||
const cfg = this.cfg;
|
||||
|
||||
// Jump (A key, edge-triggered, ground only)
|
||||
if (this.keyA.isDown && !this.keyAPressed) {
|
||||
this.keyAPressed = true;
|
||||
if (p.state === 'ground') {
|
||||
p.state = 'jumping';
|
||||
p.vy = -cfg.jumpVelocity;
|
||||
this._playFx('bkJump', 0.5);
|
||||
}
|
||||
}
|
||||
if (!this.keyA.isDown) this.keyAPressed = false;
|
||||
|
||||
if (p.state === 'ground') {
|
||||
p.vx = 0;
|
||||
if (this.cursors.left.isDown) { p.vx = -cfg.playerSpeed; p.facingDir = -1; }
|
||||
if (this.cursors.right.isDown) { p.vx = cfg.playerSpeed; p.facingDir = 1; }
|
||||
|
||||
p.x += p.vx * dt;
|
||||
p.x = Phaser.Math.Clamp(p.x, PLATFORMS[p.platformIndex].xMin + PLAYER_W / 2,
|
||||
PLATFORMS[p.platformIndex].xMax - PLAYER_W / 2);
|
||||
|
||||
// Snap y to current platform surface
|
||||
p.y = PLATFORMS[p.platformIndex].y - PLAYER_H;
|
||||
|
||||
// Start climbing: up arrow near ladder bottom on current platform
|
||||
if (this.cursors.up.isDown) {
|
||||
const li = this._nearLadderBottom(p);
|
||||
if (li >= 0) {
|
||||
p.state = 'ladder';
|
||||
p.ladderIndex = li;
|
||||
p.x = LADDERS[li].x;
|
||||
p.vx = 0;
|
||||
}
|
||||
}
|
||||
} else if (p.state === 'jumping') {
|
||||
p.vy += cfg.gravity * dt;
|
||||
p.x += p.vx * dt;
|
||||
p.y += p.vy * dt;
|
||||
p.x = Phaser.Math.Clamp(p.x, 55, 1545);
|
||||
|
||||
// Land on current platform (only if moving downward and crossing platform top)
|
||||
const plat = PLATFORMS[p.platformIndex];
|
||||
const platTop = plat.y - PLATFORM_H;
|
||||
if (p.vy > 0 && p.y + PLAYER_H >= platTop) {
|
||||
p.y = plat.y - PLAYER_H;
|
||||
p.vy = 0;
|
||||
p.state = 'ground';
|
||||
}
|
||||
} else if (p.state === 'ladder') {
|
||||
const ladder = LADDERS[p.ladderIndex];
|
||||
|
||||
if (this.cursors.up.isDown) {
|
||||
p.y -= cfg.climbSpeed * dt;
|
||||
} else if (this.cursors.down.isDown) {
|
||||
p.y += cfg.climbSpeed * dt;
|
||||
}
|
||||
|
||||
// Dismount at top: reached upper platform
|
||||
if (p.y <= ladder.yTop - PLAYER_H) {
|
||||
const newPlatformIndex = ladder.fromPlatform + 1;
|
||||
p.y = PLATFORMS[newPlatformIndex].y - PLAYER_H;
|
||||
p.platformIndex = newPlatformIndex;
|
||||
p.state = 'ground';
|
||||
p.ladderIndex = -1;
|
||||
|
||||
// Win: reached Kong platform
|
||||
if (p.platformIndex === 4) {
|
||||
this._endGame(true, 'MADE IT!');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Dismount at bottom: dropped below ladder bottom
|
||||
if (p.y + PLAYER_H >= ladder.yBottom) {
|
||||
p.y = PLATFORMS[ladder.fromPlatform].y - PLAYER_H;
|
||||
p.platformIndex = ladder.fromPlatform;
|
||||
p.state = 'ground';
|
||||
p.ladderIndex = -1;
|
||||
}
|
||||
|
||||
// Dismount sideways: left/right while on ladder (onto current platform level)
|
||||
if (this.cursors.left.isDown || this.cursors.right.isDown) {
|
||||
// Find which platform the player's midpoint is closest to
|
||||
const midY = p.y + PLAYER_H / 2;
|
||||
let bestPlat = ladder.fromPlatform;
|
||||
let bestDist = Infinity;
|
||||
for (let i = ladder.fromPlatform; i <= ladder.fromPlatform + 1; i++) {
|
||||
const d = Math.abs(PLATFORMS[i].y - PLATFORM_H / 2 - midY);
|
||||
if (d < bestDist) { bestDist = d; bestPlat = i; }
|
||||
}
|
||||
p.platformIndex = bestPlat;
|
||||
p.y = PLATFORMS[bestPlat].y - PLAYER_H;
|
||||
p.state = 'ground';
|
||||
p.facingDir = this.cursors.left.isDown ? -1 : 1;
|
||||
p.ladderIndex = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_nearLadderBottom(p) {
|
||||
for (let i = 0; i < LADDERS.length; i++) {
|
||||
const l = LADDERS[i];
|
||||
if (l.fromPlatform !== p.platformIndex) continue;
|
||||
if (Math.abs(p.x - l.x) <= LADDER_GRAB_RANGE) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// ─── Spawn ────────────────────────────────────────────────────────────────
|
||||
|
||||
_spawnBarrels(dt) {
|
||||
this.spawnTimer += dt;
|
||||
if (this.spawnTimer < this.cfg.barrelSpawnInterval) return;
|
||||
if (this.barrels.filter(b => b.alive).length >= this.cfg.maxBarrels) return;
|
||||
this.spawnTimer = 0;
|
||||
|
||||
this.barrels.push({
|
||||
x: 200,
|
||||
y: PLATFORMS[4].y - BARREL_R - PLATFORM_H,
|
||||
platformIndex: 4,
|
||||
dir: BARREL_DIR[4],
|
||||
falling: false,
|
||||
vy: 0,
|
||||
alive: true,
|
||||
cleared: false,
|
||||
});
|
||||
|
||||
this.kongArmRaise = 0.6;
|
||||
this._playFx('bkBarrel', 0.5);
|
||||
}
|
||||
|
||||
// ─── Barrel update ────────────────────────────────────────────────────────
|
||||
|
||||
_updateBarrels(dt) {
|
||||
const cfg = this.cfg;
|
||||
|
||||
for (const b of this.barrels) {
|
||||
if (!b.alive) continue;
|
||||
|
||||
if (b.falling) {
|
||||
b.vy += cfg.gravity * dt;
|
||||
b.y += b.vy * dt;
|
||||
|
||||
// Land on next platform down
|
||||
const nextIdx = b.platformIndex - 1;
|
||||
if (nextIdx < 0) {
|
||||
b.alive = false;
|
||||
continue;
|
||||
}
|
||||
const nextPlat = PLATFORMS[nextIdx];
|
||||
const landY = nextPlat.y - BARREL_R - PLATFORM_H;
|
||||
if (b.y >= landY) {
|
||||
b.y = landY;
|
||||
b.falling = false;
|
||||
b.vy = 0;
|
||||
b.platformIndex = nextIdx;
|
||||
b.dir = BARREL_DIR[nextIdx];
|
||||
}
|
||||
} else {
|
||||
b.x += b.dir * cfg.barrelSpeed * dt;
|
||||
|
||||
const plat = PLATFORMS[b.platformIndex];
|
||||
// Fall off edge
|
||||
if (b.dir > 0 && b.x > plat.xMax - BARREL_R) {
|
||||
if (b.platformIndex === 0) {
|
||||
b.alive = false; // off the floor
|
||||
} else {
|
||||
b.falling = true;
|
||||
b.vy = 0;
|
||||
b.x = plat.xMax - BARREL_R;
|
||||
}
|
||||
} else if (b.dir < 0 && b.x < plat.xMin + BARREL_R) {
|
||||
if (b.platformIndex === 0) {
|
||||
b.alive = false;
|
||||
} else {
|
||||
b.falling = true;
|
||||
b.vy = 0;
|
||||
b.x = plat.xMin + BARREL_R;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.barrels = this.barrels.filter(b => b.alive);
|
||||
if (this.kongArmRaise > 0) this.kongArmRaise -= dt;
|
||||
}
|
||||
|
||||
// ─── Collision ────────────────────────────────────────────────────────────
|
||||
|
||||
_checkCollisions() {
|
||||
if (!this.gameActive) return;
|
||||
const p = this.player;
|
||||
const pLeft = p.x - PLAYER_W / 2;
|
||||
const pRight = p.x + PLAYER_W / 2;
|
||||
const pTop = p.y;
|
||||
const pBottom = p.y + PLAYER_H;
|
||||
const pCenterX = p.x;
|
||||
|
||||
for (const b of this.barrels) {
|
||||
if (!b.alive || b.falling) continue;
|
||||
// Only check barrels on same or adjacent platform
|
||||
if (Math.abs(b.platformIndex - p.platformIndex) > 0) continue;
|
||||
if (b.platformIndex !== p.platformIndex) continue;
|
||||
|
||||
const dx = pCenterX - b.x;
|
||||
const dy = (p.y + PLAYER_H / 2) - b.y;
|
||||
const dist = Math.hypot(dx, dy);
|
||||
|
||||
// Stomp: player falling, feet crossing top of barrel
|
||||
if (p.state === 'jumping' && p.vy > 0 &&
|
||||
pBottom >= b.y - BARREL_R && pBottom <= b.y + BARREL_R &&
|
||||
Math.abs(dx) < BARREL_R + PLAYER_W * 0.5) {
|
||||
b.alive = false;
|
||||
if (!b.cleared) {
|
||||
b.cleared = true;
|
||||
this.barrelsCleared++;
|
||||
}
|
||||
p.vy = -this.cfg.stompBounce;
|
||||
this._playFx('bkStomp', 0.7);
|
||||
this._checkWin();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Jump-over: player jumping, feet above barrel center, laterally overlapping
|
||||
if (p.state === 'jumping' && !b.cleared &&
|
||||
pBottom < b.y &&
|
||||
Math.abs(dx) < BARREL_R + PLAYER_W * 0.6 &&
|
||||
!p.jumpedOverBarrels.has(b)) {
|
||||
p.jumpedOverBarrels.add(b);
|
||||
b.cleared = true;
|
||||
this.barrelsCleared++;
|
||||
this._checkWin();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Side hit: AABB vs circle overlap (not a stomp or jump-over already processed)
|
||||
if (dist < BARREL_R + Math.min(PLAYER_W, PLAYER_H) * 0.45) {
|
||||
// Don't penalize if player is clearly above (already scored)
|
||||
if (p.state === 'jumping' && pBottom < b.y - BARREL_R * 0.5) continue;
|
||||
this._endGame(false, "BARREL'D!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up jump-over tracking for dead/cleared barrels
|
||||
for (const b of p.jumpedOverBarrels) {
|
||||
if (!b.alive || b.cleared) continue; // keep cleared ones out naturally
|
||||
}
|
||||
}
|
||||
|
||||
_checkWin() {
|
||||
if (this.barrelsCleared >= this.cfg.barrelsToPass) {
|
||||
this._endGame(true, 'CLEARED!');
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Drawing ──────────────────────────────────────────────────────────────
|
||||
|
||||
_draw() {
|
||||
const g = this.mainGfx;
|
||||
g.clear();
|
||||
|
||||
this._drawBackground(g);
|
||||
this._drawPlatforms(g);
|
||||
this._drawLadders(g);
|
||||
this._drawKong(g);
|
||||
this._drawBarrels(g);
|
||||
this._drawPlayer(g);
|
||||
}
|
||||
|
||||
_drawBackground(g) {
|
||||
g.fillStyle(0x00060f);
|
||||
g.fillRect(0, 0, 1600, 900);
|
||||
g.lineStyle(1, 0x0a1a2a, 0.5);
|
||||
for (let x = 0; x < 1600; x += 80) g.lineBetween(x, 0, x, 900);
|
||||
for (let y = 0; y < 900; y += 60) g.lineBetween(0, y, 1600, y);
|
||||
}
|
||||
|
||||
_drawPlatforms(g) {
|
||||
for (const plat of PLATFORMS) {
|
||||
const w = plat.xMax - plat.xMin;
|
||||
// Platform body
|
||||
g.fillStyle(0x2255bb);
|
||||
g.fillRect(plat.xMin, plat.y - PLATFORM_H, w, PLATFORM_H);
|
||||
// Bright top edge
|
||||
g.lineStyle(3, 0x44aaff, 1.0);
|
||||
g.lineBetween(plat.xMin, plat.y - PLATFORM_H, plat.xMax, plat.y - PLATFORM_H);
|
||||
}
|
||||
}
|
||||
|
||||
_drawLadders(g) {
|
||||
for (const l of LADDERS) {
|
||||
const lx = l.x - LADDER_W / 2;
|
||||
const rx = l.x + LADDER_W / 2;
|
||||
g.lineStyle(3, 0xffcc44, 0.9);
|
||||
g.lineBetween(lx, l.yBottom - PLATFORM_H, lx, l.yTop);
|
||||
g.lineBetween(rx, l.yBottom - PLATFORM_H, rx, l.yTop);
|
||||
// Rungs
|
||||
g.lineStyle(2, 0xffcc44, 0.7);
|
||||
const rungCount = Math.floor((l.yBottom - l.yTop) / 20);
|
||||
for (let r = 0; r <= rungCount; r++) {
|
||||
const ry = l.yTop + r * ((l.yBottom - PLATFORM_H - l.yTop) / rungCount);
|
||||
g.lineBetween(lx, ry, rx, ry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_drawKong(g) {
|
||||
// Kong sits above Kong platform (platform index 4)
|
||||
const kx = 95, ky = PLATFORMS[4].y - PLATFORM_H;
|
||||
const armRaised = this.kongArmRaise > 0;
|
||||
|
||||
// Body (trapezoid approximated as rect)
|
||||
g.fillStyle(0x552200);
|
||||
g.fillRect(kx - 32, ky - 95, 64, 60);
|
||||
|
||||
// Head (circle approximation via fillCircle)
|
||||
g.fillStyle(0x663300);
|
||||
g.fillCircle(kx, ky - 105, 28);
|
||||
|
||||
// Eyes
|
||||
g.fillStyle(0xffd700);
|
||||
g.fillCircle(kx - 9, ky - 110, 5);
|
||||
g.fillCircle(kx + 9, ky - 110, 5);
|
||||
g.fillStyle(0x000000);
|
||||
g.fillCircle(kx - 9, ky - 110, 2);
|
||||
g.fillCircle(kx + 9, ky - 110, 2);
|
||||
|
||||
// Arms
|
||||
g.fillStyle(0x552200);
|
||||
if (armRaised) {
|
||||
// Left arm raised
|
||||
g.fillRect(kx - 60, ky - 145, 30, 18);
|
||||
// Right arm normal
|
||||
g.fillRect(kx + 32, ky - 70, 30, 18);
|
||||
} else {
|
||||
g.fillRect(kx - 60, ky - 70, 30, 18);
|
||||
g.fillRect(kx + 32, ky - 70, 30, 18);
|
||||
}
|
||||
|
||||
// Feet
|
||||
g.fillStyle(0x442200);
|
||||
g.fillRect(kx - 28, ky - 37, 22, 18);
|
||||
g.fillRect(kx + 6, ky - 37, 22, 18);
|
||||
}
|
||||
|
||||
_drawBarrels(g) {
|
||||
for (const b of this.barrels) {
|
||||
if (!b.alive) continue;
|
||||
const r = BARREL_R;
|
||||
// Barrel body
|
||||
g.fillStyle(0xaa5500);
|
||||
g.fillCircle(b.x, b.y, r);
|
||||
// Cross-lines
|
||||
g.lineStyle(2, 0xffaa44, 0.9);
|
||||
g.lineBetween(b.x - r + 3, b.y, b.x + r - 3, b.y);
|
||||
g.lineBetween(b.x, b.y - r + 3, b.x, b.y + r - 3);
|
||||
// Outline
|
||||
g.lineStyle(1.5, 0xff8800, 0.7);
|
||||
g.strokeCircle(b.x, b.y, r);
|
||||
}
|
||||
}
|
||||
|
||||
_drawPlayer(g) {
|
||||
const p = this.player;
|
||||
const x = p.x, y = p.y;
|
||||
|
||||
// Body
|
||||
g.fillStyle(0xdd4411);
|
||||
g.fillRect(x - PLAYER_W / 2, y, PLAYER_W, PLAYER_H * 0.65);
|
||||
|
||||
// Head
|
||||
g.fillStyle(0xffaa77);
|
||||
g.fillCircle(x, y - 2, PLAYER_W * 0.42);
|
||||
|
||||
// Facing direction indicator (small triangle on chest)
|
||||
g.fillStyle(0xffff00);
|
||||
const tx = x + p.facingDir * (PLAYER_W * 0.35);
|
||||
const ty = y + PLAYER_H * 0.3;
|
||||
g.fillTriangle(
|
||||
tx, ty,
|
||||
tx - p.facingDir * 8, ty - 6,
|
||||
tx - p.facingDir * 8, ty + 6
|
||||
);
|
||||
|
||||
// Legs
|
||||
g.fillStyle(0x994400);
|
||||
g.fillRect(x - PLAYER_W / 2, y + PLAYER_H * 0.65, PLAYER_W * 0.4, PLAYER_H * 0.35);
|
||||
g.fillRect(x + PLAYER_W * 0.1, y + PLAYER_H * 0.65, PLAYER_W * 0.4, PLAYER_H * 0.35);
|
||||
}
|
||||
|
||||
// ─── HUD ──────────────────────────────────────────────────────────────────
|
||||
|
||||
_buildHUD() {
|
||||
this.livesText = this.add.text(20, 16, '', {
|
||||
fontSize: '26px', fontFamily: 'monospace',
|
||||
color: '#ff4444', stroke: '#000000', strokeThickness: 4,
|
||||
}).setDepth(10);
|
||||
|
||||
this.barrelsText = this.add.text(800, 16, '', {
|
||||
fontSize: '26px', fontFamily: 'monospace',
|
||||
color: '#ffcc44', stroke: '#000000', strokeThickness: 4,
|
||||
}).setOrigin(0.5, 0).setDepth(10);
|
||||
|
||||
this.levelText = this.add.text(1580, 16, `LEVEL ${this.level}`, {
|
||||
fontSize: '26px', fontFamily: 'monospace',
|
||||
color: '#00ccff', stroke: '#000000', strokeThickness: 4,
|
||||
}).setOrigin(1, 0).setDepth(10);
|
||||
|
||||
this.hintText = this.add.text(800, 875, 'A: Jump ↑↓: Climb Reach the top or clear barrels!', {
|
||||
fontSize: '18px', fontFamily: 'monospace',
|
||||
color: '#446688', stroke: '#000000', strokeThickness: 3,
|
||||
}).setOrigin(0.5, 1).setDepth(10);
|
||||
}
|
||||
|
||||
_updateHUD() {
|
||||
this.livesText.setText('♥ '.repeat(this.lives).trim());
|
||||
this.barrelsText.setText(`BARRELS ${this.barrelsCleared} / ${this.cfg.barrelsToPass}`);
|
||||
}
|
||||
|
||||
// ─── End game ─────────────────────────────────────────────────────────────
|
||||
|
||||
_endGame(success, msg) {
|
||||
if (!this.gameActive) return;
|
||||
this.gameActive = false;
|
||||
|
||||
if (success) this._playFx('bkComplete', 0.8);
|
||||
else this._playFx('bkHit', 0.7);
|
||||
|
||||
const color = success ? '#00ff44' : '#ff2222';
|
||||
this.add.text(800, 440, msg, {
|
||||
fontSize: '80px', fontFamily: 'monospace',
|
||||
color, stroke: '#000000', strokeThickness: 6,
|
||||
}).setOrigin(0.5).setDepth(20);
|
||||
|
||||
this.time.delayedCall(2200, () => {
|
||||
this.game.events.emit('miniGameResult', { success });
|
||||
});
|
||||
}
|
||||
|
||||
shutdown() {
|
||||
stopMusic(this);
|
||||
}
|
||||
|
||||
_playFx(key, volume = 0.6) {
|
||||
const snd = this.sound.add(key, { volume });
|
||||
snd.once('complete', () => snd.destroy());
|
||||
snd.play();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"levels": {
|
||||
"1": { "playerSpeed": 240, "jumpVelocity": 520, "gravity": 1000, "climbSpeed": 180, "barrelSpeed": 140, "barrelSpawnInterval": 4.0, "maxBarrels": 3, "barrelsToPass": 5, "stompBounce": 320 },
|
||||
"2": { "playerSpeed": 240, "jumpVelocity": 520, "gravity": 1000, "climbSpeed": 180, "barrelSpeed": 172, "barrelSpawnInterval": 3.5, "maxBarrels": 3, "barrelsToPass": 7, "stompBounce": 320 },
|
||||
"3": { "playerSpeed": 240, "jumpVelocity": 520, "gravity": 1000, "climbSpeed": 185, "barrelSpeed": 200, "barrelSpawnInterval": 3.1, "maxBarrels": 4, "barrelsToPass": 9, "stompBounce": 320 },
|
||||
"4": { "playerSpeed": 245, "jumpVelocity": 520, "gravity": 1000, "climbSpeed": 188, "barrelSpeed": 224, "barrelSpawnInterval": 2.8, "maxBarrels": 4, "barrelsToPass": 11, "stompBounce": 320 },
|
||||
"5": { "playerSpeed": 245, "jumpVelocity": 520, "gravity": 1000, "climbSpeed": 190, "barrelSpeed": 245, "barrelSpawnInterval": 2.5, "maxBarrels": 5, "barrelsToPass": 14, "stompBounce": 320 },
|
||||
"6": { "playerSpeed": 250, "jumpVelocity": 520, "gravity": 1000, "climbSpeed": 193, "barrelSpeed": 264, "barrelSpawnInterval": 2.2, "maxBarrels": 5, "barrelsToPass": 17, "stompBounce": 340 },
|
||||
"7": { "playerSpeed": 250, "jumpVelocity": 520, "gravity": 1000, "climbSpeed": 196, "barrelSpeed": 281, "barrelSpawnInterval": 2.0, "maxBarrels": 6, "barrelsToPass": 20, "stompBounce": 340 },
|
||||
"8": { "playerSpeed": 255, "jumpVelocity": 520, "gravity": 1000, "climbSpeed": 198, "barrelSpeed": 296, "barrelSpawnInterval": 1.8, "maxBarrels": 6, "barrelsToPass": 23, "stompBounce": 340 },
|
||||
"9": { "playerSpeed": 255, "jumpVelocity": 520, "gravity": 1000, "climbSpeed": 200, "barrelSpeed": 309, "barrelSpawnInterval": 1.7, "maxBarrels": 7, "barrelsToPass": 26, "stompBounce": 360 },
|
||||
"10": { "playerSpeed": 260, "jumpVelocity": 520, "gravity": 1000, "climbSpeed": 200, "barrelSpeed": 320, "barrelSpawnInterval": 1.6, "maxBarrels": 7, "barrelsToPass": 30, "stompBounce": 360 }
|
||||
}
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ import CodeBugInvaders from './games/code-bug-invaders/CodeBugInvaders.js';
|
|||
import DotDude from './games/dot-dude/DotDude.js';
|
||||
import SmashOut from './games/smash-out/SmashOut.js';
|
||||
import Vortex from './games/vortex/Vortex.js';
|
||||
import BurliKong from './games/burli-kong/BurliKong.js';
|
||||
|
||||
new Phaser.Game({
|
||||
type: Phaser.AUTO,
|
||||
|
|
@ -17,5 +18,5 @@ new Phaser.Game({
|
|||
mode: Phaser.Scale.FIT,
|
||||
autoCenter: Phaser.Scale.CENTER_BOTH,
|
||||
},
|
||||
scene: [MainMenu, GameManager, ColoradoDefense, CodeBugInvaders, DotDude, SmashOut, Vortex, GameOver, LevelComplete],
|
||||
scene: [MainMenu, GameManager, ColoradoDefense, CodeBugInvaders, DotDude, SmashOut, Vortex, BurliKong, GameOver, LevelComplete],
|
||||
});
|
||||
|
|
|
|||
|
|
@ -140,6 +140,7 @@ export default class GameManager extends Phaser.Scene {
|
|||
DotDude: 'DOT DUDE',
|
||||
SmashOut: 'SMASH OUT',
|
||||
Vortex: 'VORTEX',
|
||||
BurliKong: 'BURLI KONG',
|
||||
};
|
||||
return names[key] || key;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ export default class MainMenu extends Phaser.Scene {
|
|||
}
|
||||
|
||||
preload() {
|
||||
this.load.json('gameConfig', 'config/game.json?v=2');
|
||||
this.load.json('gameConfig', 'config/game.json?v=3');
|
||||
this.load.audio('mainTheme', 'assets/music/00-main-theme.mp3');
|
||||
this.load.image('logo-title', 'assets/images/logo-title.png');
|
||||
this.load.image('logo-people', 'assets/images/logo-people.png');
|
||||
|
|
|
|||
Loading…
Reference in New Issue