User prompt
50000 den 5000 e çek bitişi
User prompt
cevap soru ve geri sayımın puntolarını %20 artır
User prompt
tüm yazı tipleri arial black olsun
User prompt
tüm yazı tipleri bold olsun
User prompt
5 kat kalınlaştır
User prompt
score bonus ve çarpım sorularının harflerini 2 kat kalınlaştır
User prompt
oyun bittiğinde special image for game completion ekrandayken special sound for game completion 1 kere çalıp bitmeden play again butonu gelmesin
User prompt
oyun bittiğinde ekranda sadece special image for game completion kalsın
User prompt
coinler karaktere dokunduğu zaman görsel olarak kaybolsun ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
start screen içinde score ve bonus kısmı görünmesin. oyun başladıktan sonra görünsün.
User prompt
make start screen image full screen
User prompt
start screen en önde olsun görünsün
User prompt
oyuna bir başlangıç görseli ekle. bu görsel questionBg ile aynı boyutta ve aynı yerde olsun. Görsele tıklayınca oyun başlasın
User prompt
oyunu başlatmak için dokunun yazsın ekranın ortasında
User prompt
start screen image ekranı kaplasın
User prompt
başlamadan önce bir başlangıç ekranı görseli olsun. 1 kere dokunduktan sonra oyun başlasın
User prompt
score 50000 i geçtiği zaman oyun bitsin
User prompt
when game completed only play special completion sound and mute background music
User prompt
bonus en fazla 5x olsun
User prompt
Add special completion sound asset
User prompt
add a special image for game completion
User prompt
score 50000 olduğu zaman oyunda yeni bir görsel göster ve oyunu bitir
User prompt
çarpım soru ve cevapların yazılarının harflerini %15 daha kalınlaştır
User prompt
15 obstacle yerine 20 obstacle ama random olarak ayarlansın. eğer 20 obstacle gelmeden önce across-lane spawn olduysa sıfırdan saymaya başlansın obstacle
User prompt
en fazla 15 obstacle geçtikten sonra mutlaka across three lane olsun
/**** * 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 = gameSpeed; self.update = function () { self.y += self.speed; }; return self; }); var Obstacle = Container.expand(function (type) { var self = Container.call(this); var assetName = 'obstacle' + (type || 1); var obstacleGraphics = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 1.0 }); self.speed = gameSpeed; self.update = function () { self.y += self.speed; }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 1.0 }); self.lane = 1; // 0=left, 1=center, 2=right self.targetX = 0; self.update = function () { // Smooth movement to target lane var diff = self.targetX - self.x; if (Math.abs(diff) > 5) { self.x += diff * 0.15; } else { self.x = self.targetX; } }; return self; }); var QuestionPanel = Container.expand(function () { var self = Container.call(this); var background = self.attachAsset('questionBg', { anchorX: 0.5, anchorY: 0.5 }); self.questionText = new Text2('', { size: 80, fill: 0x000000 }); self.questionText.anchor.set(0.5, 0.5); self.questionText.y = -150; self.addChild(self.questionText); self.timerText = new Text2('9', { size: 75, fill: 0xFF0000 }); self.timerText.anchor.set(0.5, 0.5); self.timerText.y = -250; self.addChild(self.timerText); self.answerButtons = []; for (var i = 0; i < 3; i++) { var button = self.addChild(LK.getAsset('answerButton', { anchorX: 0.5, anchorY: 0.5 })); button.x = (i - 1) * 450; button.y = 50; var buttonText = new Text2('', { size: 63, fill: 0x000000 }); buttonText.anchor.set(0.5, 0.5); button.addChild(buttonText); button.text = buttonText; button.answerValue = 0; self.answerButtons.push(button); } self.setupQuestion = function () { var num1 = Math.floor(Math.random() * 9) + 2; var num2 = Math.floor(Math.random() * 9) + 2; var correctAnswer = num1 * num2; self.questionText.setText(num1 + ' × ' + num2 + ' = ?'); self.correctAnswer = correctAnswer; // Generate wrong answers var wrongAnswers = []; while (wrongAnswers.length < 2) { var wrong = correctAnswer + Math.floor(Math.random() * 20) - 10; if (wrong !== correctAnswer && wrong > 0 && wrongAnswers.indexOf(wrong) === -1) { wrongAnswers.push(wrong); } } // Randomize button positions var answers = [correctAnswer, wrongAnswers[0], wrongAnswers[1]]; for (var i = 0; i < 3; i++) { var randomIndex = Math.floor(Math.random() * answers.length); var answer = answers.splice(randomIndex, 1)[0]; self.answerButtons[i].answerValue = answer; self.answerButtons[i].text.setText(answer.toString()); } questionTimer = 9; self.timerText.setText(questionTimer.toString()); }; return self; }); var SpecialCoin = Container.expand(function () { var self = Container.call(this); var coinGraphics = self.attachAsset('specialCoin', { anchorX: 0.5, anchorY: 0.5 }); self.speed = gameSpeed; self.pointValue = 500; self.update = function () { self.y += self.speed; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB }); /**** * Game Code ****/ // fence // desk // backpack // Game variables var gameSpeed = 8; var initialGameSpeed = 8; var speedIncrement = 0.005; var maxSpeed = 20; var lanePositions = [2048 / 2 - 300, 2048 / 2, 2048 / 2 + 300]; var groundY = 2732 - 100; var obstacles = []; var coins = []; var specialCoins = []; var obstacleSpawnTimer = 0; var coinSpawnTimer = 0; var specialCoinSpawnTimer = 0; var scoreMultiplier = 1.0; var questionActive = false; var questionTimer = 0; var questionPanel = null; var firstCoinCollected = false; var lastBonus5xTriggered = false; var forcedQuestionTimer = 0; var forcedQuestionInterval = 1800; // 30 seconds at 60fps var obstaclesPassed = 0; var maxObstaclesBeforeForced = 15; var player = game.addChild(new Player()); player.x = lanePositions[1]; player.y = groundY; player.targetX = lanePositions[1]; // Ground var ground = game.addChild(LK.getAsset('ground', { anchorX: 0, anchorY: 0 })); ground.x = 0; ground.y = groundY; // UI Elements var scoreText = new Text2('Score: 0', { size: 60, fill: 0xFFFFFF }); scoreText.anchor.set(1, 0); scoreText.x = -20; scoreText.y = 20; LK.gui.topRight.addChild(scoreText); var multiplierText = new Text2('BONUS: 1.0x', { size: 50, fill: 0xFFFF00 }); multiplierText.anchor.set(1, 0); multiplierText.x = -20; multiplierText.y = 80; LK.gui.topRight.addChild(multiplierText); function updateUI() { scoreText.setText('Score: ' + LK.getScore()); multiplierText.setText('BONUS: ' + scoreMultiplier.toFixed(1) + 'x'); // Add flaming animation when bonus is 5x or higher if (scoreMultiplier >= 5.0) { // Play special sound when reaching 5x bonus for the first time if (!lastBonus5xTriggered) { LK.getSound('bonus5x').play(); lastBonus5xTriggered = true; } // Stop any existing tweens tween.stop(multiplierText); // Create more intense flame-like movement var flameIntensity = Math.min(scoreMultiplier / 5, 3); // Scale with multiplier, max 3x tween(multiplierText, { x: multiplierText.x + (Math.random() * 12 - 6) * flameIntensity, y: multiplierText.y + (Math.random() * 8 - 4) * flameIntensity, scaleX: 1 + (Math.random() * 0.3 - 0.15) * flameIntensity, scaleY: 1 + (Math.random() * 0.3 - 0.15) * flameIntensity }, { duration: 80, easing: tween.easeInOut, onFinish: function onFinish() { tween(multiplierText, { x: -20, y: 80, scaleX: 1, scaleY: 1 }, { duration: 80, easing: tween.easeOut }); } }); // More dramatic color transitions with multiple flame colors var flameColors = [0xFF0000, 0xFF4500, 0xFF6600, 0xFF8800, 0xFFAA00, 0xFFCC00, 0xFFFF00]; var randomColor1 = flameColors[Math.floor(Math.random() * flameColors.length)]; var randomColor2 = flameColors[Math.floor(Math.random() * flameColors.length)]; tween(multiplierText, { tint: randomColor1 }, { duration: 120, easing: tween.easeInOut, onFinish: function onFinish() { tween(multiplierText, { tint: randomColor2 }, { duration: 120, easing: tween.easeInOut, onFinish: function onFinish() { tween(multiplierText, { tint: 0xFFFF00 }, { duration: 120, easing: tween.easeOut }); } }); } }); // Add subtle rotation for more flame effect tween(multiplierText, { rotation: (Math.random() * 0.2 - 0.1) * flameIntensity }, { duration: 150, easing: tween.easeInOut, onFinish: function onFinish() { tween(multiplierText, { rotation: 0 }, { duration: 150, easing: tween.easeOut }); } }); } else { // Reset to normal appearance tween.stop(multiplierText); multiplierText.tint = 0xFFFF00; multiplierText.x = -20; multiplierText.y = 80; multiplierText.scaleX = 1; multiplierText.scaleY = 1; multiplierText.rotation = 0; // Reset 5x bonus sound trigger when below 5x lastBonus5xTriggered = false; } } function switchLane(direction) { if (questionActive) return; player.lane += direction; if (player.lane < 0) player.lane = 0; if (player.lane > 2) player.lane = 2; player.targetX = lanePositions[player.lane]; } function spawnObstacle() { var lane = Math.floor(Math.random() * 3); var type = Math.floor(Math.random() * 3) + 1; var spawnY = -100; var minDistance = 560; // 2 character widths (280 * 2) var canSpawn = true; // Check distance from other obstacles for (var i = 0; i < obstacles.length; i++) { var existingObstacle = obstacles[i]; if (existingObstacle.lane === lane && Math.abs(existingObstacle.y - spawnY) < minDistance) { canSpawn = false; break; } } // Check distance from coins if (canSpawn) { for (var i = 0; i < coins.length; i++) { var coin = coins[i]; if (coin.lane === lane && Math.abs(coin.y - spawnY) < minDistance) { canSpawn = false; break; } } } // Check distance from special coins if (canSpawn) { for (var i = 0; i < specialCoins.length; i++) { var specialCoin = specialCoins[i]; if (specialCoin.lane === lane && Math.abs(specialCoin.y - spawnY) < minDistance) { canSpawn = false; break; } } } if (canSpawn) { var obstacle = game.addChild(new Obstacle(type)); obstacle.x = lanePositions[lane]; obstacle.y = spawnY; obstacle.lane = lane; obstacles.push(obstacle); } } function spawnCoin() { var lane = Math.floor(Math.random() * 3); var spawnY = -50; var minDistance = 560; // 2 character widths (280 * 2) var canSpawn = true; // Check distance from obstacles for (var i = 0; i < obstacles.length; i++) { var obstacle = obstacles[i]; if (obstacle.lane === lane && Math.abs(obstacle.y - spawnY) < minDistance) { canSpawn = false; break; } } // Check distance from other coins if (canSpawn) { for (var i = 0; i < coins.length; i++) { var existingCoin = coins[i]; if (existingCoin.lane === lane && Math.abs(existingCoin.y - spawnY) < minDistance) { canSpawn = false; break; } } } // Check distance from special coins if (canSpawn) { for (var i = 0; i < specialCoins.length; i++) { var specialCoin = specialCoins[i]; if (specialCoin.lane === lane && Math.abs(specialCoin.y - spawnY) < minDistance) { canSpawn = false; break; } } } if (canSpawn) { var coin = game.addChild(new Coin()); coin.x = lanePositions[lane]; coin.y = spawnY; coin.lane = lane; coins.push(coin); } } function spawnSpecialCoin() { var lane = Math.floor(Math.random() * 3); var spawnY = -50; var minDistance = 560; // 2 character widths (280 * 2) var canSpawn = true; // Check distance from obstacles for (var i = 0; i < obstacles.length; i++) { var obstacle = obstacles[i]; if (obstacle.lane === lane && Math.abs(obstacle.y - spawnY) < minDistance) { canSpawn = false; break; } } // Check distance from coins if (canSpawn) { for (var i = 0; i < coins.length; i++) { var coin = coins[i]; if (coin.lane === lane && Math.abs(coin.y - spawnY) < minDistance) { canSpawn = false; break; } } } // Check distance from other special coins if (canSpawn) { for (var i = 0; i < specialCoins.length; i++) { var existingSpecialCoin = specialCoins[i]; if (existingSpecialCoin.lane === lane && Math.abs(existingSpecialCoin.y - spawnY) < minDistance) { canSpawn = false; break; } } } if (canSpawn) { var specialCoin = game.addChild(new SpecialCoin()); specialCoin.x = lanePositions[lane]; specialCoin.y = spawnY; specialCoin.lane = lane; specialCoins.push(specialCoin); } } function spawnForcedQuestionObstacles() { // Clear existing obstacles to prevent conflicts for (var i = obstacles.length - 1; i >= 0; i--) { obstacles[i].destroy(); obstacles.splice(i, 1); } // Clear existing coins and special coins for (var i = coins.length - 1; i >= 0; i--) { coins[i].destroy(); coins.splice(i, 1); } for (var i = specialCoins.length - 1; i >= 0; i--) { specialCoins[i].destroy(); specialCoins.splice(i, 1); } // Spawn obstacles in all 3 lanes at the same Y position var spawnY = -100; for (var lane = 0; lane < 3; lane++) { var type = Math.floor(Math.random() * 3) + 1; var obstacle = game.addChild(new Obstacle(type)); obstacle.x = lanePositions[lane]; obstacle.y = spawnY; obstacle.lane = lane; obstacles.push(obstacle); } } function showQuestion() { questionActive = true; // Clear all obstacles for (var i = obstacles.length - 1; i >= 0; i--) { obstacles[i].destroy(); obstacles.splice(i, 1); } // Clear all coins for (var i = coins.length - 1; i >= 0; i--) { coins[i].destroy(); coins.splice(i, 1); } // Clear all special coins for (var i = specialCoins.length - 1; i >= 0; i--) { specialCoins[i].destroy(); specialCoins.splice(i, 1); } questionPanel = game.addChild(new QuestionPanel()); questionPanel.x = 2048 / 2; questionPanel.y = 2732 / 2; questionPanel.setupQuestion(); } function hideQuestion() { if (questionPanel) { questionPanel.destroy(); questionPanel = null; } questionActive = false; } function answerQuestion(selectedAnswer) { if (!questionActive) return; var correct = selectedAnswer === questionPanel.correctAnswer; if (correct) { scoreMultiplier += 0.5; gameSpeed *= 1.01; // Increase speed by 1% for correct answers LK.getSound('correct').play(); } else { scoreMultiplier = 1.0; var speedLimit = initialGameSpeed * 1.6; // 60% more than initial speed if (gameSpeed < speedLimit) { gameSpeed *= 1.03; // Increase speed by 3% } else { // At speed limit, give 6x score bonus instead var bonusPoints = Math.round(60 * scoreMultiplier); // 6x the base 10 points LK.setScore(LK.getScore() + bonusPoints); } LK.getSound('wrong').play(); } hideQuestion(); updateUI(); } // Touch controls game.down = function (x, y, obj) { if (questionActive && questionPanel) { // Check if clicking on answer buttons for (var i = 0; i < questionPanel.answerButtons.length; i++) { var button = questionPanel.answerButtons[i]; var buttonPos = game.toLocal(button.parent.toGlobal(button.position)); if (Math.abs(x - buttonPos.x) < 200 && Math.abs(y - buttonPos.y) < 50) { answerQuestion(button.answerValue); return; } } } else { // Lane switching if (x < 2048 / 2) { switchLane(-1); // Move left } else { switchLane(1); // Move right } } }; game.update = function () { if (questionActive) { // Handle question timer if (LK.ticks % 60 === 0) { // Every second questionTimer--; if (questionPanel) { questionPanel.timerText.setText(questionTimer.toString()); } if (questionTimer <= 0) { // Time's up - wrong answer scoreMultiplier = 1.0; hideQuestion(); updateUI(); } } return; // Don't update game objects during question } // Increase speed gradually if (gameSpeed < maxSpeed) { gameSpeed += speedIncrement; } // Spawn obstacles obstacleSpawnTimer++; if (obstacleSpawnTimer > 120 - gameSpeed * 2) { // Spawn more frequently as speed increases spawnObstacle(); obstacleSpawnTimer = 0; } // Spawn coins coinSpawnTimer++; if (coinSpawnTimer > 180) { spawnCoin(); coinSpawnTimer = 0; } // Spawn special coins (less frequently) specialCoinSpawnTimer++; if (specialCoinSpawnTimer > 600) { spawnSpecialCoin(); specialCoinSpawnTimer = 0; } // Handle forced question timer forcedQuestionTimer++; if (forcedQuestionTimer > forcedQuestionInterval) { spawnForcedQuestionObstacles(); forcedQuestionTimer = 0; // Increase interval slightly each time to make it less predictable forcedQuestionInterval = Math.floor(forcedQuestionInterval * 1.1); if (forcedQuestionInterval > 3600) { // Cap at 60 seconds forcedQuestionInterval = 3600; } } // Update obstacles for (var i = obstacles.length - 1; i >= 0; i--) { var obstacle = obstacles[i]; if (!obstacle) continue; // Skip if obstacle is undefined obstacle.speed = gameSpeed; // Check collision with player if (obstacle.lane === player.lane && Math.abs(obstacle.y - player.y) < 80 && Math.abs(obstacle.x - player.x) < 60) { LK.getSound('hit').play(); showQuestion(); obstacle.destroy(); obstacles.splice(i, 1); continue; } // Remove off-screen obstacles if (obstacle.y > 2732 + 100) { obstaclesPassed++; obstacle.destroy(); obstacles.splice(i, 1); // Force across-lane obstacles after 15 obstacles passed if (obstaclesPassed >= maxObstaclesBeforeForced) { spawnForcedQuestionObstacles(); obstaclesPassed = 0; // Reset counter } } } // Update coins for (var i = coins.length - 1; i >= 0; i--) { var coin = coins[i]; if (!coin) continue; // Skip if coin is undefined coin.speed = gameSpeed; // Check collection if (coin.lane === player.lane && Math.abs(coin.y - player.y) < 60 && Math.abs(coin.x - player.x) < 50) { var coinPoints = Math.round(10 * scoreMultiplier); LK.setScore(LK.getScore() + coinPoints); LK.getSound('collect').play(); // Start background music on first coin collection if (!firstCoinCollected) { firstCoinCollected = true; LK.playMusic('onepiecesoundtrack', { loop: true }); } updateUI(); coin.destroy(); coins.splice(i, 1); continue; } // Remove off-screen coins if (coin.y > 2732 + 50) { coin.destroy(); coins.splice(i, 1); } } // Update special coins for (var i = specialCoins.length - 1; i >= 0; i--) { var specialCoin = specialCoins[i]; if (!specialCoin) continue; // Skip if specialCoin is undefined specialCoin.speed = gameSpeed; // Check collection if (specialCoin.lane === player.lane && Math.abs(specialCoin.y - player.y) < 60 && Math.abs(specialCoin.x - player.x) < 50) { var specialCoinPoints = Math.round(specialCoin.pointValue * scoreMultiplier); LK.setScore(LK.getScore() + specialCoinPoints); var specialSound = LK.getSound('specialCollect'); specialSound.play(); // Create a temporary object to tween the music volume var musicVolume = { volume: 0.3 }; // Mute background music volume when special collect sound plays tween(musicVolume, { volume: 0 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { // Update the actual music volume LK.playMusic('onepiecesoundtrack', { volume: musicVolume.volume }); } }); // Fade back to normal volume when special collect sound finishes LK.setTimeout(function () { tween(musicVolume, { volume: 0.3 }, { duration: 100, easing: tween.easeIn, onFinish: function onFinish() { // Update the actual music volume back to normal LK.playMusic('onepiecesoundtrack', { volume: musicVolume.volume }); } }); }, 630); // Duration of specialCollect sound (0.898 - 0.835) * 1000 = 63ms, but adding buffer // Start background music on first coin collection if (!firstCoinCollected) { firstCoinCollected = true; LK.playMusic('onepiecesoundtrack', { loop: true }); } updateUI(); specialCoin.destroy(); specialCoins.splice(i, 1); continue; } // Remove off-screen special coins if (specialCoin.y > 2732 + 50) { specialCoin.destroy(); specialCoins.splice(i, 1); } } }; updateUI();
/****
* 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 = gameSpeed;
self.update = function () {
self.y += self.speed;
};
return self;
});
var Obstacle = Container.expand(function (type) {
var self = Container.call(this);
var assetName = 'obstacle' + (type || 1);
var obstacleGraphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 1.0
});
self.speed = gameSpeed;
self.update = function () {
self.y += self.speed;
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 1.0
});
self.lane = 1; // 0=left, 1=center, 2=right
self.targetX = 0;
self.update = function () {
// Smooth movement to target lane
var diff = self.targetX - self.x;
if (Math.abs(diff) > 5) {
self.x += diff * 0.15;
} else {
self.x = self.targetX;
}
};
return self;
});
var QuestionPanel = Container.expand(function () {
var self = Container.call(this);
var background = self.attachAsset('questionBg', {
anchorX: 0.5,
anchorY: 0.5
});
self.questionText = new Text2('', {
size: 80,
fill: 0x000000
});
self.questionText.anchor.set(0.5, 0.5);
self.questionText.y = -150;
self.addChild(self.questionText);
self.timerText = new Text2('9', {
size: 75,
fill: 0xFF0000
});
self.timerText.anchor.set(0.5, 0.5);
self.timerText.y = -250;
self.addChild(self.timerText);
self.answerButtons = [];
for (var i = 0; i < 3; i++) {
var button = self.addChild(LK.getAsset('answerButton', {
anchorX: 0.5,
anchorY: 0.5
}));
button.x = (i - 1) * 450;
button.y = 50;
var buttonText = new Text2('', {
size: 63,
fill: 0x000000
});
buttonText.anchor.set(0.5, 0.5);
button.addChild(buttonText);
button.text = buttonText;
button.answerValue = 0;
self.answerButtons.push(button);
}
self.setupQuestion = function () {
var num1 = Math.floor(Math.random() * 9) + 2;
var num2 = Math.floor(Math.random() * 9) + 2;
var correctAnswer = num1 * num2;
self.questionText.setText(num1 + ' × ' + num2 + ' = ?');
self.correctAnswer = correctAnswer;
// Generate wrong answers
var wrongAnswers = [];
while (wrongAnswers.length < 2) {
var wrong = correctAnswer + Math.floor(Math.random() * 20) - 10;
if (wrong !== correctAnswer && wrong > 0 && wrongAnswers.indexOf(wrong) === -1) {
wrongAnswers.push(wrong);
}
}
// Randomize button positions
var answers = [correctAnswer, wrongAnswers[0], wrongAnswers[1]];
for (var i = 0; i < 3; i++) {
var randomIndex = Math.floor(Math.random() * answers.length);
var answer = answers.splice(randomIndex, 1)[0];
self.answerButtons[i].answerValue = answer;
self.answerButtons[i].text.setText(answer.toString());
}
questionTimer = 9;
self.timerText.setText(questionTimer.toString());
};
return self;
});
var SpecialCoin = Container.expand(function () {
var self = Container.call(this);
var coinGraphics = self.attachAsset('specialCoin', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = gameSpeed;
self.pointValue = 500;
self.update = function () {
self.y += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// fence
// desk
// backpack
// Game variables
var gameSpeed = 8;
var initialGameSpeed = 8;
var speedIncrement = 0.005;
var maxSpeed = 20;
var lanePositions = [2048 / 2 - 300, 2048 / 2, 2048 / 2 + 300];
var groundY = 2732 - 100;
var obstacles = [];
var coins = [];
var specialCoins = [];
var obstacleSpawnTimer = 0;
var coinSpawnTimer = 0;
var specialCoinSpawnTimer = 0;
var scoreMultiplier = 1.0;
var questionActive = false;
var questionTimer = 0;
var questionPanel = null;
var firstCoinCollected = false;
var lastBonus5xTriggered = false;
var forcedQuestionTimer = 0;
var forcedQuestionInterval = 1800; // 30 seconds at 60fps
var obstaclesPassed = 0;
var maxObstaclesBeforeForced = 15;
var player = game.addChild(new Player());
player.x = lanePositions[1];
player.y = groundY;
player.targetX = lanePositions[1];
// Ground
var ground = game.addChild(LK.getAsset('ground', {
anchorX: 0,
anchorY: 0
}));
ground.x = 0;
ground.y = groundY;
// UI Elements
var scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(1, 0);
scoreText.x = -20;
scoreText.y = 20;
LK.gui.topRight.addChild(scoreText);
var multiplierText = new Text2('BONUS: 1.0x', {
size: 50,
fill: 0xFFFF00
});
multiplierText.anchor.set(1, 0);
multiplierText.x = -20;
multiplierText.y = 80;
LK.gui.topRight.addChild(multiplierText);
function updateUI() {
scoreText.setText('Score: ' + LK.getScore());
multiplierText.setText('BONUS: ' + scoreMultiplier.toFixed(1) + 'x');
// Add flaming animation when bonus is 5x or higher
if (scoreMultiplier >= 5.0) {
// Play special sound when reaching 5x bonus for the first time
if (!lastBonus5xTriggered) {
LK.getSound('bonus5x').play();
lastBonus5xTriggered = true;
}
// Stop any existing tweens
tween.stop(multiplierText);
// Create more intense flame-like movement
var flameIntensity = Math.min(scoreMultiplier / 5, 3); // Scale with multiplier, max 3x
tween(multiplierText, {
x: multiplierText.x + (Math.random() * 12 - 6) * flameIntensity,
y: multiplierText.y + (Math.random() * 8 - 4) * flameIntensity,
scaleX: 1 + (Math.random() * 0.3 - 0.15) * flameIntensity,
scaleY: 1 + (Math.random() * 0.3 - 0.15) * flameIntensity
}, {
duration: 80,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(multiplierText, {
x: -20,
y: 80,
scaleX: 1,
scaleY: 1
}, {
duration: 80,
easing: tween.easeOut
});
}
});
// More dramatic color transitions with multiple flame colors
var flameColors = [0xFF0000, 0xFF4500, 0xFF6600, 0xFF8800, 0xFFAA00, 0xFFCC00, 0xFFFF00];
var randomColor1 = flameColors[Math.floor(Math.random() * flameColors.length)];
var randomColor2 = flameColors[Math.floor(Math.random() * flameColors.length)];
tween(multiplierText, {
tint: randomColor1
}, {
duration: 120,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(multiplierText, {
tint: randomColor2
}, {
duration: 120,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(multiplierText, {
tint: 0xFFFF00
}, {
duration: 120,
easing: tween.easeOut
});
}
});
}
});
// Add subtle rotation for more flame effect
tween(multiplierText, {
rotation: (Math.random() * 0.2 - 0.1) * flameIntensity
}, {
duration: 150,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(multiplierText, {
rotation: 0
}, {
duration: 150,
easing: tween.easeOut
});
}
});
} else {
// Reset to normal appearance
tween.stop(multiplierText);
multiplierText.tint = 0xFFFF00;
multiplierText.x = -20;
multiplierText.y = 80;
multiplierText.scaleX = 1;
multiplierText.scaleY = 1;
multiplierText.rotation = 0;
// Reset 5x bonus sound trigger when below 5x
lastBonus5xTriggered = false;
}
}
function switchLane(direction) {
if (questionActive) return;
player.lane += direction;
if (player.lane < 0) player.lane = 0;
if (player.lane > 2) player.lane = 2;
player.targetX = lanePositions[player.lane];
}
function spawnObstacle() {
var lane = Math.floor(Math.random() * 3);
var type = Math.floor(Math.random() * 3) + 1;
var spawnY = -100;
var minDistance = 560; // 2 character widths (280 * 2)
var canSpawn = true;
// Check distance from other obstacles
for (var i = 0; i < obstacles.length; i++) {
var existingObstacle = obstacles[i];
if (existingObstacle.lane === lane && Math.abs(existingObstacle.y - spawnY) < minDistance) {
canSpawn = false;
break;
}
}
// Check distance from coins
if (canSpawn) {
for (var i = 0; i < coins.length; i++) {
var coin = coins[i];
if (coin.lane === lane && Math.abs(coin.y - spawnY) < minDistance) {
canSpawn = false;
break;
}
}
}
// Check distance from special coins
if (canSpawn) {
for (var i = 0; i < specialCoins.length; i++) {
var specialCoin = specialCoins[i];
if (specialCoin.lane === lane && Math.abs(specialCoin.y - spawnY) < minDistance) {
canSpawn = false;
break;
}
}
}
if (canSpawn) {
var obstacle = game.addChild(new Obstacle(type));
obstacle.x = lanePositions[lane];
obstacle.y = spawnY;
obstacle.lane = lane;
obstacles.push(obstacle);
}
}
function spawnCoin() {
var lane = Math.floor(Math.random() * 3);
var spawnY = -50;
var minDistance = 560; // 2 character widths (280 * 2)
var canSpawn = true;
// Check distance from obstacles
for (var i = 0; i < obstacles.length; i++) {
var obstacle = obstacles[i];
if (obstacle.lane === lane && Math.abs(obstacle.y - spawnY) < minDistance) {
canSpawn = false;
break;
}
}
// Check distance from other coins
if (canSpawn) {
for (var i = 0; i < coins.length; i++) {
var existingCoin = coins[i];
if (existingCoin.lane === lane && Math.abs(existingCoin.y - spawnY) < minDistance) {
canSpawn = false;
break;
}
}
}
// Check distance from special coins
if (canSpawn) {
for (var i = 0; i < specialCoins.length; i++) {
var specialCoin = specialCoins[i];
if (specialCoin.lane === lane && Math.abs(specialCoin.y - spawnY) < minDistance) {
canSpawn = false;
break;
}
}
}
if (canSpawn) {
var coin = game.addChild(new Coin());
coin.x = lanePositions[lane];
coin.y = spawnY;
coin.lane = lane;
coins.push(coin);
}
}
function spawnSpecialCoin() {
var lane = Math.floor(Math.random() * 3);
var spawnY = -50;
var minDistance = 560; // 2 character widths (280 * 2)
var canSpawn = true;
// Check distance from obstacles
for (var i = 0; i < obstacles.length; i++) {
var obstacle = obstacles[i];
if (obstacle.lane === lane && Math.abs(obstacle.y - spawnY) < minDistance) {
canSpawn = false;
break;
}
}
// Check distance from coins
if (canSpawn) {
for (var i = 0; i < coins.length; i++) {
var coin = coins[i];
if (coin.lane === lane && Math.abs(coin.y - spawnY) < minDistance) {
canSpawn = false;
break;
}
}
}
// Check distance from other special coins
if (canSpawn) {
for (var i = 0; i < specialCoins.length; i++) {
var existingSpecialCoin = specialCoins[i];
if (existingSpecialCoin.lane === lane && Math.abs(existingSpecialCoin.y - spawnY) < minDistance) {
canSpawn = false;
break;
}
}
}
if (canSpawn) {
var specialCoin = game.addChild(new SpecialCoin());
specialCoin.x = lanePositions[lane];
specialCoin.y = spawnY;
specialCoin.lane = lane;
specialCoins.push(specialCoin);
}
}
function spawnForcedQuestionObstacles() {
// Clear existing obstacles to prevent conflicts
for (var i = obstacles.length - 1; i >= 0; i--) {
obstacles[i].destroy();
obstacles.splice(i, 1);
}
// Clear existing coins and special coins
for (var i = coins.length - 1; i >= 0; i--) {
coins[i].destroy();
coins.splice(i, 1);
}
for (var i = specialCoins.length - 1; i >= 0; i--) {
specialCoins[i].destroy();
specialCoins.splice(i, 1);
}
// Spawn obstacles in all 3 lanes at the same Y position
var spawnY = -100;
for (var lane = 0; lane < 3; lane++) {
var type = Math.floor(Math.random() * 3) + 1;
var obstacle = game.addChild(new Obstacle(type));
obstacle.x = lanePositions[lane];
obstacle.y = spawnY;
obstacle.lane = lane;
obstacles.push(obstacle);
}
}
function showQuestion() {
questionActive = true;
// Clear all obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
obstacles[i].destroy();
obstacles.splice(i, 1);
}
// Clear all coins
for (var i = coins.length - 1; i >= 0; i--) {
coins[i].destroy();
coins.splice(i, 1);
}
// Clear all special coins
for (var i = specialCoins.length - 1; i >= 0; i--) {
specialCoins[i].destroy();
specialCoins.splice(i, 1);
}
questionPanel = game.addChild(new QuestionPanel());
questionPanel.x = 2048 / 2;
questionPanel.y = 2732 / 2;
questionPanel.setupQuestion();
}
function hideQuestion() {
if (questionPanel) {
questionPanel.destroy();
questionPanel = null;
}
questionActive = false;
}
function answerQuestion(selectedAnswer) {
if (!questionActive) return;
var correct = selectedAnswer === questionPanel.correctAnswer;
if (correct) {
scoreMultiplier += 0.5;
gameSpeed *= 1.01; // Increase speed by 1% for correct answers
LK.getSound('correct').play();
} else {
scoreMultiplier = 1.0;
var speedLimit = initialGameSpeed * 1.6; // 60% more than initial speed
if (gameSpeed < speedLimit) {
gameSpeed *= 1.03; // Increase speed by 3%
} else {
// At speed limit, give 6x score bonus instead
var bonusPoints = Math.round(60 * scoreMultiplier); // 6x the base 10 points
LK.setScore(LK.getScore() + bonusPoints);
}
LK.getSound('wrong').play();
}
hideQuestion();
updateUI();
}
// Touch controls
game.down = function (x, y, obj) {
if (questionActive && questionPanel) {
// Check if clicking on answer buttons
for (var i = 0; i < questionPanel.answerButtons.length; i++) {
var button = questionPanel.answerButtons[i];
var buttonPos = game.toLocal(button.parent.toGlobal(button.position));
if (Math.abs(x - buttonPos.x) < 200 && Math.abs(y - buttonPos.y) < 50) {
answerQuestion(button.answerValue);
return;
}
}
} else {
// Lane switching
if (x < 2048 / 2) {
switchLane(-1); // Move left
} else {
switchLane(1); // Move right
}
}
};
game.update = function () {
if (questionActive) {
// Handle question timer
if (LK.ticks % 60 === 0) {
// Every second
questionTimer--;
if (questionPanel) {
questionPanel.timerText.setText(questionTimer.toString());
}
if (questionTimer <= 0) {
// Time's up - wrong answer
scoreMultiplier = 1.0;
hideQuestion();
updateUI();
}
}
return; // Don't update game objects during question
}
// Increase speed gradually
if (gameSpeed < maxSpeed) {
gameSpeed += speedIncrement;
}
// Spawn obstacles
obstacleSpawnTimer++;
if (obstacleSpawnTimer > 120 - gameSpeed * 2) {
// Spawn more frequently as speed increases
spawnObstacle();
obstacleSpawnTimer = 0;
}
// Spawn coins
coinSpawnTimer++;
if (coinSpawnTimer > 180) {
spawnCoin();
coinSpawnTimer = 0;
}
// Spawn special coins (less frequently)
specialCoinSpawnTimer++;
if (specialCoinSpawnTimer > 600) {
spawnSpecialCoin();
specialCoinSpawnTimer = 0;
}
// Handle forced question timer
forcedQuestionTimer++;
if (forcedQuestionTimer > forcedQuestionInterval) {
spawnForcedQuestionObstacles();
forcedQuestionTimer = 0;
// Increase interval slightly each time to make it less predictable
forcedQuestionInterval = Math.floor(forcedQuestionInterval * 1.1);
if (forcedQuestionInterval > 3600) {
// Cap at 60 seconds
forcedQuestionInterval = 3600;
}
}
// Update obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
if (!obstacle) continue; // Skip if obstacle is undefined
obstacle.speed = gameSpeed;
// Check collision with player
if (obstacle.lane === player.lane && Math.abs(obstacle.y - player.y) < 80 && Math.abs(obstacle.x - player.x) < 60) {
LK.getSound('hit').play();
showQuestion();
obstacle.destroy();
obstacles.splice(i, 1);
continue;
}
// Remove off-screen obstacles
if (obstacle.y > 2732 + 100) {
obstaclesPassed++;
obstacle.destroy();
obstacles.splice(i, 1);
// Force across-lane obstacles after 15 obstacles passed
if (obstaclesPassed >= maxObstaclesBeforeForced) {
spawnForcedQuestionObstacles();
obstaclesPassed = 0; // Reset counter
}
}
}
// Update coins
for (var i = coins.length - 1; i >= 0; i--) {
var coin = coins[i];
if (!coin) continue; // Skip if coin is undefined
coin.speed = gameSpeed;
// Check collection
if (coin.lane === player.lane && Math.abs(coin.y - player.y) < 60 && Math.abs(coin.x - player.x) < 50) {
var coinPoints = Math.round(10 * scoreMultiplier);
LK.setScore(LK.getScore() + coinPoints);
LK.getSound('collect').play();
// Start background music on first coin collection
if (!firstCoinCollected) {
firstCoinCollected = true;
LK.playMusic('onepiecesoundtrack', {
loop: true
});
}
updateUI();
coin.destroy();
coins.splice(i, 1);
continue;
}
// Remove off-screen coins
if (coin.y > 2732 + 50) {
coin.destroy();
coins.splice(i, 1);
}
}
// Update special coins
for (var i = specialCoins.length - 1; i >= 0; i--) {
var specialCoin = specialCoins[i];
if (!specialCoin) continue; // Skip if specialCoin is undefined
specialCoin.speed = gameSpeed;
// Check collection
if (specialCoin.lane === player.lane && Math.abs(specialCoin.y - player.y) < 60 && Math.abs(specialCoin.x - player.x) < 50) {
var specialCoinPoints = Math.round(specialCoin.pointValue * scoreMultiplier);
LK.setScore(LK.getScore() + specialCoinPoints);
var specialSound = LK.getSound('specialCollect');
specialSound.play();
// Create a temporary object to tween the music volume
var musicVolume = {
volume: 0.3
};
// Mute background music volume when special collect sound plays
tween(musicVolume, {
volume: 0
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
// Update the actual music volume
LK.playMusic('onepiecesoundtrack', {
volume: musicVolume.volume
});
}
});
// Fade back to normal volume when special collect sound finishes
LK.setTimeout(function () {
tween(musicVolume, {
volume: 0.3
}, {
duration: 100,
easing: tween.easeIn,
onFinish: function onFinish() {
// Update the actual music volume back to normal
LK.playMusic('onepiecesoundtrack', {
volume: musicVolume.volume
});
}
});
}, 630); // Duration of specialCollect sound (0.898 - 0.835) * 1000 = 63ms, but adding buffer
// Start background music on first coin collection
if (!firstCoinCollected) {
firstCoinCollected = true;
LK.playMusic('onepiecesoundtrack', {
loop: true
});
}
updateUI();
specialCoin.destroy();
specialCoins.splice(i, 1);
continue;
}
// Remove off-screen special coins
if (specialCoin.y > 2732 + 50) {
specialCoin.destroy();
specialCoins.splice(i, 1);
}
}
};
updateUI();