/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ // Bowling Ball Class var BowlingBall = Container.expand(function () { var self = Container.call(this); // Attach bowling ball asset (blue ellipse) var ball = self.attachAsset('bowlingBall', { anchorX: 0.5, anchorY: 0.5 }); // Ball state self.isMoving = false; self.vx = 0; self.vy = 0; // Ball radius for collision self.radius = ball.width / 2; // Reset ball to initial position self.reset = function () { self.x = 2048 / 2; self.y = 2732 - 350; self.vx = 0; self.vy = 0; self.isMoving = false; }; // Update ball position self.update = function () { if (self.isMoving) { self.x += self.vx; self.y += self.vy; // Friction self.vx *= 0.985; self.vy *= 0.985; // Stop if very slow if (Math.abs(self.vx) < 0.5 && Math.abs(self.vy) < 0.5) { self.vx = 0; self.vy = 0; self.isMoving = false; } // Clamp to game area if (self.x < self.radius) self.x = self.radius; if (self.x > 2048 - self.radius) self.x = 2048 - self.radius; if (self.y < self.radius) self.y = self.radius; if (self.y > 2732 - self.radius) self.y = 2732 - self.radius; } }; return self; }); // Pin Class var Pin = Container.expand(function () { var self = Container.call(this); // Attach pin asset (white box) var pin = self.attachAsset('pin', { anchorX: 0.5, anchorY: 1.0 }); self.isStanding = true; // Knock down pin self.knockDown = function () { if (self.isStanding) { self.isStanding = false; // Animate: fall down (rotate and fade) tween(self, { rotation: Math.PI / 2, alpha: 0.3 }, { duration: 400, easing: tween.cubicOut }); } }; // Reset pin to standing self.reset = function () { self.isStanding = true; self.rotation = 0; self.alpha = 1; }; // Get pin center for collision self.getCenter = function () { return { x: self.x, y: self.y - pin.height / 2 }; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x222222 }); /**** * Game Code ****/ // --- Game State Variables --- // --- Asset Initialization --- // Add bowling alley background (stretched to fit game area) var bg = LK.getAsset('bowlingAlleyBg', { anchorX: 0, anchorY: 0, x: 0, y: 0, width: 2048, height: 2732 }); game.addChild(bg); var ball; var pins = []; var currentFrame = 1; var currentRoll = 1; var frameScores = []; var totalScore = 0; var pinsDownThisFrame = 0; var pinsDownThisRoll = 0; var bestScore = storage.bestScore || 0; var isAiming = false; var aimStart = null; var aimEnd = null; var canThrow = true; var isResetting = false; // --- UI Elements --- var scoreTxt = new Text2('Skor: 0', { size: 90, fill: "#fff" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); var frameTxt = new Text2('Tur: 1 / 10', { size: 70, fill: "#fff" }); frameTxt.anchor.set(0.5, 0); LK.gui.top.addChild(frameTxt); frameTxt.y = 110; var bestScoreTxt = new Text2('En İyi: ' + bestScore, { size: 60, fill: 0xFFD700 }); bestScoreTxt.anchor.set(1, 0); LK.gui.topRight.addChild(bestScoreTxt); // --- Helper Functions --- // Arrange pins in triangle (10 pins) function setupPins() { // Remove old pins for (var i = 0; i < pins.length; i++) { pins[i].destroy(); } pins = []; // Triangle layout var startX = 2048 / 2; var startY = 600; var rowSpacing = 90; var colSpacing = 80; var pinIdx = 0; for (var row = 0; row < 4; row++) { for (var col = 0; col <= row; col++) { if (pinIdx >= 10) break; var pin = new Pin(); pin.reset(); pin.x = startX + (col - row / 2) * colSpacing; pin.y = startY + row * rowSpacing; pins.push(pin); game.addChild(pin); pinIdx++; } } } // Reset ball and pins for new frame or roll function resetForNextRoll() { isResetting = true; // Reset ball ball.reset(); // Only reset pins if new frame if (currentRoll === 1) { setupPins(); } else { // Only reset fallen pins if second roll for (var i = 0; i < pins.length; i++) { if (!pins[i].isStanding) { pins[i].alpha = 0.15; } } } isResetting = false; canThrow = true; aimStart = null; aimEnd = null; } // Count standing pins function countStandingPins() { var count = 0; for (var i = 0; i < pins.length; i++) { if (pins[i].isStanding) count++; } return count; } // Update UI function updateUI() { scoreTxt.setText('Skor: ' + totalScore); frameTxt.setText('Tur: ' + currentFrame + ' / 10'); bestScoreTxt.setText('En İyi: ' + bestScore); } // Calculate score for a frame (simple: just sum pins knocked down) function calcFrameScore(frameIdx) { // For MVP, just sum pins knocked down in frame return frameScores[frameIdx] || 0; } // End of game function endGame() { if (totalScore > bestScore) { bestScore = totalScore; storage.bestScore = bestScore; } updateUI(); // Show game over popup LK.showGameOver(); } // --- Game Setup --- // Create ball ball = new BowlingBall(); game.addChild(ball); ball.reset(); // Create pins setupPins(); // Initialize scores frameScores = []; totalScore = 0; currentFrame = 1; currentRoll = 1; pinsDownThisFrame = 0; pinsDownThisRoll = 0; updateUI(); // --- Input Handling --- // Drag/Swipe to throw game.down = function (x, y, obj) { if (!canThrow || ball.isMoving || isResetting) return; // Only allow drag from ball area var dx = x - ball.x; var dy = y - ball.y; if (dx * dx + dy * dy <= ball.radius * ball.radius * 1.2) { isAiming = true; aimStart = { x: x, y: y }; aimEnd = null; } }; game.move = function (x, y, obj) { if (isAiming && aimStart) { aimEnd = { x: x, y: y }; // Optionally: show aim line (not implemented in MVP) } }; game.up = function (x, y, obj) { if (isAiming && aimStart && !ball.isMoving && canThrow) { aimEnd = { x: x, y: y }; // Calculate velocity var dx = aimEnd.x - aimStart.x; var dy = aimEnd.y - aimStart.y; // Only allow upward throws if (dy < -30) { // Map swipe to velocity var power = Math.min(Math.sqrt(dx * dx + dy * dy), 900); var angle = Math.atan2(dy, dx); var speed = 32 + power / 30; // min speed ball.vx = Math.cos(angle) * speed; ball.vy = Math.sin(angle) * speed; ball.isMoving = true; canThrow = false; } } isAiming = false; aimStart = null; aimEnd = null; }; // --- Game Loop --- game.update = function () { // Ball update ball.update(); // Collision: Ball vs Pins if (ball.isMoving) { for (var i = 0; i < pins.length; i++) { var pin = pins[i]; if (pin.isStanding) { var c = pin.getCenter(); var dx = ball.x - c.x; var dy = ball.y - c.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < ball.radius + 40) { // 40: pin "radius" pin.knockDown(); } } } } // Check if ball stopped or out of bounds if (!ball.isMoving && !canThrow && !isResetting) { // Wait a short moment before scoring isResetting = true; LK.setTimeout(function () { // Count pins knocked down this roll var pinsDown = 0; for (var i = 0; i < pins.length; i++) { if (!pins[i].isStanding && pins[i].alpha > 0.2) { pinsDown++; } } pinsDownThisRoll = pinsDown - pinsDownThisFrame; pinsDownThisFrame = pinsDown; // Add to frame score if (!frameScores[currentFrame - 1]) frameScores[currentFrame - 1] = 0; frameScores[currentFrame - 1] += pinsDownThisRoll; totalScore = 0; for (var f = 0; f < frameScores.length; f++) { totalScore += calcFrameScore(f); } updateUI(); // Strike: all pins down in first roll var allDown = countStandingPins() === 0; if (allDown && currentRoll === 1) { // Strike: skip second roll currentFrame++; currentRoll = 1; pinsDownThisFrame = 0; if (currentFrame > 10) { endGame(); return; } resetForNextRoll(); } else if (currentRoll === 1) { // Second roll currentRoll = 2; resetForNextRoll(); } else { // End of frame currentFrame++; currentRoll = 1; pinsDownThisFrame = 0; if (currentFrame > 10) { endGame(); return; } resetForNextRoll(); } }, 700); } }; // --- Initial UI Update --- updateUI();
===================================================================
--- original.js
+++ change.js
@@ -101,9 +101,19 @@
/****
* Game Code
****/
// --- Game State Variables ---
-// --- Asset Initialization ---
+// --- Asset Initialization ---
+// Add bowling alley background (stretched to fit game area)
+var bg = LK.getAsset('bowlingAlleyBg', {
+ anchorX: 0,
+ anchorY: 0,
+ x: 0,
+ y: 0,
+ width: 2048,
+ height: 2732
+});
+game.addChild(bg);
var ball;
var pins = [];
var currentFrame = 1;
var currentRoll = 1;