User prompt
Add president asset to the game. Add it to the memecoins class in the game logic and in the map
User prompt
Add cat asset to the game. Add it to the memecoins class in the game logic and in the map
User prompt
Add volt asset to the game. Add it to the memecoins class in the game logic and in the map
User prompt
Add loki asset to the game. Add it to the memecoins class in the game logic and in the map
User prompt
Add Pepe asset to the game. Add it to the memecoins class in the game logic and in the map
User prompt
Increase distance between memecoins
User prompt
Make bigger distance between memecoins load
User prompt
When the player picks up the closest coin, the one behind her also disappears. Fix it
User prompt
When the player picks up the closest coin, the one behind her also disappears.
User prompt
The level difference between the signals is too large.
User prompt
each coin type appears once during a round and then the round starts again
User prompt
reverse the spin of the coins to the other direction
User prompt
Add Shib asset to the game. Add it to the memecoins class in the game logic and in the map
User prompt
Add dogmeme asset to the game. Add it to the memecoins class in the game logic and in the map
User prompt
Add more types of memecoin assets to the memecoin class
User prompt
Change signals long more diversify
User prompt
Ensure every signal line should be vertical.
User prompt
Change signals long a little bit more diversify
User prompt
Change signals long a little bit more diversify
User prompt
Add more types of memecoins to the memecoin class
User prompt
Ensure signals cannot overlaps player in the display order
User prompt
The distance between greensignals and redsignals in height is too much!!!
User prompt
The signals layout should be mostly staggered
User prompt
Avoid signals overlap each other
User prompt
Avoid signals overlaping each other
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Memecoin = Container.expand(function (coinType) {
var self = Container.call(this);
// Define coin types and their properties
self.coinTypes = {
'doge': {
color: 0xffd700,
value: 50,
rotationSpeed: 0.03
},
'shiba': {
color: 0xff9900,
value: 100,
rotationSpeed: 0.05
},
'pepe': {
color: 0x00ff00,
value: 150,
rotationSpeed: 0.04
}
};
// Default to doge if no type specified
self.type = coinType || 'doge';
self.coinValue = self.coinTypes[self.type].value;
self.rotationSpeed = self.coinTypes[self.type].rotationSpeed;
// Create coin with appropriate color based on type
var coinGraphics = self.attachAsset('memecoin', {
anchorX: 0.5,
anchorY: 0.5
});
// Apply color tint based on coin type
coinGraphics.tint = self.coinTypes[self.type].color;
self.speed = 6;
self.active = true;
self.collected = false;
self.update = function () {
if (!self.active) {
return;
}
self.x -= self.speed;
// Rotate coin at type-specific speed
coinGraphics.rotation += self.rotationSpeed;
// Remove when off screen
if (self.x < -100) {
self.active = false;
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.vx = 0;
self.vy = 0;
self.gravity = 0.5;
self.jumpPower = -25; // Increased jump power from -15 to -25
self.isJumping = false;
self.isDead = false;
self.lastWasIntersecting = false;
self.jump = function () {
// Find if player is standing on a green signal
var standingOnGreenSignal = signals.some(function (s) {
return player && s.type === 'green' && player.intersects(s) && Math.abs(player.y - (s.y - 275)) < 10;
});
if (!self.isDead && (self.vy === 0 || standingOnGreenSignal)) {
self.vy = self.jumpPower;
self.isJumping = true;
LK.getSound('jump').play();
}
};
self.update = function () {
if (self.isDead) {
return;
}
// Store last position for collision detection
self.lastY = self.y;
// Apply gravity
self.vy += self.gravity;
// Apply movement
self.y += self.vy;
// Track if player is jumping or falling
self.isJumping = self.vy !== 0;
// Ground collision detection
if (self.y > 2732 - playerGraphics.height / 2) {
// Bottom of screen
self.y = 2732 - playerGraphics.height / 2;
self.vy = 0;
self.isJumping = false;
}
};
return self;
});
var Shark = Container.expand(function () {
var self = Container.call(this);
var sharkGraphics = self.attachAsset('shark', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 5;
self.direction = 1;
self.centerY = 2732 - sharkGraphics.height / 2;
self.update = function () {
// Keep shark at constant y position
self.y = self.centerY;
// Check if player exists and has fallen to shark's height level
if (player && player.y > 2732 - 350) {
// Shark hunts player - move toward player position
self.direction = player.x > self.x ? 1 : -1;
self.speed = 8; // Increase speed when hunting
// Set correct shark orientation based on direction
sharkGraphics.scale.x = self.direction;
} else {
// Normal back-and-forth movement when player isn't at shark level
self.speed = 5;
// Check if shark reached boundaries and change direction
if (self.x > 1800 && self.direction === 1) {
self.direction = -1;
sharkGraphics.scale.x = -1;
} else if (self.x < 200 && self.direction === -1) {
self.direction = 1;
sharkGraphics.scale.x = 1;
}
}
// Apply movement
self.x += self.speed * self.direction;
};
return self;
});
var Signal = Container.expand(function (type) {
var self = Container.call(this);
// Add support for more signal types
self.type = type || 'green';
var assetId, color;
// Define properties based on signal type
switch (self.type) {
case 'green':
assetId = 'greenSignal';
self.boostPower = 0;
break;
case 'red':
assetId = 'redSignal';
self.boostPower = 0;
break;
case 'boost':
assetId = 'greenSignal';
self.boostPower = -20; // Strong upward boost
color = 0x00ffff; // Cyan color for boost platforms
break;
case 'danger':
assetId = 'redSignal';
self.boostPower = 15; // Downward push
color = 0xff00ff; // Magenta color for danger platforms
break;
case 'bounce':
assetId = 'greenSignal';
self.boostPower = -15; // Medium upward boost
color = 0xffff00; // Yellow color for bounce platforms
break;
default:
assetId = 'greenSignal';
self.boostPower = 0;
}
var signalGraphics = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1 / 1.2,
scaleY: 1 / 1.2
});
// Apply custom tint if specified
if (color) {
signalGraphics.tint = color;
}
// Add visual effects for special platforms
if (self.type === 'boost' || self.type === 'bounce') {
// Add pulsing effect to special platforms
self.pulseDirection = 1;
self.pulseAmount = 0;
self.pulseSpeed = self.type === 'boost' ? 0.03 : 0.02;
}
// Rotate signal by 90 degrees to the left
signalGraphics.rotation = -Math.PI / 2; // -90 degrees in radians
self.speed = 3.5;
self.active = true;
self.update = function () {
if (!self.active) {
return;
}
self.x -= self.speed;
// Handle pulsing effect for special platforms
if (self.type === 'boost' || self.type === 'bounce') {
self.pulseAmount += self.pulseSpeed * self.pulseDirection;
if (self.pulseAmount > 0.2 || self.pulseAmount < 0) {
self.pulseDirection *= -1;
}
signalGraphics.scale.set((1 + self.pulseAmount) / 1.2, 1 / 1.2);
}
// Remove when off screen only if player is not jumping/falling
// Make sure we keep signals visible while player is falling
if (self.x < -200) {
// Only deactivate if player doesn't exist or if player is not jumping/falling
if (!player || !player.isJumping && player.vy <= 0) {
self.active = false;
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x00142A
});
/****
* Game Code
****/
// Game variables
var player;
var signals = [];
var memecoins = [];
var shark;
var isGameActive = true;
var gameSpeed = 1;
var lastSignalTime = 0;
var lastCoinTime = 0;
var score = 0;
var scoreIncrement = 0.1;
var distanceTraveled = 0;
// UI elements
var scoreTxt;
var highScoreTxt;
// Initialize UI
function initUI() {
// Score text
scoreTxt = new Text2('SCORE: 0', {
size: 70,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
scoreTxt.y = 0;
// High score text
var highScore = storage.highScore || 0;
highScoreTxt = new Text2('HIGH SCORE: ' + Math.floor(highScore), {
size: 50,
fill: 0xFFD700
});
highScoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(highScoreTxt);
highScoreTxt.y = 80;
}
// Initialize game world
function initGame() {
isGameActive = true;
score = 0;
distanceTraveled = 0;
gameSpeed = 1;
// Create player at top left, ready to fall
player = new Player();
player.x = 200;
player.y = 100;
player.vy = 5; // Start with downward velocity
game.addChild(player);
// Create shark
shark = new Shark();
shark.y = 2732 - 100;
game.addChild(shark);
// Clear signals and coins
clearEntities();
// Create initial signals that have already reached the left side
var recentHeights = [];
var heightThreshold = 60; // Increased threshold to better detect potential overlaps
for (var i = 0; i < 44; i++) {
var signalType;
// For signals that are lower than the previous, make them red
// For signals that are higher than the previous, make them green
var lastY = 1500;
if (signals.length > 0) {
lastY = signals[signals.length - 1].y;
}
var newY;
var willBeHigher = Math.random() < 0.5;
// Include special signal types in initial setup
var includeSpecials = i > 15; // Only include special signals after normal ones are established
var specialChance = includeSpecials ? 0.2 : 0; // 20% chance for special signals once enabled
if (willBeHigher) {
// More gradual ascent with varied height differences
var heightDiff = 100 + Math.random() * 150;
newY = lastY - heightDiff;
// Determine signal type for ascending platforms
if (Math.random() < specialChance) {
signalType = Math.random() < 0.7 ? 'bounce' : 'boost';
} else {
signalType = 'green';
}
} else {
// More gradual descent with varied height differences
var heightDiff = 100 + Math.random() * 150;
newY = lastY + heightDiff;
// Determine signal type for descending platforms
if (Math.random() < specialChance * 0.5) {
// Less chance for danger in initial setup
signalType = 'danger';
} else {
signalType = 'red';
}
}
// Check if this height is too similar to recent heights
var isTooSimilar = recentHeights.length > 0 && recentHeights.some(function (height) {
return Math.abs(newY - height) < heightThreshold;
});
// If too similar, adjust the height to avoid repetition
if (isTooSimilar) {
if (signalType === 'green') {
newY -= 100 + Math.random() * 80; // Increased offset for better separation
} else {
newY += 100 + Math.random() * 80; // Increased offset for better separation
}
}
// Ensure signal stays within playable area
newY = Math.max(800, Math.min(2200, newY));
// Store this height for future comparison
recentHeights.push(newY);
if (recentHeights.length > 10) {
recentHeights.shift(); // Keep only last 10 heights
}
var signal = new Signal(signalType);
// Position signals already at the left side of the screen
signal.x = -150 + i * 50; // Distribute signals across the left edge
signal.y = newY;
signals.push(signal);
// Make sure signals are placed behind the player
if (player) {
var playerIndex = game.getChildIndex(player);
game.addChildAt(signal, playerIndex);
} else {
game.addChild(signal);
}
}
// Start game music
LK.playMusic('gameMusic');
}
// Clear all entities
function clearEntities() {
for (var i = signals.length - 1; i >= 0; i--) {
signals[i].destroy();
signals.splice(i, 1);
}
for (var i = memecoins.length - 1; i >= 0; i--) {
memecoins[i].destroy();
memecoins.splice(i, 1);
}
}
// Spawn signals
function spawnSignal() {
var currentTime = Date.now();
// Spawn signals at intervals that maintain consistent spacing regardless of score
// At higher scores (1000+), we need to keep a minimum time between signals
var baseInterval = 300;
var minInterval = 150;
var adjustedInterval = score > 1000 ? Math.max(minInterval, baseInterval / gameSpeed) : baseInterval / gameSpeed;
if (currentTime - lastSignalTime > adjustedInterval) {
// This ensures spacing remains consistent even at high scores
var signal;
var lastSignalY = 1500; // Default Y position if no signals exist
// Get the Y position of the last signal to compare with
if (signals.length > 0) {
var lastSignal = signals[signals.length - 1];
lastSignalY = lastSignal.y;
}
// Calculate a new Y position
var newY;
var willBeHigher = Math.random() < 0.5; // 50% chance to go higher
// Count consecutive red signals
var redSignalCount = 0;
// Find the last signal of each type for height comparison
var lastGreenY = null;
var lastRedY = null;
var lastSpecialY = null;
// Track recent signal heights to prevent repetition
var recentHeights = [];
var heightThreshold = 60; // Increased threshold to detect potential overlaps better
// Track recent signal types
var recentTypes = [];
// Collect the last few signal heights and types for comparison
for (var i = signals.length - 1; i >= Math.max(0, signals.length - 15); i--) {
recentHeights.push(signals[i].y);
recentTypes.push(signals[i].type);
}
// Find the last green, red, and special signal Y positions
for (var i = signals.length - 1; i >= 0; i--) {
if (signals[i].type === 'green' && lastGreenY === null) {
lastGreenY = signals[i].y;
}
if (signals[i].type === 'red' && lastRedY === null) {
lastRedY = signals[i].y;
}
if ((signals[i].type === 'boost' || signals[i].type === 'bounce' || signals[i].type === 'danger') && lastSpecialY === null) {
lastSpecialY = signals[i].y;
}
if (lastGreenY !== null && lastRedY !== null && lastSpecialY !== null) {
break;
}
}
for (var i = signals.length - 1; i >= Math.max(0, signals.length - 5); i--) {
if (signals[i] && signals[i].type === 'red') {
redSignalCount++;
} else {
break;
}
}
// Count consecutive same type signals
var consecutiveSameType = 1;
for (var i = recentTypes.length - 1; i > 0; i--) {
if (recentTypes[i] === recentTypes[i - 1]) {
consecutiveSameType++;
} else {
break;
}
}
// Determine signal type based on game progression
var signalType;
var specialRate = Math.min(0.6, score / 2000); // Chance for special signals increases with score
var forceSpecialSignal = Math.random() < specialRate && score > 200;
var randomSpecial = Math.random();
// Force green signal if we've had 5 reds in a row
if (redSignalCount >= 5) {
// Force green signal (must be higher) but with more gradual ascent
newY = lastSignalY - (100 + Math.random() * 150);
// Consider introducing a boost platform after many red signals
if (forceSpecialSignal && Math.random() < 0.6) {
signalType = 'boost';
} else {
signalType = 'green';
}
signal = new Signal(signalType);
} else if (willBeHigher) {
// This signal will be higher (ascending)
// More gradual height difference for green signals
var heightDiff = 80 + Math.random() * 120; // Reduced for more cascading effect
if (lastGreenY !== null && Math.abs(lastSignalY - heightDiff - lastGreenY) > 200) {
// Limit the maximum height change between signals of same color
heightDiff = Math.min(heightDiff, 200);
}
newY = lastSignalY - heightDiff;
// Higher signals can be green or special
if (forceSpecialSignal) {
if (randomSpecial < 0.6) {
signalType = 'bounce'; // Moderate boost
} else {
signalType = 'boost'; // Strong boost
}
} else {
signalType = 'green';
}
// Avoid too many consecutive signals of the same type
if (consecutiveSameType >= 3 && recentTypes.length > 0 && recentTypes[recentTypes.length - 1] === signalType) {
// Force a different type
if (signalType === 'green') {
signalType = Math.random() < 0.7 ? 'bounce' : 'boost';
} else {
signalType = 'green';
}
}
signal = new Signal(signalType);
} else {
// This signal will be lower (descending)
// More gradual height difference for red signals
var heightDiff = 80 + Math.random() * 120; // Reduced for more cascading effect
if (lastRedY !== null && Math.abs(lastSignalY + heightDiff - lastRedY) > 200) {
// Limit the maximum height change between signals of same color
heightDiff = Math.min(heightDiff, 200);
}
newY = lastSignalY + heightDiff;
// Check if we would have too many consecutive red signals
var wouldBeConsecutiveReds = redSignalCount + 1;
if (wouldBeConsecutiveReds >= 5) {
// Force this to be a green signal instead with gradual ascent
newY = lastSignalY - (100 + Math.random() * 150);
signalType = 'green';
} else {
// Lower signals can be red or danger
if (forceSpecialSignal && Math.random() < 0.4 && score > 500) {
signalType = 'danger';
} else {
signalType = 'red';
}
// Avoid too many consecutive signals of the same type
if (consecutiveSameType >= 3 && recentTypes.length > 0 && recentTypes[recentTypes.length - 1] === signalType) {
// Force a different type
if (signalType === 'red') {
signalType = Math.random() < 0.3 ? 'danger' : 'red';
} else {
signalType = 'red';
}
}
}
signal = new Signal(signalType);
}
// Ensure signal stays within playable area
newY = Math.max(800, Math.min(2200, newY));
// Additional check for signals that might be about to overlap (within 25px)
var potentialOverlap = signals.filter(function (s) {
// Only check signals that are still on screen or about to enter
return s.active && s.x > -200 && s.x < 2300 && Math.abs(s.y - newY) < 25;
});
// If there's potential overlap, adjust the Y position
if (potentialOverlap.length > 0) {
if (signal.type === 'green') {
newY -= 100 + Math.random() * 50; // Move green signals higher
} else {
newY += 100 + Math.random() * 50; // Move red signals lower
}
// Re-check playable area boundaries
newY = Math.max(800, Math.min(2200, newY));
}
// Add height variation to signals and prevent consecutive similar heights
if (signal.type === 'green') {
// Green signals with cascading heights - increased variations
var greenOffset = Math.random() * 50 + 10;
// Check if this height is too similar to recent heights
var isTooSimilar = recentHeights.some(function (height) {
return Math.abs(newY - greenOffset - height) < heightThreshold;
});
// If too similar, significantly increase the offset to ensure different height
if (isTooSimilar) {
greenOffset += 80 + Math.random() * 60; // Increased offset to prevent overlap
}
newY -= greenOffset;
} else if (signal.type === 'red') {
// Red signals with cascading heights - increased variations
var redOffset = Math.random() * 50 + 10;
// Check if this height is too similar to recent heights
var isTooSimilar = recentHeights.some(function (height) {
return Math.abs(newY + redOffset - height) < heightThreshold;
});
// If too similar, significantly increase the offset to ensure different height
if (isTooSimilar) {
redOffset += 80 + Math.random() * 60; // Increased offset to prevent overlap
}
newY += redOffset;
}
signal.x = 2048 + 150;
signal.y = newY;
signals.push(signal);
// Add signal behind the player to ensure correct display order
if (player) {
var playerIndex = game.getChildIndex(player);
game.addChildAt(signal, playerIndex);
} else {
game.addChild(signal);
}
lastSignalTime = currentTime;
}
}
// Spawn memecoins
function spawnMemecoin() {
var currentTime = Date.now();
// Spawn coins less frequently than signals - doubled interval from 3000 to 6000
if (currentTime - lastCoinTime > 6000 / gameSpeed) {
// Find green signals that are still on screen (or about to enter)
var greenSignals = signals.filter(function (signal) {
return signal.type === 'green' && signal.x > -200 && signal.x < 2300;
});
// Only spawn coin if we have green signals
if (greenSignals.length > 0) {
// Pick a random green signal
var randomGreenSignal = greenSignals[Math.floor(Math.random() * greenSignals.length)];
// Determine coin type based on probability and score
var coinType;
var random = Math.random();
var scoreFactor = Math.min(1, score / 1000); // Higher score increases chance of rare coins
if (random < 0.6 - scoreFactor * 0.3) {
// Common coin - chance decreases as score increases
coinType = 'doge';
} else if (random < 0.9 - scoreFactor * 0.1) {
// Uncommon coin
coinType = 'shiba';
} else {
// Rare coin - chance increases as score increases
coinType = 'pepe';
}
var coin = new Memecoin(coinType);
coin.x = 2048 + 150;
// Position coin above the green signal (50-150px higher)
coin.y = randomGreenSignal.y - randomGreenSignal.width / 2 - 100 - Math.random() * 100;
memecoins.push(coin);
// Add coin behind the player to ensure correct display order
if (player) {
var playerIndex = game.getChildIndex(player);
game.addChildAt(coin, playerIndex);
} else {
game.addChild(coin);
}
lastCoinTime = currentTime;
}
}
}
// Check collisions between player and signals/coins/shark
function checkCollisions() {
if (!isGameActive) {
return;
}
// Check signal collisions
for (var i = 0; i < signals.length; i++) {
var signal = signals[i];
if (signal.active && player.intersects(signal)) {
// Store previous intersection state
var wasIntersecting = player.lastWasIntersecting;
player.lastWasIntersecting = true;
// Only handle collision if this is a new intersection
if (!wasIntersecting) {
// Check if player is above the signal and falling down
// The signal is rotated 90 degrees left, so we need to detect its height properly
// Signal's height is now its width because of the rotation
var signalHeight = 50 / 1.2; // Original height divided by scale factor
var signalWidth = 500 / 1.2; // Original width divided by scale factor
var playerHeight = 150; // Player height
// Calculate where the top of the signal is considering rotation
if (player.y < signal.y - signalWidth / 2 && player.vy > 0) {
switch (signal.type) {
case 'green':
// Land on green signals but don't automatically jump
// Position player properly on top of the signal
player.y = signal.y - signalWidth / 2 - playerHeight / 2;
player.vy = 0;
player.isJumping = false;
break;
case 'boost':
// Boost platforms give an automatic jump
player.y = signal.y - signalWidth / 2 - playerHeight / 2;
player.vy = signal.boostPower; // Strong upward boost
player.isJumping = true;
// Add boost visual effect
LK.effects.flashObject(signal, 0x00ffff, 300);
LK.getSound('jump').play();
break;
case 'bounce':
// Bounce platforms give a medium jump
player.y = signal.y - signalWidth / 2 - playerHeight / 2;
player.vy = signal.boostPower; // Medium upward boost
player.isJumping = true;
// Add bounce visual effect
LK.effects.flashObject(signal, 0xffff00, 200);
LK.getSound('jump').play();
break;
case 'danger':
// Danger platforms push player down
player.vy = signal.boostPower; // Downward push
player.isJumping = true;
// Add danger visual effect
LK.effects.flashObject(signal, 0xff00ff, 200);
break;
case 'red':
default:
// Pass through red signals, ignore collision
// Don't land on red signals, continue falling
player.vy += player.gravity;
player.isJumping = true;
break;
}
}
}
} else if (signal.active) {
// If not intersecting this signal, reset lastWasIntersecting
player.lastWasIntersecting = false;
}
}
// Check memecoin collisions
for (var i = 0; i < memecoins.length; i++) {
var coin = memecoins[i];
if (coin.active && !coin.collected && player.intersects(coin)) {
// Collect coin
coin.collected = true;
// Add points based on coin type
score += coin.coinValue;
scoreTxt.setText('SCORE: ' + Math.floor(score));
// Different effects based on coin type
var flashColor = 0xFFFFFF;
var soundVolume = 1;
var scaleEffect = 2;
var effectDuration = 300;
// Special effects for different coin types
if (coin.type === 'shiba') {
flashColor = 0xFFAA00;
scaleEffect = 2.5;
effectDuration = 400;
} else if (coin.type === 'pepe') {
flashColor = 0x00FF00;
scaleEffect = 3;
effectDuration = 500;
// Apply special boost for rare coins
player.vy = player.jumpPower * 0.7; // Smaller boost than regular jump
}
// Flash coin with appropriate color and remove
LK.effects.flashObject(coin, flashColor, effectDuration);
LK.getSound('coinCollect').play();
tween(coin, {
alpha: 0,
scaleX: scaleEffect,
scaleY: scaleEffect
}, {
duration: effectDuration,
onFinish: function onFinish() {
coin.active = false;
}
});
}
}
// Check shark collision
if (player.y > 2732 - player.height && player.intersects(shark)) {
// Game over if player touches shark
gameOver();
}
}
// Clean up inactive entities
function cleanupEntities() {
// Remove inactive signals
for (var i = signals.length - 1; i >= 0; i--) {
// Only remove signals if player is not jumping or falling
if (!signals[i].active) {
// Add extra conditions to ensure we don't remove signals that player might need to land on
if (!player || !player.isJumping && player.vy <= 0) {
signals[i].destroy();
signals.splice(i, 1);
}
}
}
// Remove inactive coins
for (var i = memecoins.length - 1; i >= 0; i--) {
if (!memecoins[i].active) {
memecoins[i].destroy();
memecoins.splice(i, 1);
}
}
}
// Game over
function gameOver() {
isGameActive = false;
player.isDead = true;
// Play crash sound
LK.getSound('crash').play();
// Flash screen red
LK.effects.flashScreen(0xFF0000, 500);
// Update high score
var highScore = storage.highScore || 0;
if (score > highScore) {
storage.highScore = score;
highScoreTxt.setText('HIGH SCORE: ' + Math.floor(score));
}
// Show game over after a short delay
LK.setTimeout(function () {
LK.showGameOver();
}, 800);
}
// Input handling
game.down = function (x, y, obj) {
// Jump when tapping/clicking
player.jump();
};
// Main game update loop
game.update = function () {
if (!isGameActive) {
return;
}
// Update score based on distance
distanceTraveled += gameSpeed;
score += scoreIncrement * gameSpeed;
// Update score display occasionally to avoid text updates every frame
if (Math.floor(score) % 5 === 0) {
scoreTxt.setText('SCORE: ' + Math.floor(score));
}
// Increase game speed gradually
gameSpeed = 1 + distanceTraveled / 10000;
// Spawn entities
spawnSignal();
spawnMemecoin();
// Check collisions
checkCollisions();
// Remove inactive entities
cleanupEntities();
// Check if player fell off screen
if (player.y > 2732 + 200) {
gameOver();
}
};
// Initialize UI and game
initUI();
initGame();
// Track signal status globally
game.onEntityDestroyed = function (entity) {
// Keep track of destroyed entities if needed
if (entity instanceof Signal && player) {
// Keep signals around longer if player is falling or jumping
if (player.isJumping || player.vy > 0) {
// Return false to prevent deletion when player might need to land
return false;
}
}
return true;
}; ===================================================================
--- original.js
+++ change.js
@@ -136,45 +136,76 @@
self.x += self.speed * self.direction;
};
return self;
});
-var Signal = Container.expand(function (type, shape) {
+var Signal = Container.expand(function (type) {
var self = Container.call(this);
+ // Add support for more signal types
self.type = type || 'green';
- var assetId = self.type === 'green' ? 'greenSignal' : 'redSignal';
- self.shape = shape || 'normal';
- // Create signal with different visual styles based on shape type
+ var assetId, color;
+ // Define properties based on signal type
+ switch (self.type) {
+ case 'green':
+ assetId = 'greenSignal';
+ self.boostPower = 0;
+ break;
+ case 'red':
+ assetId = 'redSignal';
+ self.boostPower = 0;
+ break;
+ case 'boost':
+ assetId = 'greenSignal';
+ self.boostPower = -20; // Strong upward boost
+ color = 0x00ffff; // Cyan color for boost platforms
+ break;
+ case 'danger':
+ assetId = 'redSignal';
+ self.boostPower = 15; // Downward push
+ color = 0xff00ff; // Magenta color for danger platforms
+ break;
+ case 'bounce':
+ assetId = 'greenSignal';
+ self.boostPower = -15; // Medium upward boost
+ color = 0xffff00; // Yellow color for bounce platforms
+ break;
+ default:
+ assetId = 'greenSignal';
+ self.boostPower = 0;
+ }
var signalGraphics = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1 / 1.2,
scaleY: 1 / 1.2
});
- // Keep signal vertical (no rotation)
- signalGraphics.rotation = 0; // No rotation to ensure signals are vertical
- // Apply visual variations based on shape type
- if (self.shape === 'wide') {
- signalGraphics.scaleX = 1 / 1.4; // Slightly thinner
- signalGraphics.scaleY = 1 / 0.9; // Wider signals
- } else if (self.shape === 'narrow') {
- signalGraphics.scaleX = 1 / 1.0; // Slightly thicker
- signalGraphics.scaleY = 1 / 1.5; // Narrower signals
- } else if (self.shape === 'curved') {
- signalGraphics.scaleX = 1 / 1.3;
- signalGraphics.scaleY = 1 / 1.1;
- signalGraphics.rotation = 0; // Keep vertical
- } else if (self.shape === 'angled') {
- signalGraphics.scaleX = 1 / 1.2;
- signalGraphics.scaleY = 1 / 1.2;
- signalGraphics.rotation = 0; // Keep vertical
+ // Apply custom tint if specified
+ if (color) {
+ signalGraphics.tint = color;
}
+ // Add visual effects for special platforms
+ if (self.type === 'boost' || self.type === 'bounce') {
+ // Add pulsing effect to special platforms
+ self.pulseDirection = 1;
+ self.pulseAmount = 0;
+ self.pulseSpeed = self.type === 'boost' ? 0.03 : 0.02;
+ }
+ // Rotate signal by 90 degrees to the left
+ signalGraphics.rotation = -Math.PI / 2; // -90 degrees in radians
self.speed = 3.5;
self.active = true;
self.update = function () {
if (!self.active) {
return;
}
self.x -= self.speed;
+ // Handle pulsing effect for special platforms
+ if (self.type === 'boost' || self.type === 'bounce') {
+ self.pulseAmount += self.pulseSpeed * self.pulseDirection;
+ if (self.pulseAmount > 0.2 || self.pulseAmount < 0) {
+ self.pulseDirection *= -1;
+ }
+ signalGraphics.scale.set((1 + self.pulseAmount) / 1.2, 1 / 1.2);
+ }
// Remove when off screen only if player is not jumping/falling
// Make sure we keep signals visible while player is falling
if (self.x < -200) {
// Only deactivate if player doesn't exist or if player is not jumping/falling
@@ -250,31 +281,43 @@
// Clear signals and coins
clearEntities();
// Create initial signals that have already reached the left side
var recentHeights = [];
- var recentShapes = []; // Track recent shapes to avoid repetition
var heightThreshold = 60; // Increased threshold to better detect potential overlaps
- var shapeOptions = ['normal', 'wide', 'narrow', 'curved', 'angled'];
for (var i = 0; i < 44; i++) {
- var signalType = Math.random() < 0.5 ? 'green' : 'red';
+ var signalType;
// For signals that are lower than the previous, make them red
// For signals that are higher than the previous, make them green
var lastY = 1500;
if (signals.length > 0) {
lastY = signals[signals.length - 1].y;
}
var newY;
var willBeHigher = Math.random() < 0.5;
+ // Include special signal types in initial setup
+ var includeSpecials = i > 15; // Only include special signals after normal ones are established
+ var specialChance = includeSpecials ? 0.2 : 0; // 20% chance for special signals once enabled
if (willBeHigher) {
// More gradual ascent with varied height differences
var heightDiff = 100 + Math.random() * 150;
newY = lastY - heightDiff;
- signalType = 'green';
+ // Determine signal type for ascending platforms
+ if (Math.random() < specialChance) {
+ signalType = Math.random() < 0.7 ? 'bounce' : 'boost';
+ } else {
+ signalType = 'green';
+ }
} else {
// More gradual descent with varied height differences
var heightDiff = 100 + Math.random() * 150;
newY = lastY + heightDiff;
- signalType = 'red';
+ // Determine signal type for descending platforms
+ if (Math.random() < specialChance * 0.5) {
+ // Less chance for danger in initial setup
+ signalType = 'danger';
+ } else {
+ signalType = 'red';
+ }
}
// Check if this height is too similar to recent heights
var isTooSimilar = recentHeights.length > 0 && recentHeights.some(function (height) {
return Math.abs(newY - height) < heightThreshold;
@@ -293,30 +336,9 @@
recentHeights.push(newY);
if (recentHeights.length > 10) {
recentHeights.shift(); // Keep only last 10 heights
}
- // Choose a signal shape that varies from recent shapes
- var availableShapes = shapeOptions.slice();
- // Remove the most recent shapes from options to avoid repetition
- if (recentShapes.length > 0) {
- availableShapes = availableShapes.filter(function (shape) {
- return !recentShapes.includes(shape);
- });
- }
- // If we filtered out all shapes, use any shape except the most recent one
- if (availableShapes.length === 0) {
- availableShapes = shapeOptions.filter(function (shape) {
- return shape !== recentShapes[recentShapes.length - 1];
- });
- }
- // Select a random shape from available options
- var signalShape = availableShapes[Math.floor(Math.random() * availableShapes.length)];
- // Track recent shapes
- recentShapes.push(signalShape);
- if (recentShapes.length > 3) {
- recentShapes.shift(); // Keep only the last 3 shapes
- }
- var signal = new Signal(signalType, signalShape);
+ var signal = new Signal(signalType);
// Position signals already at the left side of the screen
signal.x = -150 + i * 50; // Distribute signals across the left edge
signal.y = newY;
signals.push(signal);
@@ -353,14 +375,12 @@
if (currentTime - lastSignalTime > adjustedInterval) {
// This ensures spacing remains consistent even at high scores
var signal;
var lastSignalY = 1500; // Default Y position if no signals exist
- var lastSignalShape = 'normal'; // Default shape if no signals exist
- // Get the Y position and shape of the last signal to compare with
+ // Get the Y position of the last signal to compare with
if (signals.length > 0) {
var lastSignal = signals[signals.length - 1];
lastSignalY = lastSignal.y;
- lastSignalShape = lastSignal.shape || 'normal';
}
// Calculate a new Y position
var newY;
var willBeHigher = Math.random() < 0.5; // 50% chance to go higher
@@ -368,24 +388,31 @@
var redSignalCount = 0;
// Find the last signal of each type for height comparison
var lastGreenY = null;
var lastRedY = null;
+ var lastSpecialY = null;
// Track recent signal heights to prevent repetition
var recentHeights = [];
var heightThreshold = 60; // Increased threshold to detect potential overlaps better
- // Collect the last few signal heights for comparison
+ // Track recent signal types
+ var recentTypes = [];
+ // Collect the last few signal heights and types for comparison
for (var i = signals.length - 1; i >= Math.max(0, signals.length - 15); i--) {
recentHeights.push(signals[i].y);
+ recentTypes.push(signals[i].type);
}
- // Find the last green and red signal Y positions
+ // Find the last green, red, and special signal Y positions
for (var i = signals.length - 1; i >= 0; i--) {
if (signals[i].type === 'green' && lastGreenY === null) {
lastGreenY = signals[i].y;
}
if (signals[i].type === 'red' && lastRedY === null) {
lastRedY = signals[i].y;
}
- if (lastGreenY !== null && lastRedY !== null) {
+ if ((signals[i].type === 'boost' || signals[i].type === 'bounce' || signals[i].type === 'danger') && lastSpecialY === null) {
+ lastSpecialY = signals[i].y;
+ }
+ if (lastGreenY !== null && lastRedY !== null && lastSpecialY !== null) {
break;
}
}
for (var i = signals.length - 1; i >= Math.max(0, signals.length - 5); i--) {
@@ -394,21 +421,33 @@
} else {
break;
}
}
- // Choose a signal shape that's different from the last one
- var shapeOptions = ['normal', 'wide', 'narrow', 'curved', 'angled'];
- // Remove the last shape from options to avoid repetition
- var filteredShapes = shapeOptions.filter(function (shape) {
- return shape !== lastSignalShape;
- });
- // Select a random shape from the remaining options
- var signalShape = filteredShapes[Math.floor(Math.random() * filteredShapes.length)];
+ // Count consecutive same type signals
+ var consecutiveSameType = 1;
+ for (var i = recentTypes.length - 1; i > 0; i--) {
+ if (recentTypes[i] === recentTypes[i - 1]) {
+ consecutiveSameType++;
+ } else {
+ break;
+ }
+ }
+ // Determine signal type based on game progression
+ var signalType;
+ var specialRate = Math.min(0.6, score / 2000); // Chance for special signals increases with score
+ var forceSpecialSignal = Math.random() < specialRate && score > 200;
+ var randomSpecial = Math.random();
// Force green signal if we've had 5 reds in a row
if (redSignalCount >= 5) {
// Force green signal (must be higher) but with more gradual ascent
newY = lastSignalY - (100 + Math.random() * 150);
- signal = new Signal('green', signalShape);
+ // Consider introducing a boost platform after many red signals
+ if (forceSpecialSignal && Math.random() < 0.6) {
+ signalType = 'boost';
+ } else {
+ signalType = 'green';
+ }
+ signal = new Signal(signalType);
} else if (willBeHigher) {
// This signal will be higher (ascending)
// More gradual height difference for green signals
var heightDiff = 80 + Math.random() * 120; // Reduced for more cascading effect
@@ -416,10 +455,28 @@
// Limit the maximum height change between signals of same color
heightDiff = Math.min(heightDiff, 200);
}
newY = lastSignalY - heightDiff;
- // Higher signals must be green
- signal = new Signal('green', signalShape);
+ // Higher signals can be green or special
+ if (forceSpecialSignal) {
+ if (randomSpecial < 0.6) {
+ signalType = 'bounce'; // Moderate boost
+ } else {
+ signalType = 'boost'; // Strong boost
+ }
+ } else {
+ signalType = 'green';
+ }
+ // Avoid too many consecutive signals of the same type
+ if (consecutiveSameType >= 3 && recentTypes.length > 0 && recentTypes[recentTypes.length - 1] === signalType) {
+ // Force a different type
+ if (signalType === 'green') {
+ signalType = Math.random() < 0.7 ? 'bounce' : 'boost';
+ } else {
+ signalType = 'green';
+ }
+ }
+ signal = new Signal(signalType);
} else {
// This signal will be lower (descending)
// More gradual height difference for red signals
var heightDiff = 80 + Math.random() * 120; // Reduced for more cascading effect
@@ -432,13 +489,27 @@
var wouldBeConsecutiveReds = redSignalCount + 1;
if (wouldBeConsecutiveReds >= 5) {
// Force this to be a green signal instead with gradual ascent
newY = lastSignalY - (100 + Math.random() * 150);
- signal = new Signal('green', signalShape);
+ signalType = 'green';
} else {
- // Lower signals must be red
- signal = new Signal('red', signalShape);
+ // Lower signals can be red or danger
+ if (forceSpecialSignal && Math.random() < 0.4 && score > 500) {
+ signalType = 'danger';
+ } else {
+ signalType = 'red';
+ }
+ // Avoid too many consecutive signals of the same type
+ if (consecutiveSameType >= 3 && recentTypes.length > 0 && recentTypes[recentTypes.length - 1] === signalType) {
+ // Force a different type
+ if (signalType === 'red') {
+ signalType = Math.random() < 0.3 ? 'danger' : 'red';
+ } else {
+ signalType = 'red';
+ }
+ }
}
+ signal = new Signal(signalType);
}
// Ensure signal stays within playable area
newY = Math.max(800, Math.min(2200, newY));
// Additional check for signals that might be about to overlap (within 25px)
@@ -559,19 +630,48 @@
var signalWidth = 500 / 1.2; // Original width divided by scale factor
var playerHeight = 150; // Player height
// Calculate where the top of the signal is considering rotation
if (player.y < signal.y - signalWidth / 2 && player.vy > 0) {
- if (signal.type === 'green') {
- // Land on green signals but don't automatically jump
- // Position player properly on top of the signal
- player.y = signal.y - signalWidth / 2 - playerHeight / 2;
- player.vy = 0;
- player.isJumping = false;
- } else if (signal.type === 'red') {
- // Pass through red signals, ignore collision
- // Don't land on red signals, continue falling
- player.vy += player.gravity;
- player.isJumping = true;
+ switch (signal.type) {
+ case 'green':
+ // Land on green signals but don't automatically jump
+ // Position player properly on top of the signal
+ player.y = signal.y - signalWidth / 2 - playerHeight / 2;
+ player.vy = 0;
+ player.isJumping = false;
+ break;
+ case 'boost':
+ // Boost platforms give an automatic jump
+ player.y = signal.y - signalWidth / 2 - playerHeight / 2;
+ player.vy = signal.boostPower; // Strong upward boost
+ player.isJumping = true;
+ // Add boost visual effect
+ LK.effects.flashObject(signal, 0x00ffff, 300);
+ LK.getSound('jump').play();
+ break;
+ case 'bounce':
+ // Bounce platforms give a medium jump
+ player.y = signal.y - signalWidth / 2 - playerHeight / 2;
+ player.vy = signal.boostPower; // Medium upward boost
+ player.isJumping = true;
+ // Add bounce visual effect
+ LK.effects.flashObject(signal, 0xffff00, 200);
+ LK.getSound('jump').play();
+ break;
+ case 'danger':
+ // Danger platforms push player down
+ player.vy = signal.boostPower; // Downward push
+ player.isJumping = true;
+ // Add danger visual effect
+ LK.effects.flashObject(signal, 0xff00ff, 200);
+ break;
+ case 'red':
+ default:
+ // Pass through red signals, ignore collision
+ // Don't land on red signals, continue falling
+ player.vy += player.gravity;
+ player.isJumping = true;
+ break;
}
}
}
} else if (signal.active) {
Grey shark, sideview. In-Game asset. 2d. High contrast. No shadows
Golden Dogecoin
Golden memecoin with sunglasses
shiba inu golden memecoin
Golden memecoin with Pepe
Golden coin with Floki
Golden coin with volt
Golden coin with cute catface
Golden coin with Trump and 'WILL FIX IT' Text
Lightning line. In-Game asset. 2d. High contrast. No shadows