Code edit (1 edits merged)
Please save this source code
User prompt
Anlik score giderek asagi gidiyor onu yukari alalim sag tarafa dangerline ustunde kalsin
User prompt
Dangerline ustunde ama ona takın olsun anlik score
User prompt
Ankik score biraz daha asagi alinsin dangerline ustunde kalsin
User prompt
Score next ile best score ile benzer hizada olsun ama sag tarafa yapisik olmasin biraz daha sola gelebilir ama ekranda sagda gorunsun gene
User prompt
Best yerine best score yazsin anlik score gordugumuz sayi sag tarafta olsun next kisminin fontuda siyah olsun birde tum fontlar bold olsun
User prompt
Sagda degil solda olsun bu iki yazı
User prompt
Best score rengi siyah olsun ve next yazisinda onun hemen altinda olsun biraz daha asagi alabiliriz ama dangerline cizgisi ustunde kalsin bu iki yazi
User prompt
Meyveler yukardan aşağı düşerken dangerline dan geçebilir ama aşağıda biriken meyveler aşağıdan dangerline değerse oyun bitsin birde birazcik daha aşağı alalım dangerline cizgisini
Code edit (1 edits merged)
Please save this source code
User prompt
Meyvemer ilk duserken lazerden gecebilir ama asagida biriken meyveler lazere degerse oyun biter
User prompt
Meyve yukardan aşagı düserken lazerden geçebilir asagi düştükten sonra tekrar lazere degerse oyun biter
User prompt
Yukardan duserken lazere degebilir oyun bitmeyecek asagida biriken meyveler ekranda yer kalmayip lazere segerse o zamwn bitecek
User prompt
Daha once yapmıştın simdi neden yapamiyorsun ilk meyve asagi inerken lazerden gecebilir ama lazeri gectikten sonra asagida birikince geri yukari lazere degerse oyun biter
User prompt
Hala duserken degen meyvelerden dolayi oyun bitiyor bunu duzeltirmisin asagida biriken meyveler lazere degerse iyun bitecek
User prompt
Meyver ilk duserken lazere degebilir oyun bitmek zorunda degil ama asagida biriken meyveler lazere degerse oyun bitecek
User prompt
Biriken meyvemer üstteki lazere degiyor ama oyun bitmiyor. Birde en son meyve olan bal kabagi birleşmesin biykece ekranda yer daralmis olsun ve oyun bitmeye zorlasin
User prompt
Asagida biriken meyveler üstteki lazere degsiginde oyun bitmeli ilk yukardan düserken lazere değmesi sorun değil
User prompt
Toplam score ortada ve daha belirgin bir font renginde olsun
User prompt
Best score sol tarafta olsun next ise sağ tarafta
User prompt
Karpuzdan sonra bir tanede kabak ekleyelim
Code edit (1 edits merged)
Please save this source code
User prompt
Gerçek meyve resimleri kullanabilir misin? Birde patlama efekti ekranin titremesi olmasi onceki meyva parcalara ayriliyor gibi patlasin ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Oyun karpuzda bitmesin en yüksek puanı toplamaya çalısalım. En yüksek skor rekor kırilana kadar hafızada tutulsun. Birde meyveler birbirine degdigi anda birlessin hala birlesmedigi yada gec birleştiği oluyor birlesme efektini patlama efekti gibi yapabilir miuyiz iki meyve birlesince oatlayacak ve yeni meyve oluşacak ↪💡 Consider importing and using the following plugins: @upit/storage.v1, @upit/tween.v1
User prompt
Meyver random gelsin ilk baslarda benzer meyveler gelsin biestirmek kolay olsun diye ama zamanla meyveleri birlestirmek zorlaşsın
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Fruit = Container.expand(function (type) {
var self = Container.call(this);
self.type = type;
self.merged = false;
self.velocityY = 0;
self.velocityX = 0;
self.gravity = 0.5;
self.friction = 0.98;
self.bounce = 0.3;
self.hasSettled = false;
self.settleTimer = 0;
self.hasPassedDangerLine = false; // Track if fruit completed initial drop
// Weight system based on fruit size
var fruitWeights = {
'srtawberry': 1,
'grape': 2,
'plum': 3,
'orange': 4,
'apple': 5,
'peach': 6,
'melon': 8,
'watermelon': 10,
'pumpkin': 12
};
self.weight = fruitWeights[type] || 1;
var fruitGraphics = self.attachAsset(type, {
anchorX: 0.5,
anchorY: 0.5
});
self.getRadius = function () {
return fruitGraphics.width / 2;
};
// Method to apply external force (like being hit by another fruit)
self.applyImpulse = function (impulseX, impulseY) {
// Heavier fruits are less affected by external forces
var forceMultiplier = 1 / Math.sqrt(self.weight / 2);
self.velocityX += impulseX * forceMultiplier;
self.velocityY += impulseY * forceMultiplier;
self.hasSettled = false;
self.settleTimer = 0;
};
self.update = function () {
if (self.merged) {
return;
}
// Apply weight-based physics
var weightedGravity = self.gravity * Math.sqrt(self.weight / 5); // Heavier fruits fall faster
self.velocityY += weightedGravity;
self.x += self.velocityX;
self.y += self.velocityY;
// Ground collision with weight-based bouncing
var groundY = 2732 - 100;
if (self.y + self.getRadius() > groundY) {
self.y = groundY - self.getRadius();
// Heavier fruits bounce less
var weightedBounce = self.bounce * (1 / Math.sqrt(self.weight / 3));
self.velocityY *= -weightedBounce;
self.velocityX *= self.friction;
// Apply weight-based settling
var settleThreshold = 2 - self.weight * 0.1;
if (Math.abs(self.velocityY) < settleThreshold) {
self.velocityY = 0;
}
}
// Track if fruit has completed initial drop phase
if (!self.hasPassedDangerLine && self.y + self.getRadius() > dangerLineY + 20) {
self.hasPassedDangerLine = true;
}
// Check if fruit has settled (low velocity for some time)
if (Math.abs(self.velocityY) < 2 && Math.abs(self.velocityX) < 2) {
self.settleTimer++;
if (self.settleTimer > 10) {
// 10 frames = 0.17 seconds at 60fps - faster settling detection
self.hasSettled = true;
}
} else {
self.settleTimer = 0;
self.hasSettled = false; // Reset settled state when fruit starts moving again
}
// Wall collisions with weight-based bouncing
if (self.x - self.getRadius() < 20) {
self.x = 20 + self.getRadius();
var weightedBounce = self.bounce * (1 / Math.sqrt(self.weight / 3));
self.velocityX *= -weightedBounce;
}
if (self.x + self.getRadius() > 2048 - 20) {
self.x = 2048 - 20 - self.getRadius();
var weightedBounce = self.bounce * (1 / Math.sqrt(self.weight / 3));
self.velocityX *= -weightedBounce;
}
// Fruit collision detection with weight-based physics
for (var i = 0; i < fruits.length; i++) {
var otherFruit = fruits[i];
if (otherFruit === self || otherFruit.merged) {
continue;
}
var dx = self.x - otherFruit.x;
var dy = self.y - otherFruit.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var minDistance = self.getRadius() + otherFruit.getRadius();
if (distance < minDistance && distance > 0) {
// Calculate collision response with weight-based physics
var overlap = minDistance - distance;
var normalX = dx / distance;
var normalY = dy / distance;
// Weight-based separation (heavier fruits move less)
var totalWeight = self.weight + otherFruit.weight;
var selfSeparationRatio = otherFruit.weight / totalWeight;
var otherSeparationRatio = self.weight / totalWeight;
var separationX = normalX * overlap * selfSeparationRatio;
var separationY = normalY * overlap * selfSeparationRatio;
var otherSeparationX = -normalX * overlap * otherSeparationRatio;
var otherSeparationY = -normalY * overlap * otherSeparationRatio;
// Apply weight-based separation
self.x += separationX;
self.y += separationY;
otherFruit.x += otherSeparationX;
otherFruit.y += otherSeparationY;
// Calculate relative velocity
var relativeVelocityX = self.velocityX - otherFruit.velocityX;
var relativeVelocityY = self.velocityY - otherFruit.velocityY;
var velocityAlongNormal = relativeVelocityX * normalX + relativeVelocityY * normalY;
// Don't resolve if velocities are separating
if (velocityAlongNormal > 0) {
continue;
}
// Calculate restitution (bounciness)
var restitution = Math.min(self.bounce, otherFruit.bounce);
var impulseScalar = -(1 + restitution) * velocityAlongNormal;
impulseScalar /= 1 / self.weight + 1 / otherFruit.weight;
// Apply impulse with weight consideration
var impulseX = impulseScalar * normalX;
var impulseY = impulseScalar * normalY;
self.velocityX += impulseX / self.weight;
self.velocityY += impulseY / self.weight;
otherFruit.velocityX -= impulseX / otherFruit.weight;
otherFruit.velocityY -= impulseY / otherFruit.weight;
// Weight-based stacking effect - lighter fruits get pushed more
if (self.weight < otherFruit.weight) {
// Lighter fruit on top gets pushed sideways
var pushForce = (otherFruit.weight - self.weight) * 0.2;
self.velocityX += normalX * pushForce;
} else if (otherFruit.weight < self.weight) {
// Other lighter fruit gets pushed
var pushForce = (self.weight - otherFruit.weight) * 0.2;
otherFruit.velocityX -= normalX * pushForce;
}
}
}
// Check if fruits touch danger line - only for settled fruits that reach back up from below
if (self.y - self.getRadius() <= dangerLineY) {
// Only trigger game over if fruit has passed the danger line in initial drop,
// has settled (meaning it's part of the stack), and is now touching the danger line from below
// This ensures only stacked fruits that reach back up trigger game over
if (self.hasPassedDangerLine && self.hasSettled) {
LK.effects.flashScreen(0xFF0000, 1000);
LK.showGameOver();
}
}
};
return self;
});
var FruitParticle = Container.expand(function (x, y, fruitType) {
var self = Container.call(this);
self.x = x;
self.y = y;
// Create smaller piece of the original fruit
var particleGraphics = self.attachAsset(fruitType, {
anchorX: 0.5,
anchorY: 0.5
});
// Make it smaller like a fragment
self.scaleX = 0.3 + Math.random() * 0.2;
self.scaleY = 0.3 + Math.random() * 0.2;
// Random velocity for explosion effect
self.velocityX = (Math.random() - 0.5) * 20;
self.velocityY = (Math.random() - 0.5) * 20 - 10; // Bias upward
self.velocityY -= Math.random() * 10; // Extra upward force
// Physics properties
self.gravity = 0.8;
self.friction = 0.95;
self.bounce = 0.3;
self.life = 120; // Particle life in frames
// Rotation for spinning effect
self.rotationSpeed = (Math.random() - 0.5) * 0.3;
self.update = function () {
// Apply physics
self.velocityY += self.gravity;
self.x += self.velocityX;
self.y += self.velocityY;
self.rotation += self.rotationSpeed;
// Apply friction
self.velocityX *= self.friction;
// Ground collision
var groundY = 2732 - 100;
if (self.y + 20 > groundY) {
self.y = groundY - 20;
self.velocityY *= -self.bounce;
self.velocityX *= self.friction;
}
// Wall collisions
if (self.x < 20) {
self.x = 20;
self.velocityX *= -self.bounce;
}
if (self.x > 2048 - 20) {
self.x = 2048 - 20;
self.velocityX *= -self.bounce;
}
// Fade out over time
self.life--;
if (self.life < 60) {
self.alpha = self.life / 60;
}
// Remove when life is over
if (self.life <= 0) {
self.destroy();
// Remove from particles array
for (var i = particles.length - 1; i >= 0; i--) {
if (particles[i] === self) {
particles.splice(i, 1);
break;
}
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
var fruitTypes = ['strawberry', 'grape', 'plum', 'orange', 'apple', 'peach', 'melon', 'watermelon', 'pumpkin'];
var fruitScores = [10, 25, 50, 100, 200, 400, 800, 1600, 3200];
var fruits = [];
var particles = [];
var dropX = 1024;
var currentFruitType = 'strawberry';
var dangerLineY = 400;
var canDrop = true;
var gameStartTime = Date.now();
var totalDrops = 0;
var highScore = storage.highScore || 0;
// Create walls
var leftWall = game.addChild(LK.getAsset('walls', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
width: 20,
height: 2732
}));
var rightWall = game.addChild(LK.getAsset('walls', {
anchorX: 0,
anchorY: 0,
x: 2048 - 20,
y: 0,
width: 20,
height: 2732
}));
// Create ground
var ground = game.addChild(LK.getAsset('ground', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 2732 - 100,
width: 2048,
height: 20
}));
// Create danger line
var dangerLine = game.addChild(LK.getAsset('dangerLine', {
anchorX: 0,
anchorY: 0,
x: 0,
y: dangerLineY
}));
// Create score text
var scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFD700,
fontWeight: 'bold'
});
scoreTxt.anchor.set(1, 0);
scoreTxt.x = -150; // Move score text 150 pixels left from right edge
LK.gui.topRight.addChild(scoreTxt);
// Create next fruit indicator
var nextFruitTxt = new Text2('Next: Pineapple', {
size: 60,
fill: 0x000000,
fontWeight: 'bold'
});
nextFruitTxt.anchor.set(0, 0);
nextFruitTxt.x = 120;
nextFruitTxt.y = 100;
LK.gui.topLeft.addChild(nextFruitTxt);
// Create high score text
var highScoreTxt = new Text2('Best Score: ' + highScore, {
size: 60,
fill: 0x000000,
fontWeight: 'bold'
});
highScoreTxt.anchor.set(0, 0);
highScoreTxt.x = 120;
highScoreTxt.y = 170;
LK.gui.topLeft.addChild(highScoreTxt);
// Create preview fruit
var previewFruit = game.addChild(LK.getAsset(currentFruitType, {
anchorX: 0.5,
anchorY: 0.5,
x: dropX,
y: 150,
alpha: 0.7
}));
function getRandomFruitType() {
var gameTimeSeconds = (Date.now() - gameStartTime) / 1000;
var currentScore = LK.getScore();
// Progressive difficulty based on time and score
var maxFruitIndex = 0; // Start with only pineapple
var availableFruits = 1;
// Time-based progression (every 30 seconds, unlock next fruit type)
var timeBasedUnlocks = Math.floor(gameTimeSeconds / 30);
availableFruits = Math.min(availableFruits + timeBasedUnlocks, fruitTypes.length);
// Score-based progression (unlock fruits based on score milestones)
var scoreBasedUnlocks = 0;
if (currentScore >= 50) {
scoreBasedUnlocks = 1;
} // grape
if (currentScore >= 150) {
scoreBasedUnlocks = 2;
} // plum
if (currentScore >= 300) {
scoreBasedUnlocks = 3;
} // orange
if (currentScore >= 500) {
scoreBasedUnlocks = 4;
} // apple
if (currentScore >= 800) {
scoreBasedUnlocks = 5;
} // peach
if (currentScore >= 1200) {
scoreBasedUnlocks = 6;
} // melon
if (currentScore >= 2000) {
scoreBasedUnlocks = 7;
} // watermelon
if (currentScore >= 4000) {
scoreBasedUnlocks = 8;
} // pumpkin
availableFruits = Math.max(availableFruits, scoreBasedUnlocks + 1);
maxFruitIndex = Math.min(availableFruits - 1, fruitTypes.length - 1);
// Early game weighting - favor smaller fruits
var weights = [];
for (var i = 0; i <= maxFruitIndex; i++) {
// Weight smaller fruits more heavily early in the game
var baseWeight = maxFruitIndex - i + 1;
// Additional weighting for very early game
if (totalDrops < 20) {
if (i === 0) {
baseWeight *= 4;
} // Heavy favor for pineapple
else if (i === 1) {
baseWeight *= 2;
} // Medium favor for grape
} else if (totalDrops < 50) {
if (i <= 1) {
baseWeight *= 2;
} // Favor first two fruits
}
weights.push(baseWeight);
}
// Weighted random selection
var totalWeight = 0;
for (var i = 0; i < weights.length; i++) {
totalWeight += weights[i];
}
var randomValue = Math.random() * totalWeight;
var currentWeight = 0;
for (var i = 0; i < weights.length; i++) {
currentWeight += weights[i];
if (randomValue <= currentWeight) {
return fruitTypes[i];
}
}
// Fallback
return fruitTypes[0];
}
function updatePreviewFruit() {
game.removeChild(previewFruit);
previewFruit = game.addChild(LK.getAsset(currentFruitType, {
anchorX: 0.5,
anchorY: 0.5,
x: dropX,
y: 150,
alpha: 0.7
}));
var capitalizedType = currentFruitType.charAt(0).toUpperCase() + currentFruitType.slice(1);
nextFruitTxt.setText('Next: ' + capitalizedType);
}
function dropFruit() {
if (!canDrop) {
return;
}
var newFruit = new Fruit(currentFruitType);
newFruit.x = dropX;
newFruit.y = 200;
fruits.push(newFruit);
game.addChild(newFruit);
LK.getSound('drop').play();
totalDrops++;
currentFruitType = getRandomFruitType();
updatePreviewFruit();
canDrop = false;
LK.setTimeout(function () {
canDrop = true;
}, 500);
}
function checkMerges() {
for (var i = 0; i < fruits.length; i++) {
if (fruits[i].merged) {
continue;
}
for (var j = i + 1; j < fruits.length; j++) {
if (fruits[j].merged) {
continue;
}
var fruit1 = fruits[i];
var fruit2 = fruits[j];
if (fruit1.type === fruit2.type) {
var dx = fruit1.x - fruit2.x;
var dy = fruit1.y - fruit2.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var minDistance = fruit1.getRadius() + fruit2.getRadius();
// Merge immediately when fruits touch (with small buffer for instant merging)
if (distance <= minDistance + 5) {
mergeFruits(fruit1, fruit2);
break;
}
}
}
}
}
function mergeFruits(fruit1, fruit2) {
var currentTypeIndex = fruitTypes.indexOf(fruit1.type);
// Prevent pumpkin from merging - it's the final fruit
if (fruit1.type === 'pumpkin') {
return;
}
if (currentTypeIndex < fruitTypes.length - 1) {
var nextType = fruitTypes[currentTypeIndex + 1];
// Create new merged fruit
var mergedFruit = new Fruit(nextType);
mergedFruit.x = (fruit1.x + fruit2.x) / 2;
mergedFruit.y = (fruit1.y + fruit2.y) / 2;
// Create explosive particle effect - fragments of the original fruits
var particleCount = 8 + Math.floor(Math.random() * 6); // 8-14 particles
for (var p = 0; p < particleCount; p++) {
var particle = new FruitParticle((fruit1.x + fruit2.x) / 2 + (Math.random() - 0.5) * 60, (fruit1.y + fruit2.y) / 2 + (Math.random() - 0.5) * 60, fruit1.type);
particles.push(particle);
game.addChild(particle);
}
// Create explosive merge effect
mergedFruit.scaleX = 0.1;
mergedFruit.scaleY = 0.1;
// First explosion - quick scale up
tween(mergedFruit, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
// Second bounce - scale down to normal
tween(mergedFruit, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.bounceOut
});
}
});
// Add stronger screen shake effect for explosion
var originalX = game.x;
var originalY = game.y;
var shakeAmount = 20; // Increased shake
var shakeDuration = 30; // Shorter, more intense shake
// Multiple shake cycles for more impact
for (var shakeCount = 0; shakeCount < 6; shakeCount++) {
(function (count) {
LK.setTimeout(function () {
var currentShake = shakeAmount * (1 - count / 6); // Diminishing shake
tween(game, {
x: originalX + (Math.random() - 0.5) * currentShake * 2,
y: originalY + (Math.random() - 0.5) * currentShake * 2
}, {
duration: shakeDuration,
easing: tween.easeOut
});
}, count * shakeDuration);
})(shakeCount);
}
// Return to original position
LK.setTimeout(function () {
tween(game, {
x: originalX,
y: originalY
}, {
duration: 100,
easing: tween.easeOut
});
}, 200);
// Add rotation effect for extra visual impact
tween(mergedFruit, {
rotation: Math.PI * 2
}, {
duration: 350,
easing: tween.easeOut
});
// Add tint effect that fades from bright to normal
mergedFruit.tint = 0xFFFF00;
tween(mergedFruit, {
tint: 0xFFFFFF
}, {
duration: 500,
easing: tween.easeOut
});
fruits.push(mergedFruit);
game.addChild(mergedFruit);
// Add score
var scoreToAdd = fruitScores[currentTypeIndex + 1];
LK.setScore(LK.getScore() + scoreToAdd);
scoreTxt.setText(LK.getScore());
// Check and update high score
var currentScore = LK.getScore();
if (currentScore > highScore) {
highScore = currentScore;
storage.highScore = highScore;
highScoreTxt.setText('Best Score: ' + highScore);
// Flash high score text when broken
LK.effects.flashObject(highScoreTxt, 0xFFD700, 1000);
}
// Continue playing even after watermelon - no win condition
// Play merge sound
LK.getSound('merge').play();
// Flash effect
LK.effects.flashObject(mergedFruit, 0xFFFF00, 500);
// Push away nearby fruits from explosion
var mergeX = mergedFruit.x;
var mergeY = mergedFruit.y;
var explosionRadius = 200;
for (var k = 0; k < fruits.length; k++) {
if (fruits[k] !== mergedFruit && !fruits[k].merged) {
var dx = fruits[k].x - mergeX;
var dy = fruits[k].y - mergeY;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < explosionRadius && distance > 0) {
var force = (explosionRadius - distance) / explosionRadius * 15;
var normalX = dx / distance;
var normalY = dy / distance;
fruits[k].applyImpulse(normalX * force, normalY * force);
}
}
}
}
// Mark fruits as merged and remove them
fruit1.merged = true;
fruit2.merged = true;
// Remove from fruits array
for (var i = fruits.length - 1; i >= 0; i--) {
if (fruits[i].merged) {
fruits[i].destroy();
fruits.splice(i, 1);
}
}
}
var isDragging = false;
game.move = function (x, y, obj) {
if (canDrop && isDragging) {
dropX = Math.max(40, Math.min(2048 - 40, x));
previewFruit.x = dropX;
}
};
game.down = function (x, y, obj) {
if (canDrop) {
isDragging = true;
dropX = Math.max(40, Math.min(2048 - 40, x));
previewFruit.x = dropX;
}
};
game.up = function (x, y, obj) {
if (canDrop && isDragging) {
isDragging = false;
dropFruit();
}
};
game.update = function () {
for (var i = 0; i < fruits.length; i++) {
fruits[i].update();
}
// Update particles
for (var i = 0; i < particles.length; i++) {
particles[i].update();
}
checkMerges();
};
// Initialize first fruit type
updatePreviewFruit(); ===================================================================
--- original.js
+++ change.js
@@ -296,8 +296,9 @@
fill: 0xFFD700,
fontWeight: 'bold'
});
scoreTxt.anchor.set(1, 0);
+scoreTxt.x = -150; // Move score text 150 pixels left from right edge
LK.gui.topRight.addChild(scoreTxt);
// Create next fruit indicator
var nextFruitTxt = new Text2('Next: Pineapple', {
size: 60,