User prompt
make game faster in every 100 points not 1000 points
User prompt
no souls collected, just score text
User prompt
make score and bonus and game over titles more matched with hell theme
User prompt
make image assets bigger by x1.3
User prompt
game should be faster in every 1000 points and should be more difficult in every 2000 points
User prompt
make it in every 25000 points
User prompt
make it in every 100 points
User prompt
add an episode just character is flowing for 5 seconds without obstacles or coin in every 1000 points
User prompt
make every image assets bigger as x 1.1
User prompt
failure sound play when character hits obstacles
User prompt
✅ Make angel counsel spawn extremely rare by making spawn chance 0.2%
User prompt
add a sound effect for the moments character fails
User prompt
angelcounsel should be so rare
User prompt
add little glows to powerups too like angel glow. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
add a sound effect for angel counsel. and angel counsel is not a power up. it s a helping hand so you do not need to catch it to take advantage of. but it should be so so so so rare
User prompt
add a sound effect for die
User prompt
randomly angel counsel shown up blue and white lights and for that moment character not Being harmed ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
remove paradise gate
User prompt
draw a blue wall line at the top of the screen, the gate to paradise. it should be on top of screen as always
User prompt
draw a blue wall line at the top of the screen, the gate to paradise, constantly moving forward with the game background
User prompt
on game over music should continue. with game over music asset.
User prompt
use hellmusic as background music. and game over music for the game over screen
User prompt
game over music should start when the character dies
User prompt
add a music slot for game over screen
User prompt
give a flying motion to main character ↪💡 Consider importing and using the following plugins: @upit/tween.v1
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Car = Container.expand(function () {
var self = Container.call(this);
var carGraphics = self.attachAsset('car', {
anchorX: 0.5,
anchorY: 0.5
});
self.targetLane = 1; // 0 = left, 1 = middle, 2 = right
self.currentLane = 1;
self.invincible = false;
self.invincibilityTimer = 0;
self.slowEffect = false;
self.slowTimer = 0;
self.shrinkObstacles = false;
self.shrinkTimer = 0;
self.flyingTimer = 0;
self.flyingOffset = 0;
self.baseY = 0;
self.update = function () {
// Smooth lane transitions
var targetX = getLaneX(self.targetLane);
if (Math.abs(self.x - targetX) > 5) {
self.x += (targetX - self.x) * 0.2;
} else {
self.x = targetX;
self.currentLane = self.targetLane;
}
// Handle invincibility
if (self.invincible) {
self.invincibilityTimer--;
carGraphics.alpha = self.invincibilityTimer % 10 < 5 ? 0.3 : 1.0;
carGraphics.tint = 0x00ffff;
if (self.invincibilityTimer <= 0) {
self.invincible = false;
carGraphics.alpha = 1.0;
carGraphics.tint = 0xffffff;
}
}
// Handle slow effect
if (self.slowEffect) {
self.slowTimer--;
if (self.slowTimer <= 0) {
self.slowEffect = false;
}
}
// Handle shrink obstacles effect
if (self.shrinkObstacles) {
self.shrinkTimer--;
if (self.shrinkTimer <= 0) {
self.shrinkObstacles = false;
}
}
// Flying motion effects
self.flyingTimer++;
// Gentle bobbing motion (up and down floating)
var bobAmount = Math.sin(self.flyingTimer * 0.08) * 15;
self.flyingOffset = bobAmount;
carGraphics.y = bobAmount;
// Subtle banking/tilting motion for flying effect
var tiltAmount = Math.sin(self.flyingTimer * 0.06) * 0.05;
carGraphics.rotation = tiltAmount;
// Gentle scale breathing for floating effect
var scaleBreath = 1.0 + Math.sin(self.flyingTimer * 0.04) * 0.02;
carGraphics.scaleX = scaleBreath;
carGraphics.scaleY = scaleBreath;
// Store base Y position for collision calculations
if (self.baseY === 0) {
self.baseY = self.y;
}
};
return self;
});
var Coin = Container.expand(function () {
var self = Container.call(this);
var coinGraphics = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
self.collected = false;
self.glowTimer = 0;
self.update = function () {
self.y += gameSpeed;
// Glowing effect
self.glowTimer++;
var scale = 1.0 + Math.sin(self.glowTimer * 0.2) * 0.2;
coinGraphics.scaleX = scale;
coinGraphics.scaleY = scale;
// Rotation effect
coinGraphics.rotation += 0.1;
};
return self;
});
var LavaBackground = Container.expand(function () {
var self = Container.call(this);
var lavaGraphics = self.attachAsset('lavaBackground', {
anchorX: 0.5,
anchorY: 0.5
});
self.pulseTimer = Math.random() * 100;
self.update = function () {
self.y += gameSpeed * 0.3;
// Enhanced pulsing dark lava effect with multiple layers
self.pulseTimer++;
var pulse = 1.0 + Math.sin(self.pulseTimer * 0.05) * 0.15;
var secondaryPulse = 1.0 + Math.sin(self.pulseTimer * 0.08) * 0.08;
lavaGraphics.scaleY = pulse * secondaryPulse;
lavaGraphics.scaleX = 1.0 + Math.sin(self.pulseTimer * 0.04) * 0.05;
// Enhanced color shifting for more realistic lava
var colorShift = Math.sin(self.pulseTimer * 0.03) * 0.3;
var redIntensity = Math.sin(self.pulseTimer * 0.02) * 0.2;
var baseColor = 0x1a0000;
var redComponent = Math.floor((0.1 + colorShift + redIntensity) * 255);
var greenComponent = Math.floor(Math.sin(self.pulseTimer * 0.025) * 0.1 * 255);
lavaGraphics.tint = (redComponent << 16) + (greenComponent << 8);
// Slight rotation for flowing effect
lavaGraphics.rotation = Math.sin(self.pulseTimer * 0.01) * 0.02;
// Reset position when off screen
if (self.y > 2732 + 150) {
self.y = -150;
}
};
return self;
});
var LavaStream = Container.expand(function () {
var self = Container.call(this);
var streamGraphics = self.attachAsset('lavaStream', {
anchorX: 0.5,
anchorY: 0.5
});
self.flowTimer = Math.random() * 200;
self.update = function () {
self.y += gameSpeed * 0.5;
// Enhanced flowing lava effect with realistic motion
self.flowTimer++;
var flow = Math.sin(self.flowTimer * 0.08) * 0.08;
var crossFlow = Math.sin(self.flowTimer * 0.06) * 0.03;
streamGraphics.rotation = flow;
streamGraphics.skewX = crossFlow;
// Multi-layered intensity variation
var intensity = 1.0 + Math.sin(self.flowTimer * 0.06) * 0.4;
var secondaryIntensity = 1.0 + Math.sin(self.flowTimer * 0.09) * 0.2;
streamGraphics.alpha = 0.3 + intensity * secondaryIntensity * 0.25;
// Scale variation for bubbling effect
var scaleVar = 1.0 + Math.sin(self.flowTimer * 0.07) * 0.1;
streamGraphics.scaleX = scaleVar;
// Color variation for hot lava
var heatShift = Math.sin(self.flowTimer * 0.05) * 0.3;
var redHeat = Math.floor((0.2 + heatShift) * 255);
streamGraphics.tint = (redHeat << 16) + (Math.floor(heatShift * 0.5 * 255) << 8);
// Reset position when off screen
if (self.y > 2732 + 200) {
self.y = -200;
}
};
return self;
});
var Obstacle = Container.expand(function (type) {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset(type, {
anchorX: 0.5,
anchorY: 0.5
});
self.type = type;
self.shrunk = false;
self.update = function () {
self.y += car.slowEffect ? gameSpeed * 0.5 : gameSpeed;
// Apply shrink effect if active
if (car.shrinkObstacles && !self.shrunk) {
self.shrunk = true;
tween(obstacleGraphics, {
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 300
});
} else if (!car.shrinkObstacles && self.shrunk) {
self.shrunk = false;
tween(obstacleGraphics, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 300
});
}
// Animated effects for different obstacles
if (self.type === 'demon') {
obstacleGraphics.rotation += 0.05;
} else if (self.type === 'demonWing') {
var flap = Math.sin(LK.ticks * 0.3) * 0.3;
obstacleGraphics.scaleY = (self.shrunk ? 0.5 : 1.0) + flap;
} else if (self.type === 'firePit') {
var flicker = 1.0 + Math.sin(LK.ticks * 0.4) * 0.15;
var scale = self.shrunk ? 0.5 : 1.0;
obstacleGraphics.scaleX = scale * flicker;
obstacleGraphics.scaleY = scale * flicker;
// Add intense flickering effect with tween
if (LK.ticks % 120 === 0) {
tween(obstacleGraphics, {
alpha: 0.6
}, {
duration: 150,
onFinish: function onFinish() {
tween(obstacleGraphics, {
alpha: 1.0
}, {
duration: 150
});
}
});
}
// Play fire sound occasionally
if (LK.ticks % 240 === 0 && Math.random() < 0.3) {
LK.getSound('fireFlicker').play();
}
// Color shifting for fire effect
var heatColor = Math.sin(LK.ticks * 0.3) * 0.3;
var redIntensity = Math.floor((0.8 + heatColor) * 255);
var yellowIntensity = Math.floor(heatColor * 0.6 * 255);
obstacleGraphics.tint = (redIntensity << 16) + (yellowIntensity << 8);
} else if (self.type === 'skull') {
// Add haunting motion to skeleton/skull
var sway = Math.sin(LK.ticks * 0.1) * 0.03;
var bob = Math.sin(LK.ticks * 0.15) * 0.02;
obstacleGraphics.rotation = sway;
obstacleGraphics.skewY = bob;
// Periodic ghostly fade effect
if (LK.ticks % 180 === 0) {
tween(obstacleGraphics, {
alpha: 0.7
}, {
duration: 300,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(obstacleGraphics, {
alpha: 1.0
}, {
duration: 300,
easing: tween.easeInOut
});
}
});
}
// Play skull moan sound occasionally
if (LK.ticks % 300 === 0 && Math.random() < 0.2) {
LK.getSound('skullMoan').play();
}
// Slight scale breathing effect
var breathe = 1.0 + Math.sin(LK.ticks * 0.08) * 0.05;
var currentScale = self.shrunk ? 0.5 : 1.0;
obstacleGraphics.scaleX = currentScale * breathe;
obstacleGraphics.scaleY = currentScale * breathe;
}
};
return self;
});
var ParadiseGate = Container.expand(function () {
var self = Container.call(this);
var gateGraphics = self.attachAsset('paradiseGate', {
anchorX: 0.5,
anchorY: 0.5
});
self.glowTimer = 0;
self.update = function () {
self.y += gameSpeed;
// Add heavenly glow effect
self.glowTimer++;
var glow = 1.0 + Math.sin(self.glowTimer * 0.1) * 0.3;
gateGraphics.scaleY = glow;
// Subtle color shifting for divine effect
var colorShift = Math.sin(self.glowTimer * 0.05) * 0.2;
var blueIntensity = Math.floor((0.4 + colorShift) * 255);
var cyanIntensity = Math.floor((0.6 + colorShift) * 255);
gateGraphics.tint = (blueIntensity << 8) + cyanIntensity;
// Reset position when off screen
if (self.y > 2732 + 40) {
self.y = -40;
}
};
return self;
});
var PowerUp = Container.expand(function (type) {
var self = Container.call(this);
var assetName = type + 'PowerUp';
var powerUpGraphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
self.type = type;
self.collected = false;
self.update = function () {
self.y += gameSpeed;
// Spinning effect
powerUpGraphics.rotation += 0.1;
// Pulsing effect
var pulse = 1.2 + Math.sin(LK.ticks * 0.2) * 0.3;
powerUpGraphics.scaleX = pulse;
powerUpGraphics.scaleY = pulse;
};
return self;
});
var Road = Container.expand(function () {
var self = Container.call(this);
var roadGraphics = self.attachAsset('road', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
self.y += gameSpeed;
// Reset position when off screen
if (self.y > 2732 + 75) {
self.y = -75;
}
};
return self;
});
var SideObstacle = Container.expand(function (side, type) {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset(type, {
anchorX: 0.5,
anchorY: 0.5
});
self.side = side; // 'left' or 'right'
self.type = type;
self.speedX = side === 'left' ? 6 : -6;
self.startX = side === 'left' ? -100 : 2148;
self.targetX = side === 'left' ? 600 : 1448;
self.x = self.startX;
self.active = false;
self.update = function () {
self.y += gameSpeed * 0.8;
if (!self.active && self.x !== self.targetX) {
self.x += self.speedX;
if (self.side === 'left' && self.x >= self.targetX || self.side === 'right' && self.x <= self.targetX) {
self.x = self.targetX;
self.active = true;
// Add tween animation when reaching target
tween(obstacleGraphics, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 400,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(obstacleGraphics, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 400,
easing: tween.easeInOut
});
}
});
}
}
// Add type-specific animations
if (self.type === 'demon') {
obstacleGraphics.rotation += 0.03;
} else if (self.type === 'firePit') {
var flicker = 1.0 + Math.sin(LK.ticks * 0.5) * 0.1;
obstacleGraphics.scaleX *= flicker;
obstacleGraphics.scaleY *= flicker;
}
};
return self;
});
var Wall = Container.expand(function (side) {
var self = Container.call(this);
var wallGraphics = self.attachAsset('wall', {
anchorX: 0.5,
anchorY: 0.5
});
self.side = side; // 'left' or 'right'
self.update = function () {
self.y += gameSpeed;
// Reset position when off screen
if (self.y > 2732 + 50) {
self.y = -50;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Game variables
var gameSpeed = 8;
var baseSpeed = 8;
var car;
var coins = [];
var obstacles = [];
var powerUps = [];
var roads = [];
var walls = [];
var sideObstacles = [];
var lavaBackgrounds = [];
var lavaStreams = [];
var paradiseGates = [];
var backgroundColorPhase = 0; // 0=red, 1=purple, 2=black
var difficultyTimer = 0;
var devilEventTimer = 0;
var shakeTimer = 0;
var spawnTimer = 0;
var powerUpSpawnTimer = 0;
var sideObstacleSpawnTimer = 0;
// Lane obstacle tracking to prevent overcrowding
var laneObstacleCounts = [0, 0, 0]; // Track obstacles per lane
// Bonus system variables
var scoreMultiplier = 1;
var multiplierTimer = 0;
var comboCount = 0;
var comboTimer = 0;
var lastCollectTime = 0;
var bonusEventTimer = 0;
// Lane positions for vertical game (horizontal lanes)
var lanes = [2048 * 0.2, 2048 * 0.5, 2048 * 0.8];
function getLaneX(laneIndex) {
return lanes[laneIndex];
}
function getRandomLane() {
return Math.floor(Math.random() * 3);
}
function updateLaneObstacleCounts() {
// Reset counts
laneObstacleCounts = [0, 0, 0];
// Count obstacles in each lane
for (var i = 0; i < obstacles.length; i++) {
var obstacle = obstacles[i];
var laneIndex = Math.round((obstacle.x - lanes[0]) / (lanes[1] - lanes[0]));
if (laneIndex >= 0 && laneIndex < 3) {
laneObstacleCounts[laneIndex]++;
}
}
}
function getAvailableLane() {
updateLaneObstacleCounts();
var availableLanes = [];
// Find lanes with no obstacles to ensure at least one lane is always clear
for (var i = 0; i < 3; i++) {
if (laneObstacleCounts[i] === 0) {
availableLanes.push(i);
}
}
// If no completely clear lanes, find lanes with fewer obstacles
if (availableLanes.length === 0) {
var minObstacles = Math.min.apply(Math, laneObstacleCounts);
for (var i = 0; i < 3; i++) {
if (laneObstacleCounts[i] === minObstacles) {
availableLanes.push(i);
}
}
}
// Return random available lane
return availableLanes[Math.floor(Math.random() * availableLanes.length)];
}
function calculateBonus(basePoints) {
var bonus = basePoints * scoreMultiplier;
// Combo bonus
if (comboCount > 1) {
bonus += comboCount * 5;
}
// Speed bonus - higher speed gives more points
var speedBonus = Math.floor((gameSpeed - baseSpeed) * 2);
bonus += speedBonus;
return Math.floor(bonus);
}
function updateCombo() {
var currentTime = LK.ticks;
// Check if within combo window (2 seconds)
if (currentTime - lastCollectTime < 120) {
comboCount++;
comboTimer = 180; // Show combo for 3 seconds
} else {
comboCount = 1;
comboTimer = 180;
}
lastCollectTime = currentTime;
// Update combo display
if (comboCount > 1) {
comboTxt.setText('COMBO x' + comboCount + '!');
tween(comboTxt, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
onComplete: function onComplete() {
tween(comboTxt, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
}
});
}
}
function triggerBonusEvent() {
// Random bonus events
var eventType = Math.floor(Math.random() * 3);
if (eventType === 0) {
// Score multiplier boost
scoreMultiplier = Math.min(scoreMultiplier + 1, 5);
multiplierTimer = 600; // 10 seconds
LK.effects.flashScreen(0xffff00, 300);
LK.getSound('bonusEvent').play();
} else if (eventType === 1) {
// Instant score bonus
var bonus = calculateBonus(100);
LK.setScore(LK.getScore() + bonus);
scoreTxt.setText('Score: ' + LK.getScore());
LK.effects.flashScreen(0x00ff00, 300);
LK.getSound('bonusEvent').play();
} else {
// Combo extension
comboTimer += 300; // Extra 5 seconds
LK.effects.flashScreen(0xff6600, 300);
LK.getSound('bonusEvent').play();
}
}
// Create score display
var scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Create multiplier display
var multiplierTxt = new Text2('x1', {
size: 60,
fill: 0xffff00
});
multiplierTxt.anchor.set(1, 0);
multiplierTxt.x = -20;
multiplierTxt.y = 100;
LK.gui.topRight.addChild(multiplierTxt);
// Create combo display
var comboTxt = new Text2('', {
size: 50,
fill: 0xff6600
});
comboTxt.anchor.set(0.5, 0);
comboTxt.y = 120;
LK.gui.top.addChild(comboTxt);
// Create road segments
for (var i = 0; i < 3; i++) {
var road = new Road();
road.x = 2048 / 2;
road.y = i * 150 - 75;
roads.push(road);
game.addChild(road);
}
// Create lava backgrounds
for (var i = 0; i < 12; i++) {
var lavaBg = new LavaBackground();
lavaBg.x = 2048 / 2;
lavaBg.y = i * 250 - 300;
lavaBackgrounds.push(lavaBg);
game.addChild(lavaBg);
}
// Create lava streams
for (var i = 0; i < 6; i++) {
var lavaStream = new LavaStream();
lavaStream.x = 200 + i * 300;
lavaStream.y = 2732 / 2;
lavaStreams.push(lavaStream);
game.addChild(lavaStream);
}
// Create walls
var leftWall = new Wall('left');
leftWall.x = 100;
leftWall.y = 2732 / 2;
walls.push(leftWall);
game.addChild(leftWall);
var rightWall = new Wall('right');
rightWall.x = 2048 - 100;
rightWall.y = 2732 / 2;
walls.push(rightWall);
game.addChild(rightWall);
// Create paradise gates - blue wall lines at top
for (var i = 0; i < 3; i++) {
var paradiseGate = new ParadiseGate();
paradiseGate.x = 2048 / 2;
paradiseGate.y = i * 300 - 150;
paradiseGates.push(paradiseGate);
game.addChild(paradiseGate);
}
// Create car
car = game.addChild(new Car());
car.x = getLaneX(1);
car.y = 2732 - 200;
car.baseY = car.y;
// Touch controls
game.down = function (x, y, obj) {
if (x < 2048 / 3) {
// Left third - move left
if (car.targetLane > 0) {
car.targetLane--;
LK.getSound('laneChange').play();
// Add banking effect when changing lanes
tween(car.children[0], {
rotation: -0.2
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(car.children[0], {
rotation: 0
}, {
duration: 300,
easing: tween.easeInOut
});
}
});
}
} else if (x > 2048 * 2 / 3) {
// Right third - move right
if (car.targetLane < 2) {
car.targetLane++;
LK.getSound('laneChange').play();
// Add banking effect when changing lanes
tween(car.children[0], {
rotation: 0.2
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(car.children[0], {
rotation: 0
}, {
duration: 300,
easing: tween.easeInOut
});
}
});
}
}
};
function spawnCoin() {
var coin = new Coin();
coin.x = getLaneX(getRandomLane());
coin.y = -50;
coins.push(coin);
game.addChild(coin);
}
function spawnObstacle() {
// Check if we can spawn while ensuring one lane stays clear
updateLaneObstacleCounts();
// Count how many lanes have obstacles
var lanesWithObstacles = 0;
for (var i = 0; i < 3; i++) {
if (laneObstacleCounts[i] > 0) {
lanesWithObstacles++;
}
}
// Don't spawn if 2 lanes already have obstacles (keep at least one lane clear)
if (lanesWithObstacles >= 2) {
return;
}
var types = ['demon', 'firePit', 'lavaRock', 'skull', 'demonWing'];
var type = types[Math.floor(Math.random() * types.length)];
var obstacle = new Obstacle(type);
obstacle.x = getLaneX(getAvailableLane());
obstacle.y = -100;
obstacles.push(obstacle);
game.addChild(obstacle);
}
function spawnPowerUp() {
var types = ['invisibility', 'slow', 'shrink'];
var type = types[Math.floor(Math.random() * types.length)];
var powerUp = new PowerUp(type);
powerUp.x = getLaneX(getRandomLane());
powerUp.y = -75;
powerUps.push(powerUp);
game.addChild(powerUp);
}
function spawnSideObstacle() {
var types = ['demon', 'firePit', 'lavaRock', 'skull'];
var type = types[Math.floor(Math.random() * types.length)];
var side = Math.random() < 0.5 ? 'left' : 'right';
var sideObstacle = new SideObstacle(side, type);
sideObstacle.y = -100;
sideObstacles.push(sideObstacle);
game.addChild(sideObstacle);
}
function updateBackground() {
var score = LK.getScore();
// Change background based on score - darker lava theme
if (score > 100 && backgroundColorPhase === 0) {
backgroundColorPhase = 1;
tween(game, {
backgroundColor: 0x220000
}, {
duration: 2000
});
} else if (score > 250 && backgroundColorPhase === 1) {
backgroundColorPhase = 2;
tween(game, {
backgroundColor: 0x000000
}, {
duration: 2000
});
}
}
function triggerDevilEvent() {
// Screen shake effect
shakeTimer = 180; // 3 seconds at 60fps
// Flash screen red briefly
LK.effects.flashScreen(0xff0000, 500);
// Play devil laugh sound
LK.getSound('devilLaugh').play();
}
game.update = function () {
// Apply screen shake
if (shakeTimer > 0) {
shakeTimer--;
var shakeX = (Math.random() - 0.5) * 20;
var shakeY = (Math.random() - 0.5) * 20;
game.x = shakeX;
game.y = shakeY;
} else {
game.x = 0;
game.y = 0;
}
// Increase difficulty over time
difficultyTimer++;
if (difficultyTimer % 600 === 0) {
// Every 10 seconds
gameSpeed += 0.5;
if (gameSpeed > baseSpeed * 2.5) {
gameSpeed = baseSpeed * 2.5; // Cap speed
}
}
// Increase speed every 100 points
var currentSpeedLevel = Math.floor(LK.getScore() / 100);
var expectedSpeed = baseSpeed + currentSpeedLevel * 2;
if (expectedSpeed > gameSpeed && expectedSpeed <= baseSpeed * 3) {
gameSpeed = expectedSpeed;
// Visual feedback for speed increase
LK.effects.flashScreen(0xffaa00, 400);
}
// Devil event timer
devilEventTimer++;
if (devilEventTimer > 1800 + Math.random() * 1800) {
// 30-60 seconds
triggerDevilEvent();
devilEventTimer = 0;
}
// Spawn objects
spawnTimer++;
powerUpSpawnTimer++;
sideObstacleSpawnTimer++;
// Spawn coins
if (spawnTimer > 60 - Math.min(40, LK.getScore() / 10)) {
if (Math.random() < 0.7) {
spawnCoin();
}
spawnTimer = 0;
}
// Spawn obstacles with increased difficulty every 250 points
var difficultyLevel = Math.floor(LK.getScore() / 250);
var baseSpawnRate = 0.02 + LK.getScore() * 0.0001;
var hardDifficultyBonus = difficultyLevel * 0.01; // Extra spawn chance every 250 points
if (Math.random() < baseSpawnRate + hardDifficultyBonus) {
spawnObstacle();
}
// Spawn power-ups occasionally
if (powerUpSpawnTimer > 600 && Math.random() < 0.15) {
// Every 10+ seconds, 15% chance - increased frequency for escape availability
spawnPowerUp();
powerUpSpawnTimer = 0;
}
// Spawn side obstacles
if (sideObstacleSpawnTimer > 300 && Math.random() < 0.25) {
// Every 5+ seconds, 25% chance
spawnSideObstacle();
sideObstacleSpawnTimer = 0;
}
// Update coins
for (var i = coins.length - 1; i >= 0; i--) {
var coin = coins[i];
if (coin.y > 2732 + 100) {
coin.destroy();
coins.splice(i, 1);
continue;
}
// Check collision with car
if (!coin.collected && car.intersects(coin)) {
coin.collected = true;
var bonus = calculateBonus(10);
LK.setScore(LK.getScore() + bonus);
scoreTxt.setText('Score: ' + LK.getScore());
updateCombo();
LK.getSound('collect').play();
coin.destroy();
coins.splice(i, 1);
}
}
// Update obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
if (obstacle.y > 2732 + 150) {
if (Math.random() < 0.3) {
LK.getSound('explosion').play();
}
obstacle.destroy();
obstacles.splice(i, 1);
continue;
}
// Check collision with car
if (!car.invincible && car.currentLane === Math.round((obstacle.x - lanes[0]) / (lanes[1] - lanes[0])) && car.intersects(obstacle)) {
LK.getSound('crash').play();
LK.effects.flashScreen(0xff0000, 1000);
LK.stopMusic();
LK.playMusic('gameOverMusic', {
loop: true
});
LK.showGameOver();
return;
}
}
// Update power-ups
for (var i = powerUps.length - 1; i >= 0; i--) {
var powerUp = powerUps[i];
if (powerUp.y > 2732 + 100) {
powerUp.destroy();
powerUps.splice(i, 1);
continue;
}
// Check collision with car
if (!powerUp.collected && car.intersects(powerUp)) {
powerUp.collected = true;
if (powerUp.type === 'invisibility') {
car.invincible = true;
car.invincibilityTimer = 300; // 5 seconds
scoreMultiplier += 1;
multiplierTimer = 300; // 5 seconds
} else if (powerUp.type === 'slow') {
car.slowEffect = true;
car.slowTimer = 360; // 6 seconds
var bonus = calculateBonus(25);
LK.setScore(LK.getScore() + bonus);
scoreTxt.setText('Score: ' + LK.getScore());
} else if (powerUp.type === 'shrink') {
car.shrinkObstacles = true;
car.shrinkTimer = 480; // 8 seconds
var bonus = calculateBonus(30);
LK.setScore(LK.getScore() + bonus);
scoreTxt.setText('Score: ' + LK.getScore());
}
updateCombo();
LK.getSound('powerUp').play();
powerUp.destroy();
powerUps.splice(i, 1);
}
}
// Update side obstacles
for (var i = sideObstacles.length - 1; i >= 0; i--) {
var sideObstacle = sideObstacles[i];
if (sideObstacle.y > 2732 + 150) {
sideObstacle.destroy();
sideObstacles.splice(i, 1);
continue;
}
// Check collision with car
if (!car.invincible && car.intersects(sideObstacle)) {
LK.getSound('crash').play();
LK.effects.flashScreen(0xff0000, 1000);
LK.stopMusic();
LK.playMusic('gameOverMusic', {
loop: true
});
LK.showGameOver();
return;
}
}
// Update background color progression
updateBackground();
// Update bonus system timers
if (multiplierTimer > 0) {
multiplierTimer--;
if (multiplierTimer <= 0) {
scoreMultiplier = Math.max(1, scoreMultiplier - 1);
}
}
if (comboTimer > 0) {
comboTimer--;
if (comboTimer <= 0) {
comboCount = 0;
comboTxt.setText('');
}
}
// Update displays
multiplierTxt.setText('x' + scoreMultiplier);
if (scoreMultiplier > 1) {
multiplierTxt.fill = 0x00ff00;
} else {
multiplierTxt.fill = 0xffff00;
}
// Bonus events
bonusEventTimer++;
if (bonusEventTimer > 1200 + Math.random() * 600) {
// 20-30 seconds
if (Math.random() < 0.3) {
// 30% chance
triggerBonusEvent();
}
bonusEventTimer = 0;
}
// Add score over time with multiplier
if (LK.ticks % 30 === 0) {
var timeBonus = calculateBonus(1);
LK.setScore(LK.getScore() + timeBonus);
scoreTxt.setText('Score: ' + LK.getScore());
}
};
// Start background music with continuous loop
LK.playMusic('hellMusic', {
loop: true
}); ===================================================================
--- original.js
+++ change.js
@@ -259,8 +259,33 @@
}
};
return self;
});
+var ParadiseGate = Container.expand(function () {
+ var self = Container.call(this);
+ var gateGraphics = self.attachAsset('paradiseGate', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.glowTimer = 0;
+ self.update = function () {
+ self.y += gameSpeed;
+ // Add heavenly glow effect
+ self.glowTimer++;
+ var glow = 1.0 + Math.sin(self.glowTimer * 0.1) * 0.3;
+ gateGraphics.scaleY = glow;
+ // Subtle color shifting for divine effect
+ var colorShift = Math.sin(self.glowTimer * 0.05) * 0.2;
+ var blueIntensity = Math.floor((0.4 + colorShift) * 255);
+ var cyanIntensity = Math.floor((0.6 + colorShift) * 255);
+ gateGraphics.tint = (blueIntensity << 8) + cyanIntensity;
+ // Reset position when off screen
+ if (self.y > 2732 + 40) {
+ self.y = -40;
+ }
+ };
+ return self;
+});
var PowerUp = Container.expand(function (type) {
var self = Container.call(this);
var assetName = type + 'PowerUp';
var powerUpGraphics = self.attachAsset(assetName, {
@@ -383,8 +408,9 @@
var walls = [];
var sideObstacles = [];
var lavaBackgrounds = [];
var lavaStreams = [];
+var paradiseGates = [];
var backgroundColorPhase = 0; // 0=red, 1=purple, 2=black
var difficultyTimer = 0;
var devilEventTimer = 0;
var shakeTimer = 0;
@@ -563,8 +589,16 @@
rightWall.x = 2048 - 100;
rightWall.y = 2732 / 2;
walls.push(rightWall);
game.addChild(rightWall);
+// Create paradise gates - blue wall lines at top
+for (var i = 0; i < 3; i++) {
+ var paradiseGate = new ParadiseGate();
+ paradiseGate.x = 2048 / 2;
+ paradiseGate.y = i * 300 - 150;
+ paradiseGates.push(paradiseGate);
+ game.addChild(paradiseGate);
+}
// Create car
car = game.addChild(new Car());
car.x = getLaneX(1);
car.y = 2732 - 200;
fireFlicker
Sound effect
skullMoan
Sound effect
powerUp
Sound effect
hellMusic
Music
bonusEvent
Sound effect
laneChange
Sound effect
collect
Sound effect
gameOverMusic
Music
devilLaugh
Sound effect
explosion
Sound effect
crash
Sound effect
angelBlessing
Sound effect
failure
Sound effect
angelAppearance
Sound effect