User prompt
bomba assetini 2 kat büyüt
User prompt
play assetini iki kat büyüt ve biraz aşağı kaydır
User prompt
play asseti yerine by furkan asseti var
User prompt
o zaman şöyle yapalım oyun önce hemen açılmasın önce bir ana menüde play butonu olsun ve buna basınca oyun başlasın ve ana menüde top score da yazsın
User prompt
top score sayacı görünmüyor
User prompt
top score yazısını daha kalın yap ve sağ üste koy
User prompt
top score yazısını siyah yap
User prompt
bir puan sistemi de ekleyelim kesilen her meyve 10 puan getirsin 2 li kombolarda değer 2 kat artar ve 3 lü komboda da aynı şekilde en yüksek yapılan puan için de yukarıya bir sayaç yap
User prompt
arka plan bütün ekranı doldurmalı
User prompt
bazı meyveler sağa ya da sola kaçıyor düzelt
User prompt
tüm meyveleri iki kat büyüt
User prompt
delete fuse asset
User prompt
meyveler için asset ekle
User prompt
çok güzel oldu
Code edit (1 edits merged)
Please save this source code
User prompt
Ninja Fruit Slice
Initial prompt
ninja fruit oyununu yapalım gerçek ninja fruite benzesin farklı meyveler de olsun arka planı da değiştirmek içib bir assetimiz olsun
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ // Bomb class: Represents a bomb flying through the air var Bomb = Container.expand(function () { var self = Container.call(this); self.sliced = false; self.missed = false; // Attach bomb asset (black ellipse) var bombAsset = self.attachAsset('bomb', { anchorX: 0.5, anchorY: 0.5, width: 190, height: 190, color: 0x222222, shape: 'ellipse' }); // Add a white "fuse" (small rectangle) var fuse = self.attachAsset('fuse', { anchorX: 0.5, anchorY: 1, width: 20, height: 50, color: 0xffffff, shape: 'box', y: -80 }); // Set initial position and velocity (to be set by spawner) self.x = 0; self.y = 0; self.vx = 0; self.vy = 0; self.gravity = 0.35 + Math.random() * 0.1; self.lastY = self.y; self.update = function () { if (self.sliced) return; self.x += self.vx; self.y += self.vy; self.vy += self.gravity; bombAsset.rotation += 0.09; if (!self.missed && self.y > 2732 + 100) { self.missed = true; } }; self.slice = function () { if (self.sliced) return; self.sliced = true; // Animate: flash red and fade out tween(self, { scaleX: 1.7, scaleY: 1.7, alpha: 0 }, { duration: 250, easing: tween.easeOut, onFinish: function onFinish() { self.destroy(); } }); }; return self; }); // Fruit class: Represents a fruit flying through the air var Fruit = Container.expand(function () { var self = Container.call(this); // Fruit types and their properties var fruitTypes = [{ id: 'apple', color: 0xff2d2d, points: 1 }, { id: 'banana', color: 0xfff700, points: 2 }, { id: 'orange', color: 0xffa500, points: 3 }, { id: 'watermelon', color: 0x2ecc40, points: 5 }, { id: 'grape', color: 0x8e44ad, points: 4 }, { id: 'kiwi', color: 0x7ed957, points: 3 }, { id: 'lemon', color: 0xfff700, points: 2 }, { id: 'strawberry', color: 0xff3b6b, points: 4 }, { id: 'blueberry', color: 0x3b5fff, points: 4 }, { id: 'pineapple', color: 0xffe066, points: 5 }]; // Randomly pick a fruit type var typeIndex = Math.floor(Math.random() * fruitTypes.length); var type = fruitTypes[typeIndex]; self.fruitType = type.id; self.points = type.points; self.sliced = false; self.missed = false; // Attach fruit asset (ellipse for fruit) var fruitAsset = self.attachAsset(type.id, { anchorX: 0.5, anchorY: 0.5, width: 320, height: 320, color: type.color, shape: 'ellipse' }); // Give fruit a random initial rotation fruitAsset.rotation = Math.random() * Math.PI * 2; // Set initial position and velocity (to be set by spawner) self.x = 0; self.y = 0; self.vx = 0; self.vy = 0; self.gravity = 0.35 + Math.random() * 0.1; // For tracking if fruit is out of bounds self.lastY = self.y; // For combo detection self.sliceTick = -1; // Animate fruit (arc trajectory) self.update = function () { if (self.sliced) return; // Don't update if already sliced self.x += self.vx; self.y += self.vy; self.vy += self.gravity; // Spin fruit fruitAsset.rotation += 0.07; // If fruit falls below screen, mark as missed if (!self.missed && self.y > 2732 + 100) { self.missed = true; } }; // Slice the fruit self.slice = function () { if (self.sliced) return; self.sliced = true; // --- JUICE SPLASH EFFECT (more visible & dramatic) --- var splashCount = (self.fruitType === "strawberry" ? 22 : 14) + Math.floor(Math.random() * (self.fruitType === "strawberry" ? 8 : 4)); // more splashes for strawberry for (var i = 0; i < splashCount; i++) { // Spread splashes more evenly, but with some randomness var baseAngle = i / splashCount * Math.PI * 2; var angle = baseAngle + (Math.random() - 0.5) * (Math.PI / 8); var speed = (self.fruitType === "strawberry" ? 54 : 38) + Math.random() * (self.fruitType === "strawberry" ? 38 : 32); // faster for strawberry var splash = new Container(); // Use a colored ellipse for splash, color matches fruit var splashColor = 0xff2d2d; // default red if (self.fruitType === "lemon") { splashColor = 0xfff700; } else if (self.fruitType === "strawberry") { splashColor = 0xff1744; // bright strawberry red } else if (self.points > 3) { splashColor = 0xFFE066; } else if (self.points === 1) { splashColor = 0xff2d2d; } else if (self.points === 2) { splashColor = 0xfff700; } else if (self.points === 3) { splashColor = 0xffa500; } else if (self.points === 4) { splashColor = 0x8e44ad; } else { splashColor = 0x2ecc40; } var splashAsset = splash.attachAsset('slicingTrail', { anchorX: 0.5, anchorY: 0.5, width: 120 + Math.random() * 60, // much larger height: 32 + Math.random() * 18, // much taller color: splashColor, alpha: 0.95, // more opaque rotation: angle }); splash.x = self.x; splash.y = self.y; if (self.fruitType === "strawberry") { splash.scaleX = 1.7 + Math.random() * 1.1; splash.scaleY = 1.7 + Math.random() * 1.1; splash.alpha = 1; } else { splash.scaleX = 1.1 + Math.random() * 0.7; splash.scaleY = 1.1 + Math.random() * 0.7; } game.addChild(splash); // Animate splash: move outward, fade out, stretch and shrink (function (splash, splashAsset, angle, speed) { var dx = Math.cos(angle) * speed; var dy = Math.sin(angle) * speed; tween(splash, { x: splash.x + dx, y: splash.y + dy, alpha: 0, scaleX: splash.scaleX * (2.2 + Math.random() * 0.7), scaleY: splash.scaleY * (0.5 + Math.random() * 0.3) }, { duration: (self.fruitType === "strawberry" ? 1100 : 600) + Math.random() * (self.fruitType === "strawberry" ? 400 : 200), // longer duration for strawberry easing: tween.cubicOut, onFinish: function onFinish() { splash.destroy(); } }); })(splash, splashAsset, angle, speed); } // Animate: scale up and fade out tween(self, { scaleX: 1.5, scaleY: 1.5, alpha: 0 }, { duration: 350, easing: tween.easeOut, onFinish: function onFinish() { self.destroy(); } }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x222a36 }); /**** * Game Code ****/ // Slicing effect asset: a white ellipse, slightly transparent, for the slicing trail // --- MAIN MENU STATE --- var isGameStarted = false; // Main menu container var mainMenu = new Container(); // Top score asset and text (centered on screen) // Use persistent storage to get/set top score for this user var userTopScore = storage.userTopScore || 0; var topScoreAsset = LK.getAsset('missedX', { anchorX: 0.5, anchorY: 0.5, width: 90, height: 90, x: 2048 / 2, y: 2732 / 2 }); mainMenu.addChild(topScoreAsset); var topScoreTxt = new Text2('En Yüksek Skor: ' + userTopScore, { size: 110, fill: "#fff", font: "bold 900 110px Arial, 'GillSans-Bold', Impact, 'Arial Black', Tahoma" }); topScoreTxt.anchor.set(0.5, 0.5); // Place text below the asset, centered horizontally topScoreTxt.x = topScoreAsset.x; topScoreTxt.y = topScoreAsset.y + 120; mainMenu.addChild(topScoreTxt); // Update top score in storage and menu if needed function updateUserTopScore(newScore) { var prev = storage.userTopScore || 0; if (newScore > prev) { storage.userTopScore = newScore; if (typeof topScoreInGameTxt !== "undefined") { topScoreInGameTxt.setText('En Yüksek Skor: ' + newScore); } } } // --- GLOBALS --- var fruits = []; var bombs = []; var missedFruits = 0; var maxMissed = 5; // Increased from 3 to 5 // Add missedX asset for missed indicator var comboWindow = 20; // ticks for combo var lastSliceTick = -100; var comboCount = 0; var bestCombo = 0; var backgroundIndex = 0; var backgrounds = [{ id: 'bg1', color: 0x222a36 }, { id: 'bg2', color: 0x1a3d2f }, { id: 'bg3', color: 0x3d1a2f }, { id: 'bg4', color: 0x1e1e2f }]; var missedXNodes = []; // --- MAIN MENU STATE --- var isGameStarted = false; // Main menu container var mainMenu = new Container(); // Main menu background (reuse bg4) var menuBg = LK.getAsset('bg4', { anchorX: 0, anchorY: 0, x: 0, y: 0, width: 2048, height: 2732 }); mainMenu.addChild(menuBg); // "Play" button (now using 'by furkan' asset) var playBtn = LK.getAsset('byfurkan', { anchorX: 0.5, anchorY: 0.5, width: 400 * 2, height: 180 * 2 }); playBtn.x = 2048 / 2 + 70; playBtn.y = 2732 / 2 + 400; mainMenu.addChild(playBtn); var playBtnTxt = new Text2('PLAY', { size: 120, fill: "#fff", font: "bold 900 120px Arial, 'GillSans-Bold', Impact, 'Arial Black', Tahoma" }); playBtnTxt.anchor.set(0.5, 0.5); playBtnTxt.x = playBtn.x; playBtnTxt.y = playBtn.y; mainMenu.addChild(playBtnTxt); // Show main menu at start game.addChild(mainMenu); // Removed updateMenuTopScore function as top score text is no longer used // --- GUI Elements --- // Score text var scoreTxt = new Text2('0', { size: 120, fill: "#fff" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Top score (user's best) text, always visible at the top center, above the score var topScoreInGameTxt = new Text2('En Yüksek Skor: ' + (storage.userTopScore || 0), { size: 1040, fill: "#000", font: "bold 900 1040px Arial, 'GillSans-Bold', Impact, 'Arial Black', Tahoma" }); topScoreInGameTxt.anchor.set(0.5, 0); // Move text further to the right (e.g. +500px) topScoreInGameTxt.x = 500; // x=0 in LK.gui.top is the center, so +500px to the right topScoreInGameTxt.y = 0; // top edge LK.gui.top.addChild(topScoreInGameTxt); // Move scoreTxt a bit lower so both are visible scoreTxt.y = topScoreInGameTxt.height + 10; // High score (best combo) text var bestComboTxt = new Text2('Best: 0', { size: 120, fill: "#000", font: "bold 900 120px Arial, 'GillSans-Bold', Impact, 'Arial Black', Tahoma" }); bestComboTxt.anchor.set(1, 0); // right edge, top bestComboTxt.x = 0; // x=0 in LK.gui.topRight is the right edge bestComboTxt.y = 0; LK.gui.topRight.addChild(bestComboTxt); // Missed fruits indicator (bottom left, red X's) var missedTxt = new Text2('', { size: 90, fill: 0xFF4444 }); missedTxt.anchor.set(0, 1); LK.gui.bottomLeft.addChild(missedTxt); // Combo text (center, fades out) var comboTxt = new Text2('', { size: 180, fill: 0xFFE066 }); comboTxt.anchor.set(0.5, 0.5); comboTxt.alpha = 0; LK.gui.center.addChild(comboTxt); // Background switch button (bottom right) var bgBtn = LK.getAsset('bgBtn', { anchorX: 1, anchorY: 1, width: 180, height: 100, color: 0x8888ff, shape: 'box' }); bgBtn.x = 0; bgBtn.y = 0; LK.gui.bottomRight.addChild(bgBtn); // Removed bgBtnTxt ('BG' text) as requested // --- BACKGROUND --- // Fullscreen background image node var bgImageNode = LK.getAsset('bg4', { anchorX: 0, anchorY: 0, x: 0, y: 0, width: 2048, height: 2732 }); game.addChild(bgImageNode); function setBackground(idx) { backgroundIndex = idx % backgrounds.length; // Always keep background image behind everything if (bgImageNode.parent) { game.setChildIndex(bgImageNode, 0); } // Optionally, you could swap image asset here if you want to support more backgrounds game.setBackgroundColor(backgrounds[backgroundIndex].color); } setBackground(0); // --- FRUIT & BOMB SPAWNING --- function spawnFruitOrBomb() { // Randomly decide: 80% fruit, 20% bomb var isBomb = Math.random() < 0.2; var obj; // Spawn X within safe bounds var x = 320 + Math.random() * (2048 - 640); var y = 2732 + 80; // Calculate angle so fruit always arcs toward center var centerX = 2048 / 2; var dx = centerX - x; var minAngle = -Math.PI / 2 - Math.PI / 6; // -120deg var maxAngle = -Math.PI / 2 + Math.PI / 6; // -60deg // Angle toward center, with a little random spread var baseAngle = Math.atan2(-1200, dx); var angle = baseAngle + (Math.random() - 0.5) * (Math.PI / 12); // small random spread // Clamp angle to safe range if (angle < minAngle) angle = minAngle; if (angle > maxAngle) angle = maxAngle; var speed = 38 + Math.random() * 10; if (isBomb) { obj = new Bomb(); bombs.push(obj); } else { obj = new Fruit(); fruits.push(obj); } obj.x = x; obj.y = y; obj.vx = Math.cos(angle) * speed; obj.vy = Math.sin(angle) * speed; game.addChild(obj); } // --- GAME LOGIC --- // Swiping: track move events, draw path, and slice var swipePath = []; var swipeMaxLength = 8; // Only keep last 8 points // --- Slicing Effect --- // Slicing effect node (a white line trail) var slicingEffectNodes = []; var slicingEffectVisible = false; // Helper to clear slicing effect function clearSlicingEffect() { for (var i = 0; i < slicingEffectNodes.length; i++) { if (slicingEffectNodes[i] && slicingEffectNodes[i].parent) { slicingEffectNodes[i].parent.removeChild(slicingEffectNodes[i]); } } slicingEffectNodes = []; } // Hide gameplay GUI until game starts scoreTxt.visible = false; bestComboTxt.visible = false; missedTxt.visible = false; comboTxt.visible = false; bgBtn.visible = false; // Show/hide GUI based on game state function updateGUIVisibility() { var show = isGameStarted; scoreTxt.visible = show; bestComboTxt.visible = show; missedTxt.visible = show; comboTxt.visible = show; bgBtn.visible = show; } // Call this after Play is pressed function startGame() { isGameStarted = true; mainMenu.visible = false; updateGUIVisibility(); resetGame(); } // Play button event playBtn.down = function (x, y, obj) { startGame(); }; function handleSlice(x, y) { if (!isGameStarted) return; // Check fruits for (var i = fruits.length - 1; i >= 0; i--) { var fruit = fruits[i]; if (fruit.sliced) continue; // If swipe is close to fruit center (distance < 120) var dx = fruit.x - x; var dy = fruit.y - y; if (dx * dx + dy * dy < 120 * 120) { fruit.slice(); // Combo logic if (lastSliceTick > 0 && LK.ticks - lastSliceTick < comboWindow) { comboCount++; } else { comboCount = 1; } lastSliceTick = LK.ticks; // Combo multiplier: 1x for single, 2x for double, 3x for triple or more var comboMultiplier = 1; if (comboCount === 2) comboMultiplier = 2; if (comboCount >= 3) comboMultiplier = 3; // Each fruit is worth 10 points, multiplied by combo var pointsEarned = 10 * comboMultiplier; LK.setScore(LK.getScore() + pointsEarned); scoreTxt.setText(LK.getScore()); // Show combo text if comboCount >= 2 if (comboCount >= 2) { showCombo(comboCount); } // Track best combo if (typeof bestCombo === "undefined") { bestCombo = 0; } if (comboCount > bestCombo) { bestCombo = comboCount; bestComboTxt.setText('Best: ' + bestCombo); // Removed updateMenuTopScore call as top score text is no longer used } fruit.sliceTick = LK.ticks; } } // Check bombs for (var j = bombs.length - 1; j >= 0; j--) { var bomb = bombs[j]; if (bomb.sliced) continue; var dx = bomb.x - x; var dy = bomb.y - y; if (dx * dx + dy * dy < 120 * 120) { bomb.slice(); // Game over updateUserTopScore(LK.getScore()); if (typeof topScoreInGameTxt !== "undefined") { var userTopScoreNow = storage.userTopScore || 0; topScoreInGameTxt.setText('En Yüksek Skor: ' + userTopScoreNow); } LK.effects.flashScreen(0xff0000, 800); LK.showGameOver(); return; } } } // Show combo text function showCombo(count) { if (count < 2) return; comboTxt.setText('Combo x' + count + '!'); comboTxt.alpha = 1; tween(comboTxt, { alpha: 0 }, { duration: 900, easing: tween.linear }); } // Update missed fruits display function updateMissed() { // Remove previous X assets if any if (typeof missedXNodes !== "undefined") { for (var i = 0; i < missedXNodes.length; i++) { if (missedXNodes[i] && missedXNodes[i].parent) { missedXNodes[i].parent.removeChild(missedXNodes[i]); } } } missedXNodes = []; // Draw up to maxMissed X's for (var i = 0; i < maxMissed; i++) { var xNode = LK.getAsset('missedX', { anchorX: 0, anchorY: 1, x: i * 100, // 90px width + 10px gap y: 0, alpha: i < missedFruits ? 1 : 0.25 // faded if not missed yet }); LK.gui.bottomLeft.addChild(xNode); missedXNodes.push(xNode); } // Hide the old text indicator missedTxt.setText(''); } // --- INPUT HANDLING --- // Swiping: track move events, draw path, and slice game.move = function (x, y, obj) { if (!isGameStarted) return; // Don't allow swipes in top left 100x100 if (x < 100 && y < 100) return; // Add to swipe path swipePath.push({ x: x, y: y, tick: LK.ticks }); if (swipePath.length > swipeMaxLength) swipePath.shift(); // --- Slicing Effect: Show and update --- slicingEffectVisible = true; clearSlicingEffect(); // Draw lines between swipe points for (var i = 1; i < swipePath.length; i++) { var p0 = swipePath[i - 1]; var p1 = swipePath[i]; // Use the custom slicingTrail asset as a "segment" between points var dx = p1.x - p0.x; var dy = p1.y - p0.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { var seg = LK.getAsset('slicingTrail', { anchorX: 0.5, anchorY: 0.5, width: dist, height: 24, x: (p0.x + p1.x) / 2, y: (p0.y + p1.y) / 2, rotation: Math.atan2(dy, dx), alpha: 0.7 }); game.addChild(seg); slicingEffectNodes.push(seg); } } // For each point in swipe path, check for slicing for (var i = 0; i < swipePath.length; i++) { handleSlice(swipePath[i].x, swipePath[i].y); } }; // On down, start new swipe game.down = function (x, y, obj) { if (!isGameStarted) return; swipePath = [{ x: x, y: y, tick: LK.ticks }]; handleSlice(x, y); // --- Slicing Effect: Show on down --- slicingEffectVisible = true; clearSlicingEffect(); }; // On up, clear swipe path game.up = function (x, y, obj) { if (!isGameStarted) return; swipePath = []; // --- Slicing Effect: Hide on up --- slicingEffectVisible = false; clearSlicingEffect(); }; // Background button: tap to change background bgBtn.down = function (x, y, obj) { setBackground((backgroundIndex + 1) % backgrounds.length); }; // --- GAME UPDATE LOOP --- game.update = function () { if (!isGameStarted) { updateGUIVisibility(); return; } updateGUIVisibility(); // Spawn fruits/bombs every 35-55 ticks if (LK.ticks % (35 + Math.floor(Math.random() * 20)) === 0) { spawnFruitOrBomb(); } // Update fruits for (var i = fruits.length - 1; i >= 0; i--) { var fruit = fruits[i]; // Remove if destroyed if (fruit.destroyed) { fruits.splice(i, 1); continue; } // If missed if (fruit.missed && !fruit.sliced) { fruits.splice(i, 1); missedFruits++; updateMissed(); LK.effects.flashObject(missedTxt, 0xff0000, 400); // Check and update top score if needed before game over if (missedFruits >= maxMissed) { updateUserTopScore(LK.getScore()); if (typeof topScoreInGameTxt !== "undefined") { var userTopScoreNow = storage.userTopScore || 0; topScoreInGameTxt.setText('En Yüksek Skor: ' + userTopScoreNow); } LK.effects.flashScreen(0xff0000, 800); LK.showGameOver(); return; } } } // Update bombs for (var j = bombs.length - 1; j >= 0; j--) { var bomb = bombs[j]; if (bomb.destroyed) { bombs.splice(j, 1); continue; } } // Combo reset if (comboCount > 1 && LK.ticks - lastSliceTick > comboWindow) { comboCount = 0; } }; // --- GAME RESET HANDLING --- // On game reset, clear all arrays and reset state function resetGame() { fruits = []; bombs = []; missedFruits = 0; comboCount = 0; lastSliceTick = -100; scoreTxt.setText('0'); comboTxt.setText(''); comboTxt.alpha = 0; updateMissed(); setBackground(0); // --- Slicing Effect: Clear on reset --- clearSlicingEffect(); slicingEffectVisible = false; // On reset, update top score if needed updateUserTopScore(LK.getScore()); if (typeof topScoreInGameTxt !== "undefined") { var userTopScoreNow = storage.userTopScore || 0; topScoreInGameTxt.setText('En Yüksek Skor: ' + userTopScoreNow); } // Only reset bestCombo if not started, otherwise keep best score if (!isGameStarted) { if (typeof bestCombo === "undefined") bestCombo = 0; bestComboTxt.setText('Best: ' + bestCombo); // Removed updateMenuTopScore call as top score text is no longer used } else { bestComboTxt.setText('Best: ' + (typeof bestCombo !== "undefined" ? bestCombo : 0)); // Removed updateMenuTopScore call as top score text is no longer used } } resetGame(); // --- END OF GAME CODE ---
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
// Bomb class: Represents a bomb flying through the air
var Bomb = Container.expand(function () {
var self = Container.call(this);
self.sliced = false;
self.missed = false;
// Attach bomb asset (black ellipse)
var bombAsset = self.attachAsset('bomb', {
anchorX: 0.5,
anchorY: 0.5,
width: 190,
height: 190,
color: 0x222222,
shape: 'ellipse'
});
// Add a white "fuse" (small rectangle)
var fuse = self.attachAsset('fuse', {
anchorX: 0.5,
anchorY: 1,
width: 20,
height: 50,
color: 0xffffff,
shape: 'box',
y: -80
});
// Set initial position and velocity (to be set by spawner)
self.x = 0;
self.y = 0;
self.vx = 0;
self.vy = 0;
self.gravity = 0.35 + Math.random() * 0.1;
self.lastY = self.y;
self.update = function () {
if (self.sliced) return;
self.x += self.vx;
self.y += self.vy;
self.vy += self.gravity;
bombAsset.rotation += 0.09;
if (!self.missed && self.y > 2732 + 100) {
self.missed = true;
}
};
self.slice = function () {
if (self.sliced) return;
self.sliced = true;
// Animate: flash red and fade out
tween(self, {
scaleX: 1.7,
scaleY: 1.7,
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
self.destroy();
}
});
};
return self;
});
// Fruit class: Represents a fruit flying through the air
var Fruit = Container.expand(function () {
var self = Container.call(this);
// Fruit types and their properties
var fruitTypes = [{
id: 'apple',
color: 0xff2d2d,
points: 1
}, {
id: 'banana',
color: 0xfff700,
points: 2
}, {
id: 'orange',
color: 0xffa500,
points: 3
}, {
id: 'watermelon',
color: 0x2ecc40,
points: 5
}, {
id: 'grape',
color: 0x8e44ad,
points: 4
}, {
id: 'kiwi',
color: 0x7ed957,
points: 3
}, {
id: 'lemon',
color: 0xfff700,
points: 2
}, {
id: 'strawberry',
color: 0xff3b6b,
points: 4
}, {
id: 'blueberry',
color: 0x3b5fff,
points: 4
}, {
id: 'pineapple',
color: 0xffe066,
points: 5
}];
// Randomly pick a fruit type
var typeIndex = Math.floor(Math.random() * fruitTypes.length);
var type = fruitTypes[typeIndex];
self.fruitType = type.id;
self.points = type.points;
self.sliced = false;
self.missed = false;
// Attach fruit asset (ellipse for fruit)
var fruitAsset = self.attachAsset(type.id, {
anchorX: 0.5,
anchorY: 0.5,
width: 320,
height: 320,
color: type.color,
shape: 'ellipse'
});
// Give fruit a random initial rotation
fruitAsset.rotation = Math.random() * Math.PI * 2;
// Set initial position and velocity (to be set by spawner)
self.x = 0;
self.y = 0;
self.vx = 0;
self.vy = 0;
self.gravity = 0.35 + Math.random() * 0.1;
// For tracking if fruit is out of bounds
self.lastY = self.y;
// For combo detection
self.sliceTick = -1;
// Animate fruit (arc trajectory)
self.update = function () {
if (self.sliced) return; // Don't update if already sliced
self.x += self.vx;
self.y += self.vy;
self.vy += self.gravity;
// Spin fruit
fruitAsset.rotation += 0.07;
// If fruit falls below screen, mark as missed
if (!self.missed && self.y > 2732 + 100) {
self.missed = true;
}
};
// Slice the fruit
self.slice = function () {
if (self.sliced) return;
self.sliced = true;
// --- JUICE SPLASH EFFECT (more visible & dramatic) ---
var splashCount = (self.fruitType === "strawberry" ? 22 : 14) + Math.floor(Math.random() * (self.fruitType === "strawberry" ? 8 : 4)); // more splashes for strawberry
for (var i = 0; i < splashCount; i++) {
// Spread splashes more evenly, but with some randomness
var baseAngle = i / splashCount * Math.PI * 2;
var angle = baseAngle + (Math.random() - 0.5) * (Math.PI / 8);
var speed = (self.fruitType === "strawberry" ? 54 : 38) + Math.random() * (self.fruitType === "strawberry" ? 38 : 32); // faster for strawberry
var splash = new Container();
// Use a colored ellipse for splash, color matches fruit
var splashColor = 0xff2d2d; // default red
if (self.fruitType === "lemon") {
splashColor = 0xfff700;
} else if (self.fruitType === "strawberry") {
splashColor = 0xff1744; // bright strawberry red
} else if (self.points > 3) {
splashColor = 0xFFE066;
} else if (self.points === 1) {
splashColor = 0xff2d2d;
} else if (self.points === 2) {
splashColor = 0xfff700;
} else if (self.points === 3) {
splashColor = 0xffa500;
} else if (self.points === 4) {
splashColor = 0x8e44ad;
} else {
splashColor = 0x2ecc40;
}
var splashAsset = splash.attachAsset('slicingTrail', {
anchorX: 0.5,
anchorY: 0.5,
width: 120 + Math.random() * 60,
// much larger
height: 32 + Math.random() * 18,
// much taller
color: splashColor,
alpha: 0.95,
// more opaque
rotation: angle
});
splash.x = self.x;
splash.y = self.y;
if (self.fruitType === "strawberry") {
splash.scaleX = 1.7 + Math.random() * 1.1;
splash.scaleY = 1.7 + Math.random() * 1.1;
splash.alpha = 1;
} else {
splash.scaleX = 1.1 + Math.random() * 0.7;
splash.scaleY = 1.1 + Math.random() * 0.7;
}
game.addChild(splash);
// Animate splash: move outward, fade out, stretch and shrink
(function (splash, splashAsset, angle, speed) {
var dx = Math.cos(angle) * speed;
var dy = Math.sin(angle) * speed;
tween(splash, {
x: splash.x + dx,
y: splash.y + dy,
alpha: 0,
scaleX: splash.scaleX * (2.2 + Math.random() * 0.7),
scaleY: splash.scaleY * (0.5 + Math.random() * 0.3)
}, {
duration: (self.fruitType === "strawberry" ? 1100 : 600) + Math.random() * (self.fruitType === "strawberry" ? 400 : 200),
// longer duration for strawberry
easing: tween.cubicOut,
onFinish: function onFinish() {
splash.destroy();
}
});
})(splash, splashAsset, angle, speed);
}
// Animate: scale up and fade out
tween(self, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0
}, {
duration: 350,
easing: tween.easeOut,
onFinish: function onFinish() {
self.destroy();
}
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222a36
});
/****
* Game Code
****/
// Slicing effect asset: a white ellipse, slightly transparent, for the slicing trail
// --- MAIN MENU STATE ---
var isGameStarted = false;
// Main menu container
var mainMenu = new Container();
// Top score asset and text (centered on screen)
// Use persistent storage to get/set top score for this user
var userTopScore = storage.userTopScore || 0;
var topScoreAsset = LK.getAsset('missedX', {
anchorX: 0.5,
anchorY: 0.5,
width: 90,
height: 90,
x: 2048 / 2,
y: 2732 / 2
});
mainMenu.addChild(topScoreAsset);
var topScoreTxt = new Text2('En Yüksek Skor: ' + userTopScore, {
size: 110,
fill: "#fff",
font: "bold 900 110px Arial, 'GillSans-Bold', Impact, 'Arial Black', Tahoma"
});
topScoreTxt.anchor.set(0.5, 0.5);
// Place text below the asset, centered horizontally
topScoreTxt.x = topScoreAsset.x;
topScoreTxt.y = topScoreAsset.y + 120;
mainMenu.addChild(topScoreTxt);
// Update top score in storage and menu if needed
function updateUserTopScore(newScore) {
var prev = storage.userTopScore || 0;
if (newScore > prev) {
storage.userTopScore = newScore;
if (typeof topScoreInGameTxt !== "undefined") {
topScoreInGameTxt.setText('En Yüksek Skor: ' + newScore);
}
}
}
// --- GLOBALS ---
var fruits = [];
var bombs = [];
var missedFruits = 0;
var maxMissed = 5; // Increased from 3 to 5
// Add missedX asset for missed indicator
var comboWindow = 20; // ticks for combo
var lastSliceTick = -100;
var comboCount = 0;
var bestCombo = 0;
var backgroundIndex = 0;
var backgrounds = [{
id: 'bg1',
color: 0x222a36
}, {
id: 'bg2',
color: 0x1a3d2f
}, {
id: 'bg3',
color: 0x3d1a2f
}, {
id: 'bg4',
color: 0x1e1e2f
}];
var missedXNodes = [];
// --- MAIN MENU STATE ---
var isGameStarted = false;
// Main menu container
var mainMenu = new Container();
// Main menu background (reuse bg4)
var menuBg = LK.getAsset('bg4', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
width: 2048,
height: 2732
});
mainMenu.addChild(menuBg);
// "Play" button (now using 'by furkan' asset)
var playBtn = LK.getAsset('byfurkan', {
anchorX: 0.5,
anchorY: 0.5,
width: 400 * 2,
height: 180 * 2
});
playBtn.x = 2048 / 2 + 70;
playBtn.y = 2732 / 2 + 400;
mainMenu.addChild(playBtn);
var playBtnTxt = new Text2('PLAY', {
size: 120,
fill: "#fff",
font: "bold 900 120px Arial, 'GillSans-Bold', Impact, 'Arial Black', Tahoma"
});
playBtnTxt.anchor.set(0.5, 0.5);
playBtnTxt.x = playBtn.x;
playBtnTxt.y = playBtn.y;
mainMenu.addChild(playBtnTxt);
// Show main menu at start
game.addChild(mainMenu);
// Removed updateMenuTopScore function as top score text is no longer used
// --- GUI Elements ---
// Score text
var scoreTxt = new Text2('0', {
size: 120,
fill: "#fff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Top score (user's best) text, always visible at the top center, above the score
var topScoreInGameTxt = new Text2('En Yüksek Skor: ' + (storage.userTopScore || 0), {
size: 1040,
fill: "#000",
font: "bold 900 1040px Arial, 'GillSans-Bold', Impact, 'Arial Black', Tahoma"
});
topScoreInGameTxt.anchor.set(0.5, 0);
// Move text further to the right (e.g. +500px)
topScoreInGameTxt.x = 500; // x=0 in LK.gui.top is the center, so +500px to the right
topScoreInGameTxt.y = 0; // top edge
LK.gui.top.addChild(topScoreInGameTxt);
// Move scoreTxt a bit lower so both are visible
scoreTxt.y = topScoreInGameTxt.height + 10;
// High score (best combo) text
var bestComboTxt = new Text2('Best: 0', {
size: 120,
fill: "#000",
font: "bold 900 120px Arial, 'GillSans-Bold', Impact, 'Arial Black', Tahoma"
});
bestComboTxt.anchor.set(1, 0); // right edge, top
bestComboTxt.x = 0; // x=0 in LK.gui.topRight is the right edge
bestComboTxt.y = 0;
LK.gui.topRight.addChild(bestComboTxt);
// Missed fruits indicator (bottom left, red X's)
var missedTxt = new Text2('', {
size: 90,
fill: 0xFF4444
});
missedTxt.anchor.set(0, 1);
LK.gui.bottomLeft.addChild(missedTxt);
// Combo text (center, fades out)
var comboTxt = new Text2('', {
size: 180,
fill: 0xFFE066
});
comboTxt.anchor.set(0.5, 0.5);
comboTxt.alpha = 0;
LK.gui.center.addChild(comboTxt);
// Background switch button (bottom right)
var bgBtn = LK.getAsset('bgBtn', {
anchorX: 1,
anchorY: 1,
width: 180,
height: 100,
color: 0x8888ff,
shape: 'box'
});
bgBtn.x = 0;
bgBtn.y = 0;
LK.gui.bottomRight.addChild(bgBtn);
// Removed bgBtnTxt ('BG' text) as requested
// --- BACKGROUND ---
// Fullscreen background image node
var bgImageNode = LK.getAsset('bg4', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
width: 2048,
height: 2732
});
game.addChild(bgImageNode);
function setBackground(idx) {
backgroundIndex = idx % backgrounds.length;
// Always keep background image behind everything
if (bgImageNode.parent) {
game.setChildIndex(bgImageNode, 0);
}
// Optionally, you could swap image asset here if you want to support more backgrounds
game.setBackgroundColor(backgrounds[backgroundIndex].color);
}
setBackground(0);
// --- FRUIT & BOMB SPAWNING ---
function spawnFruitOrBomb() {
// Randomly decide: 80% fruit, 20% bomb
var isBomb = Math.random() < 0.2;
var obj;
// Spawn X within safe bounds
var x = 320 + Math.random() * (2048 - 640);
var y = 2732 + 80;
// Calculate angle so fruit always arcs toward center
var centerX = 2048 / 2;
var dx = centerX - x;
var minAngle = -Math.PI / 2 - Math.PI / 6; // -120deg
var maxAngle = -Math.PI / 2 + Math.PI / 6; // -60deg
// Angle toward center, with a little random spread
var baseAngle = Math.atan2(-1200, dx);
var angle = baseAngle + (Math.random() - 0.5) * (Math.PI / 12); // small random spread
// Clamp angle to safe range
if (angle < minAngle) angle = minAngle;
if (angle > maxAngle) angle = maxAngle;
var speed = 38 + Math.random() * 10;
if (isBomb) {
obj = new Bomb();
bombs.push(obj);
} else {
obj = new Fruit();
fruits.push(obj);
}
obj.x = x;
obj.y = y;
obj.vx = Math.cos(angle) * speed;
obj.vy = Math.sin(angle) * speed;
game.addChild(obj);
}
// --- GAME LOGIC ---
// Swiping: track move events, draw path, and slice
var swipePath = [];
var swipeMaxLength = 8; // Only keep last 8 points
// --- Slicing Effect ---
// Slicing effect node (a white line trail)
var slicingEffectNodes = [];
var slicingEffectVisible = false;
// Helper to clear slicing effect
function clearSlicingEffect() {
for (var i = 0; i < slicingEffectNodes.length; i++) {
if (slicingEffectNodes[i] && slicingEffectNodes[i].parent) {
slicingEffectNodes[i].parent.removeChild(slicingEffectNodes[i]);
}
}
slicingEffectNodes = [];
}
// Hide gameplay GUI until game starts
scoreTxt.visible = false;
bestComboTxt.visible = false;
missedTxt.visible = false;
comboTxt.visible = false;
bgBtn.visible = false;
// Show/hide GUI based on game state
function updateGUIVisibility() {
var show = isGameStarted;
scoreTxt.visible = show;
bestComboTxt.visible = show;
missedTxt.visible = show;
comboTxt.visible = show;
bgBtn.visible = show;
}
// Call this after Play is pressed
function startGame() {
isGameStarted = true;
mainMenu.visible = false;
updateGUIVisibility();
resetGame();
}
// Play button event
playBtn.down = function (x, y, obj) {
startGame();
};
function handleSlice(x, y) {
if (!isGameStarted) return;
// Check fruits
for (var i = fruits.length - 1; i >= 0; i--) {
var fruit = fruits[i];
if (fruit.sliced) continue;
// If swipe is close to fruit center (distance < 120)
var dx = fruit.x - x;
var dy = fruit.y - y;
if (dx * dx + dy * dy < 120 * 120) {
fruit.slice();
// Combo logic
if (lastSliceTick > 0 && LK.ticks - lastSliceTick < comboWindow) {
comboCount++;
} else {
comboCount = 1;
}
lastSliceTick = LK.ticks;
// Combo multiplier: 1x for single, 2x for double, 3x for triple or more
var comboMultiplier = 1;
if (comboCount === 2) comboMultiplier = 2;
if (comboCount >= 3) comboMultiplier = 3;
// Each fruit is worth 10 points, multiplied by combo
var pointsEarned = 10 * comboMultiplier;
LK.setScore(LK.getScore() + pointsEarned);
scoreTxt.setText(LK.getScore());
// Show combo text if comboCount >= 2
if (comboCount >= 2) {
showCombo(comboCount);
}
// Track best combo
if (typeof bestCombo === "undefined") {
bestCombo = 0;
}
if (comboCount > bestCombo) {
bestCombo = comboCount;
bestComboTxt.setText('Best: ' + bestCombo);
// Removed updateMenuTopScore call as top score text is no longer used
}
fruit.sliceTick = LK.ticks;
}
}
// Check bombs
for (var j = bombs.length - 1; j >= 0; j--) {
var bomb = bombs[j];
if (bomb.sliced) continue;
var dx = bomb.x - x;
var dy = bomb.y - y;
if (dx * dx + dy * dy < 120 * 120) {
bomb.slice();
// Game over
updateUserTopScore(LK.getScore());
if (typeof topScoreInGameTxt !== "undefined") {
var userTopScoreNow = storage.userTopScore || 0;
topScoreInGameTxt.setText('En Yüksek Skor: ' + userTopScoreNow);
}
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
return;
}
}
}
// Show combo text
function showCombo(count) {
if (count < 2) return;
comboTxt.setText('Combo x' + count + '!');
comboTxt.alpha = 1;
tween(comboTxt, {
alpha: 0
}, {
duration: 900,
easing: tween.linear
});
}
// Update missed fruits display
function updateMissed() {
// Remove previous X assets if any
if (typeof missedXNodes !== "undefined") {
for (var i = 0; i < missedXNodes.length; i++) {
if (missedXNodes[i] && missedXNodes[i].parent) {
missedXNodes[i].parent.removeChild(missedXNodes[i]);
}
}
}
missedXNodes = [];
// Draw up to maxMissed X's
for (var i = 0; i < maxMissed; i++) {
var xNode = LK.getAsset('missedX', {
anchorX: 0,
anchorY: 1,
x: i * 100,
// 90px width + 10px gap
y: 0,
alpha: i < missedFruits ? 1 : 0.25 // faded if not missed yet
});
LK.gui.bottomLeft.addChild(xNode);
missedXNodes.push(xNode);
}
// Hide the old text indicator
missedTxt.setText('');
}
// --- INPUT HANDLING ---
// Swiping: track move events, draw path, and slice
game.move = function (x, y, obj) {
if (!isGameStarted) return;
// Don't allow swipes in top left 100x100
if (x < 100 && y < 100) return;
// Add to swipe path
swipePath.push({
x: x,
y: y,
tick: LK.ticks
});
if (swipePath.length > swipeMaxLength) swipePath.shift();
// --- Slicing Effect: Show and update ---
slicingEffectVisible = true;
clearSlicingEffect();
// Draw lines between swipe points
for (var i = 1; i < swipePath.length; i++) {
var p0 = swipePath[i - 1];
var p1 = swipePath[i];
// Use the custom slicingTrail asset as a "segment" between points
var dx = p1.x - p0.x;
var dy = p1.y - p0.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 0) {
var seg = LK.getAsset('slicingTrail', {
anchorX: 0.5,
anchorY: 0.5,
width: dist,
height: 24,
x: (p0.x + p1.x) / 2,
y: (p0.y + p1.y) / 2,
rotation: Math.atan2(dy, dx),
alpha: 0.7
});
game.addChild(seg);
slicingEffectNodes.push(seg);
}
}
// For each point in swipe path, check for slicing
for (var i = 0; i < swipePath.length; i++) {
handleSlice(swipePath[i].x, swipePath[i].y);
}
};
// On down, start new swipe
game.down = function (x, y, obj) {
if (!isGameStarted) return;
swipePath = [{
x: x,
y: y,
tick: LK.ticks
}];
handleSlice(x, y);
// --- Slicing Effect: Show on down ---
slicingEffectVisible = true;
clearSlicingEffect();
};
// On up, clear swipe path
game.up = function (x, y, obj) {
if (!isGameStarted) return;
swipePath = [];
// --- Slicing Effect: Hide on up ---
slicingEffectVisible = false;
clearSlicingEffect();
};
// Background button: tap to change background
bgBtn.down = function (x, y, obj) {
setBackground((backgroundIndex + 1) % backgrounds.length);
};
// --- GAME UPDATE LOOP ---
game.update = function () {
if (!isGameStarted) {
updateGUIVisibility();
return;
}
updateGUIVisibility();
// Spawn fruits/bombs every 35-55 ticks
if (LK.ticks % (35 + Math.floor(Math.random() * 20)) === 0) {
spawnFruitOrBomb();
}
// Update fruits
for (var i = fruits.length - 1; i >= 0; i--) {
var fruit = fruits[i];
// Remove if destroyed
if (fruit.destroyed) {
fruits.splice(i, 1);
continue;
}
// If missed
if (fruit.missed && !fruit.sliced) {
fruits.splice(i, 1);
missedFruits++;
updateMissed();
LK.effects.flashObject(missedTxt, 0xff0000, 400);
// Check and update top score if needed before game over
if (missedFruits >= maxMissed) {
updateUserTopScore(LK.getScore());
if (typeof topScoreInGameTxt !== "undefined") {
var userTopScoreNow = storage.userTopScore || 0;
topScoreInGameTxt.setText('En Yüksek Skor: ' + userTopScoreNow);
}
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
return;
}
}
}
// Update bombs
for (var j = bombs.length - 1; j >= 0; j--) {
var bomb = bombs[j];
if (bomb.destroyed) {
bombs.splice(j, 1);
continue;
}
}
// Combo reset
if (comboCount > 1 && LK.ticks - lastSliceTick > comboWindow) {
comboCount = 0;
}
};
// --- GAME RESET HANDLING ---
// On game reset, clear all arrays and reset state
function resetGame() {
fruits = [];
bombs = [];
missedFruits = 0;
comboCount = 0;
lastSliceTick = -100;
scoreTxt.setText('0');
comboTxt.setText('');
comboTxt.alpha = 0;
updateMissed();
setBackground(0);
// --- Slicing Effect: Clear on reset ---
clearSlicingEffect();
slicingEffectVisible = false;
// On reset, update top score if needed
updateUserTopScore(LK.getScore());
if (typeof topScoreInGameTxt !== "undefined") {
var userTopScoreNow = storage.userTopScore || 0;
topScoreInGameTxt.setText('En Yüksek Skor: ' + userTopScoreNow);
}
// Only reset bestCombo if not started, otherwise keep best score
if (!isGameStarted) {
if (typeof bestCombo === "undefined") bestCombo = 0;
bestComboTxt.setText('Best: ' + bestCombo);
// Removed updateMenuTopScore call as top score text is no longer used
} else {
bestComboTxt.setText('Best: ' + (typeof bestCombo !== "undefined" ? bestCombo : 0));
// Removed updateMenuTopScore call as top score text is no longer used
}
}
resetGame();
// --- END OF GAME CODE ---
bomb. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
a chopping board with a kitchen background. In-Game asset. 2d. High contrast. No shadows
üzerinde by furkan yazan bir yazı. In-Game asset. 2d. High contrast. No shadows
double katana. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
applea. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
exploe. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
red. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Tap to play button . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat