User prompt
amk şimdi de havada uçuşuyorlar karakterin yürüdüğü hizda olması gerekiyor. birde karakterin vücüdünun yarısı alt platformun içinde kalıyor yerde yürürken. 5. phase için konuluyorum
User prompt
bravo amk iki saattir bunu anlatmaya çalışıyorum düzelt çabuk
User prompt
5. phase de natureground platformunu kaldır sadce5. için
User prompt
5. phase de alt platformun üzerinde olması gereken engeller içinde duruyor iyi bak
User prompt
engeller alt platformun altında kaldı karakter engellere değmiyor istese bile
User prompt
biraz daha yaklaştır. alt ve üst platformlar neredeyse ortada bitiyor, ekranın sonuna kadar gitmiyor bunu da düzelt
User prompt
alt ve üst platformları birbirine yaklaştır 5. phase
User prompt
alt platform yarım duruyor ekranın tamamını kaplaması gerekmez mi incele düzelt
User prompt
5. phase için bir tane altta bir tane üstte olmak üzere geçilmez platform oluştur. mario classics in su altı bölümüne benzesin
User prompt
5. phase de bariz sorunlar var hala görmüyor musun
User prompt
üst platformda bariz bir sorun var
User prompt
düzelt
User prompt
karakter diğer phaselerdeki gibi ilerlemiyor sabit duruyor
User prompt
karakter ilerlemiyor sabit duruyor 5. phase de ve iki platform arasındaki mesafeyi azalt
User prompt
5. phase için bir tane altta bir tane üstte olmak üzere geçilmez platform oluştur. karakter sanki su altında bir tünelde gidiyormuş gibi olsun. 5. phase de natureground u götmek istemiyorum
User prompt
yanlışlıkla revert ettim eski haline getirebilir misin
User prompt
üst taraftaki yosunların başlangıç noktası üst platformun altı olması gerekiyor. yukarıdan aşağıya buz sarmaşığı gibi sarkması gerekiyor ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
güzel yaklaştın ama tamamen iyi değil hala yosunun bir kısmı üst platformun dışında incele ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
ee neden düzeltmiyorsun o zaman amk ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
hala düzelmedi bir bak amk sence yosunların duruşu normal mi?
User prompt
yosunlar üst plaformun alt tarafından başlayıp aşağı doğru inmesi gerekiyor yukarı değil. karakter su altında bir tünede gibi düşün ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
5. phase'e eklemeni istediklerim: -alt platformda buluna yosunları yeşil olan üst platformun altına da yerleştir. çünkü oyuncu sadece en üstte giderek bölümü geçebilir. -küçük balıkların pirana olmasını istiyorum hızlı bir şekilde ağızlarını açıp kapatsınlar. ve köpekbalıklarından daha hızlı hareket etsinler -bir de büyük balık eklemeni istiyorum bunlar da köpek balığı olacak. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
5. phase de double jump ı sınırsız yap. karakter su altında yüzüyormuş gibi mekaniği olmasını istiyorum. sol tarafa tıkladıkça karakter yukarı doğru yüzecek yani jump yerine tıklayınva ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
iki platformu çok az uzaklaştır. 5. phase için ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
iki platformu biraz daha birbirine yaklaştır ve biraz zoom in yap ↪💡 Consider importing and using the following plugins: @upit/tween.v1
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var AmbientParticle = Container.expand(function () {
var self = Container.call(this);
var particleGfx = self.attachAsset('particle', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = (Math.random() - 0.5) * 2;
self.velocityY = (Math.random() - 0.5) * 2;
self.life = 180;
self.maxLife = 180;
self.floatPhase = Math.random() * Math.PI * 2;
self.update = function () {
self.floatPhase += 0.02;
self.x += self.velocityX + Math.sin(self.floatPhase) * 0.5;
self.y += self.velocityY + Math.cos(self.floatPhase) * 0.3;
self.life--;
var alpha = Math.min(1, self.life / 60) * Math.min(1, (self.maxLife - self.life) / 60) * 0.4;
particleGfx.alpha = alpha;
particleGfx.scaleX = 0.5;
particleGfx.scaleY = 0.5;
if (self.life <= 0) {
self.shouldDestroy = true;
}
};
return self;
});
var BackgroundShape = Container.expand(function () {
var self = Container.call(this);
var shapeGfx = self.attachAsset('bgShape', {
anchorX: 0.5,
anchorY: 0.5
});
self.pulsePhase = Math.random() * Math.PI * 2;
self.oscillatePhase = Math.random() * Math.PI * 2;
self.floatSpeed = 0.02 + Math.random() * 0.03;
self.pulseSpeed = 0.05 + Math.random() * 0.05;
self.baseScale = 0.5 + Math.random() * 1.0;
self.baseAlpha = 0.1 + Math.random() * 0.2;
self.update = function () {
self.pulsePhase += self.pulseSpeed;
self.oscillatePhase += self.floatSpeed;
// Pulsing with beat
var beatScale = 1 + beatPulse * 0.3;
var pulseScale = 1 + Math.sin(self.pulsePhase) * 0.2;
shapeGfx.scaleX = self.baseScale * beatScale * pulseScale;
shapeGfx.scaleY = self.baseScale * beatScale * pulseScale;
// Oscillating movement
self.x += Math.sin(self.oscillatePhase) * 0.5;
self.y += Math.cos(self.oscillatePhase * 0.7) * 0.3;
// Alpha varies with intensity
shapeGfx.alpha = self.baseAlpha + beatPulse * 0.1;
// Slow drift
self.x -= gameSpeed * 0.2;
};
return self;
});
var Bubble = Container.expand(function () {
var self = Container.call(this);
var bubbleGfx = self.attachAsset('bubble', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityY = -1 - Math.random() * 2;
self.velocityX = (Math.random() - 0.5) * 0.5;
self.life = 300 + Math.random() * 200;
self.maxLife = self.life;
self.floatPhase = Math.random() * Math.PI * 2;
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
self.floatPhase += 0.05;
var floatX = Math.sin(self.floatPhase) * 0.8;
self.x += floatX;
self.life--;
var alpha = Math.min(1, self.life / 60) * Math.min(1, (self.maxLife - self.life) / 60) * 0.7;
bubbleGfx.alpha = alpha;
var scale = 0.8 + Math.sin(self.floatPhase * 0.8) * 0.3;
bubbleGfx.scaleX = scale;
bubbleGfx.scaleY = scale;
if (self.life <= 0 || self.y < -50) {
self.shouldDestroy = true;
}
};
return self;
});
var BurstParticle = Container.expand(function () {
var self = Container.call(this);
var particleGfx = self.attachAsset('particle', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.life = 40;
self.maxLife = 40;
self.initialScale = 1.5;
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
self.velocityX *= 0.95;
self.velocityY *= 0.95;
self.life--;
var alpha = self.life / self.maxLife;
particleGfx.alpha = alpha;
var scale = self.initialScale * alpha;
particleGfx.scaleX = scale;
particleGfx.scaleY = scale;
if (self.life <= 0) {
self.shouldDestroy = true;
}
};
return self;
});
var Bush = Container.expand(function () {
var self = Container.call(this);
var bushGfx = self.attachAsset('bush', {
anchorX: 0.5,
anchorY: 1
});
// Larger scale for nature phase
bushGfx.scaleX = 1.5;
bushGfx.scaleY = 1.5;
self.speed = -6;
self.rustlePhase = Math.random() * Math.PI * 2;
self.update = function () {
self.x += self.speed;
// Gentle rustling animation
self.rustlePhase += 0.08;
var rustle = Math.sin(self.rustlePhase) * 0.05;
bushGfx.scaleX = 1 + rustle;
bushGfx.scaleY = 1 + rustle * 0.5;
};
return self;
});
var Cloud = Container.expand(function () {
var self = Container.call(this);
var cloudGlow = self.attachAsset('cloudGlow', {
anchorX: 0.5,
anchorY: 0.5
});
var cloudCore = self.attachAsset('cloud', {
anchorX: 0.5,
anchorY: 0.5
});
cloudGlow.alpha = 0.4;
cloudCore.alpha = 0.9;
self.speed = -4;
self.floatPhase = Math.random() * Math.PI * 2;
self.glowPhase = Math.random() * Math.PI * 2;
self.bouncePhase = 0;
self.isBouncing = false;
self.bounceIntensity = 0;
self.mistTimer = 0;
self.update = function () {
self.x += self.speed;
// Gentle floating animation
self.floatPhase += 0.03;
var floatY = Math.sin(self.floatPhase) * 8;
self.y += floatY * 0.1;
// Soft glow pulsing
self.glowPhase += 0.05;
var glowIntensity = 0.3 + Math.sin(self.glowPhase) * 0.1;
cloudGlow.alpha = glowIntensity;
// Bounce animation when stepped on
if (self.isBouncing) {
self.bouncePhase += 0.3;
self.bounceIntensity = Math.sin(self.bouncePhase) * 0.5;
cloudCore.scaleY = 1 - self.bounceIntensity * 0.2;
cloudGlow.scaleY = 1 - self.bounceIntensity * 0.15;
if (self.bouncePhase >= Math.PI) {
self.isBouncing = false;
self.bouncePhase = 0;
cloudCore.scaleY = 1;
cloudGlow.scaleY = 1;
}
}
// Create mist particles
self.mistTimer++;
if (self.mistTimer >= 40) {
self.mistTimer = 0;
self.createMist();
}
};
self.bounce = function () {
if (!self.isBouncing) {
self.isBouncing = true;
self.bouncePhase = 0;
// Play soft bounce sound
if (Math.random() < 0.3) {
LK.getSound('echoChime').play();
}
}
};
self.createMist = function () {
// Mist creation disabled
};
return self;
});
var Coral = Container.expand(function () {
var self = Container.call(this);
var coralGfx = self.attachAsset('coral', {
anchorX: 0.5,
anchorY: 1
});
self.speed = -4;
self.pulsePhase = Math.random() * Math.PI * 2;
self.update = function () {
self.x += self.speed;
self.pulsePhase += 0.03;
var pulse = 1 + Math.sin(self.pulsePhase) * 0.15;
coralGfx.scaleX = pulse;
coralGfx.scaleY = pulse;
var colorShift = Math.floor(Math.sin(self.pulsePhase * 0.5) * 80);
coralGfx.tint = 0xff69b4 + colorShift;
};
return self;
});
var DataStreamParticle = Container.expand(function () {
var self = Container.call(this);
var streamGfx = self.attachAsset('dataStream', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = -1 - Math.random() * 3;
self.velocityY = (Math.random() - 0.5) * 2;
self.life = 300 + Math.random() * 200;
self.maxLife = self.life;
self.twinklePhase = Math.random() * Math.PI * 2;
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
self.twinklePhase += 0.1;
self.life--;
// Twinkling effect
var twinkle = Math.sin(self.twinklePhase) * 0.3;
var fadeAlpha = Math.min(1, self.life / 60) * Math.min(1, (self.maxLife - self.life) / 60);
streamGfx.alpha = (0.3 + twinkle + beatPulse * 0.2) * fadeAlpha;
streamGfx.scaleX = 0.8 + beatPulse * 0.4;
streamGfx.scaleY = 0.8 + beatPulse * 0.4;
if (self.life <= 0) {
self.shouldDestroy = true;
}
};
return self;
});
var ExplosionPart = Container.expand(function () {
var self = Container.call(this);
var partGfx = self.attachAsset('explosionPart', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.rotationSpeed = 0;
self.life = 40;
self.maxLife = 40;
self.gravity = 0.3;
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
self.velocityY += self.gravity;
self.velocityX *= 0.98;
partGfx.rotation += self.rotationSpeed;
self.life--;
var alpha = self.life / self.maxLife;
partGfx.alpha = alpha;
// Color transition from bright orange to dark red
var colorProgress = 1 - alpha;
var red = 255;
var green = Math.floor(170 * (1 - colorProgress));
var blue = 0;
partGfx.tint = red << 16 | green << 8 | blue;
var scale = alpha * (1 + (1 - alpha) * 0.5);
partGfx.scaleX = scale;
partGfx.scaleY = scale;
if (self.life <= 0) {
self.shouldDestroy = true;
}
};
return self;
});
var Fish = Container.expand(function () {
var self = Container.call(this);
var fishGfx = self.attachAsset('fish', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -4 - Math.random() * 3;
self.swimPhase = Math.random() * Math.PI * 2;
self.verticalAmplitude = 30 + Math.random() * 20;
self.baseY = 0;
self.update = function () {
self.x += self.speed;
self.swimPhase += 0.08;
var swimY = Math.sin(self.swimPhase) * self.verticalAmplitude;
self.y = self.baseY + swimY;
var scale = 1 + Math.sin(self.swimPhase * 1.2) * 0.1;
fishGfx.scaleX = scale;
fishGfx.scaleY = scale;
fishGfx.rotation = Math.sin(self.swimPhase) * 0.2;
var colorShift = Math.floor(Math.sin(self.swimPhase) * 50);
fishGfx.tint = 0xff6600 + colorShift;
};
return self;
});
var GroundSegment = Container.expand(function () {
var self = Container.call(this);
var groundGfx = self.attachAsset('ground', {
anchorX: 0,
anchorY: 0
});
var shimmerGfx = self.attachAsset('groundShimmer', {
anchorX: 0,
anchorY: 0
});
shimmerGfx.y = -8;
self.shimmerPhase = Math.random() * Math.PI * 2;
self.wavePhase = Math.random() * Math.PI * 2;
self.beatIntensity = 0;
self.update = function () {
// Reflective shimmer effect
self.shimmerPhase += 0.08;
shimmerGfx.alpha = 0.4 + Math.sin(self.shimmerPhase) * 0.3;
shimmerGfx.scaleX = 1 + Math.sin(self.shimmerPhase * 0.7) * 0.1;
// Waveform moving through ground
self.wavePhase += gameSpeed * 0.02;
var waveOffset = Math.sin(self.wavePhase) * 3;
groundGfx.y = waveOffset;
shimmerGfx.y = -8 + waveOffset;
// Beat-synced effects
self.beatIntensity = beatPulse;
var glowIntensity = 0.7 + self.beatIntensity * 0.3;
groundGfx.alpha = glowIntensity;
// Color changes based on beat
var beatColor = Math.floor(self.beatIntensity * 80);
groundGfx.tint = 0x4488ff + beatColor;
shimmerGfx.tint = 0x88ccff + (beatColor << 4);
// Motion matching scrolling tempo
self.x -= gameSpeed;
};
return self;
});
var Heart = Container.expand(function () {
var self = Container.call(this);
var heartGfx = self.attachAsset('heart', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -8;
self.pulsePhase = Math.random() * Math.PI * 2;
self.glowPhase = Math.random() * Math.PI * 2;
self.isPulsing = false;
self.pulseTimer = 0;
self.maxPulseTime = 60; // 1 second at 60fps
self.sparkleTimer = 0;
self.update = function () {
self.x += self.speed;
// Gentle floating
self.pulsePhase += 0.08;
var floatY = Math.sin(self.pulsePhase) * 8;
self.y += floatY * 0.05;
// Check if should pulse with beat
if (beatPulse > 0.7 && !self.isPulsing) {
self.isPulsing = true;
self.pulseTimer = self.maxPulseTime;
}
// Handle pulsing state
if (self.isPulsing) {
self.pulseTimer--;
// Bright glow and scale during pulse
var pulseIntensity = self.pulseTimer / self.maxPulseTime;
heartGfx.alpha = 0.8 + pulseIntensity * 0.2;
heartGfx.scaleX = 1.0 + pulseIntensity * 0.4;
heartGfx.scaleY = 1.0 + pulseIntensity * 0.4;
heartGfx.tint = 0xff1144; // Bright red when pulsing
// Sparkle creation disabled
if (self.pulseTimer <= 0) {
self.isPulsing = false;
}
} else {
// Normal state - gentle glow
self.glowPhase += 0.05;
heartGfx.alpha = 0.7 + Math.sin(self.glowPhase) * 0.2;
heartGfx.scaleX = 1.0 + Math.sin(self.glowPhase) * 0.1;
heartGfx.scaleY = 1.0 + Math.sin(self.glowPhase) * 0.1;
heartGfx.tint = 0xff3366; // Normal pink-red
}
};
return self;
});
var HolographicElement = Container.expand(function () {
var self = Container.call(this);
var elementType = Math.floor(Math.random() * 3);
var elementGfx;
if (elementType === 0) {
elementGfx = self.attachAsset('waveform', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (elementType === 1) {
elementGfx = self.attachAsset('speaker', {
anchorX: 0.5,
anchorY: 0.5
});
} else {
elementGfx = self.attachAsset('freqBar', {
anchorX: 0.5,
anchorY: 1
});
}
self.fadePhase = 0;
self.maxFadePhase = 300 + Math.random() * 200;
self.pulsePhase = Math.random() * Math.PI * 2;
self.driftSpeed = -0.5 - Math.random() * 1.5;
self.baseScale = 2 + Math.random() * 3;
self.update = function () {
self.fadePhase++;
self.pulsePhase += 0.03;
self.x += self.driftSpeed;
// Fade in and out effect
var fadeProgress = self.fadePhase / self.maxFadePhase;
var fadeAlpha;
if (fadeProgress < 0.2) {
fadeAlpha = fadeProgress / 0.2;
} else if (fadeProgress > 0.8) {
fadeAlpha = (1 - fadeProgress) / 0.2;
} else {
fadeAlpha = 1;
}
// Very faint holographic appearance
elementGfx.alpha = fadeAlpha * (0.05 + beatPulse * 0.1);
// Pulse with beat
var scale = self.baseScale * (1 + Math.sin(self.pulsePhase) * 0.1 + beatPulse * 0.2);
elementGfx.scaleX = scale;
elementGfx.scaleY = scale;
// Color tinting for holographic effect
elementGfx.tint = 0x4466aa + Math.floor(beatPulse * 50);
if (self.fadePhase >= self.maxFadePhase) {
self.shouldDestroy = true;
}
};
return self;
});
var LaserBeam = Container.expand(function () {
var self = Container.call(this);
// Laser core that moves up and down
var laserCore = self.attachAsset('laserCore', {
anchorX: 0.5,
anchorY: 0.5
});
// Main laser beam
var laserBeam = self.attachAsset('laserBeam', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -6;
self.verticalSpeed = 3;
self.direction = 1; // 1 for down, -1 for up
self.warningTimer = 60; // Warning phase before activation
self.isActive = false;
self.pulsePhase = 0;
self.coreY = 0;
self.maxTravel = 150;
// Initially hide the beam, show only core
laserBeam.alpha = 0;
laserCore.y = -self.maxTravel;
self.update = function () {
self.x += self.speed;
// Warning phase
if (self.warningTimer > 0) {
self.warningTimer--;
// Blinking warning effect
laserCore.alpha = Math.sin(self.warningTimer * 0.3) * 0.5 + 0.5;
laserCore.tint = 0xff0000; // Red warning
if (self.warningTimer === 0) {
self.isActive = true;
laserBeam.alpha = 0.9;
}
}
// Active laser movement
if (self.isActive) {
self.coreY += self.verticalSpeed * self.direction;
laserCore.y = self.coreY;
// Reverse direction at limits
if (self.coreY >= self.maxTravel || self.coreY <= -self.maxTravel) {
self.direction *= -1;
}
// Pulse effects
self.pulsePhase += 0.15;
var intensity = 0.8 + Math.sin(self.pulsePhase) * 0.2 + beatPulse * 0.3;
laserBeam.alpha = intensity;
laserCore.alpha = 1.0;
// Bright laser colors
laserBeam.tint = 0xff0088 + Math.floor(beatPulse * 100);
laserCore.tint = 0xffffff;
// Scale effects
var scale = 1 + beatPulse * 0.4;
laserBeam.scaleX = scale;
laserCore.scaleX = 1 + beatPulse * 0.6;
laserCore.scaleY = 1 + beatPulse * 0.6;
}
};
return self;
});
var LightLine = Container.expand(function () {
var self = Container.call(this);
var lineGfx = self.attachAsset('lightLine', {
anchorX: 0,
anchorY: 0.5
});
self.speed = -2 - Math.random() * 4;
self.pulsePhase = Math.random() * Math.PI * 2;
self.glowPhase = Math.random() * Math.PI * 2;
self.baseAlpha = 0.2 + Math.random() * 0.3;
self.update = function () {
self.x += self.speed;
self.pulsePhase += 0.08;
self.glowPhase += 0.05;
// Flowing glow effect
lineGfx.alpha = self.baseAlpha + Math.sin(self.glowPhase) * 0.2 + beatPulse * 0.2;
lineGfx.scaleY = 0.8 + Math.sin(self.pulsePhase) * 0.4 + beatPulse * 0.3;
// Color shift with beat
var colorShift = Math.floor(beatPulse * 100);
lineGfx.tint = 0x6644ff + (colorShift << 8);
};
return self;
});
var NatureGroundSegment = Container.expand(function () {
var self = Container.call(this);
var groundGfx = self.attachAsset('natureGround', {
anchorX: 0,
anchorY: 0
});
// Larger scale for nature phase
groundGfx.scaleX = 1.4;
groundGfx.scaleY = 1.4;
self.update = function () {
self.x -= gameSpeed + 1;
};
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGfx = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 1
});
self.speed = -6;
self.pulsePhase = 0;
self.update = function () {
self.x += self.speed;
// Pulse effect
self.pulsePhase += 0.15;
var scale = 1 + Math.sin(self.pulsePhase) * 0.1;
obstacleGfx.scaleX = scale;
obstacleGfx.scaleY = scale;
// Beat sync glow
if (beatPulse > 0.5) {
obstacleGfx.tint = 0xffffff;
} else {
obstacleGfx.tint = 0xff0044;
}
};
return self;
});
var Particle = Container.expand(function () {
var self = Container.call(this);
var particleGfx = self.attachAsset('particle', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.life = 60;
self.maxLife = 60;
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
self.velocityY += 0.2;
self.life--;
particleGfx.alpha = self.life / self.maxLife;
if (self.life <= 0) {
self.shouldDestroy = true;
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
// Create main glow aura behind character
var mainGlow = self.attachAsset('playerGlow', {
anchorX: 0.5,
anchorY: 0.5
});
mainGlow.alpha = 0.3;
mainGlow.y = -10;
// Create body parts with neon light appearance
var head = self.attachAsset('playerHead', {
anchorX: 0.5,
anchorY: 0.5
});
var body = self.attachAsset('playerBody', {
anchorX: 0.5,
anchorY: 0
});
var leftArm = self.attachAsset('playerArm', {
anchorX: 0.5,
anchorY: 0
});
var rightArm = self.attachAsset('playerArm', {
anchorX: 0.5,
anchorY: 0
});
var leftLeg = self.attachAsset('playerLeg', {
anchorX: 0.5,
anchorY: 0
});
var rightLeg = self.attachAsset('playerLeg', {
anchorX: 0.5,
anchorY: 0
});
// Position body parts relative to center
head.y = -30;
body.y = -12;
leftArm.x = -10;
leftArm.y = -8;
rightArm.x = 10;
rightArm.y = -8;
leftLeg.x = -6;
leftLeg.y = 13;
rightLeg.x = 6;
rightLeg.y = 13;
// Set initial electric blue color with glow effect
head.tint = 0x00ccff;
body.tint = 0x0099ff;
leftArm.tint = 0x0088ff;
rightArm.tint = 0x0088ff;
leftLeg.tint = 0x0077ff;
rightLeg.tint = 0x0077ff;
self.velocityY = 0;
self.velocityX = 0;
self.isGrounded = false;
self.isDashing = false;
self.dashCooldown = 0;
self.canDoubleJump = false;
self.hasUsedDoubleJump = false;
self.hasJumped = false; // Track if player has actually jumped
self.glowPhase = 0;
self.walkPhase = 0;
self.constantSpeed = 3; // Constant walking speed
self.hoverPhase = 0;
self.beatReactionTimer = 0;
self.currentHue = 0; // For color shifting
self.comboStreakColor = 0x00ccff; // Base electric blue
self.update = function () {
// Floating effect - character hovers above ground
self.hoverPhase += 0.08;
var hoverOffset = Math.sin(self.hoverPhase) * 3;
// Variable jump system - apply additional upward force while jump is held
if (isJumpPressed && jumpHoldTime < maxJumpHoldTime && self.velocityY < 0) {
var holdForce = (maxJumpHoldTime - jumpHoldTime) / maxJumpHoldTime * -1.5;
self.velocityY += holdForce;
jumpHoldTime++;
}
// Simplified gravity system
if (!self.isGrounded) {
if (gamePhase === 5) {
// Underwater phase - reduced gravity and buoyancy
self.velocityY += 0.3; // Much slower falling underwater
// Add slight upward buoyancy force
self.velocityY -= 0.1;
} else if (gamePhase === 3) {
// Sky level - increased gravity
self.velocityY += 0.55;
} else {
// Normal/speed phase - standard gravity
self.velocityY += 0.6;
}
}
// Apply velocity with underwater resistance
if (gamePhase === 5) {
// Underwater movement - add resistance
self.velocityX *= 0.95; // Water resistance
self.velocityY *= 0.98; // Slower vertical movement
}
self.y += self.velocityY;
self.x += self.velocityX;
// Constant forward movement when grounded
if (self.isGrounded && !self.isDashing) {
self.x += self.constantSpeed;
}
// Ground collision with hover offset (only in normal/speed phases)
if (gamePhase !== 3) {
var groundThreshold = groundLevel - 35 + hoverOffset;
if (self.y >= groundThreshold) {
self.y = groundThreshold;
self.velocityY = 0;
self.isGrounded = true;
self.canDoubleJump = false;
self.hasUsedDoubleJump = false;
self.hasJumped = false; // Reset jump flag when grounded
}
} else {
// Sky level - check if player is actually on a cloud or seagull
var onPlatform = false;
// Check if standing on any cloud
for (var i = 0; i < clouds.length; i++) {
var cloud = clouds[i];
if (self.intersects(cloud) && self.velocityY >= 0 && self.y <= cloud.y) {
onPlatform = true;
break;
}
}
// Check if standing on any seagull
if (!onPlatform) {
for (var i = 0; i < seagulls.length; i++) {
var seagull = seagulls[i];
if (self.intersects(seagull) && self.velocityY >= 0 && self.y <= seagull.y) {
onPlatform = true;
break;
}
}
}
// If not on any platform, player should fall
if (!onPlatform) {
// Track if player was grounded before falling
var wasGrounded = self.isGrounded;
self.isGrounded = false;
// If player just started falling (was on platform, now falling)
if (wasGrounded) {
// When falling from platform, enable double jump capability
self.hasJumped = false;
self.canDoubleJump = true;
self.hasUsedDoubleJump = false;
}
} else {
// Player is on a platform
self.isGrounded = true;
self.canDoubleJump = false;
self.hasUsedDoubleJump = false;
self.hasJumped = false;
}
}
// Simple backward movement
if (self.isGrounded && self.velocityX === 0 && !self.isDashing) {
self.x -= gameSpeed * 0.8; // Smooth per-frame movement
}
// Dash cooldown
if (self.dashCooldown > 0) {
self.dashCooldown--;
}
// Rhythmic bouncing and running animation
if (self.isGrounded && !self.isDashing) {
self.walkPhase += 0.25;
// Energetic arm movements
leftArm.rotation = Math.sin(self.walkPhase) * 0.6;
rightArm.rotation = -Math.sin(self.walkPhase) * 0.6;
// Dynamic leg running motion
leftLeg.rotation = Math.sin(self.walkPhase + Math.PI) * 0.4;
rightLeg.rotation = Math.sin(self.walkPhase) * 0.4;
// Head bobbing with beat awareness
var beatBob = beatPulse > 0.5 ? beatPulse * 2 : 0;
head.y = -30 + Math.sin(self.walkPhase * 2) * 2 + beatBob;
} else {
// Reset positions when not walking
leftArm.rotation = 0;
rightArm.rotation = 0;
leftLeg.rotation = 0;
rightLeg.rotation = 0;
head.y = -30;
}
// Neon glow effects with beat reaction
self.glowPhase += 0.12;
var baseGlow = 0.9 + Math.sin(self.glowPhase) * 0.1;
var beatGlow = beatPulse * 0.3;
var totalGlow = Math.min(1.0, baseGlow + beatGlow);
// Beat reaction timer
if (self.beatReactionTimer > 0) {
self.beatReactionTimer--;
totalGlow = 1.0;
}
// Apply glow to all parts
head.alpha = totalGlow;
body.alpha = totalGlow;
leftArm.alpha = totalGlow;
rightArm.alpha = totalGlow;
leftLeg.alpha = totalGlow;
rightLeg.alpha = totalGlow;
// Main glow pulsing
mainGlow.alpha = 0.2 + beatPulse * 0.3;
mainGlow.scaleX = 1 + Math.sin(self.glowPhase * 0.7) * 0.1 + beatPulse * 0.2;
mainGlow.scaleY = 1 + Math.sin(self.glowPhase * 0.7) * 0.1 + beatPulse * 0.2;
// Color shifting based on combo streak and game phase
if (combo > 0) {
self.currentHue += 0.02;
var hueShift = Math.sin(self.currentHue) * 60;
if (gamePhase === 4) {
// Nature phase - Mario classic red and blue colors
self.comboStreakColor = 0xff3333 + Math.floor(hueShift);
} else if (gamePhase === 3) {
// Sky phase - soft golden colors
self.comboStreakColor = 0xffcc66 + Math.floor(hueShift);
} else if (gamePhase === 2) {
// Speed phase - orange/red colors
self.comboStreakColor = 0xff8800 + Math.floor(hueShift);
} else {
// Normal phase - blue colors
self.comboStreakColor = 0x0088ff + Math.floor(hueShift);
}
// Apply combo colors
head.tint = self.comboStreakColor + 0x2200;
body.tint = self.comboStreakColor;
leftArm.tint = self.comboStreakColor - 0x1100;
rightArm.tint = self.comboStreakColor - 0x1100;
leftLeg.tint = self.comboStreakColor - 0x2200;
rightLeg.tint = self.comboStreakColor - 0x2200;
mainGlow.tint = self.comboStreakColor;
} else {
if (gamePhase === 5) {
// Underwater phase - aquatic blue and teal colors
head.tint = 0x00cccc; // Cyan
body.tint = 0x0099cc; // Ocean blue
leftArm.tint = 0x0088bb; // Deeper blue
rightArm.tint = 0x0088bb; // Deeper blue
leftLeg.tint = 0x0077aa; // Deep blue
rightLeg.tint = 0x0077aa; // Deep blue
mainGlow.tint = 0x00ccff; // Bright aqua glow
} else if (gamePhase === 4) {
// Nature phase - Mario classic colors (red hat, blue overalls, brown boots)
head.tint = 0xff0000; // Red hat like Mario
body.tint = 0x0066ff; // Blue overalls like Mario
leftArm.tint = 0xffcc99; // Skin tone for arms
rightArm.tint = 0xffcc99; // Skin tone for arms
leftLeg.tint = 0x8b4513; // Brown boots like Mario
rightLeg.tint = 0x8b4513; // Brown boots like Mario
mainGlow.tint = 0xff6666; // Red glow to match
} else if (gamePhase === 3) {
// Sky phase - soft golden/white colors
head.tint = 0xffffdd;
body.tint = 0xffeeaa;
leftArm.tint = 0xffdd88;
rightArm.tint = 0xffdd88;
leftLeg.tint = 0xffcc66;
rightLeg.tint = 0xffcc66;
mainGlow.tint = 0xffee99;
} else if (gamePhase === 2) {
// Speed phase - orange colors
head.tint = 0xff9900;
body.tint = 0xff7700;
leftArm.tint = 0xff6600;
rightArm.tint = 0xff6600;
leftLeg.tint = 0xff5500;
rightLeg.tint = 0xff5500;
mainGlow.tint = 0xff8800;
} else {
// Normal phase - electric blue
head.tint = 0x00ccff;
body.tint = 0x0099ff;
leftArm.tint = 0x0088ff;
rightArm.tint = 0x0088ff;
leftLeg.tint = 0x0077ff;
rightLeg.tint = 0x0077ff;
mainGlow.tint = 0x0088ff;
}
self.currentHue = 0;
}
// Underwater platform collision detection (phase 5 only)
if (gamePhase === 5) {
// Top platform collision - prevent player from going above it
if (self.y < 950) {
self.y = 950;
if (self.velocityY < 0) self.velocityY = 0;
}
// Bottom platform collision - prevent player from going below it (account for player size)
if (self.y > 1752) {
// Moved up 30 pixels to account for player height
self.y = 1752;
if (self.velocityY > 0) self.velocityY = 0;
self.isGrounded = true;
}
}
// Keep player on screen
if (self.x < 0) self.x = 0;
if (self.x > 2048) self.x = 2048;
};
// Variable jump method
self.jump = function () {
if (self.isGrounded) {
// Calculate jump force based on hold time
var holdRatio = Math.min(jumpHoldTime / maxJumpHoldTime, 1);
var currentJumpForce = minJumpForce + (maxJumpForce - minJumpForce) * holdRatio;
self.velocityY = currentJumpForce;
self.isGrounded = false;
self.canDoubleJump = true;
self.hasUsedDoubleJump = false;
self.hasJumped = true;
self.createJumpEffect();
LK.getSound('jump').play();
} else if (self.canDoubleJump && !self.hasUsedDoubleJump) {
// Double jump with fixed force
self.velocityY = doubleJumpForce;
self.hasUsedDoubleJump = true;
// Double jump visual effects
LK.effects.flashObject(self, 0x00ffff, 300);
for (var i = 0; i < 8; i++) {
var particle = new Particle();
particle.x = self.x + (Math.random() - 0.5) * 60;
particle.y = self.y + 10;
particle.velocityY = Math.random() * 8 + 3;
particle.velocityX = (Math.random() - 0.5) * 12;
var particleGfx = particle.children[0];
particleGfx.tint = 0x00ffff;
game.addChild(particle);
particles.push(particle);
}
LK.getSound('jump').play();
}
};
self.dash = function () {
if (self.dashCooldown <= 0) {
self.velocityX = 15;
self.isDashing = true;
self.dashCooldown = 120; // 2 seconds at 60fps
LK.getSound('dash').play();
self.createDashEffect();
tween(self, {
velocityX: 0
}, {
duration: 400
});
LK.setTimeout(function () {
self.isDashing = false;
}, 400);
}
};
self.createJumpEffect = function () {
for (var i = 0; i < 5; i++) {
var particle = new Particle();
particle.x = self.x + (Math.random() - 0.5) * 40;
particle.y = self.y + 20;
particle.velocityY = Math.random() * 5 + 2;
particle.velocityX = (Math.random() - 0.5) * 8;
game.addChild(particle);
particles.push(particle);
}
};
self.createDashEffect = function () {
for (var i = 0; i < 8; i++) {
var particle = new Particle();
particle.x = self.x - 30;
particle.y = self.y + (Math.random() - 0.5) * 40;
particle.velocityY = (Math.random() - 0.5) * 6;
particle.velocityX = -Math.random() * 10 - 5;
game.addChild(particle);
particles.push(particle);
}
};
// React to beats with flash and pulse
self.reactToBeat = function () {
self.beatReactionTimer = 8; // Flash for 8 frames
// Bright flash effect
tween(self, {
alpha: 1.2
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
alpha: 1.0
}, {
duration: 200,
easing: tween.easeInOut
});
}
});
// Scale pulse
tween(self, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 250,
easing: tween.easeInOut
});
}
});
};
return self;
});
var Rock = Container.expand(function () {
var self = Container.call(this);
var rockGfx = self.attachAsset('rock', {
anchorX: 0.5,
anchorY: 1
});
// Larger scale for nature phase
rockGfx.scaleX = 1.5;
rockGfx.scaleY = 1.5;
self.speed = -6;
self.update = function () {
self.x += self.speed;
};
return self;
});
var RotatingCube = Container.expand(function () {
var self = Container.call(this);
var cubeGfx = self.attachAsset('rotatingCube', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -6;
self.rotationSpeed = 0.1 + Math.random() * 0.1;
self.pulsePhase = 0;
self.glowPhase = Math.random() * Math.PI * 2;
self.update = function () {
self.x += self.speed;
// Continuous rotation
cubeGfx.rotation += self.rotationSpeed;
// Pulse effect with beat
self.pulsePhase += 0.1;
var scale = 1 + Math.sin(self.pulsePhase) * 0.2 + beatPulse * 0.3;
cubeGfx.scaleX = scale;
cubeGfx.scaleY = scale;
// Glow effect
self.glowPhase += 0.08;
cubeGfx.alpha = 0.8 + Math.sin(self.glowPhase) * 0.2 + beatPulse * 0.2;
// Color shifting
var colorShift = Math.floor(beatPulse * 100);
cubeGfx.tint = 0xff4400 + (colorShift << 4);
};
return self;
});
var Seagull = Container.expand(function () {
var self = Container.call(this);
// Create seagull body
var body = self.attachAsset('seagullBody', {
anchorX: 0.5,
anchorY: 0.5
});
// Create wings
var leftWing = self.attachAsset('seagullWing', {
anchorX: 0.8,
anchorY: 0.5
});
var rightWing = self.attachAsset('seagullWing', {
anchorX: 0.2,
anchorY: 0.5
});
// Position wings
leftWing.x = -15;
leftWing.y = -3;
rightWing.x = 15;
rightWing.y = -3;
// Flight properties
self.speed = -5 - Math.random() * 2; // Slightly faster than clouds
self.wingPhase = Math.random() * Math.PI * 2;
self.wingSpeed = 0.3 + Math.random() * 0.2;
self.floatPhase = Math.random() * Math.PI * 2;
self.floatAmplitude = 15 + Math.random() * 10;
self.baseY = 0;
self.update = function () {
self.x += self.speed;
// Wing flapping animation
self.wingPhase += self.wingSpeed;
var wingFlap = Math.sin(self.wingPhase);
leftWing.rotation = wingFlap * 0.4;
rightWing.rotation = -wingFlap * 0.4;
leftWing.scaleY = 0.8 + wingFlap * 0.3;
rightWing.scaleY = 0.8 + wingFlap * 0.3;
// Graceful floating movement
self.floatPhase += 0.02;
var floatOffset = Math.sin(self.floatPhase) * self.floatAmplitude;
self.y = self.baseY + floatOffset;
// Subtle size pulsing for life-like movement
var sizePulse = 1 + Math.sin(self.wingPhase * 0.7) * 0.1;
body.scaleX = sizePulse;
body.scaleY = sizePulse;
// Slight transparency for ethereal sky feel
body.alpha = 0.9;
leftWing.alpha = 0.85;
rightWing.alpha = 0.85;
};
return self;
});
var Seaweed = Container.expand(function () {
var self = Container.call(this);
var seaweedGfx = self.attachAsset('seaweed', {
anchorX: 0.5,
anchorY: 1
});
self.speed = -3;
self.swayPhase = Math.random() * Math.PI * 2;
self.height = 80 + Math.random() * 40;
seaweedGfx.scaleY = self.height / 80;
self.update = function () {
self.x += self.speed;
self.swayPhase += 0.06;
var sway = Math.sin(self.swayPhase) * 0.3;
seaweedGfx.rotation = sway;
seaweedGfx.scaleX = 1 + Math.sin(self.swayPhase * 0.7) * 0.1;
var greenShift = Math.floor(Math.sin(self.swayPhase) * 30);
seaweedGfx.tint = 0x228b22 + (greenShift << 8);
};
return self;
});
var ShatterPart = Container.expand(function () {
var self = Container.call(this);
var shatterGfx = self.attachAsset('shatter', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.rotationSpeed = 0;
self.life = 60;
self.maxLife = 60;
self.gravity = 0.2;
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
self.velocityY += self.gravity;
self.velocityX *= 0.96;
shatterGfx.rotation += self.rotationSpeed;
self.life--;
var alpha = self.life / self.maxLife;
shatterGfx.alpha = alpha;
var scale = alpha * 0.8;
shatterGfx.scaleX = scale;
shatterGfx.scaleY = scale;
if (self.life <= 0) {
self.shouldDestroy = true;
}
};
return self;
});
var SunRay = Container.expand(function () {
var self = Container.call(this);
var rayGfx = self.attachAsset('sunRay', {
anchorX: 0,
anchorY: 0.5
});
self.speed = -1.5;
self.fadePhase = 0;
self.maxFadePhase = 600;
self.glowPhase = Math.random() * Math.PI * 2;
self.angle = (Math.random() - 0.5) * 0.3;
rayGfx.rotation = self.angle;
rayGfx.alpha = 0.3;
self.update = function () {
self.x += self.speed;
self.fadePhase++;
self.glowPhase += 0.02;
// Fade in and out effect
var fadeProgress = self.fadePhase / self.maxFadePhase;
var fadeAlpha;
if (fadeProgress < 0.3) {
fadeAlpha = fadeProgress / 0.3;
} else if (fadeProgress > 0.7) {
fadeAlpha = (1 - fadeProgress) / 0.3;
} else {
fadeAlpha = 1;
}
// Gentle glow pulsing
var glow = 0.8 + Math.sin(self.glowPhase) * 0.2;
rayGfx.alpha = fadeAlpha * glow * 0.25;
if (self.fadePhase >= self.maxFadePhase) {
self.shouldDestroy = true;
}
};
return self;
});
var TrailParticle = Container.expand(function () {
var self = Container.call(this);
var particleGfx = self.attachAsset('trailGlow', {
anchorX: 0.5,
anchorY: 0.5
});
self.life = 40;
self.maxLife = 40;
self.targetX = 0;
self.targetY = 0;
self.followSpeed = 0.12;
self.pulsePhase = Math.random() * Math.PI * 2;
self.update = function () {
// Follow target with smooth movement
self.x += (self.targetX - self.x) * self.followSpeed;
self.y += (self.targetY - self.y) * self.followSpeed;
self.life--;
self.pulsePhase += 0.15;
// Bright motion trail that pulses with beat
var fadeAlpha = self.life / self.maxLife;
var pulseEffect = 1 + Math.sin(self.pulsePhase) * 0.3 + beatPulse * 0.4;
particleGfx.alpha = fadeAlpha * 0.8 * pulseEffect;
var scale = fadeAlpha * 1.2 * pulseEffect;
particleGfx.scaleX = scale;
particleGfx.scaleY = scale;
// Color matches player's current color and game phase
if (gamePhase === 5) {
particleGfx.tint = player ? player.comboStreakColor : 0x00ccff; // Aqua blue
} else if (gamePhase === 4) {
particleGfx.tint = player ? player.comboStreakColor : 0xff3333; // Mario red
} else if (gamePhase === 3) {
particleGfx.tint = player ? player.comboStreakColor : 0xffee99;
} else if (gamePhase === 2) {
particleGfx.tint = player ? player.comboStreakColor : 0xff8800;
} else {
particleGfx.tint = player ? player.comboStreakColor : 0x00aaff;
}
if (self.life <= 0) {
self.shouldDestroy = true;
}
};
return self;
});
var Tree = Container.expand(function () {
var self = Container.call(this);
// Tree trunk
var trunk = self.attachAsset('tree', {
anchorX: 0.5,
anchorY: 1
});
// Tree leaves
var leaves = self.attachAsset('treeLeaves', {
anchorX: 0.5,
anchorY: 1
});
leaves.y = -120;
leaves.scaleX = 1.8;
leaves.scaleY = 1.8;
// Larger trunk for nature phase
trunk.scaleX = 1.5;
trunk.scaleY = 1.5;
self.speed = -6;
self.swayPhase = Math.random() * Math.PI * 2;
self.update = function () {
self.x += self.speed;
// Gentle swaying animation
self.swayPhase += 0.03;
var sway = Math.sin(self.swayPhase) * 0.1;
trunk.rotation = sway;
leaves.rotation = sway * 1.5;
// Slight scale variation for life
var breathe = 1 + Math.sin(self.swayPhase * 0.7) * 0.05;
leaves.scaleX = 1.8 * breathe;
leaves.scaleY = 1.8 * breathe;
};
return self;
});
var WaterCurrent = Container.expand(function () {
var self = Container.call(this);
var currentGfx = self.attachAsset('waterCurrent', {
anchorX: 0,
anchorY: 0.5
});
self.speed = -2 - Math.random() * 3;
self.flowPhase = Math.random() * Math.PI * 2;
self.baseAlpha = 0.3 + Math.random() * 0.2;
self.update = function () {
self.x += self.speed;
self.flowPhase += 0.1;
currentGfx.alpha = self.baseAlpha + Math.sin(self.flowPhase) * 0.2;
currentGfx.scaleY = 0.8 + Math.sin(self.flowPhase * 1.5) * 0.4;
var colorShift = Math.floor(Math.sin(self.flowPhase) * 40);
currentGfx.tint = 0x4488aa + (colorShift << 4);
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x0a0520
});
/****
* Game Code
****/
// Game variables
var player;
var playerLives = 3;
var maxLives = 5;
var hearts = [];
var heartSpawnTimer = 0;
var heartSpawnInterval = 900; // 15 seconds at 60fps
var lifePopupTimer = 0;
var lifePopupText = null;
var collisionCooldown = 0; // Prevent rapid successive damage
var invincibilityFrames = 0; // Global invincibility system
var maxInvincibilityFrames = 120; // 2 seconds at 60fps
var isPlayerFlashing = false;
var obstacles = [];
var rotatingCubes = [];
var laserBeams = [];
var explosionParts = [];
var shatterParts = [];
var particles = [];
var trailParticles = [];
var ambientParticles = [];
var burstParticles = [];
var backgroundShapes = [];
var lightLines = [];
var dataStreamParticles = [];
var holographicElements = [];
var groundLevel = 2200;
var gameSpeed = 6;
var spawnTimer = 0;
var beatTimer = 0;
var beatInterval = 60; // 60 frames = 1 second at 60fps
var beatPulse = 0;
var combo = 0;
var perfectHits = 0;
var trailTimer = 0;
var ambientTimer = 0;
var bgShapeTimer = 0;
var lightLineTimer = 0;
var dataStreamTimer = 0;
var holographicTimer = 0;
// Game phase variables - fixed progression
var gamePhase = 1; // 1 = normal, 2 = speed phase at 1000 points, 3 = sky level at 2000 points, 4 = nature phase at 3000 points
var speedTransitioned = false;
var skyTransitioned = false;
var natureTransitioned = false;
var underwaterTransitioned = false;
// Underwater phase elements
var bubbles = [];
var fish = [];
var seaweed = [];
var corals = [];
var waterCurrents = [];
var underwaterPlatformTop = null;
var underwaterPlatformBottom = null;
var bubbleTimer = 0;
var fishSpawnTimer = 0;
var seaweedSpawnTimer = 0;
var coralSpawnTimer = 0;
var currentSpawnTimer = 0;
var clouds = [];
var sunRays = [];
var seagulls = [];
var sunRayTimer = 0;
var cloudSpawnTimer = 0;
var seagullSpawnTimer = 0;
// Nature phase elements
var trees = [];
var rocks = [];
var bushes = [];
var waterPuddles = [];
var natureGround = [];
var treeSpawnTimer = 0;
var rockSpawnTimer = 0;
var bushSpawnTimer = 0;
var puddleSpawnTimer = 0;
// Camera variables
var cameraTargetX = 0;
var cameraTargetY = 0;
var cameraShakeIntensity = 0;
var cameraShakeDecay = 0.9;
var cameraZoom = 1;
var cameraTargetZoom = 1;
var cameraFollowSpeed = 0.1;
// UI
var scoreText = new Text2('Score: 0', {
size: 80,
fill: 0x00FFFF
});
scoreText.anchor.set(0, 0);
scoreText.x = 100;
scoreText.y = 100;
LK.gui.topLeft.addChild(scoreText);
var comboText = new Text2('Combo: 0', {
size: 60,
fill: 0xFFFF00
});
comboText.anchor.set(0, 0);
comboText.x = 100;
comboText.y = 200;
LK.gui.topLeft.addChild(comboText);
// Lives display in top right - using heart symbols
var livesContainer = new Container();
livesContainer.x = -100;
livesContainer.y = 100;
LK.gui.topRight.addChild(livesContainer);
var heartSymbols = [];
function updateLivesDisplay() {
// Clear existing hearts
for (var i = 0; i < heartSymbols.length; i++) {
livesContainer.removeChild(heartSymbols[i]);
heartSymbols[i].destroy();
}
heartSymbols = [];
// Create heart symbols for current lives
for (var i = 0; i < playerLives; i++) {
var heartSymbol = LK.getAsset('heart', {
anchorX: 1,
anchorY: 0,
scaleX: 0.8,
scaleY: 0.8
});
heartSymbol.x = -i * 35;
heartSymbol.y = 0;
heartSymbol.tint = 0xff3366;
livesContainer.addChild(heartSymbol);
heartSymbols.push(heartSymbol);
}
}
// Initialize lives display
updateLivesDisplay();
// Create ground with shimmer effects
var ground = [];
for (var i = 0; i < 12; i++) {
var groundSegment = new GroundSegment();
groundSegment.x = i * 300;
groundSegment.y = groundLevel;
ground.push(groundSegment);
game.addChild(groundSegment);
}
// Create nature ground segments for phase 4
for (var i = 0; i < 15; i++) {
var natureGroundSegment = new NatureGroundSegment();
natureGroundSegment.x = i * 200 - 300; // Use 200px spacing for 500px wide segments to create 300px overlap
natureGroundSegment.y = groundLevel;
natureGround.push(natureGroundSegment);
game.addChild(natureGroundSegment);
// Initially hide nature ground
natureGroundSegment.visible = false;
}
// Create background container
var backgroundContainer = new Container();
game.addChild(backgroundContainer);
// Add custom nature background image
var natureBackgroundImage = LK.getAsset('natureBackground', {
anchorX: 0,
anchorY: 0,
scaleX: 1,
scaleY: 1,
x: -400
});
backgroundContainer.addChild(natureBackgroundImage);
// Initially hide the background
backgroundContainer.visible = false;
// Create player
player = new Player();
player.x = 300;
player.y = groundLevel - 30;
game.addChild(player);
// Background pulse effect
function updateBackgroundPulse() {
var intensity = beatPulse * 0.2;
var fastSection = gameSpeed > 8 ? 1 : 0; // Detect fast sections
if (gamePhase === 5) {
// Underwater phase - deep ocean blue with green tints
var baseRed = 10 + Math.floor(intensity * 20) + fastSection * 10;
var baseGreen = 60 + Math.floor(intensity * 40) + fastSection * 20;
var baseBlue = 120 + Math.floor(intensity * 60) + fastSection * 40;
} else if (gamePhase === 4) {
// Nature phase - Mario classic bright green and blue palette
var baseRed = 70 + Math.floor(intensity * 20) + fastSection * 10;
var baseGreen = 180 + Math.floor(intensity * 50) + fastSection * 30;
var baseBlue = 255;
} else if (gamePhase === 3) {
// Sky phase - gradient from soft blue to pinkish-purple
var baseRed = 180 + Math.floor(intensity * 40) + fastSection * 20;
var baseGreen = 220 + Math.floor(intensity * 20) + fastSection * 10;
var baseBlue = 255;
} else if (gamePhase === 2) {
// Speed phase - orange/red colors
var baseRed = 60 + Math.floor(intensity * 50) + fastSection * 40;
var baseGreen = 20 + Math.floor(intensity * 30) + fastSection * 20;
var baseBlue = 5 + Math.floor(intensity * 15) + fastSection * 10;
} else {
// Normal phase - deep black to dark purple with intensity variations
var baseRed = 10 + Math.floor(intensity * 30) + fastSection * 20;
var baseGreen = 5 + Math.floor(intensity * 20) + fastSection * 10;
var baseBlue = 32 + Math.floor(intensity * 40) + fastSection * 30;
}
var backgroundColor = baseRed << 16 | baseGreen << 8 | baseBlue;
game.setBackgroundColor(backgroundColor);
}
// Camera system with smooth scrolling and beat sync
function updateCamera() {
// Smooth camera follow player
cameraTargetX = -player.x + 400; // Offset to keep player visible
// Adjust vertical camera position based on game phase
if (gamePhase === 4) {
// Nature phase - much higher camera position for elevated view
cameraTargetY = -player.y + 1200; // Much higher view for nature phase
} else {
// Other phases - standard centering
cameraTargetY = -player.y + 1600; // Vertical centering
}
// Apply smooth camera movement
game.x += (cameraTargetX - game.x) * cameraFollowSpeed;
game.y += (cameraTargetY - game.y) * cameraFollowSpeed;
// Apply camera shake (disabled in nature phase)
if (cameraShakeIntensity > 0 && gamePhase !== 4) {
game.x += (Math.random() - 0.5) * cameraShakeIntensity;
game.y += (Math.random() - 0.5) * cameraShakeIntensity;
cameraShakeIntensity *= cameraShakeDecay;
}
// Beat-synced zoom effect with smooth interpolation (disabled in nature phase)
var beatZoomEffect = gamePhase === 4 ? 1 : 1 + beatPulse * 0.08; // Disable beat zoom in nature phase
// Base zoom levels for different phases
var baseZoom = 1.0;
if (gamePhase === 4) {
// Nature phase - zoomed in for closer detail
baseZoom = 1.3;
} else if (gamePhase === 3) {
// Sky level - slightly closer view
baseZoom = 1.15;
}
// Combine base zoom with beat effect
cameraTargetZoom = baseZoom * beatZoomEffect;
// Smooth zoom interpolation
cameraZoom += (cameraTargetZoom - cameraZoom) * 0.05;
game.scaleX = cameraZoom;
game.scaleY = cameraZoom;
}
// Spawn obstacles on beat
function spawnObstacle() {
if (gamePhase === 5) {
// Underwater phase - spawn aquatic obstacles
var obstacleType = Math.random();
if (obstacleType < 0.4) {
spawnFish();
} else if (obstacleType < 0.7) {
spawnSeaweed();
} else {
spawnCoral();
}
return;
} else if (gamePhase === 4) {
// Nature phase - spawn natural obstacles
var obstacleType = Math.random();
if (obstacleType < 0.5) {
spawnRock();
} else {
spawnBush();
}
return;
} else if (gamePhase === 3) {
// Sky level - mostly spawn clouds instead of obstacles
if (Math.random() < 0.3) {
spawnCloud();
}
return;
}
var obstacleType = Math.random();
if (obstacleType < 0.4) {
// Regular obstacle
var obstacle = new Obstacle();
obstacle.x = 2200;
obstacle.y = groundLevel;
obstacles.push(obstacle);
game.addChild(obstacle);
} else if (obstacleType < 0.7) {
// Rotating cube
var cube = new RotatingCube();
cube.x = 2200;
cube.y = groundLevel - 60 - Math.random() * 80;
rotatingCubes.push(cube);
game.addChild(cube);
} else {
// Laser beam
var laser = new LaserBeam();
laser.x = 2200;
laser.y = groundLevel - 200;
laserBeams.push(laser);
game.addChild(laser);
}
}
// Create player trail particles with limit
function createTrailParticles() {
trailTimer++;
if (trailTimer >= 4 && trailParticles.length < 15) {
// Limit to 15 trail particles
trailTimer = 0;
var trail = new TrailParticle();
trail.x = player.x + (Math.random() - 0.5) * 20;
trail.y = player.y + (Math.random() - 0.5) * 20;
trail.targetX = player.x - 50;
trail.targetY = player.y + 10;
trailParticles.push(trail);
game.addChild(trail);
}
}
// Create radial burst particles for perfect hits
function createPerfectBurst(x, y, color) {
for (var i = 0; i < 12; i++) {
var angle = i / 12 * Math.PI * 2;
var speed = 8 + Math.random() * 4;
var burst = new BurstParticle();
burst.x = x;
burst.y = y;
burst.velocityX = Math.cos(angle) * speed;
burst.velocityY = Math.sin(angle) * speed;
var burstGfx = burst.children[0];
burstGfx.tint = color;
burstParticles.push(burst);
game.addChild(burst);
}
}
// Create ambient floating particles with limit
function createAmbientParticles() {
ambientTimer++;
if (ambientTimer >= 30 && ambientParticles.length < 20) {
// Limit to 20 ambient particles
ambientTimer = 0;
var ambient = new AmbientParticle();
ambient.x = player.x + 1200 + Math.random() * 400;
ambient.y = Math.random() * 2732;
var ambientGfx = ambient.children[0];
ambientGfx.tint = 0x888888 + Math.floor(Math.random() * 0x444444);
ambientParticles.push(ambient);
game.addChild(ambient);
}
}
// Create beat-synced particle wave
function createBeatWave() {
for (var i = 0; i < 8; i++) {
var wave = new BurstParticle();
wave.x = -200 + i * 300;
wave.y = groundLevel - 100;
wave.velocityX = 6;
wave.velocityY = -2 + (Math.random() - 0.5) * 4;
wave.life = 60;
wave.maxLife = 60;
var waveGfx = wave.children[0];
waveGfx.tint = 0x00ffff;
burstParticles.push(wave);
game.addChild(wave);
}
}
// Create background abstract shapes
function createBackgroundShapes() {
bgShapeTimer++;
if (bgShapeTimer >= 120) {
bgShapeTimer = 0;
var bgShape = new BackgroundShape();
bgShape.x = 2200 + Math.random() * 400;
bgShape.y = Math.random() * 2000;
backgroundShapes.push(bgShape);
game.addChild(bgShape);
}
}
// Create flowing light lines
function createLightLines() {
lightLineTimer++;
if (lightLineTimer >= 180) {
lightLineTimer = 0;
var lightLine = new LightLine();
lightLine.x = 2200;
lightLine.y = Math.random() * 2732;
lightLine.rotation = (Math.random() - 0.5) * 0.5;
lightLines.push(lightLine);
game.addChild(lightLine);
}
}
// Create data stream particles
function createDataStreamParticles() {
dataStreamTimer++;
if (dataStreamTimer >= 15) {
dataStreamTimer = 0;
var dataStream = new DataStreamParticle();
dataStream.x = 2200 + Math.random() * 200;
dataStream.y = Math.random() * 2732;
dataStreamParticles.push(dataStream);
game.addChild(dataStream);
}
}
// Create holographic musical elements
function createHolographicElements() {
holographicTimer++;
if (holographicTimer >= 600) {
// Less frequent appearance
holographicTimer = 0;
var holographic = new HolographicElement();
holographic.x = 1500 + Math.random() * 800;
holographic.y = 200 + Math.random() * 1800;
holographicElements.push(holographic);
game.addChild(holographic);
}
}
// Create explosion effect when obstacle is destroyed
function createExplosion(x, y, color) {
for (var i = 0; i < 8; i++) {
var explosion = new ExplosionPart();
explosion.x = x + (Math.random() - 0.5) * 40;
explosion.y = y + (Math.random() - 0.5) * 40;
explosion.velocityX = (Math.random() - 0.5) * 12;
explosion.velocityY = -Math.random() * 8 - 2;
explosion.rotationSpeed = (Math.random() - 0.5) * 0.3;
var explosionGfx = explosion.children[0];
explosionGfx.tint = color;
explosionParts.push(explosion);
game.addChild(explosion);
}
}
// Create shatter effect when obstacle breaks
function createShatter(x, y, originalColor) {
for (var i = 0; i < 6; i++) {
var shatter = new ShatterPart();
shatter.x = x + (Math.random() - 0.5) * 30;
shatter.y = y + (Math.random() - 0.5) * 30;
shatter.velocityX = (Math.random() - 0.5) * 8;
shatter.velocityY = -Math.random() * 6 - 1;
shatter.rotationSpeed = (Math.random() - 0.5) * 0.2;
var shatterGfx = shatter.children[0];
shatterGfx.tint = originalColor;
shatterParts.push(shatter);
game.addChild(shatter);
}
}
// Spawn floating clouds for sky level
function spawnCloud() {
var cloud = new Cloud();
cloud.x = 2200;
cloud.y = groundLevel - 100 - Math.random() * 300;
clouds.push(cloud);
game.addChild(cloud);
}
// Create warm sunlight rays
function createSunRays() {
sunRayTimer++;
if (sunRayTimer >= 400) {
sunRayTimer = 0;
var sunRay = new SunRay();
sunRay.x = 1800 + Math.random() * 600;
sunRay.y = 200 + Math.random() * 800;
sunRays.push(sunRay);
game.addChild(sunRay);
}
}
// Create flying seagulls above clouds
function spawnSeagull() {
var seagull = new Seagull();
seagull.x = 2200 + Math.random() * 200;
seagull.y = groundLevel - 450 - Math.random() * 200; // Spawn 450-650 pixels above ground, well above clouds
seagull.baseY = seagull.y;
seagulls.push(seagull);
game.addChild(seagull);
}
// Nature phase spawning functions
function spawnTree() {
var tree = new Tree();
tree.x = 2200;
tree.y = groundLevel;
trees.push(tree);
game.addChild(tree);
}
function spawnRock() {
var rock = new Rock();
rock.x = 2200;
rock.y = groundLevel;
rocks.push(rock);
game.addChild(rock);
}
function spawnBush() {
var bush = new Bush();
bush.x = 2200;
bush.y = groundLevel;
bushes.push(bush);
game.addChild(bush);
}
// Spawn heart pickup
// Underwater phase spawning functions
function spawnBubbles() {
for (var i = 0; i < 3; i++) {
var bubble = new Bubble();
bubble.x = player.x + 1000 + Math.random() * 500;
bubble.y = groundLevel + Math.random() * 400;
bubbles.push(bubble);
game.addChild(bubble);
}
}
function spawnFish() {
var fishObj = new Fish();
fishObj.x = 2200;
// Spawn fish at player's walking level (ground level)
fishObj.y = groundLevel - 30 - Math.random() * 50; // At player's height
fishObj.baseY = fishObj.y;
fish.push(fishObj);
game.addChild(fishObj);
}
function spawnSeaweed() {
var seaweedObj = new Seaweed();
seaweedObj.x = 2200;
// Spawn seaweed at ground level where player walks
seaweedObj.y = groundLevel;
seaweed.push(seaweedObj);
game.addChild(seaweedObj);
}
function spawnCoral() {
var coral = new Coral();
coral.x = 2200;
// Spawn coral at ground level where player walks
coral.y = groundLevel;
corals.push(coral);
game.addChild(coral);
}
function spawnWaterCurrent() {
var current = new WaterCurrent();
current.x = 2200;
// Spawn water currents between underwater platforms (y=950 to y=1782)
current.y = 950 + Math.random() * (1782 - 950);
waterCurrents.push(current);
game.addChild(current);
}
function spawnHeart() {
var heart = new Heart();
heart.x = 2200;
// Spawn hearts above clouds in sky level (where seagulls are)
if (gamePhase === 3) {
// Sky level - spawn above clouds, at seagull level
heart.y = groundLevel - 450 - Math.random() * 200; // Same height as seagulls
} else {
// Normal/speed phase - original position
heart.y = groundLevel - 200 - Math.random() * 300;
}
hearts.push(heart);
game.addChild(heart);
}
// Create life gain popup
function showLifeGainPopup(amount) {
if (lifePopupText) {
lifePopupText.destroy();
}
var popupText = '+' + amount + ' LIFE';
lifePopupText = new Text2(popupText, {
size: 80,
fill: 0xff3366
});
lifePopupText.anchor.set(0.5, 0.5);
lifePopupText.x = 1024;
lifePopupText.y = 1000;
lifePopupText.alpha = 0;
game.addChild(lifePopupText);
// Animate popup
tween(lifePopupText, {
alpha: 1,
y: 800
}, {
duration: 300,
easing: tween.easeOut
});
// Fade out after showing
LK.setTimeout(function () {
if (lifePopupText) {
tween(lifePopupText, {
alpha: 0,
y: 600
}, {
duration: 500,
easing: tween.easeIn,
onFinish: function onFinish() {
if (lifePopupText) {
lifePopupText.destroy();
lifePopupText = null;
}
}
});
}
}, 1500);
lifePopupTimer = 120; // 2 seconds
}
// Create score popup
var scorePopupText = null;
function showScorePopup(points) {
if (scorePopupText) {
scorePopupText.destroy();
}
var popupText = '+' + points;
scorePopupText = new Text2(popupText, {
size: 70,
fill: 0x00ff00
});
scorePopupText.anchor.set(0.5, 0.5);
scorePopupText.x = player.x;
scorePopupText.y = player.y - 200;
scorePopupText.alpha = 0;
game.addChild(scorePopupText);
// Animate popup
tween(scorePopupText, {
alpha: 1,
y: player.y - 250
}, {
duration: 250,
easing: tween.easeOut
});
// Fade out after showing
LK.setTimeout(function () {
if (scorePopupText) {
tween(scorePopupText, {
alpha: 0,
y: player.y - 250
}, {
duration: 400,
easing: tween.easeIn,
onFinish: function onFinish() {
if (scorePopupText) {
scorePopupText.destroy();
scorePopupText = null;
}
}
});
}
}, 1000);
}
// Check collisions
function checkCollisions() {
// Regular obstacle collisions
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
if (player.intersects(obstacle)) {
if (player.isDashing) {
// Destroy obstacle with explosion effect
createExplosion(obstacle.x, obstacle.y, 0xff4400);
createShatter(obstacle.x, obstacle.y, 0xff0044);
LK.getSound('successHit').play();
var scoreGain = 25;
LK.setScore(LK.getScore() + scoreGain);
showScorePopup(scoreGain);
combo++;
} else if (invincibilityFrames === 0) {
// Only take damage if not invincible
LK.getSound('loseLife').play();
LK.effects.flashScreen(0xff0000, 500);
combo = 0;
playerLives--;
updateLivesDisplay();
// Start invincibility period
invincibilityFrames = maxInvincibilityFrames;
// Intense camera shake on collision
cameraShakeIntensity = 20;
tween(game, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(game, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 400,
easing: tween.easeInOut
});
}
});
}
// Remove obstacle
obstacle.destroy();
obstacles.splice(i, 1);
}
}
// Rotating cube collisions
for (var i = rotatingCubes.length - 1; i >= 0; i--) {
var cube = rotatingCubes[i];
if (player.intersects(cube)) {
if (player.isDashing) {
// Destroy cube with spectacular explosion
createExplosion(cube.x, cube.y, 0xff8800);
createShatter(cube.x, cube.y, 0xff4400);
LK.getSound('successHit').play();
var scoreGain = 35;
LK.setScore(LK.getScore() + scoreGain);
showScorePopup(scoreGain);
combo++;
cameraShakeIntensity = 8;
} else if (invincibilityFrames === 0) {
// Only take damage if not invincible
LK.getSound('loseLife').play();
LK.effects.flashScreen(0xff0000, 500);
combo = 0;
playerLives--;
updateLivesDisplay();
// Start invincibility period
invincibilityFrames = maxInvincibilityFrames;
cameraShakeIntensity = 25;
}
cube.destroy();
rotatingCubes.splice(i, 1);
}
}
// Laser beam collisions
for (var i = laserBeams.length - 1; i >= 0; i--) {
var laser = laserBeams[i];
if (laser.isActive && player.intersects(laser) && invincibilityFrames === 0) {
// Only take damage if not invincible
LK.getSound('loseLife').play();
LK.effects.flashScreen(0xff0088, 600);
combo = 0;
playerLives--;
updateLivesDisplay();
// Start invincibility period
invincibilityFrames = maxInvincibilityFrames;
cameraShakeIntensity = 30;
// Create explosion at collision point
createExplosion(player.x, player.y, 0xff0088);
// Remove laser
laser.destroy();
laserBeams.splice(i, 1);
}
}
// Cloud collisions for sky level
for (var i = clouds.length - 1; i >= 0; i--) {
var cloud = clouds[i];
if (player.intersects(cloud)) {
// Landing on cloud
if (player.velocityY > 0 && player.y < cloud.y) {
player.y = cloud.y - 30;
player.velocityY = 0; // Stop bouncing
player.isGrounded = true; // Enable jumping
player.canDoubleJump = false; // Reset to allow first jump from cloud
player.hasUsedDoubleJump = false;
player.hasJumped = false; // Reset jump flag when landing on cloud
cloud.bounce();
// Soft landing sound effect
if (Math.random() < 0.5) {
LK.getSound('windWhoosh').play();
}
LK.setScore(LK.getScore() + 15);
}
}
}
// Seagull collisions - can land on seagulls
for (var i = seagulls.length - 1; i >= 0; i--) {
var seagull = seagulls[i];
if (player.intersects(seagull)) {
// Landing on seagull
if (player.velocityY > 0 && player.y < seagull.y) {
player.y = seagull.y - 35;
player.velocityY = 0;
player.isGrounded = true;
player.canDoubleJump = false; // Reset to allow first jump from seagull
player.hasUsedDoubleJump = false;
player.hasJumped = false; // Reset jump flag when landing on seagull
// Gentle landing sound
if (Math.random() < 0.3) {
LK.getSound('echoChime').play();
}
LK.setScore(LK.getScore() + 20);
}
}
}
// Rock collisions (nature phase) - rocks always damage player
for (var i = rocks.length - 1; i >= 0; i--) {
var rock = rocks[i];
if (player.intersects(rock)) {
if (player.isDashing) {
// Destroy rock with explosion effect
createExplosion(rock.x, rock.y, 0x696969);
createShatter(rock.x, rock.y, 0x696969);
LK.getSound('successHit').play();
var scoreGain = 30;
LK.setScore(LK.getScore() + scoreGain);
showScorePopup(scoreGain);
combo++;
} else if (invincibilityFrames === 0) {
// Only take damage if not invincible
LK.getSound('loseLife').play();
LK.effects.flashScreen(0xff0000, 500);
combo = 0;
playerLives--;
updateLivesDisplay();
// Start invincibility period
invincibilityFrames = maxInvincibilityFrames;
cameraShakeIntensity = 20;
}
rock.destroy();
rocks.splice(i, 1);
}
}
// Bush collisions (nature phase) - bushes damage player
for (var i = bushes.length - 1; i >= 0; i--) {
var bush = bushes[i];
if (player.intersects(bush)) {
if (player.isDashing) {
// Destroy bush with green explosion
createExplosion(bush.x, bush.y, 0x228B22);
LK.getSound('successHit').play();
var scoreGain = 20;
LK.setScore(LK.getScore() + scoreGain);
showScorePopup(scoreGain);
combo++;
} else if (invincibilityFrames === 0) {
// Only take damage if not invincible
LK.getSound('loseLife').play();
LK.effects.flashScreen(0xff0000, 500);
combo = 0;
playerLives--;
updateLivesDisplay();
// Start invincibility period
invincibilityFrames = maxInvincibilityFrames;
cameraShakeIntensity = 15;
}
bush.destroy();
bushes.splice(i, 1);
}
}
// Tree collisions (nature phase) - tree trunks damage player
for (var i = trees.length - 1; i >= 0; i--) {
var tree = trees[i];
if (player.intersects(tree)) {
if (player.isDashing) {
// Destroy tree with explosion effect
createExplosion(tree.x, tree.y, 0x8B4513);
createShatter(tree.x, tree.y, 0x228B22);
LK.getSound('successHit').play();
var scoreGain = 40;
LK.setScore(LK.getScore() + scoreGain);
showScorePopup(scoreGain);
combo++;
tree.destroy();
trees.splice(i, 1);
} else if (invincibilityFrames === 0) {
// Tree trunk damages player (only if not invincible)
LK.getSound('loseLife').play();
LK.effects.flashScreen(0xff0000, 500);
combo = 0;
playerLives--;
updateLivesDisplay();
// Start invincibility period
invincibilityFrames = maxInvincibilityFrames;
cameraShakeIntensity = 20;
}
}
}
// Fish collisions (underwater phase)
for (var i = fish.length - 1; i >= 0; i--) {
var fishObj = fish[i];
if (player.intersects(fishObj)) {
if (player.isDashing) {
// Destroy fish with splash effect
createExplosion(fishObj.x, fishObj.y, 0xff6600);
LK.getSound('successHit').play();
var scoreGain = 25;
LK.setScore(LK.getScore() + scoreGain);
showScorePopup(scoreGain);
combo++;
} else if (invincibilityFrames === 0) {
LK.getSound('loseLife').play();
LK.effects.flashScreen(0xff0000, 500);
combo = 0;
playerLives--;
updateLivesDisplay();
invincibilityFrames = maxInvincibilityFrames;
cameraShakeIntensity = 20;
}
fishObj.destroy();
fish.splice(i, 1);
}
}
// Seaweed collisions (underwater phase)
for (var i = seaweed.length - 1; i >= 0; i--) {
var seaweedObj = seaweed[i];
if (player.intersects(seaweedObj)) {
if (player.isDashing) {
createExplosion(seaweedObj.x, seaweedObj.y, 0x228b22);
LK.getSound('successHit').play();
var scoreGain = 15;
LK.setScore(LK.getScore() + scoreGain);
showScorePopup(scoreGain);
combo++;
} else if (invincibilityFrames === 0) {
LK.getSound('loseLife').play();
LK.effects.flashScreen(0xff0000, 500);
combo = 0;
playerLives--;
updateLivesDisplay();
invincibilityFrames = maxInvincibilityFrames;
cameraShakeIntensity = 15;
}
seaweedObj.destroy();
seaweed.splice(i, 1);
}
}
// Coral collisions (underwater phase)
for (var i = corals.length - 1; i >= 0; i--) {
var coral = corals[i];
if (player.intersects(coral)) {
if (player.isDashing) {
createExplosion(coral.x, coral.y, 0xff69b4);
LK.getSound('successHit').play();
var scoreGain = 35;
LK.setScore(LK.getScore() + scoreGain);
showScorePopup(scoreGain);
combo++;
} else if (invincibilityFrames === 0) {
LK.getSound('loseLife').play();
LK.effects.flashScreen(0xff0000, 500);
combo = 0;
playerLives--;
updateLivesDisplay();
invincibilityFrames = maxInvincibilityFrames;
cameraShakeIntensity = 20;
}
coral.destroy();
corals.splice(i, 1);
}
}
// Heart pickup collisions
for (var i = hearts.length - 1; i >= 0; i--) {
var heart = hearts[i];
if (player.intersects(heart)) {
var livesGained = heart.isPulsing ? 2 : 1;
// Phase 3 (sky level) allows unlimited health collection for phase 4 preparation
if (gamePhase === 3) {
playerLives += livesGained; // No limit in sky phase
} else {
playerLives = Math.min(maxLives, playerLives + livesGained); // Normal limit for other phases
}
updateLivesDisplay();
// Play life gain sound
LK.getSound('gainLife').play();
// Show popup
showLifeGainPopup(livesGained);
// Create sparkle burst effect
createPerfectBurst(heart.x, heart.y, 0xff6699);
// Camera shake for life gain
cameraShakeIntensity = 8;
// Remove heart
heart.destroy();
hearts.splice(i, 1);
}
}
}
// Beat detection and rhythm mechanics
function updateBeat() {
beatTimer++;
// Simple beat simulation (in real game this would sync with music)
if (beatTimer >= beatInterval) {
beatTimer = 0;
beatPulse = 1;
// Make player react to every beat
if (player) {
player.reactToBeat();
}
// Beat-synced camera shake and zoom (disabled in nature phase)
if (gamePhase !== 4) {
cameraShakeIntensity = 8;
tween(game, {
scaleX: 1.08,
scaleY: 1.08
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(game, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 300,
easing: tween.easeInOut
});
}
});
}
// Spawn obstacles on beat
if (Math.random() < 0.7) {
spawnObstacle();
}
// Create beat-synced particle wave
createBeatWave();
}
// Beat pulse decay
beatPulse *= 0.9;
}
// Variable jump system
var jumpForce = -12; // Base jump force (reduced significantly)
var doubleJumpForce = -10; // Fixed double jump force (reduced significantly)
var isJumpPressed = false;
var jumpHoldTime = 0;
var maxJumpHoldTime = 20; // Maximum frames to hold jump
var minJumpForce = -8; // Minimum jump force (reduced significantly)
var maxJumpForce = -16; // Maximum jump force (reduced significantly)
// Touch controls with variable jump
game.down = function (x, y, obj) {
if (x < 1024) {
// Left side - start variable jump
isJumpPressed = true;
jumpHoldTime = 0;
// Start jump immediately
player.jump();
// Check if jump was on beat
if (player.velocityY !== 0 && beatPulse > 0.7) {
perfectHits++;
combo++;
var scoreBonus = player.hasUsedDoubleJump ? 15 : 10;
var totalScore = scoreBonus + combo * 2;
LK.setScore(LK.getScore() + totalScore);
showScorePopup(totalScore);
LK.getSound('successHit').play();
LK.effects.flashObject(player, 0x00ff00, 200);
cameraShakeIntensity = 5;
createPerfectBurst(player.x, player.y, 0x00ff00);
}
} else {
// Right side - dash
player.dash();
// Check if dash was on beat
if (beatPulse > 0.7) {
perfectHits++;
combo++;
var totalScore = 15 + combo * 3;
LK.setScore(LK.getScore() + totalScore);
showScorePopup(totalScore);
LK.getSound('successHit').play();
LK.effects.flashObject(player, 0xffff00, 200);
cameraShakeIntensity = 6;
createPerfectBurst(player.x, player.y, 0xffff00);
}
}
};
// Touch up handler - stop variable jump
game.up = function (x, y, obj) {
if (x < 1024) {
// Left side - stop jump hold
isJumpPressed = false;
jumpHoldTime = 0;
}
};
// Main game loop
game.update = function () {
updateBeat();
updateBackgroundPulse();
updateCamera();
// Update collision cooldown
if (collisionCooldown > 0) {
collisionCooldown--;
}
// Update invincibility frames and player flashing
if (invincibilityFrames > 0) {
invincibilityFrames--;
// Flash player during invincibility
var flashRate = 8; // Flash every 8 frames
if (Math.floor(invincibilityFrames / flashRate) % 2 === 0) {
player.alpha = 0.3; // Semi-transparent
} else {
player.alpha = 1.0; // Full opacity
}
// Enhanced glow effect during invincibility
var mainGlow = player.children[0]; // Get the mainGlow asset
if (mainGlow) {
// Make the glow much brighter and larger during invincibility
mainGlow.alpha = 0.8 + Math.sin(LK.ticks * 0.3) * 0.2; // Pulsing bright glow
mainGlow.scaleX = 2.5 + Math.sin(LK.ticks * 0.2) * 0.5; // Much larger scale
mainGlow.scaleY = 2.5 + Math.sin(LK.ticks * 0.2) * 0.5; // Much larger scale
mainGlow.tint = 0xffffff; // Pure white glow for maximum visibility
}
isPlayerFlashing = true;
} else {
// Restore normal appearance when invincibility ends
if (isPlayerFlashing) {
player.alpha = 1.0;
// Reset mainGlow to normal state
var mainGlow = player.children[0];
if (mainGlow) {
mainGlow.alpha = 0.2 + beatPulse * 0.3; // Back to normal glow
mainGlow.scaleX = 1 + Math.sin(player.glowPhase * 0.7) * 0.1 + beatPulse * 0.2; // Back to normal scale
mainGlow.scaleY = 1 + Math.sin(player.glowPhase * 0.7) * 0.1 + beatPulse * 0.2; // Back to normal scale
// Reset tint based on current game phase
if (gamePhase === 5) {
mainGlow.tint = 0x00ccff; // Aqua glow for underwater phase
} else if (gamePhase === 4) {
mainGlow.tint = 0xff6666; // Red glow for nature phase
} else if (gamePhase === 3) {
mainGlow.tint = 0xffee99; // Golden glow for sky phase
} else if (gamePhase === 2) {
mainGlow.tint = 0xff8800; // Orange glow for speed phase
} else {
mainGlow.tint = 0x0088ff; // Blue glow for normal phase
}
}
isPlayerFlashing = false;
}
}
checkCollisions();
// Update ground segments
for (var i = 0; i < ground.length; i++) {
if (ground[i].x <= -300) {
ground[i].x += 3600; // 12 * 300
}
}
// Update nature ground segments
for (var i = 0; i < natureGround.length; i++) {
if (natureGround[i].x <= -500) {
natureGround[i].x += 3000; // 15 * 200
}
}
// Update and remove obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
if (obstacles[i].x < -100) {
obstacles[i].destroy();
obstacles.splice(i, 1);
// Bonus points for passing obstacles
var scoreGain = 5;
LK.setScore(LK.getScore() + scoreGain);
showScorePopup(scoreGain);
}
}
// Update and remove rotating cubes
for (var i = rotatingCubes.length - 1; i >= 0; i--) {
if (rotatingCubes[i].x < -100) {
rotatingCubes[i].destroy();
rotatingCubes.splice(i, 1);
var scoreGain = 8;
LK.setScore(LK.getScore() + scoreGain);
showScorePopup(scoreGain);
}
}
// Update and remove laser beams
for (var i = laserBeams.length - 1; i >= 0; i--) {
if (laserBeams[i].x < -100) {
laserBeams[i].destroy();
laserBeams.splice(i, 1);
var scoreGain = 10;
LK.setScore(LK.getScore() + scoreGain);
showScorePopup(scoreGain);
}
}
// Update and remove explosion parts
for (var i = explosionParts.length - 1; i >= 0; i--) {
if (explosionParts[i].shouldDestroy) {
explosionParts[i].destroy();
explosionParts.splice(i, 1);
}
}
// Update and remove shatter parts
for (var i = shatterParts.length - 1; i >= 0; i--) {
if (shatterParts[i].shouldDestroy) {
shatterParts[i].destroy();
shatterParts.splice(i, 1);
}
}
// Update and remove particles
for (var i = particles.length - 1; i >= 0; i--) {
if (particles[i].shouldDestroy) {
particles[i].destroy();
particles.splice(i, 1);
}
}
// Update and remove trail particles
for (var i = trailParticles.length - 1; i >= 0; i--) {
if (trailParticles[i].shouldDestroy) {
trailParticles[i].destroy();
trailParticles.splice(i, 1);
}
}
// Update and remove burst particles
for (var i = burstParticles.length - 1; i >= 0; i--) {
if (burstParticles[i].shouldDestroy) {
burstParticles[i].destroy();
burstParticles.splice(i, 1);
}
}
// Update and remove ambient particles
for (var i = ambientParticles.length - 1; i >= 0; i--) {
if (ambientParticles[i].shouldDestroy) {
ambientParticles[i].destroy();
ambientParticles.splice(i, 1);
}
}
// Update and remove background shapes
for (var i = backgroundShapes.length - 1; i >= 0; i--) {
if (backgroundShapes[i].x < -200) {
backgroundShapes[i].destroy();
backgroundShapes.splice(i, 1);
}
}
// Update and remove light lines
for (var i = lightLines.length - 1; i >= 0; i--) {
if (lightLines[i].x < -500) {
lightLines[i].destroy();
lightLines.splice(i, 1);
}
}
// Update and remove data stream particles
for (var i = dataStreamParticles.length - 1; i >= 0; i--) {
if (dataStreamParticles[i].shouldDestroy || dataStreamParticles[i].x < -100) {
dataStreamParticles[i].destroy();
dataStreamParticles.splice(i, 1);
}
}
// Update and remove holographic elements
for (var i = holographicElements.length - 1; i >= 0; i--) {
if (holographicElements[i].shouldDestroy || holographicElements[i].x < -400) {
holographicElements[i].destroy();
holographicElements.splice(i, 1);
}
}
// Update and remove clouds
for (var i = clouds.length - 1; i >= 0; i--) {
if (clouds[i].x < -200) {
clouds[i].destroy();
clouds.splice(i, 1);
}
}
// Update and remove sun rays
for (var i = sunRays.length - 1; i >= 0; i--) {
if (sunRays[i].shouldDestroy || sunRays[i].x < -500) {
sunRays[i].destroy();
sunRays.splice(i, 1);
}
}
// Update and remove seagulls
for (var i = seagulls.length - 1; i >= 0; i--) {
if (seagulls[i].x < -100) {
seagulls[i].destroy();
seagulls.splice(i, 1);
}
}
// Update and remove hearts
for (var i = hearts.length - 1; i >= 0; i--) {
if (hearts[i].x < -100) {
hearts[i].destroy();
hearts.splice(i, 1);
}
}
// Update and remove underwater elements
for (var i = bubbles.length - 1; i >= 0; i--) {
if (bubbles[i].shouldDestroy || bubbles[i].x < -100) {
bubbles[i].destroy();
bubbles.splice(i, 1);
}
}
for (var i = fish.length - 1; i >= 0; i--) {
if (fish[i].x < -100) {
fish[i].destroy();
fish.splice(i, 1);
}
}
for (var i = seaweed.length - 1; i >= 0; i--) {
if (seaweed[i].x < -100) {
seaweed[i].destroy();
seaweed.splice(i, 1);
}
}
for (var i = corals.length - 1; i >= 0; i--) {
if (corals[i].x < -100) {
corals[i].destroy();
corals.splice(i, 1);
}
}
for (var i = waterCurrents.length - 1; i >= 0; i--) {
if (waterCurrents[i].x < -100) {
waterCurrents[i].destroy();
waterCurrents.splice(i, 1);
}
}
// Lives display is updated only when lives change
// Spawn hearts occasionally
heartSpawnTimer++;
if (heartSpawnTimer >= heartSpawnInterval) {
heartSpawnTimer = 0;
// Phase 3 allows unlimited heart spawning, other phases check maxLives limit
if (gamePhase === 3 || playerLives < maxLives) {
spawnHeart();
}
}
// Update life popup timer
if (lifePopupTimer > 0) {
lifePopupTimer--;
}
// Update and remove nature elements
for (var i = trees.length - 1; i >= 0; i--) {
if (trees[i].x < -100) {
trees[i].destroy();
trees.splice(i, 1);
}
}
for (var i = rocks.length - 1; i >= 0; i--) {
if (rocks[i].x < -100) {
rocks[i].destroy();
rocks.splice(i, 1);
}
}
for (var i = bushes.length - 1; i >= 0; i--) {
if (bushes[i].x < -100) {
bushes[i].destroy();
bushes.splice(i, 1);
}
}
// Create continuous particle effects
createTrailParticles();
createAmbientParticles();
// Create background environment effects
if (gamePhase === 5) {
// Underwater phase effects
bubbleTimer++;
if (bubbleTimer >= 40) {
bubbleTimer = 0;
spawnBubbles();
}
currentSpawnTimer++;
if (currentSpawnTimer >= 180) {
currentSpawnTimer = 0;
spawnWaterCurrent();
}
} else if (gamePhase === 4) {
// Nature phase effects
// Spawn trees for background
treeSpawnTimer++;
if (treeSpawnTimer >= 200) {
treeSpawnTimer = 0;
spawnTree();
}
} else if (gamePhase === 3) {
// Sky level effects
createSunRays();
// Spawn clouds regularly
cloudSpawnTimer++;
if (cloudSpawnTimer >= 150) {
cloudSpawnTimer = 0;
spawnCloud();
}
// Spawn seagulls occasionally above clouds
seagullSpawnTimer++;
if (seagullSpawnTimer >= 300 + Math.random() * 400) {
seagullSpawnTimer = 0;
spawnSeagull();
// Add elegant entrance animation
var newSeagull = seagulls[seagulls.length - 1];
newSeagull.alpha = 0;
tween(newSeagull, {
alpha: 0.9
}, {
duration: 1000,
easing: tween.easeOut
});
}
} else {
// Normal/speed phase effects
createBackgroundShapes();
createLightLines();
createDataStreamParticles();
createHolographicElements();
}
// Show/hide custom background based on game phase
if (gamePhase === 4) {
backgroundContainer.visible = true;
} else {
backgroundContainer.visible = false;
}
// Show/hide nature ground based on game phase
for (var i = 0; i < natureGround.length; i++) {
if (gamePhase === 4) {
natureGround[i].visible = true;
} else if (gamePhase === 5) {
natureGround[i].visible = false;
} else {
natureGround[i].visible = false;
}
}
// Show/hide underwater platforms based on game phase
if (underwaterPlatformTop) {
underwaterPlatformTop.visible = gamePhase === 5;
}
if (underwaterPlatformBottom) {
underwaterPlatformBottom.visible = gamePhase === 5;
}
// Update UI
scoreText.setText('Score: ' + LK.getScore());
comboText.setText('Combo: ' + combo);
// Update dash cooldown display
if (player.dashCooldown > 0) {
var cooldownProgress = player.dashCooldown / 120; // 120 is max cooldown
var secondsLeft = Math.ceil(player.dashCooldown / 60);
dashCooldownText.setText('DASH: ' + secondsLeft + 's');
dashCooldownText.fill = 0xff4400;
dashCooldownFill.scaleX = 0.8 * cooldownProgress;
dashCooldownFill.alpha = 0.8;
// Pulse effect when almost ready
if (player.dashCooldown <= 30) {
var pulseAlpha = 0.5 + Math.sin(LK.ticks * 0.3) * 0.3;
dashCooldownText.alpha = pulseAlpha;
dashCooldownFill.alpha = pulseAlpha;
} else {
dashCooldownText.alpha = 1;
}
} else {
dashCooldownText.setText('DASH READY');
dashCooldownText.fill = 0x00FF00;
dashCooldownText.alpha = 1;
dashCooldownFill.scaleX = 0;
dashCooldownFill.alpha = 0;
}
// Game over if no lives left
if (playerLives <= 0) {
LK.showGameOver();
}
// Gradually increase difficulty
if (LK.ticks % 1800 == 0) {
// Every 30 seconds
gameSpeed += 0.5;
beatInterval = Math.max(30, beatInterval - 2);
}
// Game over condition (if player falls off screen)
if (gamePhase === 3) {
// Sky level - portal respawn system
if (player.y > 2732 + 100) {
// Respawn from top with portal effect
player.y = -100;
player.velocityY = 0;
player.isGrounded = false;
// Portal effect
LK.effects.flashScreen(0xaaccff, 800);
cameraShakeIntensity = 15;
// Play whoosh sound for portal
LK.getSound('windWhoosh').play();
}
} else {
// Normal/speed phase - game over
if (player.y > 2732 + 100) {
LK.showGameOver();
}
}
// Speed phase transition at 1000 points
if (LK.getScore() >= 1000 && !speedTransitioned) {
speedTransitioned = true;
gamePhase = 2;
gameSpeed += 3; // Increase speed
beatInterval = Math.max(40, beatInterval - 10); // Faster beats
// Visual effects for speed phase
LK.effects.flashScreen(0xff8800, 1500);
cameraShakeIntensity = 15;
}
// Sky level transition at 2000 points - dreamy sky environment
if (LK.getScore() >= 2000 && !skyTransitioned) {
skyTransitioned = true;
gamePhase = 3;
// Hide ground segments for sky level
for (var i = 0; i < ground.length; i++) {
ground[i].visible = false;
}
// Also hide nature ground during sky phase
for (var i = 0; i < natureGround.length; i++) {
natureGround[i].visible = false;
}
// Adjust player position for sky level
groundLevel = 1800;
player.y = groundLevel - 30;
// Set camera zoom target for sky level
cameraTargetZoom = 1.15; // Slightly less zoom
// Transition to sky level ambient music with fade
LK.playMusic('skyLevelMusic', {
fade: {
start: 0,
end: 0.8,
duration: 2000
}
});
// Play ambient wind sound
LK.getSound('windWhoosh').play();
// Visual effect for sky transition
LK.effects.flashScreen(0xffffcc, 3000);
// Camera shake for transition
cameraShakeIntensity = 20;
}
// Nature phase transition at 3000 points - character returns to earth
if (LK.getScore() >= 3000 && !natureTransitioned) {
natureTransitioned = true;
gamePhase = 4;
// Hide regular ground segments and show nature ground
for (var i = 0; i < ground.length; i++) {
ground[i].visible = false;
}
for (var i = 0; i < natureGround.length; i++) {
natureGround[i].visible = true;
}
// Adjust ground level back to original
groundLevel = 2200;
player.y = groundLevel - 30;
// Set camera zoom for nature phase (closer view)
cameraTargetZoom = 1.3;
// Visual effect for nature transition
LK.effects.flashScreen(0x90EE90, 2500);
cameraShakeIntensity = 25;
// Play nature ambient sounds
LK.getSound('windWhoosh').play();
}
// Underwater phase transition at 4000 points - deep sea exploration
if (LK.getScore() >= 4000 && !underwaterTransitioned) {
underwaterTransitioned = true;
gamePhase = 5;
// Show nature ground for underwater floor
for (var i = 0; i < natureGround.length; i++) {
natureGround[i].visible = true;
// Tint darker for ocean floor
natureGround[i].tint = 0x004466;
}
// Create underwater platforms (top and bottom barriers)
if (!underwaterPlatformTop) {
underwaterPlatformTop = LK.getAsset('underwaterPlatformTop', {
anchorX: 0,
anchorY: 0,
x: -1024,
y: 800
});
game.addChild(underwaterPlatformTop);
}
if (!underwaterPlatformBottom) {
underwaterPlatformBottom = LK.getAsset('underwaterPlatformBottom', {
anchorX: 0,
anchorY: 1,
x: -1024,
y: 1932
});
game.addChild(underwaterPlatformBottom);
}
// Maintain ground level
groundLevel = 2200;
player.y = groundLevel - 30;
// Set camera zoom for underwater phase
cameraTargetZoom = 1.2;
// Transition to underwater ambient music
LK.playMusic('underwaterMusic', {
fade: {
start: 0,
end: 0.8,
duration: 2000
}
});
// Play bubble sound for transition
LK.getSound('bubbleSound').play();
// Visual effect for underwater transition
LK.effects.flashScreen(0x004466, 3000);
cameraShakeIntensity = 20;
}
// New win condition at higher score (moved to 5000)
if (LK.getScore() >= 5000) {
LK.showYouWin();
}
};
// Test button to get 1000 points instantly
var testButton = new Text2('1000 PTS', {
size: 50,
fill: 0xFFFF00
});
testButton.anchor.set(1, 0);
testButton.x = -20;
testButton.y = 20;
LK.gui.topRight.addChild(testButton);
// Add click handler for test button
testButton.down = function (x, y, obj) {
LK.setScore(LK.getScore() + 1000);
};
// Dash cooldown display
var dashCooldownContainer = new Container();
dashCooldownContainer.x = 100;
dashCooldownContainer.y = -150;
LK.gui.bottomLeft.addChild(dashCooldownContainer);
var dashCooldownText = new Text2('DASH READY', {
size: 50,
fill: 0x00FF00
});
dashCooldownText.anchor.set(0, 1);
dashCooldownContainer.addChild(dashCooldownText);
var dashCooldownBar = LK.getAsset('ground', {
anchorX: 0,
anchorY: 1,
scaleX: 0.8,
scaleY: 0.3
});
dashCooldownBar.y = -60;
dashCooldownBar.tint = 0x0088ff;
dashCooldownContainer.addChild(dashCooldownBar);
var dashCooldownFill = LK.getAsset('ground', {
anchorX: 0,
anchorY: 1,
scaleX: 0.8,
scaleY: 0.3
});
dashCooldownFill.y = -60;
dashCooldownFill.tint = 0xff8800;
dashCooldownContainer.addChild(dashCooldownFill);
// Start the music
LK.playMusic('mainBgMusic');
; ===================================================================
--- original.js
+++ change.js
@@ -878,11 +878,12 @@
if (self.y < 950) {
self.y = 950;
if (self.velocityY < 0) self.velocityY = 0;
}
- // Bottom platform collision - prevent player from going below it
- if (self.y > 1782) {
- self.y = 1782;
+ // Bottom platform collision - prevent player from going below it (account for player size)
+ if (self.y > 1752) {
+ // Moved up 30 pixels to account for player height
+ self.y = 1752;
if (self.velocityY > 0) self.velocityY = 0;
self.isGrounded = true;
}
}
@@ -1788,27 +1789,27 @@
}
function spawnFish() {
var fishObj = new Fish();
fishObj.x = 2200;
- // Spawn fish between underwater platforms (y=950 to y=1782)
- fishObj.y = 950 + Math.random() * (1782 - 950);
+ // Spawn fish at player's walking level (ground level)
+ fishObj.y = groundLevel - 30 - Math.random() * 50; // At player's height
fishObj.baseY = fishObj.y;
fish.push(fishObj);
game.addChild(fishObj);
}
function spawnSeaweed() {
var seaweedObj = new Seaweed();
seaweedObj.x = 2200;
- // Spawn seaweed between underwater platforms (y=950 to y=1782)
- seaweedObj.y = 950 + Math.random() * (1782 - 950);
+ // Spawn seaweed at ground level where player walks
+ seaweedObj.y = groundLevel;
seaweed.push(seaweedObj);
game.addChild(seaweedObj);
}
function spawnCoral() {
var coral = new Coral();
coral.x = 2200;
- // Spawn coral between underwater platforms (y=950 to y=1782)
- coral.y = 950 + Math.random() * (1782 - 950);
+ // Spawn coral at ground level where player walks
+ coral.y = groundLevel;
corals.push(coral);
game.addChild(coral);
}
function spawnWaterCurrent() {
2d rock for game. In-Game asset. 2d. High contrast. No shadows
agaç gövdesi 2d. In-Game asset. 2d. High contrast. No shadows
bush 2d. In-Game asset. 2d. High contrast. No shadows
nehiri kaldır
oxygen tank 2d. In-Game asset. 2d. High contrast. No shadows
shark shadow 2d. In-Game asset. 2d. High contrast. No shadows
2 yapraklı deniz yosunu 2d. In-Game asset. 2d. High contrast. No shadows
piranha 2d. In-Game asset. 2d. High contrast. No shadows
deniz mercanı 2d. In-Game asset. 2d. High contrast. No shadows
jump
Sound effect
dash
Sound effect
failureMiss
Sound effect
mainBgMusic
Music
skyLevelMusic
Music
speedMusic
Music
natureMusic
Music
jumpNature
Sound effect
jumpUnderwater
Sound effect
dashNature
Sound effect
dashUnderwater
Sound effect
underwaterMusic
Music
jumpSpeed
Sound effect
dashSpeed
Sound effect