Code edit (1 edits merged)
Please save this source code
User prompt
Slam Dunk Challenge
Initial prompt
I want a game and in that game you are playing basketball. You are boy and you want to score in the basket. You have to pass all the levels which are 10 and beat the last one. It gets more difficult with each level.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { level: 1, highScores: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] }); /**** * Classes ****/ var AimingSystem = Container.expand(function () { var self = Container.call(this); // Create the aim arrow var arrow = self.attachAsset('aimArrow', { anchorX: 0, anchorY: 0.5, x: 0, y: 0 }); // Create power meter background var powerMeter = self.attachAsset('powerMeter', { anchorX: 0.5, anchorY: 1, x: 0, y: 0 }); // Create power indicator var powerIndicator = self.attachAsset('powerIndicator', { anchorX: 0.5, anchorY: 0.5, x: 0, y: -powerMeter.height + 10 }); self.visible = false; self.angle = -45; self.power = 0; self.powerIncreasing = true; self.powerSpeed = 2; self.maxPower = 100; // Position offset from power meter to arrow var offsetX = 100; self.setPosition = function (x, y) { self.x = x; self.y = y; powerMeter.x = x - offsetX; powerMeter.y = y; }; self.setAngle = function (angle) { self.angle = angle; arrow.rotation = angle * Math.PI / 180; }; self.setPower = function (power) { self.power = power; var normalizedPower = power / self.maxPower; powerIndicator.y = -powerMeter.height * normalizedPower + 10; }; self.startPowerPhase = function () { self.power = 0; self.powerIncreasing = true; self.visible = true; }; self.update = function () { if (gameState === "power" && self.visible) { if (self.powerIncreasing) { self.power += self.powerSpeed; if (self.power >= self.maxPower) { self.power = self.maxPower; self.powerIncreasing = false; } } else { self.power -= self.powerSpeed; if (self.power <= 0) { self.power = 0; self.powerIncreasing = true; } } self.setPower(self.power); } }; return self; }); var BasketHoop = Container.expand(function () { var self = Container.call(this); // Create backboard var backboard = self.attachAsset('backboard', { anchorX: 0.5, anchorY: 0, x: 0, y: 0 }); // Create rim var hoop = self.attachAsset('hoop', { anchorX: 0.5, anchorY: 0, x: 0, y: backboard.height + 20 }); // Create net self.net = self.attachAsset('net', { anchorX: 0.5, anchorY: 0, x: 0, y: backboard.height + 20 + hoop.height / 2, alpha: 0.5 }); // For hoop movement self.originalX = 0; self.originalY = 0; self.moveSpeed = 0; self.moveRange = 0; self.moveDir = 1; self.setMoving = function (speed, range) { self.moveSpeed = speed; self.moveRange = range; self.originalX = self.x; }; self.update = function () { if (self.moveSpeed > 0) { self.x += self.moveSpeed * self.moveDir; if (self.x > self.originalX + self.moveRange) { self.x = self.originalX + self.moveRange; self.moveDir = -1; } else if (self.x < self.originalX - self.moveRange) { self.x = self.originalX - self.moveRange; self.moveDir = 1; } } }; return self; }); var Basketball = Container.expand(function () { var self = Container.call(this); var ball = self.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5 }); var ballShine = self.attachAsset('ballShine', { anchorX: 0.5, anchorY: 0.5, x: -20, y: -20 }); self.velocity = { x: 0, y: 0 }; self.gravity = 0.5; self.bounceDecay = 0.65; self.friction = 0.98; self.active = false; self.scored = false; self.update = function () { if (!self.active) { return; } // Apply physics self.velocity.y += self.gravity; self.x += self.velocity.x; self.y += self.velocity.y; // Apply wind if present if (currentLevel.wind) { self.velocity.x += currentLevel.wind / 50; } // Ball rotation based on horizontal movement ball.rotation += self.velocity.x / 30; // Check floor collision if (self.y > floorY - ball.height / 2) { self.y = floorY - ball.height / 2; self.velocity.y = -self.velocity.y * self.bounceDecay; self.velocity.x *= self.friction; LK.getSound('bounce').play(); // Stop ball if it's bounced enough and is slow if (Math.abs(self.velocity.y) < 2 && Math.abs(self.velocity.x) < 1) { self.active = false; shotsRemaining--; updateShotsText(); if (shotsRemaining <= 0 && !levelComplete) { LK.setTimeout(function () { if (!levelComplete) { LK.showGameOver(); } }, 1500); } else if (!levelComplete) { resetShot(); } } } // Check wall collisions if (self.x < ball.width / 2) { self.x = ball.width / 2; self.velocity.x = -self.velocity.x * self.bounceDecay; LK.getSound('bounce').play(); } else if (self.x > 2048 - ball.width / 2) { self.x = 2048 - ball.width / 2; self.velocity.x = -self.velocity.x * self.bounceDecay; LK.getSound('bounce').play(); } // Check obstacle collisions for (var i = 0; i < obstacles.length; i++) { if (self.intersects(obstacles[i])) { // Basic collision response var dx = self.x - obstacles[i].x; var dy = self.y - obstacles[i].y; var dist = Math.sqrt(dx * dx + dy * dy); var nx = dx / dist; var ny = dy / dist; // Push ball away from obstacle self.x += nx * 5; self.y += ny * 5; // Reflect velocity var dotProduct = self.velocity.x * nx + self.velocity.y * ny; self.velocity.x = (self.velocity.x - 2 * dotProduct * nx) * self.bounceDecay; self.velocity.y = (self.velocity.y - 2 * dotProduct * ny) * self.bounceDecay; LK.getSound('bounce').play(); } } // Check defenders for (var i = 0; i < defenders.length; i++) { if (self.intersects(defenders[i])) { // Simplified collision with defenders - just bounce back self.velocity.x = -self.velocity.x * self.bounceDecay; self.velocity.y = -self.velocity.y * self.bounceDecay; LK.getSound('bounce').play(); } } // Check hoop scoring if (!self.scored && self.intersects(basketHoop.net)) { // Ball position relative to hoop var ballToHoop = self.toLocal(basketHoop.net.position, basketHoop); // Only count if the ball is going down and is near the center of the hoop if (self.velocity.y > 0 && Math.abs(ballToHoop.x) < basketHoop.net.width / 4) { self.scored = true; levelScore++; LK.setScore(LK.getScore() + 100); updateScoreText(); LK.getSound('swish').play(); // Check if level is complete if (levelScore >= currentLevel.requiredScores) { levelComplete = true; // Update high score if necessary var highScores = storage.highScores; if (LK.getScore() > highScores[currentLevelIndex]) { highScores[currentLevelIndex] = LK.getScore(); storage.highScores = highScores; } // Advance to next level currentLevelIndex++; if (currentLevelIndex < levels.length) { LK.setTimeout(function () { levelTitleText.setText("LEVEL " + (currentLevelIndex + 1) + " COMPLETE!"); LK.effects.flashScreen(0x27ae60, 1000); LK.getSound('levelUp').play(); LK.setTimeout(function () { loadLevel(currentLevelIndex); }, 2000); }, 1000); } else { // Game completed LK.setTimeout(function () { levelTitleText.setText("GAME COMPLETED!"); LK.effects.flashScreen(0x27ae60, 1000); LK.getSound('levelUp').play(); LK.setTimeout(function () { LK.showYouWin(); }, 2000); }, 1000); } } else { // Continue level with next shot LK.setTimeout(function () { if (!levelComplete) { resetShot(); } }, 1500); } } } }; return self; }); var Defender = Container.expand(function () { var self = Container.call(this); // Create defender body var body = self.attachAsset('player', { anchorX: 0.5, anchorY: 1, x: 0, y: 0, tint: 0xe74c3c }); // Create defender head var head = self.attachAsset('playerHead', { anchorX: 0.5, anchorY: 1, x: 0, y: -body.height, tint: 0xe74c3c }); // For defender movement self.originalX = 0; self.moveSpeed = 0; self.moveRange = 0; self.moveDir = 1; self.setMoving = function (speed, range) { self.moveSpeed = speed; self.moveRange = range; self.originalX = self.x; }; self.update = function () { if (self.moveSpeed > 0) { self.x += self.moveSpeed * self.moveDir; if (self.x > self.originalX + self.moveRange) { self.x = self.originalX + self.moveRange; self.moveDir = -1; } else if (self.x < self.originalX - self.moveRange) { self.x = self.originalX - self.moveRange; self.moveDir = 1; } } }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); // Create player body var body = self.attachAsset('player', { anchorX: 0.5, anchorY: 1, x: 0, y: 0 }); // Create player head var head = self.attachAsset('playerHead', { anchorX: 0.5, anchorY: 1, x: 0, y: -body.height }); self.canShoot = true; self.down = function (x, y, obj) { if (gameState === "aiming" && self.canShoot) { startAiming(self.x, self.y - body.height / 2); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x3498db }); /**** * Game Code ****/ // Game state management var gameState = "start"; // "start", "aiming", "power", "shooting" var currentLevelIndex = storage.level - 1; var currentLevel; var levels = []; var floorY = 2600; var levelComplete = false; var levelScore = 0; var shotsRemaining = 5; // Game elements var basketball; var basketHoop; var player; var aimingSystem; var obstacles = []; var defenders = []; // UI elements var levelTitleText; var scoreText; var shotsText; var windText; var levelInfoText; // Level definitions function initLevels() { levels = [{ title: "Rookie Shot", description: "Make simple shots to learn the basics", hoopX: 1600, hoopY: 1600, playerX: 400, playerY: floorY, requiredScores: 3, shotsAllowed: 5, movingHoop: false, wind: 0, obstacles: [], defenders: [] }, { title: "Side Angle", description: "Shoot from the side", hoopX: 1700, hoopY: 1600, playerX: 300, playerY: floorY, requiredScores: 3, shotsAllowed: 5, movingHoop: false, wind: 0, obstacles: [], defenders: [] }, { title: "Moving Target", description: "Hit a moving basket", hoopX: 1500, hoopY: 1600, playerX: 400, playerY: floorY, requiredScores: 3, shotsAllowed: 6, movingHoop: true, hoopSpeed: 3, hoopRange: 300, wind: 0, obstacles: [], defenders: [] }, { title: "Obstacle Course", description: "Navigate around obstacles", hoopX: 1600, hoopY: 1600, playerX: 400, playerY: floorY, requiredScores: 2, shotsAllowed: 5, movingHoop: false, wind: 0, obstacles: [{ x: 1000, y: 2000, width: 100, height: 100 }], defenders: [] }, { title: "Defender Pressure", description: "Shoot past defenders", hoopX: 1600, hoopY: 1600, playerX: 400, playerY: floorY, requiredScores: 2, shotsAllowed: 5, movingHoop: false, wind: 0, obstacles: [], defenders: [{ x: 1000, y: floorY, speed: 0, range: 0 }] }, { title: "Windy Day", description: "Account for wind when shooting", hoopX: 1600, hoopY: 1600, playerX: 400, playerY: floorY, requiredScores: 2, shotsAllowed: 6, movingHoop: false, wind: 1.5, obstacles: [], defenders: [] }, { title: "Moving Defenders", description: "Time your shots carefully", hoopX: 1600, hoopY: 1600, playerX: 400, playerY: floorY, requiredScores: 2, shotsAllowed: 5, movingHoop: false, wind: 0, obstacles: [], defenders: [{ x: 800, y: floorY, speed: 4, range: 200 }, { x: 1200, y: floorY, speed: 3, range: 150 }] }, { title: "Complex Challenge", description: "Wind, moving hoop, and defenders", hoopX: 1600, hoopY: 1600, playerX: 400, playerY: floorY, requiredScores: 2, shotsAllowed: 6, movingHoop: true, hoopSpeed: 2, hoopRange: 200, wind: 1, obstacles: [], defenders: [{ x: 1000, y: floorY, speed: 3, range: 200 }] }, { title: "Obstacle Maze", description: "Navigate through multiple obstacles", hoopX: 1600, hoopY: 1600, playerX: 400, playerY: floorY, requiredScores: 2, shotsAllowed: 6, movingHoop: false, wind: 0.5, obstacles: [{ x: 800, y: 2000, width: 100, height: 100 }, { x: 1200, y: 1800, width: 100, height: 100 }], defenders: [] }, { title: "Championship", description: "Use all your skills for the final challenge", hoopX: 1600, hoopY: 1500, playerX: 400, playerY: floorY, requiredScores: 3, shotsAllowed: 5, movingHoop: true, hoopSpeed: 4, hoopRange: 300, wind: 1.2, obstacles: [{ x: 900, y: 2000, width: 100, height: 100 }], defenders: [{ x: 1200, y: floorY, speed: 5, range: 250 }] }]; } // Function to load a specific level function loadLevel(levelIndex) { // Clear previous level objects clearLevel(); // Set current level currentLevel = levels[levelIndex]; storage.level = levelIndex + 1; // Reset level state levelComplete = false; levelScore = 0; shotsRemaining = currentLevel.shotsAllowed; // Create floor var floor = game.addChild(LK.getAsset('floor', { anchorX: 0, anchorY: 0, x: 0, y: floorY })); // Create basketball hoop basketHoop = game.addChild(new BasketHoop()); basketHoop.x = currentLevel.hoopX; basketHoop.y = currentLevel.hoopY; if (currentLevel.movingHoop) { basketHoop.setMoving(currentLevel.hoopSpeed, currentLevel.hoopRange); } // Create player player = game.addChild(new Player()); player.x = currentLevel.playerX; player.y = currentLevel.playerY; // Create obstacles for (var i = 0; i < currentLevel.obstacles.length; i++) { var obstacleData = currentLevel.obstacles[i]; var obstacle = game.addChild(LK.getAsset('obstacle', { anchorX: 0.5, anchorY: 0.5, x: obstacleData.x, y: obstacleData.y })); obstacles.push(obstacle); } // Create defenders for (var i = 0; i < currentLevel.defenders.length; i++) { var defenderData = currentLevel.defenders[i]; var defender = game.addChild(new Defender()); defender.x = defenderData.x; defender.y = defenderData.y; if (defenderData.speed > 0) { defender.setMoving(defenderData.speed, defenderData.range); } defenders.push(defender); } // Create basketball basketball = game.addChild(new Basketball()); resetShot(); // Create aiming system aimingSystem = game.addChild(new AimingSystem()); aimingSystem.visible = false; // Update UI levelTitleText.setText("LEVEL " + (levelIndex + 1) + ": " + currentLevel.title); updateShotsText(); updateWindText(); levelInfoText.setText(currentLevel.description); // Reset game state gameState = "start"; // Show level intro effect LK.effects.flashScreen(0x3498db, 1000); } // Function to clear current level objects function clearLevel() { if (basketball) { basketball.destroy(); basketball = null; } if (basketHoop) { basketHoop.destroy(); basketHoop = null; } if (player) { player.destroy(); player = null; } if (aimingSystem) { aimingSystem.destroy(); aimingSystem = null; } // Clear obstacles for (var i = 0; i < obstacles.length; i++) { obstacles[i].destroy(); } obstacles = []; // Clear defenders for (var i = 0; i < defenders.length; i++) { defenders[i].destroy(); } defenders = []; } // Function to reset shot function resetShot() { basketball.x = player.x; basketball.y = player.y - 150; basketball.velocity.x = 0; basketball.velocity.y = 0; basketball.active = false; basketball.scored = false; gameState = "start"; // Make sure aiming system is hidden if (aimingSystem) { aimingSystem.visible = false; } } // Function to start aiming function startAiming(x, y) { gameState = "aiming"; aimingSystem.setPosition(x, y); aimingSystem.visible = true; } // Function to shoot the ball function shootBall() { var angle = aimingSystem.angle; var power = aimingSystem.power / 20; // Scale power appropriately basketball.velocity.x = Math.cos(angle * Math.PI / 180) * power; basketball.velocity.y = Math.sin(angle * Math.PI / 180) * power; basketball.active = true; gameState = "shooting"; aimingSystem.visible = false; } // Setup UI function setupUI() { // Level title text levelTitleText = new Text2("LEVEL 1", { size: 80, fill: 0xFFFFFF }); levelTitleText.anchor.set(0.5, 0); LK.gui.top.addChild(levelTitleText); // Score text scoreText = new Text2("SCORE: 0", { size: 60, fill: 0xFFFFFF }); scoreText.anchor.set(0, 0); scoreText.x = 150; LK.gui.topRight.addChild(scoreText); // Shots text shotsText = new Text2("SHOTS: 5", { size: 60, fill: 0xFFFFFF }); shotsText.anchor.set(0, 0); shotsText.x = 150; shotsText.y = 80; LK.gui.topRight.addChild(shotsText); // Wind text windText = new Text2("WIND: 0", { size: 60, fill: 0xFFFFFF }); windText.anchor.set(0, 0); windText.x = 150; windText.y = 160; LK.gui.topRight.addChild(windText); // Level info text levelInfoText = new Text2("Make simple shots to learn the basics", { size: 40, fill: 0xFFFFFF }); levelInfoText.anchor.set(0.5, 0); levelInfoText.y = 100; LK.gui.top.addChild(levelInfoText); } // Update UI helper functions function updateScoreText() { scoreText.setText("SCORE: " + LK.getScore()); } function updateShotsText() { shotsText.setText("SHOTS: " + shotsRemaining); } function updateWindText() { if (currentLevel && currentLevel.wind) { var direction = currentLevel.wind > 0 ? "→" : "←"; var strength = Math.abs(currentLevel.wind); var windStr = ""; for (var i = 0; i < Math.ceil(strength); i++) { windStr += direction; } windText.setText("WIND: " + windStr); } else { windText.setText("WIND: NONE"); } } // Input handling game.down = function (x, y, obj) { if (gameState === "aiming") { gameState = "power"; aimingSystem.startPowerPhase(); } else if (gameState === "power") { gameState = "shooting"; shootBall(); } else if (gameState === "start" && player && player.canShoot) { startAiming(player.x, player.y - 150); } }; game.move = function (x, y, obj) { if (gameState === "aiming" && aimingSystem && aimingSystem.visible) { // Calculate angle based on mouse position relative to player var dx = x - player.x; var dy = y - player.y; var angle = Math.atan2(dy, dx) * 180 / Math.PI; // Constrain angle for shooting upward only if (angle > 0) { angle = 0; } if (angle < -90) { angle = -90; } aimingSystem.setAngle(angle); } }; // Game update loop game.update = function () { // Update game objects if (basketball) { basketball.update(); } if (basketHoop) { basketHoop.update(); } if (aimingSystem) { aimingSystem.update(); } // Update defenders for (var i = 0; i < defenders.length; i++) { defenders[i].update(); } }; // Initialize game function initGame() { // Initialize levels initLevels(); // Setup UI setupUI(); // Reset score LK.setScore(0); updateScoreText(); // Load first level loadLevel(currentLevelIndex); // Play background music LK.playMusic('gameMusic'); } // Start the game initGame();
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,817 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1", {
+ level: 1,
+ highScores: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
+});
+
+/****
+* Classes
+****/
+var AimingSystem = Container.expand(function () {
+ var self = Container.call(this);
+ // Create the aim arrow
+ var arrow = self.attachAsset('aimArrow', {
+ anchorX: 0,
+ anchorY: 0.5,
+ x: 0,
+ y: 0
+ });
+ // Create power meter background
+ var powerMeter = self.attachAsset('powerMeter', {
+ anchorX: 0.5,
+ anchorY: 1,
+ x: 0,
+ y: 0
+ });
+ // Create power indicator
+ var powerIndicator = self.attachAsset('powerIndicator', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 0,
+ y: -powerMeter.height + 10
+ });
+ self.visible = false;
+ self.angle = -45;
+ self.power = 0;
+ self.powerIncreasing = true;
+ self.powerSpeed = 2;
+ self.maxPower = 100;
+ // Position offset from power meter to arrow
+ var offsetX = 100;
+ self.setPosition = function (x, y) {
+ self.x = x;
+ self.y = y;
+ powerMeter.x = x - offsetX;
+ powerMeter.y = y;
+ };
+ self.setAngle = function (angle) {
+ self.angle = angle;
+ arrow.rotation = angle * Math.PI / 180;
+ };
+ self.setPower = function (power) {
+ self.power = power;
+ var normalizedPower = power / self.maxPower;
+ powerIndicator.y = -powerMeter.height * normalizedPower + 10;
+ };
+ self.startPowerPhase = function () {
+ self.power = 0;
+ self.powerIncreasing = true;
+ self.visible = true;
+ };
+ self.update = function () {
+ if (gameState === "power" && self.visible) {
+ if (self.powerIncreasing) {
+ self.power += self.powerSpeed;
+ if (self.power >= self.maxPower) {
+ self.power = self.maxPower;
+ self.powerIncreasing = false;
+ }
+ } else {
+ self.power -= self.powerSpeed;
+ if (self.power <= 0) {
+ self.power = 0;
+ self.powerIncreasing = true;
+ }
+ }
+ self.setPower(self.power);
+ }
+ };
+ return self;
+});
+var BasketHoop = Container.expand(function () {
+ var self = Container.call(this);
+ // Create backboard
+ var backboard = self.attachAsset('backboard', {
+ anchorX: 0.5,
+ anchorY: 0,
+ x: 0,
+ y: 0
+ });
+ // Create rim
+ var hoop = self.attachAsset('hoop', {
+ anchorX: 0.5,
+ anchorY: 0,
+ x: 0,
+ y: backboard.height + 20
+ });
+ // Create net
+ self.net = self.attachAsset('net', {
+ anchorX: 0.5,
+ anchorY: 0,
+ x: 0,
+ y: backboard.height + 20 + hoop.height / 2,
+ alpha: 0.5
+ });
+ // For hoop movement
+ self.originalX = 0;
+ self.originalY = 0;
+ self.moveSpeed = 0;
+ self.moveRange = 0;
+ self.moveDir = 1;
+ self.setMoving = function (speed, range) {
+ self.moveSpeed = speed;
+ self.moveRange = range;
+ self.originalX = self.x;
+ };
+ self.update = function () {
+ if (self.moveSpeed > 0) {
+ self.x += self.moveSpeed * self.moveDir;
+ if (self.x > self.originalX + self.moveRange) {
+ self.x = self.originalX + self.moveRange;
+ self.moveDir = -1;
+ } else if (self.x < self.originalX - self.moveRange) {
+ self.x = self.originalX - self.moveRange;
+ self.moveDir = 1;
+ }
+ }
+ };
+ return self;
+});
+var Basketball = Container.expand(function () {
+ var self = Container.call(this);
+ var ball = self.attachAsset('ball', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ var ballShine = self.attachAsset('ballShine', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: -20,
+ y: -20
+ });
+ self.velocity = {
+ x: 0,
+ y: 0
+ };
+ self.gravity = 0.5;
+ self.bounceDecay = 0.65;
+ self.friction = 0.98;
+ self.active = false;
+ self.scored = false;
+ self.update = function () {
+ if (!self.active) {
+ return;
+ }
+ // Apply physics
+ self.velocity.y += self.gravity;
+ self.x += self.velocity.x;
+ self.y += self.velocity.y;
+ // Apply wind if present
+ if (currentLevel.wind) {
+ self.velocity.x += currentLevel.wind / 50;
+ }
+ // Ball rotation based on horizontal movement
+ ball.rotation += self.velocity.x / 30;
+ // Check floor collision
+ if (self.y > floorY - ball.height / 2) {
+ self.y = floorY - ball.height / 2;
+ self.velocity.y = -self.velocity.y * self.bounceDecay;
+ self.velocity.x *= self.friction;
+ LK.getSound('bounce').play();
+ // Stop ball if it's bounced enough and is slow
+ if (Math.abs(self.velocity.y) < 2 && Math.abs(self.velocity.x) < 1) {
+ self.active = false;
+ shotsRemaining--;
+ updateShotsText();
+ if (shotsRemaining <= 0 && !levelComplete) {
+ LK.setTimeout(function () {
+ if (!levelComplete) {
+ LK.showGameOver();
+ }
+ }, 1500);
+ } else if (!levelComplete) {
+ resetShot();
+ }
+ }
+ }
+ // Check wall collisions
+ if (self.x < ball.width / 2) {
+ self.x = ball.width / 2;
+ self.velocity.x = -self.velocity.x * self.bounceDecay;
+ LK.getSound('bounce').play();
+ } else if (self.x > 2048 - ball.width / 2) {
+ self.x = 2048 - ball.width / 2;
+ self.velocity.x = -self.velocity.x * self.bounceDecay;
+ LK.getSound('bounce').play();
+ }
+ // Check obstacle collisions
+ for (var i = 0; i < obstacles.length; i++) {
+ if (self.intersects(obstacles[i])) {
+ // Basic collision response
+ var dx = self.x - obstacles[i].x;
+ var dy = self.y - obstacles[i].y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ var nx = dx / dist;
+ var ny = dy / dist;
+ // Push ball away from obstacle
+ self.x += nx * 5;
+ self.y += ny * 5;
+ // Reflect velocity
+ var dotProduct = self.velocity.x * nx + self.velocity.y * ny;
+ self.velocity.x = (self.velocity.x - 2 * dotProduct * nx) * self.bounceDecay;
+ self.velocity.y = (self.velocity.y - 2 * dotProduct * ny) * self.bounceDecay;
+ LK.getSound('bounce').play();
+ }
+ }
+ // Check defenders
+ for (var i = 0; i < defenders.length; i++) {
+ if (self.intersects(defenders[i])) {
+ // Simplified collision with defenders - just bounce back
+ self.velocity.x = -self.velocity.x * self.bounceDecay;
+ self.velocity.y = -self.velocity.y * self.bounceDecay;
+ LK.getSound('bounce').play();
+ }
+ }
+ // Check hoop scoring
+ if (!self.scored && self.intersects(basketHoop.net)) {
+ // Ball position relative to hoop
+ var ballToHoop = self.toLocal(basketHoop.net.position, basketHoop);
+ // Only count if the ball is going down and is near the center of the hoop
+ if (self.velocity.y > 0 && Math.abs(ballToHoop.x) < basketHoop.net.width / 4) {
+ self.scored = true;
+ levelScore++;
+ LK.setScore(LK.getScore() + 100);
+ updateScoreText();
+ LK.getSound('swish').play();
+ // Check if level is complete
+ if (levelScore >= currentLevel.requiredScores) {
+ levelComplete = true;
+ // Update high score if necessary
+ var highScores = storage.highScores;
+ if (LK.getScore() > highScores[currentLevelIndex]) {
+ highScores[currentLevelIndex] = LK.getScore();
+ storage.highScores = highScores;
+ }
+ // Advance to next level
+ currentLevelIndex++;
+ if (currentLevelIndex < levels.length) {
+ LK.setTimeout(function () {
+ levelTitleText.setText("LEVEL " + (currentLevelIndex + 1) + " COMPLETE!");
+ LK.effects.flashScreen(0x27ae60, 1000);
+ LK.getSound('levelUp').play();
+ LK.setTimeout(function () {
+ loadLevel(currentLevelIndex);
+ }, 2000);
+ }, 1000);
+ } else {
+ // Game completed
+ LK.setTimeout(function () {
+ levelTitleText.setText("GAME COMPLETED!");
+ LK.effects.flashScreen(0x27ae60, 1000);
+ LK.getSound('levelUp').play();
+ LK.setTimeout(function () {
+ LK.showYouWin();
+ }, 2000);
+ }, 1000);
+ }
+ } else {
+ // Continue level with next shot
+ LK.setTimeout(function () {
+ if (!levelComplete) {
+ resetShot();
+ }
+ }, 1500);
+ }
+ }
+ }
+ };
+ return self;
+});
+var Defender = Container.expand(function () {
+ var self = Container.call(this);
+ // Create defender body
+ var body = self.attachAsset('player', {
+ anchorX: 0.5,
+ anchorY: 1,
+ x: 0,
+ y: 0,
+ tint: 0xe74c3c
+ });
+ // Create defender head
+ var head = self.attachAsset('playerHead', {
+ anchorX: 0.5,
+ anchorY: 1,
+ x: 0,
+ y: -body.height,
+ tint: 0xe74c3c
+ });
+ // For defender movement
+ self.originalX = 0;
+ self.moveSpeed = 0;
+ self.moveRange = 0;
+ self.moveDir = 1;
+ self.setMoving = function (speed, range) {
+ self.moveSpeed = speed;
+ self.moveRange = range;
+ self.originalX = self.x;
+ };
+ self.update = function () {
+ if (self.moveSpeed > 0) {
+ self.x += self.moveSpeed * self.moveDir;
+ if (self.x > self.originalX + self.moveRange) {
+ self.x = self.originalX + self.moveRange;
+ self.moveDir = -1;
+ } else if (self.x < self.originalX - self.moveRange) {
+ self.x = self.originalX - self.moveRange;
+ self.moveDir = 1;
+ }
+ }
+ };
+ return self;
+});
+var Player = Container.expand(function () {
+ var self = Container.call(this);
+ // Create player body
+ var body = self.attachAsset('player', {
+ anchorX: 0.5,
+ anchorY: 1,
+ x: 0,
+ y: 0
+ });
+ // Create player head
+ var head = self.attachAsset('playerHead', {
+ anchorX: 0.5,
+ anchorY: 1,
+ x: 0,
+ y: -body.height
+ });
+ self.canShoot = true;
+ self.down = function (x, y, obj) {
+ if (gameState === "aiming" && self.canShoot) {
+ startAiming(self.x, self.y - body.height / 2);
+ }
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x3498db
+});
+
+/****
+* Game Code
+****/
+// Game state management
+var gameState = "start"; // "start", "aiming", "power", "shooting"
+var currentLevelIndex = storage.level - 1;
+var currentLevel;
+var levels = [];
+var floorY = 2600;
+var levelComplete = false;
+var levelScore = 0;
+var shotsRemaining = 5;
+// Game elements
+var basketball;
+var basketHoop;
+var player;
+var aimingSystem;
+var obstacles = [];
+var defenders = [];
+// UI elements
+var levelTitleText;
+var scoreText;
+var shotsText;
+var windText;
+var levelInfoText;
+// Level definitions
+function initLevels() {
+ levels = [{
+ title: "Rookie Shot",
+ description: "Make simple shots to learn the basics",
+ hoopX: 1600,
+ hoopY: 1600,
+ playerX: 400,
+ playerY: floorY,
+ requiredScores: 3,
+ shotsAllowed: 5,
+ movingHoop: false,
+ wind: 0,
+ obstacles: [],
+ defenders: []
+ }, {
+ title: "Side Angle",
+ description: "Shoot from the side",
+ hoopX: 1700,
+ hoopY: 1600,
+ playerX: 300,
+ playerY: floorY,
+ requiredScores: 3,
+ shotsAllowed: 5,
+ movingHoop: false,
+ wind: 0,
+ obstacles: [],
+ defenders: []
+ }, {
+ title: "Moving Target",
+ description: "Hit a moving basket",
+ hoopX: 1500,
+ hoopY: 1600,
+ playerX: 400,
+ playerY: floorY,
+ requiredScores: 3,
+ shotsAllowed: 6,
+ movingHoop: true,
+ hoopSpeed: 3,
+ hoopRange: 300,
+ wind: 0,
+ obstacles: [],
+ defenders: []
+ }, {
+ title: "Obstacle Course",
+ description: "Navigate around obstacles",
+ hoopX: 1600,
+ hoopY: 1600,
+ playerX: 400,
+ playerY: floorY,
+ requiredScores: 2,
+ shotsAllowed: 5,
+ movingHoop: false,
+ wind: 0,
+ obstacles: [{
+ x: 1000,
+ y: 2000,
+ width: 100,
+ height: 100
+ }],
+ defenders: []
+ }, {
+ title: "Defender Pressure",
+ description: "Shoot past defenders",
+ hoopX: 1600,
+ hoopY: 1600,
+ playerX: 400,
+ playerY: floorY,
+ requiredScores: 2,
+ shotsAllowed: 5,
+ movingHoop: false,
+ wind: 0,
+ obstacles: [],
+ defenders: [{
+ x: 1000,
+ y: floorY,
+ speed: 0,
+ range: 0
+ }]
+ }, {
+ title: "Windy Day",
+ description: "Account for wind when shooting",
+ hoopX: 1600,
+ hoopY: 1600,
+ playerX: 400,
+ playerY: floorY,
+ requiredScores: 2,
+ shotsAllowed: 6,
+ movingHoop: false,
+ wind: 1.5,
+ obstacles: [],
+ defenders: []
+ }, {
+ title: "Moving Defenders",
+ description: "Time your shots carefully",
+ hoopX: 1600,
+ hoopY: 1600,
+ playerX: 400,
+ playerY: floorY,
+ requiredScores: 2,
+ shotsAllowed: 5,
+ movingHoop: false,
+ wind: 0,
+ obstacles: [],
+ defenders: [{
+ x: 800,
+ y: floorY,
+ speed: 4,
+ range: 200
+ }, {
+ x: 1200,
+ y: floorY,
+ speed: 3,
+ range: 150
+ }]
+ }, {
+ title: "Complex Challenge",
+ description: "Wind, moving hoop, and defenders",
+ hoopX: 1600,
+ hoopY: 1600,
+ playerX: 400,
+ playerY: floorY,
+ requiredScores: 2,
+ shotsAllowed: 6,
+ movingHoop: true,
+ hoopSpeed: 2,
+ hoopRange: 200,
+ wind: 1,
+ obstacles: [],
+ defenders: [{
+ x: 1000,
+ y: floorY,
+ speed: 3,
+ range: 200
+ }]
+ }, {
+ title: "Obstacle Maze",
+ description: "Navigate through multiple obstacles",
+ hoopX: 1600,
+ hoopY: 1600,
+ playerX: 400,
+ playerY: floorY,
+ requiredScores: 2,
+ shotsAllowed: 6,
+ movingHoop: false,
+ wind: 0.5,
+ obstacles: [{
+ x: 800,
+ y: 2000,
+ width: 100,
+ height: 100
+ }, {
+ x: 1200,
+ y: 1800,
+ width: 100,
+ height: 100
+ }],
+ defenders: []
+ }, {
+ title: "Championship",
+ description: "Use all your skills for the final challenge",
+ hoopX: 1600,
+ hoopY: 1500,
+ playerX: 400,
+ playerY: floorY,
+ requiredScores: 3,
+ shotsAllowed: 5,
+ movingHoop: true,
+ hoopSpeed: 4,
+ hoopRange: 300,
+ wind: 1.2,
+ obstacles: [{
+ x: 900,
+ y: 2000,
+ width: 100,
+ height: 100
+ }],
+ defenders: [{
+ x: 1200,
+ y: floorY,
+ speed: 5,
+ range: 250
+ }]
+ }];
+}
+// Function to load a specific level
+function loadLevel(levelIndex) {
+ // Clear previous level objects
+ clearLevel();
+ // Set current level
+ currentLevel = levels[levelIndex];
+ storage.level = levelIndex + 1;
+ // Reset level state
+ levelComplete = false;
+ levelScore = 0;
+ shotsRemaining = currentLevel.shotsAllowed;
+ // Create floor
+ var floor = game.addChild(LK.getAsset('floor', {
+ anchorX: 0,
+ anchorY: 0,
+ x: 0,
+ y: floorY
+ }));
+ // Create basketball hoop
+ basketHoop = game.addChild(new BasketHoop());
+ basketHoop.x = currentLevel.hoopX;
+ basketHoop.y = currentLevel.hoopY;
+ if (currentLevel.movingHoop) {
+ basketHoop.setMoving(currentLevel.hoopSpeed, currentLevel.hoopRange);
+ }
+ // Create player
+ player = game.addChild(new Player());
+ player.x = currentLevel.playerX;
+ player.y = currentLevel.playerY;
+ // Create obstacles
+ for (var i = 0; i < currentLevel.obstacles.length; i++) {
+ var obstacleData = currentLevel.obstacles[i];
+ var obstacle = game.addChild(LK.getAsset('obstacle', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: obstacleData.x,
+ y: obstacleData.y
+ }));
+ obstacles.push(obstacle);
+ }
+ // Create defenders
+ for (var i = 0; i < currentLevel.defenders.length; i++) {
+ var defenderData = currentLevel.defenders[i];
+ var defender = game.addChild(new Defender());
+ defender.x = defenderData.x;
+ defender.y = defenderData.y;
+ if (defenderData.speed > 0) {
+ defender.setMoving(defenderData.speed, defenderData.range);
+ }
+ defenders.push(defender);
+ }
+ // Create basketball
+ basketball = game.addChild(new Basketball());
+ resetShot();
+ // Create aiming system
+ aimingSystem = game.addChild(new AimingSystem());
+ aimingSystem.visible = false;
+ // Update UI
+ levelTitleText.setText("LEVEL " + (levelIndex + 1) + ": " + currentLevel.title);
+ updateShotsText();
+ updateWindText();
+ levelInfoText.setText(currentLevel.description);
+ // Reset game state
+ gameState = "start";
+ // Show level intro effect
+ LK.effects.flashScreen(0x3498db, 1000);
+}
+// Function to clear current level objects
+function clearLevel() {
+ if (basketball) {
+ basketball.destroy();
+ basketball = null;
+ }
+ if (basketHoop) {
+ basketHoop.destroy();
+ basketHoop = null;
+ }
+ if (player) {
+ player.destroy();
+ player = null;
+ }
+ if (aimingSystem) {
+ aimingSystem.destroy();
+ aimingSystem = null;
+ }
+ // Clear obstacles
+ for (var i = 0; i < obstacles.length; i++) {
+ obstacles[i].destroy();
+ }
+ obstacles = [];
+ // Clear defenders
+ for (var i = 0; i < defenders.length; i++) {
+ defenders[i].destroy();
+ }
+ defenders = [];
+}
+// Function to reset shot
+function resetShot() {
+ basketball.x = player.x;
+ basketball.y = player.y - 150;
+ basketball.velocity.x = 0;
+ basketball.velocity.y = 0;
+ basketball.active = false;
+ basketball.scored = false;
+ gameState = "start";
+ // Make sure aiming system is hidden
+ if (aimingSystem) {
+ aimingSystem.visible = false;
+ }
+}
+// Function to start aiming
+function startAiming(x, y) {
+ gameState = "aiming";
+ aimingSystem.setPosition(x, y);
+ aimingSystem.visible = true;
+}
+// Function to shoot the ball
+function shootBall() {
+ var angle = aimingSystem.angle;
+ var power = aimingSystem.power / 20; // Scale power appropriately
+ basketball.velocity.x = Math.cos(angle * Math.PI / 180) * power;
+ basketball.velocity.y = Math.sin(angle * Math.PI / 180) * power;
+ basketball.active = true;
+ gameState = "shooting";
+ aimingSystem.visible = false;
+}
+// Setup UI
+function setupUI() {
+ // Level title text
+ levelTitleText = new Text2("LEVEL 1", {
+ size: 80,
+ fill: 0xFFFFFF
+ });
+ levelTitleText.anchor.set(0.5, 0);
+ LK.gui.top.addChild(levelTitleText);
+ // Score text
+ scoreText = new Text2("SCORE: 0", {
+ size: 60,
+ fill: 0xFFFFFF
+ });
+ scoreText.anchor.set(0, 0);
+ scoreText.x = 150;
+ LK.gui.topRight.addChild(scoreText);
+ // Shots text
+ shotsText = new Text2("SHOTS: 5", {
+ size: 60,
+ fill: 0xFFFFFF
+ });
+ shotsText.anchor.set(0, 0);
+ shotsText.x = 150;
+ shotsText.y = 80;
+ LK.gui.topRight.addChild(shotsText);
+ // Wind text
+ windText = new Text2("WIND: 0", {
+ size: 60,
+ fill: 0xFFFFFF
+ });
+ windText.anchor.set(0, 0);
+ windText.x = 150;
+ windText.y = 160;
+ LK.gui.topRight.addChild(windText);
+ // Level info text
+ levelInfoText = new Text2("Make simple shots to learn the basics", {
+ size: 40,
+ fill: 0xFFFFFF
+ });
+ levelInfoText.anchor.set(0.5, 0);
+ levelInfoText.y = 100;
+ LK.gui.top.addChild(levelInfoText);
+}
+// Update UI helper functions
+function updateScoreText() {
+ scoreText.setText("SCORE: " + LK.getScore());
+}
+function updateShotsText() {
+ shotsText.setText("SHOTS: " + shotsRemaining);
+}
+function updateWindText() {
+ if (currentLevel && currentLevel.wind) {
+ var direction = currentLevel.wind > 0 ? "→" : "←";
+ var strength = Math.abs(currentLevel.wind);
+ var windStr = "";
+ for (var i = 0; i < Math.ceil(strength); i++) {
+ windStr += direction;
+ }
+ windText.setText("WIND: " + windStr);
+ } else {
+ windText.setText("WIND: NONE");
+ }
+}
+// Input handling
+game.down = function (x, y, obj) {
+ if (gameState === "aiming") {
+ gameState = "power";
+ aimingSystem.startPowerPhase();
+ } else if (gameState === "power") {
+ gameState = "shooting";
+ shootBall();
+ } else if (gameState === "start" && player && player.canShoot) {
+ startAiming(player.x, player.y - 150);
+ }
+};
+game.move = function (x, y, obj) {
+ if (gameState === "aiming" && aimingSystem && aimingSystem.visible) {
+ // Calculate angle based on mouse position relative to player
+ var dx = x - player.x;
+ var dy = y - player.y;
+ var angle = Math.atan2(dy, dx) * 180 / Math.PI;
+ // Constrain angle for shooting upward only
+ if (angle > 0) {
+ angle = 0;
+ }
+ if (angle < -90) {
+ angle = -90;
+ }
+ aimingSystem.setAngle(angle);
+ }
+};
+// Game update loop
+game.update = function () {
+ // Update game objects
+ if (basketball) {
+ basketball.update();
+ }
+ if (basketHoop) {
+ basketHoop.update();
+ }
+ if (aimingSystem) {
+ aimingSystem.update();
+ }
+ // Update defenders
+ for (var i = 0; i < defenders.length; i++) {
+ defenders[i].update();
+ }
+};
+// Initialize game
+function initGame() {
+ // Initialize levels
+ initLevels();
+ // Setup UI
+ setupUI();
+ // Reset score
+ LK.setScore(0);
+ updateScoreText();
+ // Load first level
+ loadLevel(currentLevelIndex);
+ // Play background music
+ LK.playMusic('gameMusic');
+}
+// Start the game
+initGame();
\ No newline at end of file