User prompt
bşala diyince seviyr 10 çıkıyor 1 çıkması gerekiyor
User prompt
oyuna menüde yap
User prompt
Please fix the bug: 'TypeError: Cannot use 'in' operator to search for 'scaleX' in null' in or related to this line: 'tween(piece, {' Line Number: 523
User prompt
Please fix the bug: 'TypeError: Cannot set properties of null (setting 'isPlaced')' in or related to this line: 'piece.isPlaced = true;' Line Number: 517
User prompt
Please fix the bug: 'TypeError: Cannot use 'in' operator to search for 'scaleX' in null' in or related to this line: 'tween(draggingPiece, {' Line Number: 613
User prompt
Please fix the bug: 'LK.hasAsset is not a function' in or related to this line: 'if (!LK.hasAsset(id)) {}' Line Number: 393
Code edit (1 edits merged)
Please save this source code
User prompt
Zenge: Sakin Bulmaca Yolculuğu
Initial prompt
Zenge Hikayeli, çok basit bulmaca oyunu. Sadece sürükle-bırak. Grafikler sakin. ⏱️ ~30-40 dakika ama leveli olsun 10 level olsun
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
level: 1
});
/****
* Classes
****/
// PuzzlePiece: Draggable puzzle piece
var PuzzlePiece = Container.expand(function () {
var self = Container.call(this);
// Properties to be set after creation:
// self.pieceId: index of this piece in the level
// self.targetX, self.targetY: where this piece should be placed
// self.isPlaced: whether the piece is already placed
self.isPlaced = false;
// Attach the shape asset (box or ellipse, color, size)
// These are set after creation via self.setShape
self.shape = null;
self.setShape = function (shapeId, options) {
if (self.shape) {
self.shape.destroy();
}
self.shape = self.attachAsset(shapeId, {
anchorX: 0.5,
anchorY: 0.5
});
if (options && options.alpha !== undefined) {
self.shape.alpha = options.alpha;
}
};
// Animate piece to its target position
self.animateToTarget = function (onFinish) {
tween(self, {
x: self.targetX,
y: self.targetY
}, {
duration: 400,
easing: tween.cubicOut,
onFinish: onFinish
});
};
// Animate piece back to its original position
self.animateToOrigin = function (onFinish) {
tween(self, {
x: self.originX,
y: self.originY
}, {
duration: 350,
easing: tween.easeOut,
onFinish: onFinish
});
};
return self;
});
// TargetSlot: Where a piece should be placed
var TargetSlot = Container.expand(function () {
var self = Container.call(this);
// Attach the shape asset (box or ellipse, color, size)
self.shape = null;
self.setShape = function (shapeId, options) {
if (self.shape) {
self.shape.destroy();
}
self.shape = self.attachAsset(shapeId, {
anchorX: 0.5,
anchorY: 0.5
});
if (options && options.alpha !== undefined) {
self.shape.alpha = options.alpha;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222222
});
/****
* Game Code
****/
/*
We use only simple shapes for puzzle pieces and targets.
Each level will use a different color for its pieces and targets for visual variety.
Assets are initialized dynamically as needed.
*/
// --- Level Data ---
// Each level defines: pieces: [{shape, color, width, height, targetX, targetY, startX, startY}], and optionally a levelText
var levels = [
// Level 1: Simple square
{
levelText: "Bir kareyi tamamla.",
pieces: [{
shape: 'box',
color: 0x6ec6ff,
width: 320,
height: 320,
targetX: 1024,
targetY: 900,
startX: 600,
startY: 1800
}, {
shape: 'box',
color: 0x6ec6ff,
width: 320,
height: 320,
targetX: 1344,
targetY: 900,
startX: 1440,
startY: 1800
}]
},
// Level 2: Two ellipses
{
levelText: "İki daireyi birleştir.",
pieces: [{
shape: 'ellipse',
color: 0xffb74d,
width: 280,
height: 280,
targetX: 900,
targetY: 1100,
startX: 400,
startY: 2000
}, {
shape: 'ellipse',
color: 0xffb74d,
width: 280,
height: 280,
targetX: 1148,
targetY: 1100,
startX: 1600,
startY: 2000
}]
},
// Level 3: L-shape
{
levelText: "L şeklini oluştur.",
pieces: [{
shape: 'box',
color: 0x81c784,
width: 200,
height: 400,
targetX: 900,
targetY: 900,
startX: 400,
startY: 1800
}, {
shape: 'box',
color: 0x81c784,
width: 400,
height: 200,
targetX: 1100,
targetY: 1100,
startX: 1600,
startY: 1800
}]
},
// Level 4: T-shape
{
levelText: "T harfini tamamla.",
pieces: [{
shape: 'box',
color: 0xe57373,
width: 400,
height: 120,
targetX: 1024,
targetY: 900,
startX: 600,
startY: 1800
}, {
shape: 'box',
color: 0xe57373,
width: 120,
height: 320,
targetX: 1024,
targetY: 1060,
startX: 1440,
startY: 1800
}]
},
// Level 5: Triangle (approximate with boxes)
{
levelText: "Bir üçgen oluştur.",
pieces: [{
shape: 'box',
color: 0xba68c8,
width: 320,
height: 80,
targetX: 1024,
targetY: 900,
startX: 600,
startY: 1800
}, {
shape: 'box',
color: 0xba68c8,
width: 80,
height: 320,
targetX: 864,
targetY: 1060,
startX: 1440,
startY: 1800
}, {
shape: 'box',
color: 0xba68c8,
width: 80,
height: 320,
targetX: 1184,
targetY: 1060,
startX: 900,
startY: 2000
}]
},
// Level 6: Overlapping ellipses (Venn)
{
levelText: "Kesişen iki daireyi yerleştir.",
pieces: [{
shape: 'ellipse',
color: 0x4db6ac,
width: 260,
height: 260,
targetX: 950,
targetY: 1000,
startX: 400,
startY: 2000
}, {
shape: 'ellipse',
color: 0x4db6ac,
width: 260,
height: 260,
targetX: 1100,
targetY: 1000,
startX: 1600,
startY: 2000
}]
},
// Level 7: Barbell (two circles, one rectangle)
{
levelText: "Bir halter oluştur.",
pieces: [{
shape: 'ellipse',
color: 0xff8a65,
width: 180,
height: 180,
targetX: 900,
targetY: 1000,
startX: 400,
startY: 2000
}, {
shape: 'ellipse',
color: 0xff8a65,
width: 180,
height: 180,
targetX: 1148,
targetY: 1000,
startX: 1600,
startY: 2000
}, {
shape: 'box',
color: 0xff8a65,
width: 248,
height: 60,
targetX: 1024,
targetY: 1000,
startX: 1024,
startY: 1800
}]
},
// Level 8: Cross
{
levelText: "Bir artı işareti yap.",
pieces: [{
shape: 'box',
color: 0xa1887f,
width: 80,
height: 320,
targetX: 1024,
targetY: 900,
startX: 600,
startY: 1800
}, {
shape: 'box',
color: 0xa1887f,
width: 320,
height: 80,
targetX: 1024,
targetY: 900,
startX: 1440,
startY: 1800
}]
},
// Level 9: Rectangle with a hole (two boxes)
{
levelText: "Bir çerçeve oluştur.",
pieces: [{
shape: 'box',
color: 0x90caf9,
width: 400,
height: 80,
targetX: 1024,
targetY: 900,
startX: 600,
startY: 1800
}, {
shape: 'box',
color: 0x90caf9,
width: 80,
height: 400,
targetX: 824,
targetY: 1100,
startX: 1440,
startY: 1800
}, {
shape: 'box',
color: 0x90caf9,
width: 80,
height: 400,
targetX: 1224,
targetY: 1100,
startX: 900,
startY: 2000
}, {
shape: 'box',
color: 0x90caf9,
width: 400,
height: 80,
targetX: 1024,
targetY: 1300,
startX: 1200,
startY: 2200
}]
},
// Level 10: Heart (approximate with ellipses and box)
{
levelText: "Bir kalp oluştur.",
pieces: [{
shape: 'ellipse',
color: 0xf06292,
width: 180,
height: 180,
targetX: 980,
targetY: 1000,
startX: 400,
startY: 2000
}, {
shape: 'ellipse',
color: 0xf06292,
width: 180,
height: 180,
targetX: 1068,
targetY: 1000,
startX: 1600,
startY: 2000
}, {
shape: 'box',
color: 0xf06292,
width: 180,
height: 220,
targetX: 1024,
targetY: 1120,
startX: 1024,
startY: 1800
}]
}];
// --- State ---
var currentLevel = storage.level || 1;
if (currentLevel < 1) currentLevel = 1;
if (currentLevel > levels.length) currentLevel = 1;
var pieces = []; // PuzzlePiece instances
var slots = []; // TargetSlot instances
var draggingPiece = null;
var dragOffsetX = 0;
var dragOffsetY = 0;
var placedCount = 0;
var levelTextObj = null;
var levelNumTextObj = null;
var youWinTextObj = null;
// --- Helper: Create asset for a shape ---
function getShapeAssetId(shape, color, width, height) {
var id = shape + '_' + color.toString(16) + '_' + width + '_' + height;
// Only initialize if not already done
if (!LK.hasAsset(id)) {}
return id;
}
// --- Helper: Remove all pieces and slots from game ---
function clearLevel() {
for (var i = 0; i < pieces.length; i++) {
pieces[i].destroy();
}
for (var j = 0; j < slots.length; j++) {
slots[j].destroy();
}
pieces = [];
slots = [];
placedCount = 0;
if (levelTextObj) {
levelTextObj.destroy();
levelTextObj = null;
}
if (levelNumTextObj) {
levelNumTextObj.destroy();
levelNumTextObj = null;
}
if (youWinTextObj) {
youWinTextObj.destroy();
youWinTextObj = null;
}
}
// --- Helper: Show level text ---
function showLevelText(levelIdx) {
var level = levels[levelIdx];
// Level number
levelNumTextObj = new Text2("Seviye " + (levelIdx + 1), {
size: 90,
fill: 0xFFFFFF
});
levelNumTextObj.anchor.set(0.5, 0);
LK.gui.top.addChild(levelNumTextObj);
// Level description
levelTextObj = new Text2(level.levelText, {
size: 70,
fill: 0xBDBDBD
});
levelTextObj.anchor.set(0.5, 0);
LK.gui.top.addChild(levelTextObj);
// Position: levelNum at top center, levelText below it
levelNumTextObj.x = LK.gui.top.width / 2;
levelNumTextObj.y = 120;
levelTextObj.x = LK.gui.top.width / 2;
levelTextObj.y = 220;
}
// --- Helper: Show "Tebrikler" at the end ---
function showYouWinText() {
youWinTextObj = new Text2("Tebrikler!\nTüm seviyeleri tamamladın.", {
size: 120,
fill: 0xFFF176,
align: "center"
});
youWinTextObj.anchor.set(0.5, 0.5);
LK.gui.center.addChild(youWinTextObj);
youWinTextObj.x = LK.gui.center.width / 2;
youWinTextObj.y = LK.gui.center.height / 2;
}
// --- Load a level ---
function loadLevel(levelIdx) {
clearLevel();
showLevelText(levelIdx);
var level = levels[levelIdx];
var pieceData = level.pieces;
placedCount = 0;
// Create slots (targets)
for (var i = 0; i < pieceData.length; i++) {
var p = pieceData[i];
var slot = new TargetSlot();
var slotAssetId = getShapeAssetId(p.shape, p.color, p.width, p.height);
slot.setShape(slotAssetId, {
alpha: 0.18
});
slot.x = p.targetX;
slot.y = p.targetY;
slot.pieceId = i;
game.addChild(slot);
slots.push(slot);
}
// Create pieces
for (var j = 0; j < pieceData.length; j++) {
var p2 = pieceData[j];
var piece = new PuzzlePiece();
var pieceAssetId = getShapeAssetId(p2.shape, p2.color, p2.width, p2.height);
piece.setShape(pieceAssetId, {
alpha: 1
});
piece.x = p2.startX;
piece.y = p2.startY;
piece.originX = p2.startX;
piece.originY = p2.startY;
piece.targetX = p2.targetX;
piece.targetY = p2.targetY;
piece.pieceId = j;
piece.isPlaced = false;
game.addChild(piece);
pieces.push(piece);
}
}
// --- Check if a piece is close enough to its slot ---
function isPieceOnSlot(piece, slot) {
// Use distance between centers, allow some tolerance
var dx = piece.x - slot.x;
var dy = piece.y - slot.y;
var dist = Math.sqrt(dx * dx + dy * dy);
var tolerance = 80;
return dist < tolerance;
}
// --- Place a piece to its slot ---
function placePiece(piece, slot) {
piece.isPlaced = true;
piece.x = slot.x;
piece.y = slot.y;
// Animate a little scale effect
tween(piece, {
scaleX: 1.12,
scaleY: 1.12
}, {
duration: 120,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(piece, {
scaleX: 1,
scaleY: 1
}, {
duration: 120
});
}
});
placedCount++;
}
// --- Handle drag and drop logic ---
function findPieceAt(x, y) {
// Return topmost piece under (x, y) that is not placed
for (var i = pieces.length - 1; i >= 0; i--) {
var piece = pieces[i];
if (piece.isPlaced) continue;
var px = piece.x,
py = piece.y;
var w = piece.shape.width,
h = piece.shape.height;
if (x >= px - w / 2 && x <= px + w / 2 && y >= py - h / 2 && y <= py + h / 2) {
return piece;
}
}
return null;
}
// --- Game event handlers ---
// Drag start
game.down = function (x, y, obj) {
if (draggingPiece) return;
var piece = findPieceAt(x, y);
if (piece && !piece.isPlaced) {
draggingPiece = piece;
dragOffsetX = x - piece.x;
dragOffsetY = y - piece.y;
// Bring to front
game.removeChild(piece);
game.addChild(piece);
// Animate scale up
tween(piece, {
scaleX: 1.08,
scaleY: 1.08
}, {
duration: 100
});
}
};
// Drag move
game.move = function (x, y, obj) {
if (draggingPiece && !draggingPiece.isPlaced) {
draggingPiece.x = x - dragOffsetX;
draggingPiece.y = y - dragOffsetY;
}
};
// Drag end
game.up = function (x, y, obj) {
if (draggingPiece && !draggingPiece.isPlaced) {
// Check if over correct slot
var slot = slots[draggingPiece.pieceId];
if (isPieceOnSlot(draggingPiece, slot)) {
// Snap to slot
draggingPiece.animateToTarget(function () {
placePiece(draggingPiece, slot);
// Check if level complete
if (placedCount === pieces.length) {
// Next level or win
LK.setTimeout(function () {
if (currentLevel < levels.length) {
currentLevel++;
storage.level = currentLevel;
loadLevel(currentLevel - 1);
} else {
showYouWinText();
LK.showYouWin();
}
}, 600);
}
});
} else {
// Animate back to origin
draggingPiece.animateToOrigin(function () {
tween(draggingPiece, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
});
}
}
draggingPiece = null;
};
// --- Game update (not used for logic here) ---
game.update = function () {
// No per-frame logic needed
};
// --- Start the game ---
loadLevel(currentLevel - 1); ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,611 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1", {
+ level: 1
+});
+
+/****
+* Classes
+****/
+// PuzzlePiece: Draggable puzzle piece
+var PuzzlePiece = Container.expand(function () {
+ var self = Container.call(this);
+ // Properties to be set after creation:
+ // self.pieceId: index of this piece in the level
+ // self.targetX, self.targetY: where this piece should be placed
+ // self.isPlaced: whether the piece is already placed
+ self.isPlaced = false;
+ // Attach the shape asset (box or ellipse, color, size)
+ // These are set after creation via self.setShape
+ self.shape = null;
+ self.setShape = function (shapeId, options) {
+ if (self.shape) {
+ self.shape.destroy();
+ }
+ self.shape = self.attachAsset(shapeId, {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ if (options && options.alpha !== undefined) {
+ self.shape.alpha = options.alpha;
+ }
+ };
+ // Animate piece to its target position
+ self.animateToTarget = function (onFinish) {
+ tween(self, {
+ x: self.targetX,
+ y: self.targetY
+ }, {
+ duration: 400,
+ easing: tween.cubicOut,
+ onFinish: onFinish
+ });
+ };
+ // Animate piece back to its original position
+ self.animateToOrigin = function (onFinish) {
+ tween(self, {
+ x: self.originX,
+ y: self.originY
+ }, {
+ duration: 350,
+ easing: tween.easeOut,
+ onFinish: onFinish
+ });
+ };
+ return self;
+});
+// TargetSlot: Where a piece should be placed
+var TargetSlot = Container.expand(function () {
+ var self = Container.call(this);
+ // Attach the shape asset (box or ellipse, color, size)
+ self.shape = null;
+ self.setShape = function (shapeId, options) {
+ if (self.shape) {
+ self.shape.destroy();
+ }
+ self.shape = self.attachAsset(shapeId, {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ if (options && options.alpha !== undefined) {
+ self.shape.alpha = options.alpha;
+ }
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x222222
+});
+
+/****
+* Game Code
+****/
+/*
+We use only simple shapes for puzzle pieces and targets.
+Each level will use a different color for its pieces and targets for visual variety.
+Assets are initialized dynamically as needed.
+*/
+// --- Level Data ---
+// Each level defines: pieces: [{shape, color, width, height, targetX, targetY, startX, startY}], and optionally a levelText
+var levels = [
+// Level 1: Simple square
+{
+ levelText: "Bir kareyi tamamla.",
+ pieces: [{
+ shape: 'box',
+ color: 0x6ec6ff,
+ width: 320,
+ height: 320,
+ targetX: 1024,
+ targetY: 900,
+ startX: 600,
+ startY: 1800
+ }, {
+ shape: 'box',
+ color: 0x6ec6ff,
+ width: 320,
+ height: 320,
+ targetX: 1344,
+ targetY: 900,
+ startX: 1440,
+ startY: 1800
+ }]
+},
+// Level 2: Two ellipses
+{
+ levelText: "İki daireyi birleştir.",
+ pieces: [{
+ shape: 'ellipse',
+ color: 0xffb74d,
+ width: 280,
+ height: 280,
+ targetX: 900,
+ targetY: 1100,
+ startX: 400,
+ startY: 2000
+ }, {
+ shape: 'ellipse',
+ color: 0xffb74d,
+ width: 280,
+ height: 280,
+ targetX: 1148,
+ targetY: 1100,
+ startX: 1600,
+ startY: 2000
+ }]
+},
+// Level 3: L-shape
+{
+ levelText: "L şeklini oluştur.",
+ pieces: [{
+ shape: 'box',
+ color: 0x81c784,
+ width: 200,
+ height: 400,
+ targetX: 900,
+ targetY: 900,
+ startX: 400,
+ startY: 1800
+ }, {
+ shape: 'box',
+ color: 0x81c784,
+ width: 400,
+ height: 200,
+ targetX: 1100,
+ targetY: 1100,
+ startX: 1600,
+ startY: 1800
+ }]
+},
+// Level 4: T-shape
+{
+ levelText: "T harfini tamamla.",
+ pieces: [{
+ shape: 'box',
+ color: 0xe57373,
+ width: 400,
+ height: 120,
+ targetX: 1024,
+ targetY: 900,
+ startX: 600,
+ startY: 1800
+ }, {
+ shape: 'box',
+ color: 0xe57373,
+ width: 120,
+ height: 320,
+ targetX: 1024,
+ targetY: 1060,
+ startX: 1440,
+ startY: 1800
+ }]
+},
+// Level 5: Triangle (approximate with boxes)
+{
+ levelText: "Bir üçgen oluştur.",
+ pieces: [{
+ shape: 'box',
+ color: 0xba68c8,
+ width: 320,
+ height: 80,
+ targetX: 1024,
+ targetY: 900,
+ startX: 600,
+ startY: 1800
+ }, {
+ shape: 'box',
+ color: 0xba68c8,
+ width: 80,
+ height: 320,
+ targetX: 864,
+ targetY: 1060,
+ startX: 1440,
+ startY: 1800
+ }, {
+ shape: 'box',
+ color: 0xba68c8,
+ width: 80,
+ height: 320,
+ targetX: 1184,
+ targetY: 1060,
+ startX: 900,
+ startY: 2000
+ }]
+},
+// Level 6: Overlapping ellipses (Venn)
+{
+ levelText: "Kesişen iki daireyi yerleştir.",
+ pieces: [{
+ shape: 'ellipse',
+ color: 0x4db6ac,
+ width: 260,
+ height: 260,
+ targetX: 950,
+ targetY: 1000,
+ startX: 400,
+ startY: 2000
+ }, {
+ shape: 'ellipse',
+ color: 0x4db6ac,
+ width: 260,
+ height: 260,
+ targetX: 1100,
+ targetY: 1000,
+ startX: 1600,
+ startY: 2000
+ }]
+},
+// Level 7: Barbell (two circles, one rectangle)
+{
+ levelText: "Bir halter oluştur.",
+ pieces: [{
+ shape: 'ellipse',
+ color: 0xff8a65,
+ width: 180,
+ height: 180,
+ targetX: 900,
+ targetY: 1000,
+ startX: 400,
+ startY: 2000
+ }, {
+ shape: 'ellipse',
+ color: 0xff8a65,
+ width: 180,
+ height: 180,
+ targetX: 1148,
+ targetY: 1000,
+ startX: 1600,
+ startY: 2000
+ }, {
+ shape: 'box',
+ color: 0xff8a65,
+ width: 248,
+ height: 60,
+ targetX: 1024,
+ targetY: 1000,
+ startX: 1024,
+ startY: 1800
+ }]
+},
+// Level 8: Cross
+{
+ levelText: "Bir artı işareti yap.",
+ pieces: [{
+ shape: 'box',
+ color: 0xa1887f,
+ width: 80,
+ height: 320,
+ targetX: 1024,
+ targetY: 900,
+ startX: 600,
+ startY: 1800
+ }, {
+ shape: 'box',
+ color: 0xa1887f,
+ width: 320,
+ height: 80,
+ targetX: 1024,
+ targetY: 900,
+ startX: 1440,
+ startY: 1800
+ }]
+},
+// Level 9: Rectangle with a hole (two boxes)
+{
+ levelText: "Bir çerçeve oluştur.",
+ pieces: [{
+ shape: 'box',
+ color: 0x90caf9,
+ width: 400,
+ height: 80,
+ targetX: 1024,
+ targetY: 900,
+ startX: 600,
+ startY: 1800
+ }, {
+ shape: 'box',
+ color: 0x90caf9,
+ width: 80,
+ height: 400,
+ targetX: 824,
+ targetY: 1100,
+ startX: 1440,
+ startY: 1800
+ }, {
+ shape: 'box',
+ color: 0x90caf9,
+ width: 80,
+ height: 400,
+ targetX: 1224,
+ targetY: 1100,
+ startX: 900,
+ startY: 2000
+ }, {
+ shape: 'box',
+ color: 0x90caf9,
+ width: 400,
+ height: 80,
+ targetX: 1024,
+ targetY: 1300,
+ startX: 1200,
+ startY: 2200
+ }]
+},
+// Level 10: Heart (approximate with ellipses and box)
+{
+ levelText: "Bir kalp oluştur.",
+ pieces: [{
+ shape: 'ellipse',
+ color: 0xf06292,
+ width: 180,
+ height: 180,
+ targetX: 980,
+ targetY: 1000,
+ startX: 400,
+ startY: 2000
+ }, {
+ shape: 'ellipse',
+ color: 0xf06292,
+ width: 180,
+ height: 180,
+ targetX: 1068,
+ targetY: 1000,
+ startX: 1600,
+ startY: 2000
+ }, {
+ shape: 'box',
+ color: 0xf06292,
+ width: 180,
+ height: 220,
+ targetX: 1024,
+ targetY: 1120,
+ startX: 1024,
+ startY: 1800
+ }]
+}];
+// --- State ---
+var currentLevel = storage.level || 1;
+if (currentLevel < 1) currentLevel = 1;
+if (currentLevel > levels.length) currentLevel = 1;
+var pieces = []; // PuzzlePiece instances
+var slots = []; // TargetSlot instances
+var draggingPiece = null;
+var dragOffsetX = 0;
+var dragOffsetY = 0;
+var placedCount = 0;
+var levelTextObj = null;
+var levelNumTextObj = null;
+var youWinTextObj = null;
+// --- Helper: Create asset for a shape ---
+function getShapeAssetId(shape, color, width, height) {
+ var id = shape + '_' + color.toString(16) + '_' + width + '_' + height;
+ // Only initialize if not already done
+ if (!LK.hasAsset(id)) {}
+ return id;
+}
+// --- Helper: Remove all pieces and slots from game ---
+function clearLevel() {
+ for (var i = 0; i < pieces.length; i++) {
+ pieces[i].destroy();
+ }
+ for (var j = 0; j < slots.length; j++) {
+ slots[j].destroy();
+ }
+ pieces = [];
+ slots = [];
+ placedCount = 0;
+ if (levelTextObj) {
+ levelTextObj.destroy();
+ levelTextObj = null;
+ }
+ if (levelNumTextObj) {
+ levelNumTextObj.destroy();
+ levelNumTextObj = null;
+ }
+ if (youWinTextObj) {
+ youWinTextObj.destroy();
+ youWinTextObj = null;
+ }
+}
+// --- Helper: Show level text ---
+function showLevelText(levelIdx) {
+ var level = levels[levelIdx];
+ // Level number
+ levelNumTextObj = new Text2("Seviye " + (levelIdx + 1), {
+ size: 90,
+ fill: 0xFFFFFF
+ });
+ levelNumTextObj.anchor.set(0.5, 0);
+ LK.gui.top.addChild(levelNumTextObj);
+ // Level description
+ levelTextObj = new Text2(level.levelText, {
+ size: 70,
+ fill: 0xBDBDBD
+ });
+ levelTextObj.anchor.set(0.5, 0);
+ LK.gui.top.addChild(levelTextObj);
+ // Position: levelNum at top center, levelText below it
+ levelNumTextObj.x = LK.gui.top.width / 2;
+ levelNumTextObj.y = 120;
+ levelTextObj.x = LK.gui.top.width / 2;
+ levelTextObj.y = 220;
+}
+// --- Helper: Show "Tebrikler" at the end ---
+function showYouWinText() {
+ youWinTextObj = new Text2("Tebrikler!\nTüm seviyeleri tamamladın.", {
+ size: 120,
+ fill: 0xFFF176,
+ align: "center"
+ });
+ youWinTextObj.anchor.set(0.5, 0.5);
+ LK.gui.center.addChild(youWinTextObj);
+ youWinTextObj.x = LK.gui.center.width / 2;
+ youWinTextObj.y = LK.gui.center.height / 2;
+}
+// --- Load a level ---
+function loadLevel(levelIdx) {
+ clearLevel();
+ showLevelText(levelIdx);
+ var level = levels[levelIdx];
+ var pieceData = level.pieces;
+ placedCount = 0;
+ // Create slots (targets)
+ for (var i = 0; i < pieceData.length; i++) {
+ var p = pieceData[i];
+ var slot = new TargetSlot();
+ var slotAssetId = getShapeAssetId(p.shape, p.color, p.width, p.height);
+ slot.setShape(slotAssetId, {
+ alpha: 0.18
+ });
+ slot.x = p.targetX;
+ slot.y = p.targetY;
+ slot.pieceId = i;
+ game.addChild(slot);
+ slots.push(slot);
+ }
+ // Create pieces
+ for (var j = 0; j < pieceData.length; j++) {
+ var p2 = pieceData[j];
+ var piece = new PuzzlePiece();
+ var pieceAssetId = getShapeAssetId(p2.shape, p2.color, p2.width, p2.height);
+ piece.setShape(pieceAssetId, {
+ alpha: 1
+ });
+ piece.x = p2.startX;
+ piece.y = p2.startY;
+ piece.originX = p2.startX;
+ piece.originY = p2.startY;
+ piece.targetX = p2.targetX;
+ piece.targetY = p2.targetY;
+ piece.pieceId = j;
+ piece.isPlaced = false;
+ game.addChild(piece);
+ pieces.push(piece);
+ }
+}
+// --- Check if a piece is close enough to its slot ---
+function isPieceOnSlot(piece, slot) {
+ // Use distance between centers, allow some tolerance
+ var dx = piece.x - slot.x;
+ var dy = piece.y - slot.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ var tolerance = 80;
+ return dist < tolerance;
+}
+// --- Place a piece to its slot ---
+function placePiece(piece, slot) {
+ piece.isPlaced = true;
+ piece.x = slot.x;
+ piece.y = slot.y;
+ // Animate a little scale effect
+ tween(piece, {
+ scaleX: 1.12,
+ scaleY: 1.12
+ }, {
+ duration: 120,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ tween(piece, {
+ scaleX: 1,
+ scaleY: 1
+ }, {
+ duration: 120
+ });
+ }
+ });
+ placedCount++;
+}
+// --- Handle drag and drop logic ---
+function findPieceAt(x, y) {
+ // Return topmost piece under (x, y) that is not placed
+ for (var i = pieces.length - 1; i >= 0; i--) {
+ var piece = pieces[i];
+ if (piece.isPlaced) continue;
+ var px = piece.x,
+ py = piece.y;
+ var w = piece.shape.width,
+ h = piece.shape.height;
+ if (x >= px - w / 2 && x <= px + w / 2 && y >= py - h / 2 && y <= py + h / 2) {
+ return piece;
+ }
+ }
+ return null;
+}
+// --- Game event handlers ---
+// Drag start
+game.down = function (x, y, obj) {
+ if (draggingPiece) return;
+ var piece = findPieceAt(x, y);
+ if (piece && !piece.isPlaced) {
+ draggingPiece = piece;
+ dragOffsetX = x - piece.x;
+ dragOffsetY = y - piece.y;
+ // Bring to front
+ game.removeChild(piece);
+ game.addChild(piece);
+ // Animate scale up
+ tween(piece, {
+ scaleX: 1.08,
+ scaleY: 1.08
+ }, {
+ duration: 100
+ });
+ }
+};
+// Drag move
+game.move = function (x, y, obj) {
+ if (draggingPiece && !draggingPiece.isPlaced) {
+ draggingPiece.x = x - dragOffsetX;
+ draggingPiece.y = y - dragOffsetY;
+ }
+};
+// Drag end
+game.up = function (x, y, obj) {
+ if (draggingPiece && !draggingPiece.isPlaced) {
+ // Check if over correct slot
+ var slot = slots[draggingPiece.pieceId];
+ if (isPieceOnSlot(draggingPiece, slot)) {
+ // Snap to slot
+ draggingPiece.animateToTarget(function () {
+ placePiece(draggingPiece, slot);
+ // Check if level complete
+ if (placedCount === pieces.length) {
+ // Next level or win
+ LK.setTimeout(function () {
+ if (currentLevel < levels.length) {
+ currentLevel++;
+ storage.level = currentLevel;
+ loadLevel(currentLevel - 1);
+ } else {
+ showYouWinText();
+ LK.showYouWin();
+ }
+ }, 600);
+ }
+ });
+ } else {
+ // Animate back to origin
+ draggingPiece.animateToOrigin(function () {
+ tween(draggingPiece, {
+ scaleX: 1,
+ scaleY: 1
+ }, {
+ duration: 100
+ });
+ });
+ }
+ }
+ draggingPiece = null;
+};
+// --- Game update (not used for logic here) ---
+game.update = function () {
+ // No per-frame logic needed
+};
+// --- Start the game ---
+loadLevel(currentLevel - 1);
\ No newline at end of file