Code edit (5 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
User prompt
put hearts top left corner and give little bir space between score and distance
User prompt
Please fix the bug: 'LK.getHighScore is not a function' in or related to this line: 'var highScore = LK.getHighScore() || 0;' Line Number: 1164 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
fix all of ui and add a menu ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
make game easier obstacles are coming so fast. but keep increase difficulty by levels
User prompt
keep background more pixeleted aesthatic and fix the lighting with a proper pixel-art sunlight and reflection. they must be infinite and related with Level 1 (day), Level 2 (sunset), Level 3 (night), Level 4 (storm) ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Remix started
Copy Maritime Quiz Navigator
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Coin = Container.expand(function () {
var self = Container.call(this);
var coinGraphics = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 4;
self.update = function () {
if (gamePaused) return; // Freeze movement during quiz
self.y += self.speed;
coinGraphics.rotation += 0.1;
};
return self;
});
var CrewMember = Container.expand(function () {
var self = Container.call(this);
var crewGraphics = self.attachAsset('crew', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 4;
self.update = function () {
if (gamePaused) return; // Freeze movement during quiz
self.y += self.speed;
};
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 5;
self.update = function () {
if (gamePaused) return; // Freeze movement during quiz
self.y += self.speed;
};
return self;
});
var Pirate = Container.expand(function () {
var self = Container.call(this);
var pirateGraphics = self.attachAsset('pirate', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6;
self.update = function () {
if (gamePaused) return; // Freeze movement during quiz
self.y += self.speed;
pirateGraphics.rotation += 0.05;
};
return self;
});
var Ship = Container.expand(function () {
var self = Container.call(this);
var shipGraphics = self.attachAsset('ship', {
anchorX: 0.5,
anchorY: 0.5
});
self.baseSpeed = 3;
self.currentSpeed = self.baseSpeed;
self.isShielded = false;
self.shieldTime = 0;
self.stickyTime = 0;
self.isSizeModified = false;
self.sizeTime = 0;
self.originalScale = 1;
var shieldGraphics = self.attachAsset('shield', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5
});
shieldGraphics.visible = false;
self.activateShield = function () {
self.isShielded = true;
self.shieldTime = 300;
shieldGraphics.visible = true;
};
self.activateStickyControls = function () {
self.stickyTime = 300;
};
self.setSizeModifier = function (scale, duration) {
self.isSizeModified = true;
self.sizeTime = duration;
tween(shipGraphics, {
scaleX: scale,
scaleY: scale
}, {
duration: 200
});
tween(shieldGraphics, {
scaleX: scale,
scaleY: scale
}, {
duration: 200
});
};
self.update = function () {
if (gamePaused) {
return;
} // Freeze movement when game is paused
if (self.shieldTime > 0) {
self.shieldTime--;
if (self.shieldTime <= 0) {
self.isShielded = false;
shieldGraphics.visible = false;
}
}
if (self.stickyTime > 0) {
self.stickyTime--;
}
if (self.sizeTime > 0) {
self.sizeTime--;
if (self.sizeTime <= 0) {
self.isSizeModified = false;
tween(shipGraphics, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
tween(shieldGraphics, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
}
}
// Ship stays in place - world moves around it
};
return self;
});
var Stone = Container.expand(function () {
var self = Container.call(this);
var stoneGraphics = self.attachAsset('stone', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 7;
self.update = function () {
if (gamePaused) return; // Freeze movement during quiz
self.y += self.speed;
stoneGraphics.rotation += 0.08;
};
return self;
});
var Sunlight = Container.expand(function () {
var self = Container.call(this);
var sunGraphics = self.attachAsset('sunlight', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 1;
self.update = function () {
if (gamePaused) return;
self.y += self.speed;
// Animate sunlight rays
sunGraphics.alpha = 0.3 + Math.sin(LK.ticks * 0.05 + self.x * 0.02) * 0.2;
sunGraphics.scaleX = 1 + Math.sin(LK.ticks * 0.03) * 0.1;
};
return self;
});
var WaterTile = Container.expand(function () {
var self = Container.call(this);
var tileGraphics = self.attachAsset('waterTile', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.update = function () {
if (gamePaused) return;
self.y += self.speed;
// Add subtle wave animation
tileGraphics.alpha = 0.8 + Math.sin(LK.ticks * 0.02 + self.x * 0.01) * 0.2;
};
return self;
});
var Wave = Container.expand(function () {
var self = Container.call(this);
var waveGraphics = self.attachAsset('wave', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 4;
self.update = function () {
if (gamePaused) return; // Freeze movement during quiz
self.y += self.speed;
waveGraphics.scaleX = 1 + Math.sin(LK.ticks * 0.1) * 0.2;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
var ship;
var obstacles = [];
var crewMembers = [];
var coins = [];
var hearts = [];
var waterTiles = [];
var sunlightRays = [];
var level = 1;
var health = 3;
var crewCount = 0;
var coinCount = 0;
var distance = 0;
var gamePaused = false;
var distanceText = new Text2('Distance: 0m', {
size: 55,
fill: 0xFF69B4
});
distanceText.anchor.set(0, 0);
distanceText.x = 120;
distanceText.y = 100;
LK.gui.top.addChild(distanceText);
var gameSpeed = 2;
var quizActive = false;
var quizTimer = 0;
var nextQuizTime = 480; // Start first quiz after 8 seconds
var doubleCoinsTime = 0;
var extraObstaclesTime = 0;
var clearPathTime = 0;
var scoreFreezeTime = 0;
// Quiz system
var quizQuestions = [{
question: "What does FOB stand for in shipping terms?",
answers: ["Free On Board", "Freight on Boat", "Foreign Object Bureau", "Full Ocean Bill"],
correct: 0
}, {
question: "Which maritime organization sets international shipping standards?",
answers: ["WHO", "IMO", "WTO", "ILO"],
correct: 1
}, {
question: "What is the front of a ship called?",
answers: ["Stern", "Port", "Bow", "Starboard"],
correct: 2
}, {
question: "EXW means the seller delivers when goods are:",
answers: ["At seller's premises", "On the ship", "At destination", "In transit"],
correct: 0
}, {
question: "What does CIF include in shipping terms?",
answers: ["Cost only", "Insurance only", "Freight only", "Cost, Insurance, Freight"],
correct: 3
}, {
question: "What is the right side of a ship called?",
answers: ["Port", "Starboard", "Bow", "Stern"],
correct: 1
}, {
question: "DDP means the seller is responsible for:",
answers: ["Delivery at port", "Delivery duty paid", "Dock departure point", "Direct delivery purchase"],
correct: 1
}, {
question: "What does TEU stand for in container shipping?",
answers: ["Total Export Unit", "Twenty-foot Equivalent Unit", "Terminal Exchange Unit", "Transport Equipment Unit"],
correct: 1
}, {
question: "Which term means 'Carrier alongside ship'?",
answers: ["CAS", "FAS", "DAS", "PAS"],
correct: 1
}, {
question: "What is the kitchen area on a ship called?",
answers: ["Mess", "Galley", "Cabin", "Hold"],
correct: 1
}, {
question: "CFR includes which costs?",
answers: ["Cost and freight", "Cost, freight, risk", "Customs, freight, rate", "Container freight rate"],
correct: 0
}, {
question: "What does DAP stand for?",
answers: ["Delivery at place", "Dock arrival point", "Delivered at place", "Direct arrival point"],
correct: 2
}, {
question: "The left side of a ship is called:",
answers: ["Starboard", "Port", "Bow", "Stern"],
correct: 1
}, {
question: "What is a ship's maximum cargo capacity called?",
answers: ["Deadweight", "Gross tonnage", "Net tonnage", "Displacement"],
correct: 0
}, {
question: "FCA means:",
answers: ["Free carrier", "Freight cost allowance", "Full container access", "Forward cargo arrangement"],
correct: 0
}];
var currentQuiz = null;
var quizContainer = null;
var quizTimeRemaining = 600; // 10 seconds
var effectDisplay = null;
var lastAppliedEffect = '';
var effectExpirationDisplay = null;
// UI Elements - Better separated and positioned
var scoreText = new Text2('Score: 0', {
size: 70,
fill: 0x00FF00
});
scoreText.anchor.set(0, 0);
scoreText.x = 120;
scoreText.y = 20;
LK.gui.top.addChild(scoreText);
var levelText = new Text2('Level: 1', {
size: 60,
fill: 0xFFD700
});
levelText.anchor.set(0, 0);
levelText.x = 120;
levelText.y = 20;
LK.gui.topLeft.addChild(levelText);
var crewText = new Text2('Crew: 0', {
size: 50,
fill: 0x00BFFF
});
crewText.anchor.set(0, 1);
crewText.x = 20;
crewText.y = -20;
LK.gui.bottomLeft.addChild(crewText);
var coinText = new Text2('Coins: 0', {
size: 50,
fill: 0xffd700
});
coinText.anchor.set(1, 1);
coinText.x = -20;
coinText.y = -20;
LK.gui.bottomRight.addChild(coinText);
// Initialize pixelated ocean background
createWaterTileGrid();
// Initialize game elements
ship = game.addChild(new Ship());
ship.x = 1024;
ship.y = 2400;
// Create hearts display
for (var i = 0; i < 3; i++) {
var heart = LK.getAsset('heart', {
anchorX: 0.5,
anchorY: 0.5,
x: 150 + i * 60,
y: 100
});
hearts.push(heart);
LK.gui.topLeft.addChild(heart);
}
function updateScore() {
if (scoreFreezeTime <= 0) {
var score = Math.floor(distance) + crewCount * 100;
LK.setScore(score);
scoreText.setText('Score: ' + score);
}
}
function updateLevel() {
var newLevel = Math.floor(distance / 3000) + 1; // Level up faster for increased difficulty
if (newLevel > level && newLevel <= 4) {
level = newLevel;
levelText.setText('Level: ' + level);
gameSpeed += 0.5; // Increased speed boost per level
// Change background color and lighting based on level
if (level === 1) {
game.setBackgroundColor(0x87CEEB); // Day - bright sky blue
updateWaterTileColors(0x0066cc); // Bright blue water
updateSunlightColors(0xffff99, 0.4); // Bright yellow sunlight
} else if (level === 2) {
game.setBackgroundColor(0xFF8C00); // Sunset - orange
updateWaterTileColors(0x004499); // Darker blue water
updateSunlightColors(0xffcc66, 0.5); // Orange sunset light
} else if (level === 3) {
game.setBackgroundColor(0x191970); // Night - dark blue
updateWaterTileColors(0x002266); // Very dark blue water
updateSunlightColors(0x9999ff, 0.2); // Moonlight - pale blue
} else if (level === 4) {
game.setBackgroundColor(0x2F4F4F); // Storm - dark gray
updateWaterTileColors(0x003344); // Dark stormy water
updateSunlightColors(0xcccccc, 0.1); // Storm light - gray
}
}
}
function updateWaterTileColors(color) {
for (var i = 0; i < waterTiles.length; i++) {
if (waterTiles[i] && waterTiles[i].children[0]) {
tween(waterTiles[i].children[0], {
tint: color
}, {
duration: 2000
});
}
}
}
function updateSunlightColors(color, maxAlpha) {
for (var i = 0; i < sunlightRays.length; i++) {
if (sunlightRays[i] && sunlightRays[i].children[0]) {
tween(sunlightRays[i].children[0], {
tint: color
}, {
duration: 2000
});
sunlightRays[i].maxAlpha = maxAlpha;
}
}
}
function createWaterTileGrid() {
// Create a grid of water tiles for pixelated ocean background
for (var x = 0; x < 22; x++) {
// Cover full width with some overlap
for (var y = -5; y < 35; y++) {
// Cover full height with extra tiles
var waterTile = new WaterTile();
waterTile.x = x * 95; // Slight overlap for seamless look
waterTile.y = y * 95;
waterTiles.push(waterTile);
game.addChild(waterTile);
}
}
}
function spawnSunlightRay() {
var sunray = new Sunlight();
sunray.x = Math.random() * 2048;
sunray.y = -400;
sunray.maxAlpha = level === 1 ? 0.4 : level === 2 ? 0.5 : level === 3 ? 0.2 : 0.1;
sunlightRays.push(sunray);
game.addChild(sunray);
}
function spawnObstacle() {
if (clearPathTime > 0) {
return;
}
var obstacleType = Math.floor(Math.random() * 4);
var obstacle;
switch (obstacleType) {
case 0:
obstacle = new Obstacle();
break;
case 1:
obstacle = new Pirate();
break;
case 2:
obstacle = new Wave();
break;
case 3:
obstacle = new Stone();
break;
}
obstacle.x = Math.random() * 1800 + 124;
obstacle.y = -100;
obstacle.speed = obstacle.speed + gameSpeed + level * 0.8; // Faster obstacles at higher levels
obstacles.push(obstacle);
game.addChild(obstacle);
}
function spawnCrewMember() {
var crew = new CrewMember();
crew.x = Math.random() * 1800 + 124;
crew.y = -100;
crew.speed = 3 + gameSpeed;
crewMembers.push(crew);
game.addChild(crew);
}
function spawnCoin() {
var coin = new Coin();
coin.x = Math.random() * 1800 + 124;
coin.y = -100;
coin.speed = 3 + gameSpeed;
coins.push(coin);
game.addChild(coin);
}
function showQuiz() {
if (quizActive) {
return;
}
quizActive = true;
gamePaused = true; // Freeze all game movement
quizTimeRemaining = 1200; // 20 seconds
currentQuiz = quizQuestions[Math.floor(Math.random() * quizQuestions.length)];
quizContainer = game.addChild(new Container());
quizContainer.alpha = 0; // Start invisible for smooth entrance
var bg = quizContainer.attachAsset('quizBg', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366,
alpha: 0.95
});
// Animate quiz entrance
tween(quizContainer, {
alpha: 1
}, {
duration: 300
});
// Show current active effects
var effectsText = getActiveEffectsText();
if (effectsText) {
var effectDisplay = new Text2(effectsText, {
size: 45,
fill: 0xFFFF00
});
effectDisplay.anchor.set(0.5, 0.5);
effectDisplay.x = 1024;
effectDisplay.y = 900;
quizContainer.addChild(effectDisplay);
}
var questionText = new Text2(currentQuiz.question, {
size: 65,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 2,
wordWrap: true,
wordWrapWidth: 1600
});
questionText.anchor.set(0.5, 0.5);
questionText.x = 1024;
questionText.y = 1150;
quizContainer.addChild(questionText);
var timerText = new Text2('Time: 20', {
size: 80,
fill: 0xFFFF00,
stroke: 0x000000,
strokeThickness: 3
});
timerText.anchor.set(0.5, 0.5);
timerText.x = 1024;
timerText.y = 950;
quizContainer.addChild(timerText);
quizContainer.timerText = timerText;
// Create answer buttons with improved styling
quizContainer.answerButtons = [];
for (var i = 0; i < 4; i++) {
var answerContainer = new Container();
answerContainer.x = 1024;
answerContainer.y = 1350 + i * 140;
answerContainer.answerIndex = i;
var answerBg = answerContainer.attachAsset('quizBg', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.9,
scaleY: 0.25,
alpha: 0.8
});
var answerText = new Text2(String.fromCharCode(65 + i) + ') ' + currentQuiz.answers[i], {
size: 55,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 2
});
answerText.anchor.set(0.5, 0.5);
answerContainer.addChild(answerText);
// Store references for animations
answerContainer.bg = answerBg;
answerContainer.text = answerText;
// Store index in closure to avoid reference issues
answerContainer.down = function (index) {
return function (x, y, obj) {
// Animate button press - use the stored references instead of obj properties
tween(answerContainer.bg, {
scaleX: 0.95,
scaleY: 0.22
}, {
duration: 100
});
tween(answerContainer.text, {
alpha: 0.8
}, {
duration: 100
});
handleQuizAnswer(index);
};
}(i);
quizContainer.answerButtons.push(answerContainer);
quizContainer.addChild(answerContainer);
}
}
function handleQuizAnswer(answerIndex) {
if (!quizActive) {
return;
}
// Prevent multiple answers
quizActive = false;
var isCorrect = answerIndex === currentQuiz.correct;
if (isCorrect) {
LK.getSound('correct').play();
applyPowerUp();
} else {
LK.getSound('wrong').play();
applyPenalty();
}
// Show effect feedback for 2 seconds
if (lastAppliedEffect) {
showEffectFeedback(lastAppliedEffect, isCorrect);
}
hideQuiz();
nextQuizTime = LK.ticks + 480; // Every 8 seconds
}
function getActiveEffectsText() {
var effects = [];
if (ship.isShielded) {
effects.push('🛡️ Shield Active');
}
if (doubleCoinsTime > 0) {
effects.push('💰 Double Coins');
}
if (ship.isSizeModified && ship.children[0].scaleX < 1) {
effects.push('⬇️ Smaller Ship');
}
if (ship.isSizeModified && ship.children[0].scaleX > 1) {
effects.push('⬆️ Bigger Ship');
}
if (ship.stickyTime > 0) {
effects.push('🐌 Sticky Controls');
}
if (extraObstaclesTime > 0) {
effects.push('⚠️ Extra Obstacles');
}
if (scoreFreezeTime > 0) {
effects.push('❄️ Score Frozen');
}
if (clearPathTime > 0) {
effects.push('🚫 Clear Path');
}
if (effects.length === 0) {
return null;
}
return 'Active Effects:\n' + effects.join('\n');
}
function applyPowerUp() {
var powerUps = ['shield', 'doubleCoins', 'extraLife', 'clearPath', 'smallerShip'];
var powerUp = powerUps[Math.floor(Math.random() * powerUps.length)];
switch (powerUp) {
case 'shield':
ship.activateShield();
lastAppliedEffect = '🛡️ Shield Activated!';
break;
case 'doubleCoins':
doubleCoinsTime = 600;
lastAppliedEffect = '💰 Double Coins for 10s!';
break;
case 'extraLife':
if (health < 5) {
health++;
updateHearts();
lastAppliedEffect = '❤️ Extra Life Gained!';
} else {
lastAppliedEffect = '❤️ Life Full Already!';
}
break;
case 'clearPath':
clearPathTime = 240;
lastAppliedEffect = '🚫 Clear Path for 4s!';
// Remove existing obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
obstacles[i].destroy();
obstacles.splice(i, 1);
}
break;
case 'smallerShip':
ship.setSizeModifier(0.7, 300);
lastAppliedEffect = '⬇️ Smaller Ship for 5s!';
break;
}
}
function applyPenalty() {
var penalties = ['extraObstacles', 'healthLoss', 'stickyControls', 'scoreFreeze', 'biggerShip'];
var penalty = penalties[Math.floor(Math.random() * penalties.length)];
switch (penalty) {
case 'extraObstacles':
extraObstaclesTime = 480;
lastAppliedEffect = '⚠️ Extra Obstacles for 8s!';
break;
case 'healthLoss':
takeDamage();
lastAppliedEffect = '💔 Lost 1 Heart!';
break;
case 'stickyControls':
ship.activateStickyControls();
lastAppliedEffect = '🐌 Sticky Controls for 5s!';
break;
case 'scoreFreeze':
scoreFreezeTime = 300;
lastAppliedEffect = '❄️ Score Frozen for 5s!';
break;
case 'biggerShip':
ship.setSizeModifier(1.4, 240);
lastAppliedEffect = '⬆️ Bigger Ship for 4s!';
break;
}
}
function showEffectExpiration(effectName) {
if (effectExpirationDisplay) {
effectExpirationDisplay.destroy();
}
effectExpirationDisplay = game.addChild(new Container());
var expirationBg = effectExpirationDisplay.attachAsset('quizBg', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 400,
scaleX: 0.5,
scaleY: 0.2,
alpha: 0.8
});
var expirationText = new Text2(effectName + ' Expired!', {
size: 45,
fill: 0xFFAA00
});
expirationText.anchor.set(0.5, 0.5);
expirationText.x = 1024;
expirationText.y = 400;
effectExpirationDisplay.addChild(expirationText);
// Auto-hide after 1.5 seconds
LK.setTimeout(function () {
if (effectExpirationDisplay) {
effectExpirationDisplay.destroy();
effectExpirationDisplay = null;
}
}, 1500);
}
function showEffectFeedback(effectText, isPositive) {
if (effectDisplay) {
effectDisplay.destroy();
}
effectDisplay = game.addChild(new Container());
var feedbackBg = effectDisplay.attachAsset('quizBg', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366,
scaleX: 0.6,
scaleY: 0.3,
alpha: 0.8
});
var feedbackText = new Text2(effectText, {
size: 60,
fill: isPositive ? 0x00FF00 : 0xFF4444
});
feedbackText.anchor.set(0.5, 0.5);
feedbackText.x = 1024;
feedbackText.y = 1366;
effectDisplay.addChild(feedbackText);
// Auto-hide after 2 seconds
LK.setTimeout(function () {
if (effectDisplay) {
effectDisplay.destroy();
effectDisplay = null;
}
}, 2000);
}
function hideQuiz() {
quizActive = false;
gamePaused = false; // Resume game movement
if (quizContainer) {
// Animate quiz exit
tween(quizContainer, {
alpha: 0
}, {
duration: 200,
onFinish: function onFinish() {
if (quizContainer) {
quizContainer.destroy();
quizContainer = null;
}
}
});
}
}
function takeDamage() {
if (ship.isShielded) {
return;
}
health--;
updateHearts();
LK.getSound('hit').play();
LK.effects.flashScreen(0xff0000, 500);
if (health <= 0) {
// Create custom game over display with statistics
var gameOverContainer = game.addChild(new Container());
var gameOverBg = gameOverContainer.attachAsset('quizBg', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366,
scaleX: 1.2,
scaleY: 1.4,
alpha: 0.95
});
var finalScore = Math.floor(distance) + crewCount * 100;
var statsText = 'GAME OVER\n\n' + 'Final Statistics:\n' + 'Score: ' + finalScore + '\n' + 'Distance: ' + Math.floor(distance) + 'm\n' + 'Crew Members: ' + crewCount + '\n' + 'Coins: ' + coinCount + '\n' + 'Level Reached: ' + level;
var statsDisplay = new Text2(statsText, {
size: 60,
fill: 0xFFFFFF
});
statsDisplay.anchor.set(0.5, 0.5);
statsDisplay.x = 1024;
statsDisplay.y = 1366;
gameOverContainer.addChild(statsDisplay);
// Show standard game over after 3 seconds
LK.setTimeout(function () {
LK.showGameOver();
}, 3000);
}
}
function updateHearts() {
for (var i = 0; i < hearts.length; i++) {
hearts[i].visible = i < health;
}
}
var targetX = 1024;
game.move = function (x, y, obj) {
if (quizActive) {
return;
}
targetX = x;
};
game.update = function () {
if (quizActive) {
// Update quiz timer
if (quizTimeRemaining > 0) {
quizTimeRemaining--;
var secondsLeft = Math.ceil(quizTimeRemaining / 60);
if (quizContainer && quizContainer.timerText) {
quizContainer.timerText.setText('Time: ' + secondsLeft);
// Change timer color as time runs out
if (secondsLeft <= 5) {
quizContainer.timerText.tint = 0xFF0000; // Red when almost out of time
tween(quizContainer.timerText, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 100
});
tween(quizContainer.timerText, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
} else if (secondsLeft <= 10) {
quizContainer.timerText.tint = 0xFFAA00; // Orange warning
} else {
quizContainer.timerText.tint = 0xFFFF00; // Yellow normal
}
}
if (quizTimeRemaining <= 0) {
// Time's up - apply penalty
LK.getSound('wrong').play();
applyPenalty();
hideQuiz();
nextQuizTime = LK.ticks + 480; // 8 seconds after timeout
}
}
return; // Completely freeze game while quiz is active
}
// Move ship towards target
if (ship.stickyTime <= 0) {
var diff = targetX - ship.x;
ship.x += diff * 0.1;
} else {
var stickyDiff = targetX - ship.x;
ship.x += stickyDiff * 0.02; // Much slower movement
}
// Keep ship in bounds
if (ship.x < 60) {
ship.x = 60;
}
if (ship.x > 1988) {
ship.x = 1988;
}
// Update distance and score
distance += gameSpeed;
updateScore();
updateLevel();
// Update distance display
distanceText.setText('Distance: ' + Math.floor(distance) + 'm');
// Progressive difficulty scaling based on distance
var difficultyMultiplier = 1 + Math.floor(distance / 500) * 0.3; // Increase difficulty every 500m
gameSpeed = Math.min(8, 2 + difficultyMultiplier); // Cap max speed at 8
// Update timers and show expiration notifications
if (doubleCoinsTime > 0) {
doubleCoinsTime--;
if (doubleCoinsTime === 0) {
showEffectExpiration('💰 Double Coins');
}
}
if (extraObstaclesTime > 0) {
extraObstaclesTime--;
if (extraObstaclesTime === 0) {
showEffectExpiration('⚠️ Extra Obstacles');
}
}
if (clearPathTime > 0) {
clearPathTime--;
if (clearPathTime === 0) {
showEffectExpiration('🛡️ Clear Path');
}
}
if (scoreFreezeTime > 0) {
scoreFreezeTime--;
if (scoreFreezeTime === 0) {
showEffectExpiration('❄️ Score Freeze');
}
}
// Show quiz
if (LK.ticks >= nextQuizTime) {
showQuiz();
}
// Spawn objects - increased difficulty based on distance
var baseSpawnRate = Math.max(8, 40 - Math.floor(distance / 300)); // Faster spawning every 300m distance
var obstacleSpawnRate = Math.max(5, baseSpawnRate - level * 3); // Much faster spawning at higher levels
if (LK.ticks % obstacleSpawnRate === 0) {
spawnObstacle();
// Spawn additional obstacles based on distance traveled
if (distance > 1000 && LK.ticks % (obstacleSpawnRate * 2) === 0) {
spawnObstacle(); // Extra obstacle after 1000m
}
if (distance > 2000 && LK.ticks % (obstacleSpawnRate * 3) === 0) {
spawnObstacle(); // Even more obstacles after 2000m
}
if (extraObstaclesTime > 0 && LK.ticks % Math.max(4, obstacleSpawnRate / 4) === 0) {
spawnObstacle(); // Extra obstacles during penalty
}
}
if (LK.ticks % 600 === 0) {
// Every 10 seconds - less frequent crew
spawnCrewMember();
}
if (LK.ticks % 150 === 0) {
// Every 2.5 seconds - slightly more frequent coins
spawnCoin();
}
// Update obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
if (obstacle.y > 2800) {
obstacle.destroy();
obstacles.splice(i, 1);
continue;
}
if (ship.intersects(obstacle)) {
obstacle.destroy();
obstacles.splice(i, 1);
takeDamage();
continue;
}
}
// Update crew members
for (var i = crewMembers.length - 1; i >= 0; i--) {
var crew = crewMembers[i];
if (crew.y > 2800) {
crew.destroy();
crewMembers.splice(i, 1);
continue;
}
if (ship.intersects(crew)) {
crewCount++;
crewText.setText('Crew: ' + crewCount);
crew.destroy();
crewMembers.splice(i, 1);
LK.getSound('collect').play();
continue;
}
}
// Update water tiles for infinite scrolling
for (var i = waterTiles.length - 1; i >= 0; i--) {
var tile = waterTiles[i];
if (tile.y > 2800) {
// Reset tile position to top for infinite scrolling
tile.y = -100;
}
}
// Spawn sunlight rays periodically
if (LK.ticks % 180 === 0) {
// Every 3 seconds
spawnSunlightRay();
}
// Update sunlight rays
for (var i = sunlightRays.length - 1; i >= 0; i--) {
var ray = sunlightRays[i];
if (ray.y > 2800) {
ray.destroy();
sunlightRays.splice(i, 1);
continue;
}
// Update alpha based on level and animation
if (ray.children[0]) {
ray.children[0].alpha = (ray.maxAlpha || 0.3) + Math.sin(LK.ticks * 0.05 + ray.x * 0.02) * 0.2;
}
}
// Update coins
for (var i = coins.length - 1; i >= 0; i--) {
var coin = coins[i];
if (coin.y > 2800) {
coin.destroy();
coins.splice(i, 1);
continue;
}
if (ship.intersects(coin)) {
var coinValue = doubleCoinsTime > 0 ? 20 : 10;
coinCount++;
coinText.setText('Coins: ' + coinCount);
if (scoreFreezeTime <= 0) {
distance += coinValue;
}
coin.destroy();
coins.splice(i, 1);
LK.getSound('collect').play();
continue;
}
}
}; ===================================================================
--- original.js
+++ change.js
@@ -153,8 +153,39 @@
stoneGraphics.rotation += 0.08;
};
return self;
});
+var Sunlight = Container.expand(function () {
+ var self = Container.call(this);
+ var sunGraphics = self.attachAsset('sunlight', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 1;
+ self.update = function () {
+ if (gamePaused) return;
+ self.y += self.speed;
+ // Animate sunlight rays
+ sunGraphics.alpha = 0.3 + Math.sin(LK.ticks * 0.05 + self.x * 0.02) * 0.2;
+ sunGraphics.scaleX = 1 + Math.sin(LK.ticks * 0.03) * 0.1;
+ };
+ return self;
+});
+var WaterTile = Container.expand(function () {
+ var self = Container.call(this);
+ var tileGraphics = self.attachAsset('waterTile', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 2;
+ self.update = function () {
+ if (gamePaused) return;
+ self.y += self.speed;
+ // Add subtle wave animation
+ tileGraphics.alpha = 0.8 + Math.sin(LK.ticks * 0.02 + self.x * 0.01) * 0.2;
+ };
+ return self;
+});
var Wave = Container.expand(function () {
var self = Container.call(this);
var waveGraphics = self.attachAsset('wave', {
anchorX: 0.5,
@@ -183,8 +214,10 @@
var obstacles = [];
var crewMembers = [];
var coins = [];
var hearts = [];
+var waterTiles = [];
+var sunlightRays = [];
var level = 1;
var health = 3;
var crewCount = 0;
var coinCount = 0;
@@ -306,8 +339,10 @@
coinText.anchor.set(1, 1);
coinText.x = -20;
coinText.y = -20;
LK.gui.bottomRight.addChild(coinText);
+// Initialize pixelated ocean background
+createWaterTileGrid();
// Initialize game elements
ship = game.addChild(new Ship());
ship.x = 1024;
ship.y = 2400;
@@ -334,18 +369,73 @@
if (newLevel > level && newLevel <= 4) {
level = newLevel;
levelText.setText('Level: ' + level);
gameSpeed += 0.5; // Increased speed boost per level
- // Change background color based on level
- if (level === 2) {
- game.setBackgroundColor(0xFF8C00); // Orange sunset
+ // Change background color and lighting based on level
+ if (level === 1) {
+ game.setBackgroundColor(0x87CEEB); // Day - bright sky blue
+ updateWaterTileColors(0x0066cc); // Bright blue water
+ updateSunlightColors(0xffff99, 0.4); // Bright yellow sunlight
+ } else if (level === 2) {
+ game.setBackgroundColor(0xFF8C00); // Sunset - orange
+ updateWaterTileColors(0x004499); // Darker blue water
+ updateSunlightColors(0xffcc66, 0.5); // Orange sunset light
} else if (level === 3) {
- game.setBackgroundColor(0x191970); // Dark blue night
+ game.setBackgroundColor(0x191970); // Night - dark blue
+ updateWaterTileColors(0x002266); // Very dark blue water
+ updateSunlightColors(0x9999ff, 0.2); // Moonlight - pale blue
} else if (level === 4) {
- game.setBackgroundColor(0x2F4F4F); // Dark gray storm
+ game.setBackgroundColor(0x2F4F4F); // Storm - dark gray
+ updateWaterTileColors(0x003344); // Dark stormy water
+ updateSunlightColors(0xcccccc, 0.1); // Storm light - gray
}
}
}
+function updateWaterTileColors(color) {
+ for (var i = 0; i < waterTiles.length; i++) {
+ if (waterTiles[i] && waterTiles[i].children[0]) {
+ tween(waterTiles[i].children[0], {
+ tint: color
+ }, {
+ duration: 2000
+ });
+ }
+ }
+}
+function updateSunlightColors(color, maxAlpha) {
+ for (var i = 0; i < sunlightRays.length; i++) {
+ if (sunlightRays[i] && sunlightRays[i].children[0]) {
+ tween(sunlightRays[i].children[0], {
+ tint: color
+ }, {
+ duration: 2000
+ });
+ sunlightRays[i].maxAlpha = maxAlpha;
+ }
+ }
+}
+function createWaterTileGrid() {
+ // Create a grid of water tiles for pixelated ocean background
+ for (var x = 0; x < 22; x++) {
+ // Cover full width with some overlap
+ for (var y = -5; y < 35; y++) {
+ // Cover full height with extra tiles
+ var waterTile = new WaterTile();
+ waterTile.x = x * 95; // Slight overlap for seamless look
+ waterTile.y = y * 95;
+ waterTiles.push(waterTile);
+ game.addChild(waterTile);
+ }
+ }
+}
+function spawnSunlightRay() {
+ var sunray = new Sunlight();
+ sunray.x = Math.random() * 2048;
+ sunray.y = -400;
+ sunray.maxAlpha = level === 1 ? 0.4 : level === 2 ? 0.5 : level === 3 ? 0.2 : 0.1;
+ sunlightRays.push(sunray);
+ game.addChild(sunray);
+}
function spawnObstacle() {
if (clearPathTime > 0) {
return;
}
@@ -879,8 +969,34 @@
LK.getSound('collect').play();
continue;
}
}
+ // Update water tiles for infinite scrolling
+ for (var i = waterTiles.length - 1; i >= 0; i--) {
+ var tile = waterTiles[i];
+ if (tile.y > 2800) {
+ // Reset tile position to top for infinite scrolling
+ tile.y = -100;
+ }
+ }
+ // Spawn sunlight rays periodically
+ if (LK.ticks % 180 === 0) {
+ // Every 3 seconds
+ spawnSunlightRay();
+ }
+ // Update sunlight rays
+ for (var i = sunlightRays.length - 1; i >= 0; i--) {
+ var ray = sunlightRays[i];
+ if (ray.y > 2800) {
+ ray.destroy();
+ sunlightRays.splice(i, 1);
+ continue;
+ }
+ // Update alpha based on level and animation
+ if (ray.children[0]) {
+ ray.children[0].alpha = (ray.maxAlpha || 0.3) + Math.sin(LK.ticks * 0.05 + ray.x * 0.02) * 0.2;
+ }
+ }
// Update coins
for (var i = coins.length - 1; i >= 0; i--) {
var coin = coins[i];
if (coin.y > 2800) {
Really good maritime-ship for runner game. In-Game asset. 2d. High contrast. No shadows
heart, 3d pixel art, no background. In-Game asset. 2d. High contrast. No shadows
2d pirate no background. In-Game asset. 2d. High contrast. No shadows
tsunami wave no background. In-Game asset. 2d. High contrast. No shadows
stone 2d no background. In-Game asset. 2d. High contrast. No shadows