Code edit (1 edits merged)
Please save this source code
User prompt
Powerpuff Girls Jigsaw Puzzle
Initial prompt
Toca jigsaw puzzle (2016). Tap to choose a powerpuff girls jigsaw level 1 easy, level 2 medium, or level 3 hard, use your finger to drag and drop the puzzle pieces onto the board to create the picture, finish the jigsaw till balloons and confetti, tap on the balloons to pop them.
/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
/**** 
* Classes
****/ 
var Balloon = Container.expand(function (balloonColor) {
	var self = Container.call(this);
	var graphics = self.attachAsset('balloon', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	graphics.tint = balloonColor;
	self.popAnimationPlaying = false;
	// Floating animation
	var floatOffset = Math.random() * 2 - 1;
	tween(self, {
		y: self.y + floatOffset * 20
	}, {
		duration: 2000 + Math.random() * 1000,
		easing: tween.easeInOut,
		onFinish: function onFinish() {
			if (!self.popAnimationPlaying) {
				tween(self, {
					y: self.y - floatOffset * 20
				}, {
					duration: 2000 + Math.random() * 1000,
					easing: tween.easeInOut
				});
			}
		}
	});
	self.down = function (x, y, obj) {
		if (!self.popAnimationPlaying) {
			self.popAnimationPlaying = true;
			LK.getSound('popSound').play();
			// Pop animation
			tween(self, {
				scaleX: 1.5,
				scaleY: 1.5,
				alpha: 0
			}, {
				duration: 300,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					self.destroy();
				}
			});
		}
	};
	return self;
});
var Confetti = Container.expand(function () {
	var self = Container.call(this);
	var graphics = self.attachAsset('confetti', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	var colors = [0xff6b6b, 0x4ecdc4, 0x45b7d1, 0xfeca57, 0xff9ff3, 0x54a0ff];
	graphics.tint = colors[Math.floor(Math.random() * colors.length)];
	self.velocityX = (Math.random() - 0.5) * 10;
	self.velocityY = Math.random() * -15 - 5;
	self.gravity = 0.5;
	self.rotation = Math.random() * Math.PI * 2;
	self.rotationSpeed = (Math.random() - 0.5) * 0.2;
	self.update = function () {
		self.x += self.velocityX;
		self.y += self.velocityY;
		self.velocityY += self.gravity;
		self.rotation += self.rotationSpeed;
		if (self.y > 2732 + 50) {
			self.destroy();
		}
	};
	return self;
});
var LevelButton = Container.expand(function (difficulty, text, color) {
	var self = Container.call(this);
	var buttonBg = self.attachAsset('levelButton', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	buttonBg.tint = color;
	var buttonText = new Text2(text, {
		size: 40,
		fill: 0xFFFFFF
	});
	buttonText.anchor.set(0.5, 0.5);
	self.addChild(buttonText);
	self.difficulty = difficulty;
	self.down = function (x, y, obj) {
		// Button press animation
		tween(self, {
			scaleX: 0.95,
			scaleY: 0.95
		}, {
			duration: 100,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				tween(self, {
					scaleX: 1,
					scaleY: 1
				}, {
					duration: 100,
					easing: tween.easeOut
				});
			}
		});
		startPuzzle(self.difficulty);
	};
	return self;
});
var PuzzlePiece = Container.expand(function (correctX, correctY, pieceIndex) {
	var self = Container.call(this);
	var graphics = self.attachAsset('puzzlePiece', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.correctX = correctX;
	self.correctY = correctY;
	self.pieceIndex = pieceIndex;
	self.isPlaced = false;
	self.isDragging = false;
	self.startX = 0;
	self.startY = 0;
	// Set different colors for visual distinction
	var colors = [0xff69b4, 0x4ecdc4, 0x45b7d1, 0x96ceb4, 0xfeca57, 0xff9ff3, 0x54a0ff, 0x5f27cd];
	graphics.tint = colors[pieceIndex % colors.length];
	self.down = function (x, y, obj) {
		if (!self.isPlaced) {
			self.isDragging = true;
			self.startX = self.x;
			self.startY = self.y;
			// Bring to front
			self.parent.addChild(self);
		}
	};
	self.checkSnap = function () {
		var distance = Math.sqrt(Math.pow(self.x - self.correctX, 2) + Math.pow(self.y - self.correctY, 2));
		if (distance < 40) {
			self.x = self.correctX;
			self.y = self.correctY;
			self.isPlaced = true;
			self.isDragging = false;
			LK.getSound('snapSound').play();
			// Scale animation
			tween(self, {
				scaleX: 1.2,
				scaleY: 1.2
			}, {
				duration: 200,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					tween(self, {
						scaleX: 1,
						scaleY: 1
					}, {
						duration: 200,
						easing: tween.easeOut
					});
				}
			});
			checkPuzzleComplete();
		}
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x87ceeb
});
/**** 
* Game Code
****/ 
var currentState = 'menu'; // 'menu', 'puzzle', 'celebration'
var currentDifficulty = 'easy';
var puzzlePieces = [];
var puzzleBoard = null;
var balloons = [];
var confettiParticles = [];
var draggedPiece = null;
// Difficulty settings
var difficultySettings = {
	easy: {
		pieces: 9,
		gridSize: 3,
		pieceSize: 120
	},
	medium: {
		pieces: 16,
		gridSize: 4,
		pieceSize: 100
	},
	hard: {
		pieces: 25,
		gridSize: 5,
		pieceSize: 80
	}
};
// Level selection buttons
var easyButton = new LevelButton('easy', 'EASY\n9 Pieces', 0x4ecdc4);
var mediumButton = new LevelButton('medium', 'MEDIUM\n16 Pieces', 0xf39c12);
var hardButton = new LevelButton('hard', 'HARD\n25 Pieces', 0xe74c3c);
// Position buttons
easyButton.x = 1024;
easyButton.y = 1000;
mediumButton.x = 1024;
mediumButton.y = 1200;
hardButton.x = 1024;
hardButton.y = 1400;
// Add buttons to game
game.addChild(easyButton);
game.addChild(mediumButton);
game.addChild(hardButton);
// Title text
var titleText = new Text2('Powerpuff Girls\nJigsaw Puzzle', {
	size: 80,
	fill: 0xFF1493
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 600;
game.addChild(titleText);
function startPuzzle(difficulty) {
	currentState = 'puzzle';
	currentDifficulty = difficulty;
	// Hide menu elements
	easyButton.visible = false;
	mediumButton.visible = false;
	hardButton.visible = false;
	titleText.visible = false;
	createPuzzle();
}
function createPuzzle() {
	var settings = difficultySettings[currentDifficulty];
	puzzlePieces = [];
	// Create puzzle board
	puzzleBoard = LK.getAsset('puzzleBoard', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	puzzleBoard.width = settings.gridSize * settings.pieceSize;
	puzzleBoard.height = settings.gridSize * settings.pieceSize;
	puzzleBoard.x = 1024;
	puzzleBoard.y = 1000;
	game.addChild(puzzleBoard);
	// Create puzzle pieces
	for (var i = 0; i < settings.pieces; i++) {
		var row = Math.floor(i / settings.gridSize);
		var col = i % settings.gridSize;
		var correctX = puzzleBoard.x - settings.gridSize * settings.pieceSize / 2 + col * settings.pieceSize + settings.pieceSize / 2;
		var correctY = puzzleBoard.y - settings.gridSize * settings.pieceSize / 2 + row * settings.pieceSize + settings.pieceSize / 2;
		var piece = new PuzzlePiece(correctX, correctY, i);
		piece.width = settings.pieceSize - 4;
		piece.height = settings.pieceSize - 4;
		// Scatter pieces randomly
		piece.x = Math.random() * 1500 + 200;
		piece.y = Math.random() * 800 + 200;
		// Make sure pieces don't overlap with board initially
		while (Math.abs(piece.x - puzzleBoard.x) < 450 && Math.abs(piece.y - puzzleBoard.y) < 450) {
			piece.x = Math.random() * 1500 + 200;
			piece.y = Math.random() * 800 + 200;
		}
		puzzlePieces.push(piece);
		game.addChild(piece);
	}
}
function checkPuzzleComplete() {
	var placedPieces = 0;
	for (var i = 0; i < puzzlePieces.length; i++) {
		if (puzzlePieces[i].isPlaced) {
			placedPieces++;
		}
	}
	if (placedPieces === puzzlePieces.length) {
		LK.getSound('winSound').play();
		startCelebration();
	}
}
function startCelebration() {
	currentState = 'celebration';
	// Create balloons
	var balloonColors = [0xff6b6b, 0x4ecdc4, 0x45b7d1, 0xfeca57, 0xff9ff3, 0x54a0ff];
	for (var i = 0; i < 12; i++) {
		var balloon = new Balloon(balloonColors[i % balloonColors.length]);
		balloon.x = Math.random() * 1800 + 124;
		balloon.y = Math.random() * 1000 + 1500;
		balloons.push(balloon);
		game.addChild(balloon);
	}
	// Create confetti
	for (var j = 0; j < 50; j++) {
		var confetti = new Confetti();
		confetti.x = Math.random() * 2048;
		confetti.y = -50;
		confettiParticles.push(confetti);
		game.addChild(confetti);
	}
	// Add back to menu button
	var backButton = new LevelButton('menu', 'BACK TO MENU', 0x2c3e50);
	backButton.x = 1024;
	backButton.y = 2500;
	game.addChild(backButton);
	backButton.down = function () {
		resetToMenu();
	};
}
function resetToMenu() {
	currentState = 'menu';
	// Clear all game objects
	for (var i = 0; i < puzzlePieces.length; i++) {
		puzzlePieces[i].destroy();
	}
	puzzlePieces = [];
	if (puzzleBoard) {
		puzzleBoard.destroy();
		puzzleBoard = null;
	}
	for (var j = 0; j < balloons.length; j++) {
		balloons[j].destroy();
	}
	balloons = [];
	for (var k = 0; k < confettiParticles.length; k++) {
		confettiParticles[k].destroy();
	}
	confettiParticles = [];
	// Show menu elements
	easyButton.visible = true;
	mediumButton.visible = true;
	hardButton.visible = true;
	titleText.visible = true;
	// Remove back button
	game.children.forEach(function (child) {
		if (child.difficulty === 'menu') {
			child.destroy();
		}
	});
}
game.move = function (x, y, obj) {
	if (currentState === 'puzzle' && draggedPiece && draggedPiece.isDragging) {
		draggedPiece.x = x;
		draggedPiece.y = y;
	}
};
game.down = function (x, y, obj) {
	if (currentState === 'puzzle') {
		// Find the topmost piece at this position
		for (var i = puzzlePieces.length - 1; i >= 0; i--) {
			var piece = puzzlePieces[i];
			if (!piece.isPlaced && x >= piece.x - piece.width / 2 && x <= piece.x + piece.width / 2 && y >= piece.y - piece.height / 2 && y <= piece.y + piece.height / 2) {
				draggedPiece = piece;
				piece.isDragging = true;
				piece.startX = piece.x;
				piece.startY = piece.y;
				// Bring to front
				game.addChild(piece);
				break;
			}
		}
	}
};
game.up = function (x, y, obj) {
	if (currentState === 'puzzle' && draggedPiece) {
		draggedPiece.checkSnap();
		draggedPiece.isDragging = false;
		draggedPiece = null;
	}
};
game.update = function () {
	// Update confetti particles
	for (var i = confettiParticles.length - 1; i >= 0; i--) {
		var confetti = confettiParticles[i];
		if (confetti.parent) {
			// Confetti update is handled in the class
		} else {
			confettiParticles.splice(i, 1);
		}
	}
	// Clean up destroyed balloons
	for (var j = balloons.length - 1; j >= 0; j--) {
		if (!balloons[j].parent) {
			balloons.splice(j, 1);
		}
	}
}; ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,391 @@
-/****
+/**** 
+* Plugins
+****/ 
+var tween = LK.import("@upit/tween.v1");
+
+/**** 
+* Classes
+****/ 
+var Balloon = Container.expand(function (balloonColor) {
+	var self = Container.call(this);
+	var graphics = self.attachAsset('balloon', {
+		anchorX: 0.5,
+		anchorY: 0.5
+	});
+	graphics.tint = balloonColor;
+	self.popAnimationPlaying = false;
+	// Floating animation
+	var floatOffset = Math.random() * 2 - 1;
+	tween(self, {
+		y: self.y + floatOffset * 20
+	}, {
+		duration: 2000 + Math.random() * 1000,
+		easing: tween.easeInOut,
+		onFinish: function onFinish() {
+			if (!self.popAnimationPlaying) {
+				tween(self, {
+					y: self.y - floatOffset * 20
+				}, {
+					duration: 2000 + Math.random() * 1000,
+					easing: tween.easeInOut
+				});
+			}
+		}
+	});
+	self.down = function (x, y, obj) {
+		if (!self.popAnimationPlaying) {
+			self.popAnimationPlaying = true;
+			LK.getSound('popSound').play();
+			// Pop animation
+			tween(self, {
+				scaleX: 1.5,
+				scaleY: 1.5,
+				alpha: 0
+			}, {
+				duration: 300,
+				easing: tween.easeOut,
+				onFinish: function onFinish() {
+					self.destroy();
+				}
+			});
+		}
+	};
+	return self;
+});
+var Confetti = Container.expand(function () {
+	var self = Container.call(this);
+	var graphics = self.attachAsset('confetti', {
+		anchorX: 0.5,
+		anchorY: 0.5
+	});
+	var colors = [0xff6b6b, 0x4ecdc4, 0x45b7d1, 0xfeca57, 0xff9ff3, 0x54a0ff];
+	graphics.tint = colors[Math.floor(Math.random() * colors.length)];
+	self.velocityX = (Math.random() - 0.5) * 10;
+	self.velocityY = Math.random() * -15 - 5;
+	self.gravity = 0.5;
+	self.rotation = Math.random() * Math.PI * 2;
+	self.rotationSpeed = (Math.random() - 0.5) * 0.2;
+	self.update = function () {
+		self.x += self.velocityX;
+		self.y += self.velocityY;
+		self.velocityY += self.gravity;
+		self.rotation += self.rotationSpeed;
+		if (self.y > 2732 + 50) {
+			self.destroy();
+		}
+	};
+	return self;
+});
+var LevelButton = Container.expand(function (difficulty, text, color) {
+	var self = Container.call(this);
+	var buttonBg = self.attachAsset('levelButton', {
+		anchorX: 0.5,
+		anchorY: 0.5
+	});
+	buttonBg.tint = color;
+	var buttonText = new Text2(text, {
+		size: 40,
+		fill: 0xFFFFFF
+	});
+	buttonText.anchor.set(0.5, 0.5);
+	self.addChild(buttonText);
+	self.difficulty = difficulty;
+	self.down = function (x, y, obj) {
+		// Button press animation
+		tween(self, {
+			scaleX: 0.95,
+			scaleY: 0.95
+		}, {
+			duration: 100,
+			easing: tween.easeOut,
+			onFinish: function onFinish() {
+				tween(self, {
+					scaleX: 1,
+					scaleY: 1
+				}, {
+					duration: 100,
+					easing: tween.easeOut
+				});
+			}
+		});
+		startPuzzle(self.difficulty);
+	};
+	return self;
+});
+var PuzzlePiece = Container.expand(function (correctX, correctY, pieceIndex) {
+	var self = Container.call(this);
+	var graphics = self.attachAsset('puzzlePiece', {
+		anchorX: 0.5,
+		anchorY: 0.5
+	});
+	self.correctX = correctX;
+	self.correctY = correctY;
+	self.pieceIndex = pieceIndex;
+	self.isPlaced = false;
+	self.isDragging = false;
+	self.startX = 0;
+	self.startY = 0;
+	// Set different colors for visual distinction
+	var colors = [0xff69b4, 0x4ecdc4, 0x45b7d1, 0x96ceb4, 0xfeca57, 0xff9ff3, 0x54a0ff, 0x5f27cd];
+	graphics.tint = colors[pieceIndex % colors.length];
+	self.down = function (x, y, obj) {
+		if (!self.isPlaced) {
+			self.isDragging = true;
+			self.startX = self.x;
+			self.startY = self.y;
+			// Bring to front
+			self.parent.addChild(self);
+		}
+	};
+	self.checkSnap = function () {
+		var distance = Math.sqrt(Math.pow(self.x - self.correctX, 2) + Math.pow(self.y - self.correctY, 2));
+		if (distance < 40) {
+			self.x = self.correctX;
+			self.y = self.correctY;
+			self.isPlaced = true;
+			self.isDragging = false;
+			LK.getSound('snapSound').play();
+			// Scale animation
+			tween(self, {
+				scaleX: 1.2,
+				scaleY: 1.2
+			}, {
+				duration: 200,
+				easing: tween.easeOut,
+				onFinish: function onFinish() {
+					tween(self, {
+						scaleX: 1,
+						scaleY: 1
+					}, {
+						duration: 200,
+						easing: tween.easeOut
+					});
+				}
+			});
+			checkPuzzleComplete();
+		}
+	};
+	return self;
+});
+
+/**** 
 * Initialize Game
-****/
+****/ 
 var game = new LK.Game({
-	backgroundColor: 0x000000
-});
\ No newline at end of file
+	backgroundColor: 0x87ceeb
+});
+
+/**** 
+* Game Code
+****/ 
+var currentState = 'menu'; // 'menu', 'puzzle', 'celebration'
+var currentDifficulty = 'easy';
+var puzzlePieces = [];
+var puzzleBoard = null;
+var balloons = [];
+var confettiParticles = [];
+var draggedPiece = null;
+// Difficulty settings
+var difficultySettings = {
+	easy: {
+		pieces: 9,
+		gridSize: 3,
+		pieceSize: 120
+	},
+	medium: {
+		pieces: 16,
+		gridSize: 4,
+		pieceSize: 100
+	},
+	hard: {
+		pieces: 25,
+		gridSize: 5,
+		pieceSize: 80
+	}
+};
+// Level selection buttons
+var easyButton = new LevelButton('easy', 'EASY\n9 Pieces', 0x4ecdc4);
+var mediumButton = new LevelButton('medium', 'MEDIUM\n16 Pieces', 0xf39c12);
+var hardButton = new LevelButton('hard', 'HARD\n25 Pieces', 0xe74c3c);
+// Position buttons
+easyButton.x = 1024;
+easyButton.y = 1000;
+mediumButton.x = 1024;
+mediumButton.y = 1200;
+hardButton.x = 1024;
+hardButton.y = 1400;
+// Add buttons to game
+game.addChild(easyButton);
+game.addChild(mediumButton);
+game.addChild(hardButton);
+// Title text
+var titleText = new Text2('Powerpuff Girls\nJigsaw Puzzle', {
+	size: 80,
+	fill: 0xFF1493
+});
+titleText.anchor.set(0.5, 0.5);
+titleText.x = 1024;
+titleText.y = 600;
+game.addChild(titleText);
+function startPuzzle(difficulty) {
+	currentState = 'puzzle';
+	currentDifficulty = difficulty;
+	// Hide menu elements
+	easyButton.visible = false;
+	mediumButton.visible = false;
+	hardButton.visible = false;
+	titleText.visible = false;
+	createPuzzle();
+}
+function createPuzzle() {
+	var settings = difficultySettings[currentDifficulty];
+	puzzlePieces = [];
+	// Create puzzle board
+	puzzleBoard = LK.getAsset('puzzleBoard', {
+		anchorX: 0.5,
+		anchorY: 0.5
+	});
+	puzzleBoard.width = settings.gridSize * settings.pieceSize;
+	puzzleBoard.height = settings.gridSize * settings.pieceSize;
+	puzzleBoard.x = 1024;
+	puzzleBoard.y = 1000;
+	game.addChild(puzzleBoard);
+	// Create puzzle pieces
+	for (var i = 0; i < settings.pieces; i++) {
+		var row = Math.floor(i / settings.gridSize);
+		var col = i % settings.gridSize;
+		var correctX = puzzleBoard.x - settings.gridSize * settings.pieceSize / 2 + col * settings.pieceSize + settings.pieceSize / 2;
+		var correctY = puzzleBoard.y - settings.gridSize * settings.pieceSize / 2 + row * settings.pieceSize + settings.pieceSize / 2;
+		var piece = new PuzzlePiece(correctX, correctY, i);
+		piece.width = settings.pieceSize - 4;
+		piece.height = settings.pieceSize - 4;
+		// Scatter pieces randomly
+		piece.x = Math.random() * 1500 + 200;
+		piece.y = Math.random() * 800 + 200;
+		// Make sure pieces don't overlap with board initially
+		while (Math.abs(piece.x - puzzleBoard.x) < 450 && Math.abs(piece.y - puzzleBoard.y) < 450) {
+			piece.x = Math.random() * 1500 + 200;
+			piece.y = Math.random() * 800 + 200;
+		}
+		puzzlePieces.push(piece);
+		game.addChild(piece);
+	}
+}
+function checkPuzzleComplete() {
+	var placedPieces = 0;
+	for (var i = 0; i < puzzlePieces.length; i++) {
+		if (puzzlePieces[i].isPlaced) {
+			placedPieces++;
+		}
+	}
+	if (placedPieces === puzzlePieces.length) {
+		LK.getSound('winSound').play();
+		startCelebration();
+	}
+}
+function startCelebration() {
+	currentState = 'celebration';
+	// Create balloons
+	var balloonColors = [0xff6b6b, 0x4ecdc4, 0x45b7d1, 0xfeca57, 0xff9ff3, 0x54a0ff];
+	for (var i = 0; i < 12; i++) {
+		var balloon = new Balloon(balloonColors[i % balloonColors.length]);
+		balloon.x = Math.random() * 1800 + 124;
+		balloon.y = Math.random() * 1000 + 1500;
+		balloons.push(balloon);
+		game.addChild(balloon);
+	}
+	// Create confetti
+	for (var j = 0; j < 50; j++) {
+		var confetti = new Confetti();
+		confetti.x = Math.random() * 2048;
+		confetti.y = -50;
+		confettiParticles.push(confetti);
+		game.addChild(confetti);
+	}
+	// Add back to menu button
+	var backButton = new LevelButton('menu', 'BACK TO MENU', 0x2c3e50);
+	backButton.x = 1024;
+	backButton.y = 2500;
+	game.addChild(backButton);
+	backButton.down = function () {
+		resetToMenu();
+	};
+}
+function resetToMenu() {
+	currentState = 'menu';
+	// Clear all game objects
+	for (var i = 0; i < puzzlePieces.length; i++) {
+		puzzlePieces[i].destroy();
+	}
+	puzzlePieces = [];
+	if (puzzleBoard) {
+		puzzleBoard.destroy();
+		puzzleBoard = null;
+	}
+	for (var j = 0; j < balloons.length; j++) {
+		balloons[j].destroy();
+	}
+	balloons = [];
+	for (var k = 0; k < confettiParticles.length; k++) {
+		confettiParticles[k].destroy();
+	}
+	confettiParticles = [];
+	// Show menu elements
+	easyButton.visible = true;
+	mediumButton.visible = true;
+	hardButton.visible = true;
+	titleText.visible = true;
+	// Remove back button
+	game.children.forEach(function (child) {
+		if (child.difficulty === 'menu') {
+			child.destroy();
+		}
+	});
+}
+game.move = function (x, y, obj) {
+	if (currentState === 'puzzle' && draggedPiece && draggedPiece.isDragging) {
+		draggedPiece.x = x;
+		draggedPiece.y = y;
+	}
+};
+game.down = function (x, y, obj) {
+	if (currentState === 'puzzle') {
+		// Find the topmost piece at this position
+		for (var i = puzzlePieces.length - 1; i >= 0; i--) {
+			var piece = puzzlePieces[i];
+			if (!piece.isPlaced && x >= piece.x - piece.width / 2 && x <= piece.x + piece.width / 2 && y >= piece.y - piece.height / 2 && y <= piece.y + piece.height / 2) {
+				draggedPiece = piece;
+				piece.isDragging = true;
+				piece.startX = piece.x;
+				piece.startY = piece.y;
+				// Bring to front
+				game.addChild(piece);
+				break;
+			}
+		}
+	}
+};
+game.up = function (x, y, obj) {
+	if (currentState === 'puzzle' && draggedPiece) {
+		draggedPiece.checkSnap();
+		draggedPiece.isDragging = false;
+		draggedPiece = null;
+	}
+};
+game.update = function () {
+	// Update confetti particles
+	for (var i = confettiParticles.length - 1; i >= 0; i--) {
+		var confetti = confettiParticles[i];
+		if (confetti.parent) {
+			// Confetti update is handled in the class
+		} else {
+			confettiParticles.splice(i, 1);
+		}
+	}
+	// Clean up destroyed balloons
+	for (var j = balloons.length - 1; j >= 0; j--) {
+		if (!balloons[j].parent) {
+			balloons.splice(j, 1);
+		}
+	}
+};
\ No newline at end of file