/****
* Classes
****/
// Class for the big circle (background)
var BigCircle = Container.expand(function () {
var self = Container.call(this);
// Attach the big circle asset (ellipse)
var circle = self.attachAsset('bigCircle', {
anchorX: 0.5,
anchorY: 0.5
});
// For possible future use: self.radius = circle.width / 2;
return self;
});
// Character class: simple box character
var Character = Container.expand(function () {
var self = Container.call(this);
// Attach a red box asset as the character
var charAsset = self.attachAsset('character', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
// We need tween for possible future animations, but not required for MVP.
// var tween = LK.import('@upit/tween.v1');
// Class for the draggable small circle
var SmallCircle = Container.expand(function () {
var self = Container.call(this);
// Attach the small circle asset (ellipse)
var circle = self.attachAsset('smallCircle', {
anchorX: 0.5,
anchorY: 0.5
});
// For possible future use: self.radius = circle.width / 2;
// No per-object event handlers; all drag logic is handled in the main game.
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xae890f // Açık renkli arka plan
});
/****
* Game Code
****/
// --- Start the timer when the game starts ---
// (Timer removed)
// --- Score Text in Top-Center ---
// Create score text and add to gui.top (top-center of the screen)
var scoreTxt = new Text2(LK.getScore().toString(), {
size: 100,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0); // Center horizontally, top edge
scoreTxt.x = 0; // x=0 for gui.top, which is already centered
scoreTxt.y = 20; // Some padding from top
LK.gui.top.addChild(scoreTxt);
// Update score text when score changes (patch game.update)
var _oldUpdate = game.update;
game.update = function () {
if (_oldUpdate) {
_oldUpdate.apply(this, arguments);
}
if (scoreTxt) {
scoreTxt.setText(LK.getScore().toString());
}
// If player wins or loses, stop timer
if ((LK.getScore() >= 100 || can === 0) && typeof timerInterval !== "undefined" && !timerBitti) {
timerBitti = true;
LK.clearInterval(timerInterval);
}
};
// --- Reset logic: when the game is reset, everything is re-initialized by LK ---;
// --- Game Variables ---
var bigCircle, smallCircle;
var dragNode = null;
var lastInside = true;
// --- Create and Position Circles ---
// Place both circles in the bottom-left corner, scaled down
// New radii for smaller circles
var bigCircleScale = 0.35;
var smallCircleScale = 0.35;
// Create big circle and add to game
bigCircle = new BigCircle();
game.addChild(bigCircle);
// Scale down big circle
bigCircle.scaleX = bigCircleScale;
bigCircle.scaleY = bigCircleScale;
// Lower opacity for big circle
bigCircle.alpha = 0.4;
// Calculate position so the big circle is fully visible in the bottom-left
var bigR = 0;
if (bigCircle.children && bigCircle.children[0] && typeof bigCircle.children[0].width === "number") {
bigR = bigCircle.children[0].width / 2 * bigCircleScale;
} else {
// fallback: use asset size directly if children[0] is not available
var tempAsset = LK.getAsset('bigCircle', {
anchorX: 0.5,
anchorY: 0.5
});
bigR = tempAsset.width / 2 * bigCircleScale;
tempAsset.destroy && tempAsset.destroy();
}
bigCircle.x = bigR + 40; // 40px margin from left
bigCircle.y = 2732 - bigR - 40; // 40px margin from bottom
// Overlay a smaller circle of background color to create a ring effect
var ringInnerScale = 0.80; // Adjust for ring thickness (0.80 = 80% of big circle)
var ringInner = LK.getAsset('bigCircle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: ringInnerScale,
scaleY: ringInnerScale,
x: 0,
y: 0,
color: 0x222222 // match background color
});
bigCircle.addChild(ringInner);
// Create small circle and add to game
smallCircle = new SmallCircle();
game.addChild(smallCircle);
// Scale down small circle
smallCircle.scaleX = smallCircleScale;
smallCircle.scaleY = smallCircleScale;
// Place small circle at center of big circle
var smallR = 0;
if (smallCircle.children && smallCircle.children[0] && typeof smallCircle.children[0].width === "number") {
smallR = smallCircle.children[0].width / 2 * smallCircleScale;
} else {
var tempAsset = LK.getAsset('smallCircle', {
anchorX: 0.5,
anchorY: 0.5
});
smallR = tempAsset.width / 2 * smallCircleScale;
tempAsset.destroy && tempAsset.destroy();
}
smallCircle.x = bigCircle.x;
smallCircle.y = bigCircle.y;
// --- Add multiple kurabiye (cookies) and bombs outside the big circle ---
var kurabiyeler = [];
var bombalar = [];
var numKurabiye = 8; // You can increase for more cookies
var numBomba = 5; // Number of bombs to spawn (always 5 bombs)
var can = 3; // Player starts with 3 can (lives)
// Can (life) text in top-center, below score
var canTxt = new Text2("❤❤❤", {
size: 80,
fill: 0xff4444
});
canTxt.anchor.set(0.5, 0);
canTxt.x = 0;
canTxt.y = 120; // Below score
LK.gui.top.addChild(canTxt);
// Timer text below can
var sureTxt = new Text2("60", {
size: 70,
fill: 0xFFFFFF
});
sureTxt.anchor.set(0.5, 0);
sureTxt.x = 0;
sureTxt.y = 200; // Below can
LK.gui.top.addChild(sureTxt);
// Helper to update can text
function updateCanText() {
var hearts = "";
for (var i = 0; i < can; i++) hearts += "❤";
canTxt.setText(hearts);
}
// Timer logic
var sureKalan = 60; // seconds
var timerBitti = false;
var timerInterval = LK.setInterval(function () {
if (timerBitti) return;
sureKalan--;
if (sureKalan < 0) sureKalan = 0;
if (sureTxt) sureTxt.setText(sureKalan.toString());
// If time runs out and score < 100, lose
if (sureKalan === 0 && LK.getScore() < 100) {
timerBitti = true;
LK.showGameOver();
}
}, 1000);
// Helper function to place an item (kurabiye or bomba) outside the big circle ring
function placeItemOutsideRing(assetId) {
var item = LK.getAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
game.addChild(item);
var itemR = item.width / 2;
var placed = false;
var maxTries = 100;
var tries = 0;
while (!placed && tries < maxTries) {
// Random position anywhere in game area, but not inside or touching the big circle ring
var x = itemR + 10 + Math.random() * (2048 - 2 * (itemR + 10));
var y = itemR + 10 + Math.random() * (2732 - 2 * (itemR + 10));
// Distance from big circle center
var dx = x - bigCircle.x;
var dy = y - bigCircle.y;
var dist = Math.sqrt(dx * dx + dy * dy);
var bigOuterR = bigCircle.children[0].width / 2 * bigCircle.scaleX;
var ringInnerScale = 0.80;
var bigInnerR = bigOuterR * ringInnerScale;
// Place only if item is NOT overlapping the ring (not inside or touching the ring)
// So: dist + itemR < bigInnerR OR dist - itemR > bigOuterR
if (dist + itemR < bigInnerR || dist - itemR > bigOuterR) {
item.x = x;
item.y = y;
placed = true;
}
tries++;
}
// If not placed after maxTries, just put it in a random valid spot at the edge
if (!placed) {
// Place at a random angle just outside the big circle
var angle = Math.random() * 2 * Math.PI;
var distance = bigCircle.children[0].width / 2 * bigCircle.scaleX + itemR + 20;
item.x = bigCircle.x + Math.cos(angle) * distance;
item.y = bigCircle.y + Math.sin(angle) * distance;
// Clamp to stay inside game area
if (item.x < itemR) {
item.x = itemR + 10;
}
if (item.x > 2048 - itemR) {
item.x = 2048 - itemR - 10;
}
if (item.y < itemR) {
item.y = itemR + 10;
}
if (item.y > 2732 - itemR) {
item.y = 2732 - itemR - 10;
}
}
return item;
}
// Spawn kurabiyeler
for (var i = 0; i < numKurabiye; i++) {
var kurabiye = placeItemOutsideRing('kurabiye');
kurabiyeler.push(kurabiye);
}
// Spawn bombalar
for (var i = 0; i < numBomba; i++) {
var bomba = placeItemOutsideRing('bomba');
bombalar.push(bomba);
}
updateCanText();
// --- Create and position character in the center of the screen ---
var character = new Character();
game.addChild(character);
// Center character on screen (2048x2732), anchor is 0.5 so this is true center
character.x = 2048 / 2;
character.y = 2732 / 2;
// --- Helper: Check if small circle is fully inside big circle ---
function isSmallCircleInsideBigCircle() {
// Both circles are centered at their x/y
var dx = smallCircle.x - bigCircle.x;
var dy = smallCircle.y - bigCircle.y;
var dist = Math.sqrt(dx * dx + dy * dy);
// Use scaled radii
var bigR = 0;
if (bigCircle.children && bigCircle.children[0] && typeof bigCircle.children[0].width === "number") {
bigR = bigCircle.children[0].width / 2 * bigCircle.scaleX;
} else {
var tempAsset = LK.getAsset('bigCircle', {
anchorX: 0.5,
anchorY: 0.5
});
bigR = tempAsset.width / 2 * bigCircle.scaleX;
tempAsset.destroy && tempAsset.destroy();
}
var smallR = 0;
if (smallCircle.children && smallCircle.children[0] && typeof smallCircle.children[0].width === "number") {
smallR = smallCircle.children[0].width / 2 * smallCircle.scaleX;
} else {
var tempAsset2 = LK.getAsset('smallCircle', {
anchorX: 0.5,
anchorY: 0.5
});
smallR = tempAsset2.width / 2 * smallCircle.scaleX;
tempAsset2.destroy && tempAsset2.destroy();
}
// The small circle is fully inside if its center is at most (bigR - smallR) from the center
return dist <= bigR - smallR;
}
// --- Timer Logic ---
// (Timer logic removed)
// --- Drag Logic ---
// Convert move to keep smallCircle inside bigCircle
function clampSmallCirclePosition(x, y) {
var bigR = 0;
if (bigCircle.children && bigCircle.children[0] && typeof bigCircle.children[0].width === "number") {
bigR = bigCircle.children[0].width / 2 * bigCircle.scaleX;
} else {
var tempAsset = LK.getAsset('bigCircle', {
anchorX: 0.5,
anchorY: 0.5
});
bigR = tempAsset.width / 2 * bigCircle.scaleX;
tempAsset.destroy && tempAsset.destroy();
}
var smallR = 0;
if (smallCircle.children && smallCircle.children[0] && typeof smallCircle.children[0].width === "number") {
smallR = smallCircle.children[0].width / 2 * smallCircle.scaleX;
} else {
var tempAsset2 = LK.getAsset('smallCircle', {
anchorX: 0.5,
anchorY: 0.5
});
smallR = tempAsset2.width / 2 * smallCircle.scaleX;
tempAsset2.destroy && tempAsset2.destroy();
}
var dx = x - bigCircle.x;
var dy = y - bigCircle.y;
var dist = Math.sqrt(dx * dx + dy * dy);
var maxDist = bigR - smallR;
if (dist > maxDist) {
// Clamp to the edge
var angle = Math.atan2(dy, dx);
x = bigCircle.x + Math.cos(angle) * maxDist;
y = bigCircle.y + Math.sin(angle) * maxDist;
}
return {
x: x,
y: y
};
}
// --- Game Event Handlers ---
// Only allow dragging the small circle
game.down = function (x, y, obj) {
// Check if the down is on the small circle
// Convert global to local for smallCircle
var local = smallCircle.toLocal(game.toGlobal({
x: x,
y: y
}));
var smallR = 0;
if (smallCircle.children && smallCircle.children[0] && typeof smallCircle.children[0].width === "number") {
smallR = smallCircle.children[0].width / 2;
} else {
var tempAsset = LK.getAsset('smallCircle', {
anchorX: 0.5,
anchorY: 0.5
});
smallR = tempAsset.width / 2;
tempAsset.destroy && tempAsset.destroy();
}
// Check if within the circle
if ((local.x - 0) * (local.x - 0) + (local.y - 0) * (local.y - 0) <= smallR * smallR) {
dragNode = smallCircle;
}
};
game.up = function (x, y, obj) {
dragNode = null;
// When releasing, snap smallCircle to center of bigCircle
smallCircle.x = bigCircle.x;
smallCircle.y = bigCircle.y;
};
function handleMove(x, y, obj) {
if (dragNode === smallCircle) {
// Clamp position so the small circle never leaves the big circle
var clamped = clampSmallCirclePosition(x, y);
smallCircle.x = clamped.x;
smallCircle.y = clamped.y;
}
// Check if small circle is still inside big circle
// (No game over or timer logic needed)
lastInside = isSmallCircleInsideBigCircle();
}
game.move = handleMove;
// --- Game Update Loop ---
game.update = function () {
// Calculate direction from bigCircle center to smallCircle center
var dx = smallCircle.x - bigCircle.x;
var dy = smallCircle.y - bigCircle.y;
var dist = Math.sqrt(dx * dx + dy * dy);
// Only move if the small circle is not exactly at the center AND is being dragged
if (dist > 1 && dragNode === smallCircle) {
// Normalize direction
var dirX = dx / dist;
var dirY = dy / dist;
// Move character a fixed speed per frame (e.g. 8px per frame)
var speed = 8;
character.x += dirX * speed;
character.y += dirY * speed;
}
// Clamp character position so it cannot leave the game area
var charW = 0,
charH = 0;
if (character.children && character.children[0] && typeof character.children[0].width === "number") {
charW = character.children[0].width * 0.5;
charH = character.children[0].height * 0.5;
} else {
var tempAsset = LK.getAsset('character', {
anchorX: 0.5,
anchorY: 0.5
});
charW = tempAsset.width * 0.5;
charH = tempAsset.height * 0.5;
tempAsset.destroy && tempAsset.destroy();
}
if (character.x < charW) {
character.x = charW;
}
if (character.x > 2048 - charW) {
character.x = 2048 - charW;
}
if (character.y < charH) {
character.y = charH;
}
if (character.y > 2732 - charH) {
character.y = 2732 - charH;
}
// --- Kurabiye collision and score logic ---
for (var i = kurabiyeler.length - 1; i >= 0; i--) {
var k = kurabiyeler[i];
if (k && character.intersects(k)) {
LK.getSound('eat').play();
k.destroy();
kurabiyeler.splice(i, 1);
// Her bir kurabiyeye temas edince 5 puan artır
LK.setScore(LK.getScore() + 5);
if (scoreTxt) {
scoreTxt.setText(LK.getScore().toString());
}
// Win if score is 100 or more
if (LK.getScore() >= 100) {
if (typeof timerInterval !== "undefined" && !timerBitti) {
timerBitti = true;
LK.clearInterval(timerInterval);
}
LK.showYouWin();
return;
}
// --- Spawn a new kurabiye outside the big circle ring ---
var kurabiye = LK.getAsset('kurabiye', {
anchorX: 0.5,
anchorY: 0.5
});
game.addChild(kurabiye);
var kurabiyeR = kurabiye.width / 2;
var placed = false;
var maxTries = 100;
var tries = 0;
while (!placed && tries < maxTries) {
// Random position anywhere in game area, but not inside or touching the big circle ring
var x = kurabiyeR + 10 + Math.random() * (2048 - 2 * (kurabiyeR + 10));
var y = kurabiyeR + 10 + Math.random() * (2732 - 2 * (kurabiyeR + 10));
// Distance from big circle center
var dx = x - bigCircle.x;
var dy = y - bigCircle.y;
var dist = Math.sqrt(dx * dx + dy * dy);
var bigOuterR = bigCircle.children[0].width / 2 * bigCircle.scaleX;
var ringInnerScale = 0.80;
var bigInnerR = bigOuterR * ringInnerScale;
// Place only if kurabiye is NOT overlapping the ring (not inside or touching the ring)
// So: dist + kurabiyeR < bigInnerR OR dist - kurabiyeR > bigOuterR
if (dist + kurabiyeR < bigInnerR || dist - kurabiyeR > bigOuterR) {
kurabiye.x = x;
kurabiye.y = y;
placed = true;
}
tries++;
}
// If not placed after maxTries, just put it in a random valid spot at the edge
if (!placed) {
// Place at a random angle just outside the big circle
var angle = Math.random() * 2 * Math.PI;
var distance = bigOuterR + kurabiyeR + 20;
kurabiye.x = bigCircle.x + Math.cos(angle) * distance;
kurabiye.y = bigCircle.y + Math.sin(angle) * distance;
// Clamp to stay inside game area
if (kurabiye.x < kurabiyeR) {
kurabiye.x = kurabiyeR + 10;
}
if (kurabiye.x > 2048 - kurabiyeR) {
kurabiye.x = 2048 - kurabiyeR - 10;
}
if (kurabiye.y < kurabiyeR) {
kurabiye.y = kurabiyeR + 10;
}
if (kurabiye.y > 2732 - kurabiyeR) {
kurabiye.y = 2732 - kurabiyeR - 10;
}
}
kurabiyeler.push(kurabiye);
}
}
;
// --- Bomb collision and can logic ---
for (var i = bombalar.length - 1; i >= 0; i--) {
var b = bombalar[i];
if (b && character.intersects(b)) {
LK.getSound('bomb').play();
b.destroy();
bombalar.splice(i, 1);
can--;
if (can < 0) can = 0;
if (typeof updateCanText === "function") updateCanText();
// Game over if can is 0
if (can === 0) {
if (typeof timerInterval !== "undefined" && !timerBitti) {
timerBitti = true;
LK.clearInterval(timerInterval);
}
LK.showGameOver();
return;
}
// Always keep 5 bombs on screen
while (bombalar.length < numBomba) {
var newBomba = placeItemOutsideRing('bomba');
bombalar.push(newBomba);
}
}
}
};
// --- Start the timer when the game starts ---
// (Timer removed)
// --- Reset logic: when the game is reset, everything is re-initialized by LK --- /****
* Classes
****/
// Class for the big circle (background)
var BigCircle = Container.expand(function () {
var self = Container.call(this);
// Attach the big circle asset (ellipse)
var circle = self.attachAsset('bigCircle', {
anchorX: 0.5,
anchorY: 0.5
});
// For possible future use: self.radius = circle.width / 2;
return self;
});
// Character class: simple box character
var Character = Container.expand(function () {
var self = Container.call(this);
// Attach a red box asset as the character
var charAsset = self.attachAsset('character', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
// We need tween for possible future animations, but not required for MVP.
// var tween = LK.import('@upit/tween.v1');
// Class for the draggable small circle
var SmallCircle = Container.expand(function () {
var self = Container.call(this);
// Attach the small circle asset (ellipse)
var circle = self.attachAsset('smallCircle', {
anchorX: 0.5,
anchorY: 0.5
});
// For possible future use: self.radius = circle.width / 2;
// No per-object event handlers; all drag logic is handled in the main game.
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xae890f // Açık renkli arka plan
});
/****
* Game Code
****/
// --- Start the timer when the game starts ---
// (Timer removed)
// --- Score Text in Top-Center ---
// Create score text and add to gui.top (top-center of the screen)
var scoreTxt = new Text2(LK.getScore().toString(), {
size: 100,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0); // Center horizontally, top edge
scoreTxt.x = 0; // x=0 for gui.top, which is already centered
scoreTxt.y = 20; // Some padding from top
LK.gui.top.addChild(scoreTxt);
// Update score text when score changes (patch game.update)
var _oldUpdate = game.update;
game.update = function () {
if (_oldUpdate) {
_oldUpdate.apply(this, arguments);
}
if (scoreTxt) {
scoreTxt.setText(LK.getScore().toString());
}
// If player wins or loses, stop timer
if ((LK.getScore() >= 100 || can === 0) && typeof timerInterval !== "undefined" && !timerBitti) {
timerBitti = true;
LK.clearInterval(timerInterval);
}
};
// --- Reset logic: when the game is reset, everything is re-initialized by LK ---;
// --- Game Variables ---
var bigCircle, smallCircle;
var dragNode = null;
var lastInside = true;
// --- Create and Position Circles ---
// Place both circles in the bottom-left corner, scaled down
// New radii for smaller circles
var bigCircleScale = 0.35;
var smallCircleScale = 0.35;
// Create big circle and add to game
bigCircle = new BigCircle();
game.addChild(bigCircle);
// Scale down big circle
bigCircle.scaleX = bigCircleScale;
bigCircle.scaleY = bigCircleScale;
// Lower opacity for big circle
bigCircle.alpha = 0.4;
// Calculate position so the big circle is fully visible in the bottom-left
var bigR = 0;
if (bigCircle.children && bigCircle.children[0] && typeof bigCircle.children[0].width === "number") {
bigR = bigCircle.children[0].width / 2 * bigCircleScale;
} else {
// fallback: use asset size directly if children[0] is not available
var tempAsset = LK.getAsset('bigCircle', {
anchorX: 0.5,
anchorY: 0.5
});
bigR = tempAsset.width / 2 * bigCircleScale;
tempAsset.destroy && tempAsset.destroy();
}
bigCircle.x = bigR + 40; // 40px margin from left
bigCircle.y = 2732 - bigR - 40; // 40px margin from bottom
// Overlay a smaller circle of background color to create a ring effect
var ringInnerScale = 0.80; // Adjust for ring thickness (0.80 = 80% of big circle)
var ringInner = LK.getAsset('bigCircle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: ringInnerScale,
scaleY: ringInnerScale,
x: 0,
y: 0,
color: 0x222222 // match background color
});
bigCircle.addChild(ringInner);
// Create small circle and add to game
smallCircle = new SmallCircle();
game.addChild(smallCircle);
// Scale down small circle
smallCircle.scaleX = smallCircleScale;
smallCircle.scaleY = smallCircleScale;
// Place small circle at center of big circle
var smallR = 0;
if (smallCircle.children && smallCircle.children[0] && typeof smallCircle.children[0].width === "number") {
smallR = smallCircle.children[0].width / 2 * smallCircleScale;
} else {
var tempAsset = LK.getAsset('smallCircle', {
anchorX: 0.5,
anchorY: 0.5
});
smallR = tempAsset.width / 2 * smallCircleScale;
tempAsset.destroy && tempAsset.destroy();
}
smallCircle.x = bigCircle.x;
smallCircle.y = bigCircle.y;
// --- Add multiple kurabiye (cookies) and bombs outside the big circle ---
var kurabiyeler = [];
var bombalar = [];
var numKurabiye = 8; // You can increase for more cookies
var numBomba = 5; // Number of bombs to spawn (always 5 bombs)
var can = 3; // Player starts with 3 can (lives)
// Can (life) text in top-center, below score
var canTxt = new Text2("❤❤❤", {
size: 80,
fill: 0xff4444
});
canTxt.anchor.set(0.5, 0);
canTxt.x = 0;
canTxt.y = 120; // Below score
LK.gui.top.addChild(canTxt);
// Timer text below can
var sureTxt = new Text2("60", {
size: 70,
fill: 0xFFFFFF
});
sureTxt.anchor.set(0.5, 0);
sureTxt.x = 0;
sureTxt.y = 200; // Below can
LK.gui.top.addChild(sureTxt);
// Helper to update can text
function updateCanText() {
var hearts = "";
for (var i = 0; i < can; i++) hearts += "❤";
canTxt.setText(hearts);
}
// Timer logic
var sureKalan = 60; // seconds
var timerBitti = false;
var timerInterval = LK.setInterval(function () {
if (timerBitti) return;
sureKalan--;
if (sureKalan < 0) sureKalan = 0;
if (sureTxt) sureTxt.setText(sureKalan.toString());
// If time runs out and score < 100, lose
if (sureKalan === 0 && LK.getScore() < 100) {
timerBitti = true;
LK.showGameOver();
}
}, 1000);
// Helper function to place an item (kurabiye or bomba) outside the big circle ring
function placeItemOutsideRing(assetId) {
var item = LK.getAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
game.addChild(item);
var itemR = item.width / 2;
var placed = false;
var maxTries = 100;
var tries = 0;
while (!placed && tries < maxTries) {
// Random position anywhere in game area, but not inside or touching the big circle ring
var x = itemR + 10 + Math.random() * (2048 - 2 * (itemR + 10));
var y = itemR + 10 + Math.random() * (2732 - 2 * (itemR + 10));
// Distance from big circle center
var dx = x - bigCircle.x;
var dy = y - bigCircle.y;
var dist = Math.sqrt(dx * dx + dy * dy);
var bigOuterR = bigCircle.children[0].width / 2 * bigCircle.scaleX;
var ringInnerScale = 0.80;
var bigInnerR = bigOuterR * ringInnerScale;
// Place only if item is NOT overlapping the ring (not inside or touching the ring)
// So: dist + itemR < bigInnerR OR dist - itemR > bigOuterR
if (dist + itemR < bigInnerR || dist - itemR > bigOuterR) {
item.x = x;
item.y = y;
placed = true;
}
tries++;
}
// If not placed after maxTries, just put it in a random valid spot at the edge
if (!placed) {
// Place at a random angle just outside the big circle
var angle = Math.random() * 2 * Math.PI;
var distance = bigCircle.children[0].width / 2 * bigCircle.scaleX + itemR + 20;
item.x = bigCircle.x + Math.cos(angle) * distance;
item.y = bigCircle.y + Math.sin(angle) * distance;
// Clamp to stay inside game area
if (item.x < itemR) {
item.x = itemR + 10;
}
if (item.x > 2048 - itemR) {
item.x = 2048 - itemR - 10;
}
if (item.y < itemR) {
item.y = itemR + 10;
}
if (item.y > 2732 - itemR) {
item.y = 2732 - itemR - 10;
}
}
return item;
}
// Spawn kurabiyeler
for (var i = 0; i < numKurabiye; i++) {
var kurabiye = placeItemOutsideRing('kurabiye');
kurabiyeler.push(kurabiye);
}
// Spawn bombalar
for (var i = 0; i < numBomba; i++) {
var bomba = placeItemOutsideRing('bomba');
bombalar.push(bomba);
}
updateCanText();
// --- Create and position character in the center of the screen ---
var character = new Character();
game.addChild(character);
// Center character on screen (2048x2732), anchor is 0.5 so this is true center
character.x = 2048 / 2;
character.y = 2732 / 2;
// --- Helper: Check if small circle is fully inside big circle ---
function isSmallCircleInsideBigCircle() {
// Both circles are centered at their x/y
var dx = smallCircle.x - bigCircle.x;
var dy = smallCircle.y - bigCircle.y;
var dist = Math.sqrt(dx * dx + dy * dy);
// Use scaled radii
var bigR = 0;
if (bigCircle.children && bigCircle.children[0] && typeof bigCircle.children[0].width === "number") {
bigR = bigCircle.children[0].width / 2 * bigCircle.scaleX;
} else {
var tempAsset = LK.getAsset('bigCircle', {
anchorX: 0.5,
anchorY: 0.5
});
bigR = tempAsset.width / 2 * bigCircle.scaleX;
tempAsset.destroy && tempAsset.destroy();
}
var smallR = 0;
if (smallCircle.children && smallCircle.children[0] && typeof smallCircle.children[0].width === "number") {
smallR = smallCircle.children[0].width / 2 * smallCircle.scaleX;
} else {
var tempAsset2 = LK.getAsset('smallCircle', {
anchorX: 0.5,
anchorY: 0.5
});
smallR = tempAsset2.width / 2 * smallCircle.scaleX;
tempAsset2.destroy && tempAsset2.destroy();
}
// The small circle is fully inside if its center is at most (bigR - smallR) from the center
return dist <= bigR - smallR;
}
// --- Timer Logic ---
// (Timer logic removed)
// --- Drag Logic ---
// Convert move to keep smallCircle inside bigCircle
function clampSmallCirclePosition(x, y) {
var bigR = 0;
if (bigCircle.children && bigCircle.children[0] && typeof bigCircle.children[0].width === "number") {
bigR = bigCircle.children[0].width / 2 * bigCircle.scaleX;
} else {
var tempAsset = LK.getAsset('bigCircle', {
anchorX: 0.5,
anchorY: 0.5
});
bigR = tempAsset.width / 2 * bigCircle.scaleX;
tempAsset.destroy && tempAsset.destroy();
}
var smallR = 0;
if (smallCircle.children && smallCircle.children[0] && typeof smallCircle.children[0].width === "number") {
smallR = smallCircle.children[0].width / 2 * smallCircle.scaleX;
} else {
var tempAsset2 = LK.getAsset('smallCircle', {
anchorX: 0.5,
anchorY: 0.5
});
smallR = tempAsset2.width / 2 * smallCircle.scaleX;
tempAsset2.destroy && tempAsset2.destroy();
}
var dx = x - bigCircle.x;
var dy = y - bigCircle.y;
var dist = Math.sqrt(dx * dx + dy * dy);
var maxDist = bigR - smallR;
if (dist > maxDist) {
// Clamp to the edge
var angle = Math.atan2(dy, dx);
x = bigCircle.x + Math.cos(angle) * maxDist;
y = bigCircle.y + Math.sin(angle) * maxDist;
}
return {
x: x,
y: y
};
}
// --- Game Event Handlers ---
// Only allow dragging the small circle
game.down = function (x, y, obj) {
// Check if the down is on the small circle
// Convert global to local for smallCircle
var local = smallCircle.toLocal(game.toGlobal({
x: x,
y: y
}));
var smallR = 0;
if (smallCircle.children && smallCircle.children[0] && typeof smallCircle.children[0].width === "number") {
smallR = smallCircle.children[0].width / 2;
} else {
var tempAsset = LK.getAsset('smallCircle', {
anchorX: 0.5,
anchorY: 0.5
});
smallR = tempAsset.width / 2;
tempAsset.destroy && tempAsset.destroy();
}
// Check if within the circle
if ((local.x - 0) * (local.x - 0) + (local.y - 0) * (local.y - 0) <= smallR * smallR) {
dragNode = smallCircle;
}
};
game.up = function (x, y, obj) {
dragNode = null;
// When releasing, snap smallCircle to center of bigCircle
smallCircle.x = bigCircle.x;
smallCircle.y = bigCircle.y;
};
function handleMove(x, y, obj) {
if (dragNode === smallCircle) {
// Clamp position so the small circle never leaves the big circle
var clamped = clampSmallCirclePosition(x, y);
smallCircle.x = clamped.x;
smallCircle.y = clamped.y;
}
// Check if small circle is still inside big circle
// (No game over or timer logic needed)
lastInside = isSmallCircleInsideBigCircle();
}
game.move = handleMove;
// --- Game Update Loop ---
game.update = function () {
// Calculate direction from bigCircle center to smallCircle center
var dx = smallCircle.x - bigCircle.x;
var dy = smallCircle.y - bigCircle.y;
var dist = Math.sqrt(dx * dx + dy * dy);
// Only move if the small circle is not exactly at the center AND is being dragged
if (dist > 1 && dragNode === smallCircle) {
// Normalize direction
var dirX = dx / dist;
var dirY = dy / dist;
// Move character a fixed speed per frame (e.g. 8px per frame)
var speed = 8;
character.x += dirX * speed;
character.y += dirY * speed;
}
// Clamp character position so it cannot leave the game area
var charW = 0,
charH = 0;
if (character.children && character.children[0] && typeof character.children[0].width === "number") {
charW = character.children[0].width * 0.5;
charH = character.children[0].height * 0.5;
} else {
var tempAsset = LK.getAsset('character', {
anchorX: 0.5,
anchorY: 0.5
});
charW = tempAsset.width * 0.5;
charH = tempAsset.height * 0.5;
tempAsset.destroy && tempAsset.destroy();
}
if (character.x < charW) {
character.x = charW;
}
if (character.x > 2048 - charW) {
character.x = 2048 - charW;
}
if (character.y < charH) {
character.y = charH;
}
if (character.y > 2732 - charH) {
character.y = 2732 - charH;
}
// --- Kurabiye collision and score logic ---
for (var i = kurabiyeler.length - 1; i >= 0; i--) {
var k = kurabiyeler[i];
if (k && character.intersects(k)) {
LK.getSound('eat').play();
k.destroy();
kurabiyeler.splice(i, 1);
// Her bir kurabiyeye temas edince 5 puan artır
LK.setScore(LK.getScore() + 5);
if (scoreTxt) {
scoreTxt.setText(LK.getScore().toString());
}
// Win if score is 100 or more
if (LK.getScore() >= 100) {
if (typeof timerInterval !== "undefined" && !timerBitti) {
timerBitti = true;
LK.clearInterval(timerInterval);
}
LK.showYouWin();
return;
}
// --- Spawn a new kurabiye outside the big circle ring ---
var kurabiye = LK.getAsset('kurabiye', {
anchorX: 0.5,
anchorY: 0.5
});
game.addChild(kurabiye);
var kurabiyeR = kurabiye.width / 2;
var placed = false;
var maxTries = 100;
var tries = 0;
while (!placed && tries < maxTries) {
// Random position anywhere in game area, but not inside or touching the big circle ring
var x = kurabiyeR + 10 + Math.random() * (2048 - 2 * (kurabiyeR + 10));
var y = kurabiyeR + 10 + Math.random() * (2732 - 2 * (kurabiyeR + 10));
// Distance from big circle center
var dx = x - bigCircle.x;
var dy = y - bigCircle.y;
var dist = Math.sqrt(dx * dx + dy * dy);
var bigOuterR = bigCircle.children[0].width / 2 * bigCircle.scaleX;
var ringInnerScale = 0.80;
var bigInnerR = bigOuterR * ringInnerScale;
// Place only if kurabiye is NOT overlapping the ring (not inside or touching the ring)
// So: dist + kurabiyeR < bigInnerR OR dist - kurabiyeR > bigOuterR
if (dist + kurabiyeR < bigInnerR || dist - kurabiyeR > bigOuterR) {
kurabiye.x = x;
kurabiye.y = y;
placed = true;
}
tries++;
}
// If not placed after maxTries, just put it in a random valid spot at the edge
if (!placed) {
// Place at a random angle just outside the big circle
var angle = Math.random() * 2 * Math.PI;
var distance = bigOuterR + kurabiyeR + 20;
kurabiye.x = bigCircle.x + Math.cos(angle) * distance;
kurabiye.y = bigCircle.y + Math.sin(angle) * distance;
// Clamp to stay inside game area
if (kurabiye.x < kurabiyeR) {
kurabiye.x = kurabiyeR + 10;
}
if (kurabiye.x > 2048 - kurabiyeR) {
kurabiye.x = 2048 - kurabiyeR - 10;
}
if (kurabiye.y < kurabiyeR) {
kurabiye.y = kurabiyeR + 10;
}
if (kurabiye.y > 2732 - kurabiyeR) {
kurabiye.y = 2732 - kurabiyeR - 10;
}
}
kurabiyeler.push(kurabiye);
}
}
;
// --- Bomb collision and can logic ---
for (var i = bombalar.length - 1; i >= 0; i--) {
var b = bombalar[i];
if (b && character.intersects(b)) {
LK.getSound('bomb').play();
b.destroy();
bombalar.splice(i, 1);
can--;
if (can < 0) can = 0;
if (typeof updateCanText === "function") updateCanText();
// Game over if can is 0
if (can === 0) {
if (typeof timerInterval !== "undefined" && !timerBitti) {
timerBitti = true;
LK.clearInterval(timerInterval);
}
LK.showGameOver();
return;
}
// Always keep 5 bombs on screen
while (bombalar.length < numBomba) {
var newBomba = placeItemOutsideRing('bomba');
bombalar.push(newBomba);
}
}
}
};
// --- Start the timer when the game starts ---
// (Timer removed)
// --- Reset logic: when the game is reset, everything is re-initialized by LK ---