User prompt
If we are low on health after 100 points, let the falling speed of the incoming heart be 16x
User prompt
If he has passed 100 points and only has 1 heart left, only 1 heart will spawn on the screen and think about it. If he can't catch it, he won't be able to get it, but if he clicks, he will get 1 life. After getting the life, it will not appear again.
User prompt
What you will add: bananas 14x after 150 scores, 15x after 160 scores, 16x after 170 scores, 17x after 180 scores, 18x after 190 scores, 19x after 200 scores, 20x. Do this banana acceleration.
User prompt
What you will add: bananas 9x after 90 scores, 9.5x after 100 scores, 10x after 110 scores, 10.5x after 120 scores, 11x after 130 scores, 12x after 140 scores, 13x. Do this banana acceleration.
User prompt
Things to add: Bananas increase 6x after 30 scores, 6.5x after 40 scores, 7x after 50 scores, 7.5x after 60 scores, 8x after 70 scores and 8.5x after 80 scores. Add these bananas to the speedup code.
User prompt
Increase your speed in this order. After 5 scores 2x, after 10 scores 3x, after 20 scores 5x% etc. I want you to do this.
User prompt
Please fix the bug: 'Uncaught TypeError: tween.to is not a function' in or related to this line: 'tween.to(self, 0.2, {' Line Number: 79 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please save this source code
Code edit (1 edits merged)
Please save this source code
User prompt
Kalpleri sağ tarafa al.
Code edit (1 edits merged)
Please save this source code
User prompt
Don't Drop It
Initial prompt
Oyunda yukarıdan muzlar düşecek ve oyuncu tıklamazsa ve en aşağı düşerse oyunu kaybedecek. Muzlar yavaştan başlayıp git gide hızlanacak. Ve 15 skordan sonra bombalar düşmeye başlayacak. 3 tane de kalbimiz olacak. Bunu yap. Oyunun adı da "Don't Drop It"
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { scoreHistory: [] }); /**** * Classes ****/ var BananaClickEffect = Container.expand(function () { var self = Container.call(this); var effect = self.attachAsset('bananaClickEffect', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 0.5, alpha: 1 }); self.init = function (x, y) { self.x = x; self.y = y; // Animate: scale up and fade out tween(effect, { scaleX: 1.2, scaleY: 1.2, alpha: 0 }, { duration: 600, easing: tween.easeOut, onFinish: function onFinish() { self.destroy(); } }); }; return self; }); var BananaEffect = Container.expand(function () { var self = Container.call(this); self.init = function (x, y) { // Create multiple banana particles for (var i = 0; i < 8; i++) { var particle = self.attachAsset('banana', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.2, scaleY: 0.2, alpha: 0.8 }); // Calculate angle for particle direction var angle = Math.PI * 2 * (i / 8); // Position particle particle.x = 0; particle.y = 0; // Calculate target position for the tween var targetX = Math.cos(angle) * 100; var targetY = Math.sin(angle) * 100; // Animate particle tween(particle, { x: targetX, y: targetY, alpha: 0, rotation: Math.random() * Math.PI * 2, scaleX: 0.05, scaleY: 0.05 }, { duration: 800 + Math.random() * 400, easing: tween.easeOut }); } // Set position of the effect self.x = x; self.y = y; // Auto-destroy after all animations complete LK.setTimeout(function () { self.destroy(); }, 1500); }; return self; }); var FallingItem = Container.expand(function () { var self = Container.call(this); self.type = "banana"; // default type self.speed = 2; // default speed self.lastY = 0; self.active = true; self.graphics = null; self.init = function (type, speed) { self.type = type || "banana"; self.speed = speed || 2; // Remove any existing graphics if (self.graphics) { self.removeChild(self.graphics); } // Create the appropriate graphics based on type if (self.type === "banana") { self.graphics = self.attachAsset('banana', { anchorX: 0.5, anchorY: 0.5 }); } else if (self.type === "bomb") { self.graphics = self.attachAsset('bomb', { anchorX: 0.5, anchorY: 0.5 }); } else if (self.type === "heart") { self.graphics = self.attachAsset('heartRestore', { anchorX: 0.5, anchorY: 0.5 }); } else if (self.type === "rottenBanana") { self.graphics = self.attachAsset('rottenBanana', { anchorX: 0.5, anchorY: 0.5 }); } // Set initial position self.x = Math.random() * (2048 - 200) + 100; self.y = -100; self.lastY = self.y; // Interactive for tapping self.interactive = true; }; self.update = function () { if (!self.active) { return; } self.lastY = self.y; self.y += self.speed; }; self.down = function (x, y, obj) { if (!self.active) { return; } if (self.type === "banana") { // Score 1 point for each banana LK.setScore(LK.getScore() + 1); LK.getSound('pop').play(); // Create banana effect at tap position createBananaEffect(self.x, self.y); // Create banana click effect at tap position createBananaClickEffect(self.x, self.y); self.remove(false); } else if (self.type === "bomb") { // Lost a life by tapping bomb LK.getSound('explosion').play(); decreaseLife(); self.remove(); } else if (self.type === "heart") { // Gained a life by tapping heart LK.getSound('heartRestoreSound').play(); increaseLife(); self.remove(); } else if (self.type === "rottenBanana") { // Lost a life by tapping rotten banana LK.getSound('rottenBananaSound').play(); decreaseLife(); self.remove(); } }; self.remove = function (createSouls) { self.active = false; // Create soul effect based on item type, but only if createSouls is not false if (createSouls !== false) { if (self.type === "banana") { createSoulEffect(self.x, self.y, 3); } else if (self.type === "heart") { createSoulEffect(self.x, self.y, 5); } else if (self.type === "bomb" || self.type === "rottenBanana") { // No souls for negative items } } tween(self, { alpha: 0, scaleX: 0.3, scaleY: 0.3 }, { duration: 200, onFinish: function onFinish() { self.destroy(); } }); }; return self; }); var Menu = Container.expand(function () { var self = Container.call(this); // Menu background var bg = self.attachAsset('menuBg', { anchorX: 0.5, anchorY: 0.5, x: SCREEN_WIDTH / 2, y: SCREEN_HEIGHT / 2 }); // Play button var playBtn = self.attachAsset('playButton', { anchorX: 0.5, anchorY: 0.5, x: SCREEN_WIDTH / 2, y: SCREEN_HEIGHT / 2 - 100 }); // Settings button var settingsBtn = self.attachAsset('settingsButton', { anchorX: 0.5, anchorY: 0.5, x: SCREEN_WIDTH / 2, y: SCREEN_HEIGHT / 2 + 120 }); // Title text var titleText = new Text2('Banana Game', { size: 140, fill: 0xFFF200, stroke: 0x000000, strokeThickness: 10, bold: true }); titleText.anchor.set(0.5, 0.5); titleText.x = SCREEN_WIDTH / 2; titleText.y = SCREEN_HEIGHT / 2 - 350; self.addChild(titleText); // Play button text var playText = new Text2('Play', { size: 90, fill: 0xFFFFFF, stroke: 0x000000, strokeThickness: 8, bold: true }); playText.anchor.set(0.5, 0.5); playText.x = SCREEN_WIDTH / 2; playText.y = SCREEN_HEIGHT / 2 - 100; self.addChild(playText); // Settings button text var settingsText = new Text2('Settings', { size: 70, fill: 0xFFFFFF, stroke: 0x000000, strokeThickness: 6, bold: true }); settingsText.anchor.set(0.5, 0.5); settingsText.x = SCREEN_WIDTH / 2; settingsText.y = SCREEN_HEIGHT / 2 + 120; self.addChild(settingsText); // Assets button (top right) var assetsBtn = self.attachAsset('pastScoresMenuButton', { anchorX: 1, anchorY: 0, x: SCREEN_WIDTH - 50, y: 23.05 // moved down by 0.3cm (11.55px) }); var assetsText = new Text2('Past Scores', { size: 60, fill: 0xFFFFFF, stroke: 0x000000, strokeThickness: 5, bold: true }); assetsText.anchor.set(1, 0.5); assetsText.x = SCREEN_WIDTH - 80; assetsText.y = 50 + 60; self.addChild(assetsText); assetsBtn.interactive = true; assetsBtn.down = function () { showScoreHistoryPopup(); }; // Button interactivity playBtn.interactive = true; playBtn.down = function () { if (self.parent) self.parent.removeChild(self); showGame(); }; settingsBtn.interactive = true; settingsBtn.down = function () { if (self.parent) self.parent.removeChild(self); showSettingsMenu(); }; return self; }); var SettingsMenu = Container.expand(function () { var self = Container.call(this); // Settings background var bg = self.attachAsset('menuBg', { anchorX: 0.5, anchorY: 0.5, x: SCREEN_WIDTH / 2, y: SCREEN_HEIGHT / 2 }); // Title var settingsTitle = new Text2('Settings', { size: 120, fill: 0xFFF200, stroke: 0x000000, strokeThickness: 8, bold: true }); settingsTitle.anchor.set(0.5, 0.5); settingsTitle.x = SCREEN_WIDTH / 2; settingsTitle.y = SCREEN_HEIGHT / 2 - 300; self.addChild(settingsTitle); // Back button var backBtn = self.attachAsset('menuButton', { anchorX: 0.5, anchorY: 0.5, x: SCREEN_WIDTH / 2, y: SCREEN_HEIGHT / 2 + 350 }); var backText = new Text2('Back', { size: 80, fill: 0xFFFFFF, stroke: 0x000000, strokeThickness: 7, bold: true }); backText.anchor.set(0.5, 0.5); backText.x = SCREEN_WIDTH / 2; backText.y = SCREEN_HEIGHT / 2 + 350; self.addChild(backText); // Example settings text var infoText = new Text2('Sound: On\nMusic: On', { size: 70, fill: 0xFFFFFF, stroke: 0x000000, strokeThickness: 5, bold: true }); infoText.anchor.set(0.5, 0.5); infoText.x = SCREEN_WIDTH / 2; infoText.y = SCREEN_HEIGHT / 2; self.addChild(infoText); backBtn.interactive = true; backBtn.down = function () { if (self.parent) self.parent.removeChild(self); showMenu(); }; return self; }); var Soul = Container.expand(function () { var self = Container.call(this); self.init = function (x, y) { // Create soul graphics var soulGraphics = self.attachAsset('heart', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 0.5, alpha: 0.7 }); // Set initial position self.x = x; self.y = y; // Randomize direction slightly self.targetX = Math.random() * 300 - 150 + x; self.targetY = y - 300 - Math.random() * 200; // Always float upward // Start the float animation tween(self, { x: self.targetX, y: self.targetY, alpha: 0, scaleX: 0.1, scaleY: 0.1 }, { duration: 1500 + Math.random() * 1000, easing: tween.easeOut, onFinish: function onFinish() { self.destroy(); } }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Menu and settings assets // New effect asset ; // Game constants var SCREEN_WIDTH = 2048; var SCREEN_HEIGHT = 2732; var MAX_LIVES = 3; var BOMB_THRESHOLD_SCORE = 15; var SPAWN_INTERVAL_INITIAL = 60; // frames var MIN_SPAWN_INTERVAL = 20; // frames var INTERVAL_DECREMENT = 1; // Game variables var fallingItems = []; var lives = MAX_LIVES; var spawnCounter = 0; var currentSpawnInterval = SPAWN_INTERVAL_INITIAL; var currentSpeed = 2; var isGameOver = false; var extraHeartSpawned = false; var extraHeartCaught = false; var gameStarted = false; // Banana combo system variables (REMOVED) // var bananaCombo = 0; // var bananaComboTimer = null; // var BANANA_COMBO_TIMEOUT = 1500; // ms // var maxBananaCombo = 0; // Combo text UI (REMOVED) // var comboText = new Text2('', { // size: 120, // fill: 0xA259FF, // // purple // stroke: 0x000000, // strokeThickness: 8, // bold: true // }); // comboText.anchor.set(0.5, 0); // comboText.x = SCREEN_WIDTH / 2; // comboText.y = 200; // comboText.visible = false; // game.addChild(comboText); // Add background var background = game.addChild(LK.getAsset('background', { anchorX: 0, anchorY: 0 })); // Menu logic var menuInstance = null; var settingsMenuInstance = null; // Show popup with past scores function showScoreHistoryPopup() { // Remove existing popup if present if (game.scoreHistoryPopup && game.scoreHistoryPopup.parent) { game.removeChild(game.scoreHistoryPopup); game.scoreHistoryPopup = null; } var popup = new Container(); // Popup background var bg = popup.attachAsset('menuBg', { anchorX: 0.5, anchorY: 0.5, x: SCREEN_WIDTH / 2, y: SCREEN_HEIGHT / 2, scaleX: 0.7, scaleY: 0.7 }); // Title var title = new Text2('Past Scores', { size: 90, fill: 0xFFF200, stroke: 0x000000, strokeThickness: 7, bold: true }); title.anchor.set(0.5, 0.5); title.x = SCREEN_WIDTH / 2; title.y = SCREEN_HEIGHT / 2 - 350; popup.addChild(title); // Get score history from storage (show up to 10 most recent) var history = storage.scoreHistory || []; var displayScores = history.slice(-10).reverse(); var scoresText = displayScores.length > 0 ? displayScores.map(function (s, i) { return i + 1 + '. ' + s; }).join('\n') : 'No scores yet!'; var scoresList = new Text2(scoresText, { size: 70, fill: 0xFFFFFF, stroke: 0x000000, strokeThickness: 5, bold: true }); scoresList.anchor.set(0.5, 0); scoresList.x = SCREEN_WIDTH / 2; scoresList.y = SCREEN_HEIGHT / 2 - 220; popup.addChild(scoresList); // Close button var closeBtn = popup.attachAsset('menuButton', { anchorX: 0.5, anchorY: 0.5, x: SCREEN_WIDTH / 2, y: SCREEN_HEIGHT / 2 + 350, scaleX: 0.7, scaleY: 0.7 }); var closeText = new Text2('Close', { size: 70, fill: 0xFFFFFF, stroke: 0x000000, strokeThickness: 6, bold: true }); closeText.anchor.set(0.5, 0.5); closeText.x = SCREEN_WIDTH / 2; closeText.y = SCREEN_HEIGHT / 2 + 350; popup.addChild(closeText); closeBtn.interactive = true; closeBtn.down = function () { if (popup.parent) game.removeChild(popup); game.scoreHistoryPopup = null; }; game.addChild(popup); game.scoreHistoryPopup = popup; } // Show menu function showMenu() { if (menuInstance) { if (!menuInstance.parent) game.addChild(menuInstance); return; } menuInstance = new Menu(); game.addChild(menuInstance); } // Show settings menu function showSettingsMenu() { if (settingsMenuInstance) { if (!settingsMenuInstance.parent) game.addChild(settingsMenuInstance); return; } settingsMenuInstance = new SettingsMenu(); game.addChild(settingsMenuInstance); } // Hide menu and start game function showGame() { gameStarted = true; clickToPlayText.visible = false; initGame(); } // Show menu on game start LK.setTimeout(function () { showMenu(); }, 10); // Initialize score text var scoreText = new Text2('Score: 0', { size: 80, fill: 0xFFFFFF, stroke: 0x000000, strokeThickness: 8, bold: true }); scoreText.anchor.set(0.5, 0); scoreText.x = SCREEN_WIDTH / 2; scoreText.y = 50; game.addChild(scoreText); // Create click to play text (hidden, menu will be used instead) var clickToPlayText = new Text2('Click to Start', { size: 120, fill: 0xFFFFFF, stroke: 0x000000, strokeThickness: 8, bold: true }); clickToPlayText.anchor.set(0.5, 0.5); clickToPlayText.x = SCREEN_WIDTH / 2; clickToPlayText.y = SCREEN_HEIGHT / 2; clickToPlayText.visible = false; game.addChild(clickToPlayText); // Create hearts container var heartsContainer = new Container(); heartsContainer.x = 1410; heartsContainer.y = 50; game.addChild(heartsContainer); // Initialize hearts display function initLives() { // Clear existing hearts while (heartsContainer.children.length > 0) { heartsContainer.removeChildAt(0); } // Add hearts based on current lives for (var i = 0; i < lives; i++) { var heart = LK.getAsset('heart', { anchorX: 0, anchorY: 0, x: i * 190, y: 0 }); heartsContainer.addChild(heart); } } // Function to create floating soul effect function createSoulEffect(x, y, count) { count = count || 1; for (var i = 0; i < count; i++) { var soul = new Soul(); soul.init(x, y); game.addChild(soul); } } // Function to create banana effect when banana is clicked function createBananaEffect(x, y) { var effect = new BananaEffect(); effect.init(x, y); game.addChild(effect); } // Function to create banana click effect animation function createBananaClickEffect(x, y) { var effect = new BananaClickEffect(); effect.init(x, y); game.addChild(effect); } // Function to check if a heart is already falling function isHeartAlreadyFalling() { for (var i = 0; i < fallingItems.length; i++) { if (fallingItems[i] && fallingItems[i].type === "heart" && fallingItems[i].active) { return true; } } return false; } // Function to increase life function increaseLife() { if (lives < MAX_LIVES) { lives++; initLives(); extraHeartCaught = true; // Mark that a heart was caught } } // Function to decrease life function decreaseLife() { // Create soul effect at heart position that was lost var heartIndex = lives - 1; if (heartIndex >= 0 && heartsContainer.children[heartIndex]) { var heartPos = heartsContainer.children[heartIndex]; var globalPos = heartsContainer.toGlobal({ x: heartPos.x + 50, y: heartPos.y + 50 }); var gamePos = game.toLocal(globalPos); createSoulEffect(gamePos.x, gamePos.y, 7); } lives--; initLives(); // We only play the heart loss sound for actual life losses, not from bombs or rotten bananas // This is handled in the game.update and FallingItem.down methods where decreaseLife is called. // LK.getSound('heartLossSound').play(); // Removed sound here // Shake the screen using the tween library tween(game, { x: game.x + 5 }, { duration: 50, easing: tween.easeOut, onFinish: function onFinish() { tween(game, { x: game.x - 10 }, { duration: 100, easing: tween.easeInOut, onFinish: function onFinish() { tween(game, { x: game.x + 5 }, { duration: 50, easing: tween.easeIn, onFinish: function onFinish() { // Check for game over after shake is complete if (lives <= 0) { gameOver(); } } }); } }); } }); } // Function to handle game over function gameOver() { if (isGameOver) { return; } isGameOver = true; gameStarted = false; // Reset banana combo system (REMOVED) // bananaCombo = 0; // comboText.visible = false; // if (bananaComboTimer) { // LK.clearTimeout(bananaComboTimer); // bananaComboTimer = null; // } LK.getSound('gameover').play(); LK.effects.flashScreen(0xff0000, 1000); // [Bu kısım kaldırıldı] -> createSoulEffect ile kalp efektleri artık çıkmayacak // Remove all falling items for (var i = fallingItems.length - 1; i >= 0; i--) { fallingItems[i].destroy(); } fallingItems = []; // Save score to storage history var score = LK.getScore(); if (typeof score === "number" && score > 0) { var history = storage.scoreHistory || []; history.push(score); // Keep only last 20 scores if (history.length > 20) { history = history.slice(history.length - 20); } storage.scoreHistory = history; } // Show game over screen LK.setTimeout(function () { LK.showGameOver(); }, 1000); // Show click to play text again clickToPlayText.visible = true; } function spawnItem() { var score = LK.getScore(); var isBomb = false; var isRottenBanana = false; var isHeart = false; // Heart spawn logic if (!isHeartAlreadyFalling()) { if (score >= 50 && lives === 1 && !extraHeartSpawned) { isHeart = true; extraHeartSpawned = true; } else if (score >= 70 && lives === 1 && extraHeartSpawned && !extraHeartCaught) { isHeart = true; } } // Rotten banana and bomb logic (independent, so both can spawn) if (!isHeart) { if (score >= 20 && Math.random() < 0.3) { isRottenBanana = true; } else if (score >= 10 && Math.random() < 0.3) { isBomb = true; } } var itemType = "banana"; if (isHeart) { itemType = "heart"; } else if (isRottenBanana) { itemType = "rottenBanana"; } else if (isBomb) { itemType = "bomb"; } var item = new FallingItem(); if (itemType === "heart" && score > 100 && lives === 1) { item.init(itemType, 16); } else if (itemType === "heart" && score >= 50 && lives === 1) { item.init(itemType, 10); } else { item.init(itemType, currentSpeed); } fallingItems.push(item); game.addChild(item); return item; } // Update game state each frame game.update = function () { if (!gameStarted || isGameOver) { return; } // Update all falling items for (var i = fallingItems.length - 1; i >= 0; i--) { var item = fallingItems[i]; // Check if item has fallen off screen if (item && item.lastY !== undefined && item.active && item.lastY < SCREEN_HEIGHT && item.y >= SCREEN_HEIGHT) { if (item.type === "banana" && item.active) { // Missed a banana - lose a life decreaseLife(); LK.getSound('heartLossSound').play(); // Play sound for missed banana item.remove(); } else if (item.type === "bomb" && item.active || item.type === "rottenBanana" && item.active) { // Bomb or rotten banana fell off screen - remove it with no penalty item.destroy(); fallingItems.splice(i, 1); } } // Remove destroyed items from array if (!item || !item.active || item.alpha <= 0) { fallingItems.splice(i, 1); } } // Spawn new items at intervals spawnCounter++; // Get current score for difficulty calculations var score = LK.getScore(); // Hearts will be spawned based on specific conditions in spawnItem function if (spawnCounter >= currentSpawnInterval) { spawnItem(); spawnCounter = 0; // Set speed multiplier based on score thresholds var speedMultiplier = 1; // 0-150 arası sabit artışlar (orijinal hız tablosu) if (score >= 150) { speedMultiplier = 21; } else if (score >= 140) { speedMultiplier = 20.5; } else if (score >= 130) { speedMultiplier = 20; } else if (score >= 120) { speedMultiplier = 19.5; } else if (score >= 110) { speedMultiplier = 19; } else if (score >= 100) { speedMultiplier = 18; } else if (score >= 90) { speedMultiplier = 17; } else if (score >= 80) { speedMultiplier = 16; } else if (score >= 70) { speedMultiplier = 15; } else if (score >= 60) { speedMultiplier = 14; } else if (score >= 50) { speedMultiplier = 12.5; } else if (score >= 40) { speedMultiplier = 12; } else if (score >= 30) { speedMultiplier = 11.5; } else if (score >= 20) { speedMultiplier = 11; } else if (score >= 10) { speedMultiplier = 10; } else if (score >= 0) { speedMultiplier = 9; } else { speedMultiplier = 7; } // 150’den sonra 300000’e kadar dinamik artış: +0.25 her 1 skor artışı için if (score > 150 && score <= 300000) { speedMultiplier = 15 + (score - 150) * 0.5; } // Eğer istersen 300000’den sonrası için burada farklı artış mantığı eklenebilir. // Örnek olarak, 300000’den sonra her 1000 puanda 0.1 artış veya başka bir şey gibi. // Güncellenen hız, oyun içindeki hız değişkenine atanıyor currentSpeed = 2 * speedMultiplier; // Spawn interval (yeniden item çıkma aralığı) puana göre azalıyor ama minimum sınırı var currentSpawnInterval = Math.max(MIN_SPAWN_INTERVAL, SPAWN_INTERVAL_INITIAL - score * INTERVAL_DECREMENT); } // Score text’i güncelle scoreText.setText('Score: ' + score); }; // Initialize the game function initGame() { // Reset game variables lives = MAX_LIVES; LK.setScore(0); spawnCounter = 0; currentSpawnInterval = SPAWN_INTERVAL_INITIAL; currentSpeed = 2; isGameOver = false; extraHeartSpawned = false; // Reset heart spawn tracking extraHeartCaught = false; // Reset heart catch tracking fallingItems = []; // Reset banana combo system (REMOVED) // bananaCombo = 0; // maxBananaCombo = 0; // comboText.visible = false; // if (bananaComboTimer) { // LK.clearTimeout(bananaComboTimer); // bananaComboTimer = null; // } // Initialize UI initLives(); scoreText.setText('Score: 0'); // Play background music LK.playMusic('gameMusic'); } // Set up click handler to start game // (Removed, menu handles game start) // Initialize but don't start the game yet lives = MAX_LIVES; initLives();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
scoreHistory: []
});
/****
* Classes
****/
var BananaClickEffect = Container.expand(function () {
var self = Container.call(this);
var effect = self.attachAsset('bananaClickEffect', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5,
alpha: 1
});
self.init = function (x, y) {
self.x = x;
self.y = y;
// Animate: scale up and fade out
tween(effect, {
scaleX: 1.2,
scaleY: 1.2,
alpha: 0
}, {
duration: 600,
easing: tween.easeOut,
onFinish: function onFinish() {
self.destroy();
}
});
};
return self;
});
var BananaEffect = Container.expand(function () {
var self = Container.call(this);
self.init = function (x, y) {
// Create multiple banana particles
for (var i = 0; i < 8; i++) {
var particle = self.attachAsset('banana', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.2,
scaleY: 0.2,
alpha: 0.8
});
// Calculate angle for particle direction
var angle = Math.PI * 2 * (i / 8);
// Position particle
particle.x = 0;
particle.y = 0;
// Calculate target position for the tween
var targetX = Math.cos(angle) * 100;
var targetY = Math.sin(angle) * 100;
// Animate particle
tween(particle, {
x: targetX,
y: targetY,
alpha: 0,
rotation: Math.random() * Math.PI * 2,
scaleX: 0.05,
scaleY: 0.05
}, {
duration: 800 + Math.random() * 400,
easing: tween.easeOut
});
}
// Set position of the effect
self.x = x;
self.y = y;
// Auto-destroy after all animations complete
LK.setTimeout(function () {
self.destroy();
}, 1500);
};
return self;
});
var FallingItem = Container.expand(function () {
var self = Container.call(this);
self.type = "banana"; // default type
self.speed = 2; // default speed
self.lastY = 0;
self.active = true;
self.graphics = null;
self.init = function (type, speed) {
self.type = type || "banana";
self.speed = speed || 2;
// Remove any existing graphics
if (self.graphics) {
self.removeChild(self.graphics);
}
// Create the appropriate graphics based on type
if (self.type === "banana") {
self.graphics = self.attachAsset('banana', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (self.type === "bomb") {
self.graphics = self.attachAsset('bomb', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (self.type === "heart") {
self.graphics = self.attachAsset('heartRestore', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (self.type === "rottenBanana") {
self.graphics = self.attachAsset('rottenBanana', {
anchorX: 0.5,
anchorY: 0.5
});
}
// Set initial position
self.x = Math.random() * (2048 - 200) + 100;
self.y = -100;
self.lastY = self.y;
// Interactive for tapping
self.interactive = true;
};
self.update = function () {
if (!self.active) {
return;
}
self.lastY = self.y;
self.y += self.speed;
};
self.down = function (x, y, obj) {
if (!self.active) {
return;
}
if (self.type === "banana") {
// Score 1 point for each banana
LK.setScore(LK.getScore() + 1);
LK.getSound('pop').play();
// Create banana effect at tap position
createBananaEffect(self.x, self.y);
// Create banana click effect at tap position
createBananaClickEffect(self.x, self.y);
self.remove(false);
} else if (self.type === "bomb") {
// Lost a life by tapping bomb
LK.getSound('explosion').play();
decreaseLife();
self.remove();
} else if (self.type === "heart") {
// Gained a life by tapping heart
LK.getSound('heartRestoreSound').play();
increaseLife();
self.remove();
} else if (self.type === "rottenBanana") {
// Lost a life by tapping rotten banana
LK.getSound('rottenBananaSound').play();
decreaseLife();
self.remove();
}
};
self.remove = function (createSouls) {
self.active = false;
// Create soul effect based on item type, but only if createSouls is not false
if (createSouls !== false) {
if (self.type === "banana") {
createSoulEffect(self.x, self.y, 3);
} else if (self.type === "heart") {
createSoulEffect(self.x, self.y, 5);
} else if (self.type === "bomb" || self.type === "rottenBanana") {
// No souls for negative items
}
}
tween(self, {
alpha: 0,
scaleX: 0.3,
scaleY: 0.3
}, {
duration: 200,
onFinish: function onFinish() {
self.destroy();
}
});
};
return self;
});
var Menu = Container.expand(function () {
var self = Container.call(this);
// Menu background
var bg = self.attachAsset('menuBg', {
anchorX: 0.5,
anchorY: 0.5,
x: SCREEN_WIDTH / 2,
y: SCREEN_HEIGHT / 2
});
// Play button
var playBtn = self.attachAsset('playButton', {
anchorX: 0.5,
anchorY: 0.5,
x: SCREEN_WIDTH / 2,
y: SCREEN_HEIGHT / 2 - 100
});
// Settings button
var settingsBtn = self.attachAsset('settingsButton', {
anchorX: 0.5,
anchorY: 0.5,
x: SCREEN_WIDTH / 2,
y: SCREEN_HEIGHT / 2 + 120
});
// Title text
var titleText = new Text2('Banana Game', {
size: 140,
fill: 0xFFF200,
stroke: 0x000000,
strokeThickness: 10,
bold: true
});
titleText.anchor.set(0.5, 0.5);
titleText.x = SCREEN_WIDTH / 2;
titleText.y = SCREEN_HEIGHT / 2 - 350;
self.addChild(titleText);
// Play button text
var playText = new Text2('Play', {
size: 90,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 8,
bold: true
});
playText.anchor.set(0.5, 0.5);
playText.x = SCREEN_WIDTH / 2;
playText.y = SCREEN_HEIGHT / 2 - 100;
self.addChild(playText);
// Settings button text
var settingsText = new Text2('Settings', {
size: 70,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 6,
bold: true
});
settingsText.anchor.set(0.5, 0.5);
settingsText.x = SCREEN_WIDTH / 2;
settingsText.y = SCREEN_HEIGHT / 2 + 120;
self.addChild(settingsText);
// Assets button (top right)
var assetsBtn = self.attachAsset('pastScoresMenuButton', {
anchorX: 1,
anchorY: 0,
x: SCREEN_WIDTH - 50,
y: 23.05 // moved down by 0.3cm (11.55px)
});
var assetsText = new Text2('Past Scores', {
size: 60,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 5,
bold: true
});
assetsText.anchor.set(1, 0.5);
assetsText.x = SCREEN_WIDTH - 80;
assetsText.y = 50 + 60;
self.addChild(assetsText);
assetsBtn.interactive = true;
assetsBtn.down = function () {
showScoreHistoryPopup();
};
// Button interactivity
playBtn.interactive = true;
playBtn.down = function () {
if (self.parent) self.parent.removeChild(self);
showGame();
};
settingsBtn.interactive = true;
settingsBtn.down = function () {
if (self.parent) self.parent.removeChild(self);
showSettingsMenu();
};
return self;
});
var SettingsMenu = Container.expand(function () {
var self = Container.call(this);
// Settings background
var bg = self.attachAsset('menuBg', {
anchorX: 0.5,
anchorY: 0.5,
x: SCREEN_WIDTH / 2,
y: SCREEN_HEIGHT / 2
});
// Title
var settingsTitle = new Text2('Settings', {
size: 120,
fill: 0xFFF200,
stroke: 0x000000,
strokeThickness: 8,
bold: true
});
settingsTitle.anchor.set(0.5, 0.5);
settingsTitle.x = SCREEN_WIDTH / 2;
settingsTitle.y = SCREEN_HEIGHT / 2 - 300;
self.addChild(settingsTitle);
// Back button
var backBtn = self.attachAsset('menuButton', {
anchorX: 0.5,
anchorY: 0.5,
x: SCREEN_WIDTH / 2,
y: SCREEN_HEIGHT / 2 + 350
});
var backText = new Text2('Back', {
size: 80,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 7,
bold: true
});
backText.anchor.set(0.5, 0.5);
backText.x = SCREEN_WIDTH / 2;
backText.y = SCREEN_HEIGHT / 2 + 350;
self.addChild(backText);
// Example settings text
var infoText = new Text2('Sound: On\nMusic: On', {
size: 70,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 5,
bold: true
});
infoText.anchor.set(0.5, 0.5);
infoText.x = SCREEN_WIDTH / 2;
infoText.y = SCREEN_HEIGHT / 2;
self.addChild(infoText);
backBtn.interactive = true;
backBtn.down = function () {
if (self.parent) self.parent.removeChild(self);
showMenu();
};
return self;
});
var Soul = Container.expand(function () {
var self = Container.call(this);
self.init = function (x, y) {
// Create soul graphics
var soulGraphics = self.attachAsset('heart', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5,
alpha: 0.7
});
// Set initial position
self.x = x;
self.y = y;
// Randomize direction slightly
self.targetX = Math.random() * 300 - 150 + x;
self.targetY = y - 300 - Math.random() * 200; // Always float upward
// Start the float animation
tween(self, {
x: self.targetX,
y: self.targetY,
alpha: 0,
scaleX: 0.1,
scaleY: 0.1
}, {
duration: 1500 + Math.random() * 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
self.destroy();
}
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Menu and settings assets
// New effect asset
;
// Game constants
var SCREEN_WIDTH = 2048;
var SCREEN_HEIGHT = 2732;
var MAX_LIVES = 3;
var BOMB_THRESHOLD_SCORE = 15;
var SPAWN_INTERVAL_INITIAL = 60; // frames
var MIN_SPAWN_INTERVAL = 20; // frames
var INTERVAL_DECREMENT = 1;
// Game variables
var fallingItems = [];
var lives = MAX_LIVES;
var spawnCounter = 0;
var currentSpawnInterval = SPAWN_INTERVAL_INITIAL;
var currentSpeed = 2;
var isGameOver = false;
var extraHeartSpawned = false;
var extraHeartCaught = false;
var gameStarted = false;
// Banana combo system variables (REMOVED)
// var bananaCombo = 0;
// var bananaComboTimer = null;
// var BANANA_COMBO_TIMEOUT = 1500; // ms
// var maxBananaCombo = 0;
// Combo text UI (REMOVED)
// var comboText = new Text2('', {
// size: 120,
// fill: 0xA259FF,
// // purple
// stroke: 0x000000,
// strokeThickness: 8,
// bold: true
// });
// comboText.anchor.set(0.5, 0);
// comboText.x = SCREEN_WIDTH / 2;
// comboText.y = 200;
// comboText.visible = false;
// game.addChild(comboText);
// Add background
var background = game.addChild(LK.getAsset('background', {
anchorX: 0,
anchorY: 0
}));
// Menu logic
var menuInstance = null;
var settingsMenuInstance = null;
// Show popup with past scores
function showScoreHistoryPopup() {
// Remove existing popup if present
if (game.scoreHistoryPopup && game.scoreHistoryPopup.parent) {
game.removeChild(game.scoreHistoryPopup);
game.scoreHistoryPopup = null;
}
var popup = new Container();
// Popup background
var bg = popup.attachAsset('menuBg', {
anchorX: 0.5,
anchorY: 0.5,
x: SCREEN_WIDTH / 2,
y: SCREEN_HEIGHT / 2,
scaleX: 0.7,
scaleY: 0.7
});
// Title
var title = new Text2('Past Scores', {
size: 90,
fill: 0xFFF200,
stroke: 0x000000,
strokeThickness: 7,
bold: true
});
title.anchor.set(0.5, 0.5);
title.x = SCREEN_WIDTH / 2;
title.y = SCREEN_HEIGHT / 2 - 350;
popup.addChild(title);
// Get score history from storage (show up to 10 most recent)
var history = storage.scoreHistory || [];
var displayScores = history.slice(-10).reverse();
var scoresText = displayScores.length > 0 ? displayScores.map(function (s, i) {
return i + 1 + '. ' + s;
}).join('\n') : 'No scores yet!';
var scoresList = new Text2(scoresText, {
size: 70,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 5,
bold: true
});
scoresList.anchor.set(0.5, 0);
scoresList.x = SCREEN_WIDTH / 2;
scoresList.y = SCREEN_HEIGHT / 2 - 220;
popup.addChild(scoresList);
// Close button
var closeBtn = popup.attachAsset('menuButton', {
anchorX: 0.5,
anchorY: 0.5,
x: SCREEN_WIDTH / 2,
y: SCREEN_HEIGHT / 2 + 350,
scaleX: 0.7,
scaleY: 0.7
});
var closeText = new Text2('Close', {
size: 70,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 6,
bold: true
});
closeText.anchor.set(0.5, 0.5);
closeText.x = SCREEN_WIDTH / 2;
closeText.y = SCREEN_HEIGHT / 2 + 350;
popup.addChild(closeText);
closeBtn.interactive = true;
closeBtn.down = function () {
if (popup.parent) game.removeChild(popup);
game.scoreHistoryPopup = null;
};
game.addChild(popup);
game.scoreHistoryPopup = popup;
}
// Show menu
function showMenu() {
if (menuInstance) {
if (!menuInstance.parent) game.addChild(menuInstance);
return;
}
menuInstance = new Menu();
game.addChild(menuInstance);
}
// Show settings menu
function showSettingsMenu() {
if (settingsMenuInstance) {
if (!settingsMenuInstance.parent) game.addChild(settingsMenuInstance);
return;
}
settingsMenuInstance = new SettingsMenu();
game.addChild(settingsMenuInstance);
}
// Hide menu and start game
function showGame() {
gameStarted = true;
clickToPlayText.visible = false;
initGame();
}
// Show menu on game start
LK.setTimeout(function () {
showMenu();
}, 10);
// Initialize score text
var scoreText = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 8,
bold: true
});
scoreText.anchor.set(0.5, 0);
scoreText.x = SCREEN_WIDTH / 2;
scoreText.y = 50;
game.addChild(scoreText);
// Create click to play text (hidden, menu will be used instead)
var clickToPlayText = new Text2('Click to Start', {
size: 120,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 8,
bold: true
});
clickToPlayText.anchor.set(0.5, 0.5);
clickToPlayText.x = SCREEN_WIDTH / 2;
clickToPlayText.y = SCREEN_HEIGHT / 2;
clickToPlayText.visible = false;
game.addChild(clickToPlayText);
// Create hearts container
var heartsContainer = new Container();
heartsContainer.x = 1410;
heartsContainer.y = 50;
game.addChild(heartsContainer);
// Initialize hearts display
function initLives() {
// Clear existing hearts
while (heartsContainer.children.length > 0) {
heartsContainer.removeChildAt(0);
}
// Add hearts based on current lives
for (var i = 0; i < lives; i++) {
var heart = LK.getAsset('heart', {
anchorX: 0,
anchorY: 0,
x: i * 190,
y: 0
});
heartsContainer.addChild(heart);
}
}
// Function to create floating soul effect
function createSoulEffect(x, y, count) {
count = count || 1;
for (var i = 0; i < count; i++) {
var soul = new Soul();
soul.init(x, y);
game.addChild(soul);
}
}
// Function to create banana effect when banana is clicked
function createBananaEffect(x, y) {
var effect = new BananaEffect();
effect.init(x, y);
game.addChild(effect);
}
// Function to create banana click effect animation
function createBananaClickEffect(x, y) {
var effect = new BananaClickEffect();
effect.init(x, y);
game.addChild(effect);
}
// Function to check if a heart is already falling
function isHeartAlreadyFalling() {
for (var i = 0; i < fallingItems.length; i++) {
if (fallingItems[i] && fallingItems[i].type === "heart" && fallingItems[i].active) {
return true;
}
}
return false;
}
// Function to increase life
function increaseLife() {
if (lives < MAX_LIVES) {
lives++;
initLives();
extraHeartCaught = true; // Mark that a heart was caught
}
}
// Function to decrease life
function decreaseLife() {
// Create soul effect at heart position that was lost
var heartIndex = lives - 1;
if (heartIndex >= 0 && heartsContainer.children[heartIndex]) {
var heartPos = heartsContainer.children[heartIndex];
var globalPos = heartsContainer.toGlobal({
x: heartPos.x + 50,
y: heartPos.y + 50
});
var gamePos = game.toLocal(globalPos);
createSoulEffect(gamePos.x, gamePos.y, 7);
}
lives--;
initLives();
// We only play the heart loss sound for actual life losses, not from bombs or rotten bananas
// This is handled in the game.update and FallingItem.down methods where decreaseLife is called.
// LK.getSound('heartLossSound').play(); // Removed sound here
// Shake the screen using the tween library
tween(game, {
x: game.x + 5
}, {
duration: 50,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(game, {
x: game.x - 10
}, {
duration: 100,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(game, {
x: game.x + 5
}, {
duration: 50,
easing: tween.easeIn,
onFinish: function onFinish() {
// Check for game over after shake is complete
if (lives <= 0) {
gameOver();
}
}
});
}
});
}
});
}
// Function to handle game over
function gameOver() {
if (isGameOver) {
return;
}
isGameOver = true;
gameStarted = false;
// Reset banana combo system (REMOVED)
// bananaCombo = 0;
// comboText.visible = false;
// if (bananaComboTimer) {
// LK.clearTimeout(bananaComboTimer);
// bananaComboTimer = null;
// }
LK.getSound('gameover').play();
LK.effects.flashScreen(0xff0000, 1000);
// [Bu kısım kaldırıldı] -> createSoulEffect ile kalp efektleri artık çıkmayacak
// Remove all falling items
for (var i = fallingItems.length - 1; i >= 0; i--) {
fallingItems[i].destroy();
}
fallingItems = [];
// Save score to storage history
var score = LK.getScore();
if (typeof score === "number" && score > 0) {
var history = storage.scoreHistory || [];
history.push(score);
// Keep only last 20 scores
if (history.length > 20) {
history = history.slice(history.length - 20);
}
storage.scoreHistory = history;
}
// Show game over screen
LK.setTimeout(function () {
LK.showGameOver();
}, 1000);
// Show click to play text again
clickToPlayText.visible = true;
}
function spawnItem() {
var score = LK.getScore();
var isBomb = false;
var isRottenBanana = false;
var isHeart = false;
// Heart spawn logic
if (!isHeartAlreadyFalling()) {
if (score >= 50 && lives === 1 && !extraHeartSpawned) {
isHeart = true;
extraHeartSpawned = true;
} else if (score >= 70 && lives === 1 && extraHeartSpawned && !extraHeartCaught) {
isHeart = true;
}
}
// Rotten banana and bomb logic (independent, so both can spawn)
if (!isHeart) {
if (score >= 20 && Math.random() < 0.3) {
isRottenBanana = true;
} else if (score >= 10 && Math.random() < 0.3) {
isBomb = true;
}
}
var itemType = "banana";
if (isHeart) {
itemType = "heart";
} else if (isRottenBanana) {
itemType = "rottenBanana";
} else if (isBomb) {
itemType = "bomb";
}
var item = new FallingItem();
if (itemType === "heart" && score > 100 && lives === 1) {
item.init(itemType, 16);
} else if (itemType === "heart" && score >= 50 && lives === 1) {
item.init(itemType, 10);
} else {
item.init(itemType, currentSpeed);
}
fallingItems.push(item);
game.addChild(item);
return item;
}
// Update game state each frame
game.update = function () {
if (!gameStarted || isGameOver) {
return;
}
// Update all falling items
for (var i = fallingItems.length - 1; i >= 0; i--) {
var item = fallingItems[i];
// Check if item has fallen off screen
if (item && item.lastY !== undefined && item.active && item.lastY < SCREEN_HEIGHT && item.y >= SCREEN_HEIGHT) {
if (item.type === "banana" && item.active) {
// Missed a banana - lose a life
decreaseLife();
LK.getSound('heartLossSound').play(); // Play sound for missed banana
item.remove();
} else if (item.type === "bomb" && item.active || item.type === "rottenBanana" && item.active) {
// Bomb or rotten banana fell off screen - remove it with no penalty
item.destroy();
fallingItems.splice(i, 1);
}
}
// Remove destroyed items from array
if (!item || !item.active || item.alpha <= 0) {
fallingItems.splice(i, 1);
}
}
// Spawn new items at intervals
spawnCounter++;
// Get current score for difficulty calculations
var score = LK.getScore();
// Hearts will be spawned based on specific conditions in spawnItem function
if (spawnCounter >= currentSpawnInterval) {
spawnItem();
spawnCounter = 0;
// Set speed multiplier based on score thresholds
var speedMultiplier = 1;
// 0-150 arası sabit artışlar (orijinal hız tablosu)
if (score >= 150) {
speedMultiplier = 21;
} else if (score >= 140) {
speedMultiplier = 20.5;
} else if (score >= 130) {
speedMultiplier = 20;
} else if (score >= 120) {
speedMultiplier = 19.5;
} else if (score >= 110) {
speedMultiplier = 19;
} else if (score >= 100) {
speedMultiplier = 18;
} else if (score >= 90) {
speedMultiplier = 17;
} else if (score >= 80) {
speedMultiplier = 16;
} else if (score >= 70) {
speedMultiplier = 15;
} else if (score >= 60) {
speedMultiplier = 14;
} else if (score >= 50) {
speedMultiplier = 12.5;
} else if (score >= 40) {
speedMultiplier = 12;
} else if (score >= 30) {
speedMultiplier = 11.5;
} else if (score >= 20) {
speedMultiplier = 11;
} else if (score >= 10) {
speedMultiplier = 10;
} else if (score >= 0) {
speedMultiplier = 9;
} else {
speedMultiplier = 7;
}
// 150’den sonra 300000’e kadar dinamik artış: +0.25 her 1 skor artışı için
if (score > 150 && score <= 300000) {
speedMultiplier = 15 + (score - 150) * 0.5;
}
// Eğer istersen 300000’den sonrası için burada farklı artış mantığı eklenebilir.
// Örnek olarak, 300000’den sonra her 1000 puanda 0.1 artış veya başka bir şey gibi.
// Güncellenen hız, oyun içindeki hız değişkenine atanıyor
currentSpeed = 2 * speedMultiplier;
// Spawn interval (yeniden item çıkma aralığı) puana göre azalıyor ama minimum sınırı var
currentSpawnInterval = Math.max(MIN_SPAWN_INTERVAL, SPAWN_INTERVAL_INITIAL - score * INTERVAL_DECREMENT);
}
// Score text’i güncelle
scoreText.setText('Score: ' + score);
};
// Initialize the game
function initGame() {
// Reset game variables
lives = MAX_LIVES;
LK.setScore(0);
spawnCounter = 0;
currentSpawnInterval = SPAWN_INTERVAL_INITIAL;
currentSpeed = 2;
isGameOver = false;
extraHeartSpawned = false; // Reset heart spawn tracking
extraHeartCaught = false; // Reset heart catch tracking
fallingItems = [];
// Reset banana combo system (REMOVED)
// bananaCombo = 0;
// maxBananaCombo = 0;
// comboText.visible = false;
// if (bananaComboTimer) {
// LK.clearTimeout(bananaComboTimer);
// bananaComboTimer = null;
// }
// Initialize UI
initLives();
scoreText.setText('Score: 0');
// Play background music
LK.playMusic('gameMusic');
}
// Set up click handler to start game
// (Removed, menu handles game start)
// Initialize but don't start the game yet
lives = MAX_LIVES;
initLives();
Pixel banana. In-Game asset. High contrast. No shadows
Pixel art Bomb.. In-Game asset. High contrast. No shadows
Pixel art Heart. In-Game asset. High contrast. No shadows
Pixel art Forest background. In-Game asset. High contrast. No shadows
Purple color "+1" in pixels art style . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Simple empty clean pixel art background in brown. In-Game asset. 2d. High contrast. No shadows. Game menu background.
Menu button. Pixel art dark brown.. In-Game asset. 2d. High contrast. No shadows No writing inside