/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Ball = Container.expand(function () { var self = Container.call(this); var ballGraphics = self.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5 }); self.velocityX = 0; self.velocityY = 0; self.gravity = 0.8; self.isMoving = false; self.hasScored = false; self["throw"] = function (targetX, targetY) { if (self.isMoving) return; self.isMoving = true; self.hasScored = false; // Calculate trajectory to reach target position var deltaX = targetX - self.x; var deltaY = targetY - self.y; // Calculate time to reach target (assuming parabolic trajectory) var timeToTarget = Math.sqrt(Math.abs(deltaY) / self.gravity) * 2; if (timeToTarget < 2.0) timeToTarget = 2.0; // Minimum time for slower ball movement if (timeToTarget > 5) timeToTarget = 5; // Maximum time to prevent too slow throws // Calculate velocities needed to reach target self.velocityX = deltaX / timeToTarget; self.velocityY = deltaY / timeToTarget - self.gravity * timeToTarget / 2; LK.getSound('swoosh').play(); }; self.reset = function () { self.x = character.x; self.y = character.y - 50; self.velocityX = 0; self.velocityY = 0; self.isMoving = false; self.hasScored = false; }; self.update = function () { if (!self.isMoving) return; // Apply physics self.x += self.velocityX; self.y += self.velocityY; self.velocityY += self.gravity; // Check if ball goes off screen if (self.y > 2732 + 100 || self.x < -100 || self.x > 2148) { missedShots++; character.catchBall(self); // Check if we've missed 3 times if (missedShots >= 3) { LK.showGameOver(); return; } } // Check collision with hoop - ball must hit from above if (!self.hasScored && self.velocityY > 0) { var hoopLeft = hoop.x - 100; var hoopRight = hoop.x + 100; var hoopTop = hoop.y - 20; // Track if ball was above hoop in previous frame if (self.lastY === undefined) self.lastY = self.y; // Check if ball hits the top of the hoop (was above hoop, now at hoop level) if (self.x > hoopLeft && self.x < hoopRight && self.lastY <= hoopTop && self.y >= hoopTop) { // Score! LK.setScore(LK.getScore() + 1); pointsThisLevel++; scoreTxt.setText(LK.getScore()); self.hasScored = true; LK.getSound('score').play(); // Flash effect LK.effects.flashObject(hoop, 0x00ff00, 500); // Return ball to character after short delay LK.setTimeout(function () { character.catchBall(self); }, 1000); // Check level progression if (pointsThisLevel >= pointsToNextLevel) { currentLevel++; storage.level = currentLevel; pointsThisLevel = 0; pointsToNextLevel = 8 + currentLevel * 2; hoop.speed = 6 + currentLevel * 2; // Update hoop speed LK.effects.flashScreen(0x00ff00, 1000); // Level up flash } // Check win condition (level 10) if (currentLevel >= 10) { LK.showYouWin(); } } // Update last position for next frame self.lastY = self.y; } }; return self; }); var Character = Container.expand(function () { var self = Container.call(this); var characterGraphics = self.attachAsset('character', { anchorX: 0.5, anchorY: 0.5 }); self.isHoldingBall = true; self.ball = null; self.moveSpeed = 8; self.throwBall = function (targetX, targetY) { if (!self.isHoldingBall || !self.ball) return; self.isHoldingBall = false; self.ball["throw"](targetX, targetY); }; self.catchBall = function (ball) { if (self.isHoldingBall) return; self.isHoldingBall = true; ball.reset(); ball.x = self.x; ball.y = self.y - 50; }; self.update = function () { if (self.isHoldingBall && self.ball) { self.ball.x = self.x; self.ball.y = self.y - 50; } }; return self; }); var Hoop = Container.expand(function () { var self = Container.call(this); // Create backboard var backboard = self.attachAsset('backboard', { anchorX: 0.5, anchorY: 0.5, x: 110, y: -40 }); // Create hoop var hoopGraphics = self.attachAsset('hoop', { anchorX: 0.5, anchorY: 0.5 }); // Create net var net = self.attachAsset('net', { anchorX: 0.5, anchorY: 0, y: 20, alpha: 0.3 }); self.direction = 1; self.speed = 6 + currentLevel * 2; // Speed increases with level self.update = function () { // Move hoop horizontally with faster speed self.x += self.speed * self.direction; // Bounce off screen edges if (self.x <= 200) { self.x = 200; self.direction = 1; } if (self.x >= 1848) { self.x = 1848; self.direction = -1; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB }); /**** * Game Code ****/ // Game variables var missedShots = 0; var maxMisses = 3; // Fixed at 3 misses for game over var currentLevel = storage.level || 1; var pointsThisLevel = 0; var pointsToNextLevel = 8 + currentLevel * 2; // More points needed for higher levels // Create score display var scoreTxt = new Text2('0', { size: 120, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Create missed shots display var missedTxt = new Text2('Misses: 0/' + maxMisses, { size: 80, fill: 0xFFFFFF }); missedTxt.anchor.set(0, 0); missedTxt.x = 50; missedTxt.y = 50; LK.gui.topLeft.addChild(missedTxt); // Create level display var levelTxt = new Text2('Level: ' + currentLevel, { size: 80, fill: 0xFFD700 }); levelTxt.anchor.set(1, 0); levelTxt.x = -50; levelTxt.y = 50; LK.gui.topRight.addChild(levelTxt); // Create progress display var progressTxt = new Text2('Progress: 0/' + pointsToNextLevel, { size: 60, fill: 0xFFFFFF }); progressTxt.anchor.set(0.5, 0); progressTxt.y = 150; LK.gui.top.addChild(progressTxt); // Create instructions var instructionTxt = new Text2('Drag character to move, tap far to throw ball!', { size: 60, fill: 0xFFFFFF }); instructionTxt.anchor.set(0.5, 1); LK.gui.bottom.addChild(instructionTxt); // Create game objects var hoop = game.addChild(new Hoop()); hoop.x = 1024; hoop.y = 2400; var character = game.addChild(new Character()); character.x = 1024; character.y = 600; var ball = game.addChild(new Ball()); character.ball = ball; ball.reset(); // Touch controls for character movement and ball throwing var isDragging = false; game.down = function (x, y, obj) { isDragging = true; if (character.isHoldingBall) { // If tapping far from character, throw ball var distanceFromCharacter = Math.sqrt((x - character.x) * (x - character.x) + (y - character.y) * (y - character.y)); if (distanceFromCharacter > 150) { character.throwBall(x, y); isDragging = false; } } }; game.move = function (x, y, obj) { if (isDragging && character.isHoldingBall) { character.x = x; if (character.x < 100) character.x = 100; if (character.x > 1948) character.x = 1948; } }; game.up = function (x, y, obj) { isDragging = false; }; // Main game loop game.update = function () { // Update missed shots display missedTxt.setText('Misses: ' + missedShots + '/' + maxMisses); // Update level display levelTxt.setText('Level: ' + currentLevel); // Update progress display progressTxt.setText('Progress: ' + pointsThisLevel + '/' + pointsToNextLevel); // Check game over condition if (missedShots >= maxMisses) { LK.showGameOver(); } // Update score display scoreTxt.setText(LK.getScore()); };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Ball = Container.expand(function () {
var self = Container.call(this);
var ballGraphics = self.attachAsset('ball', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.gravity = 0.8;
self.isMoving = false;
self.hasScored = false;
self["throw"] = function (targetX, targetY) {
if (self.isMoving) return;
self.isMoving = true;
self.hasScored = false;
// Calculate trajectory to reach target position
var deltaX = targetX - self.x;
var deltaY = targetY - self.y;
// Calculate time to reach target (assuming parabolic trajectory)
var timeToTarget = Math.sqrt(Math.abs(deltaY) / self.gravity) * 2;
if (timeToTarget < 2.0) timeToTarget = 2.0; // Minimum time for slower ball movement
if (timeToTarget > 5) timeToTarget = 5; // Maximum time to prevent too slow throws
// Calculate velocities needed to reach target
self.velocityX = deltaX / timeToTarget;
self.velocityY = deltaY / timeToTarget - self.gravity * timeToTarget / 2;
LK.getSound('swoosh').play();
};
self.reset = function () {
self.x = character.x;
self.y = character.y - 50;
self.velocityX = 0;
self.velocityY = 0;
self.isMoving = false;
self.hasScored = false;
};
self.update = function () {
if (!self.isMoving) return;
// Apply physics
self.x += self.velocityX;
self.y += self.velocityY;
self.velocityY += self.gravity;
// Check if ball goes off screen
if (self.y > 2732 + 100 || self.x < -100 || self.x > 2148) {
missedShots++;
character.catchBall(self);
// Check if we've missed 3 times
if (missedShots >= 3) {
LK.showGameOver();
return;
}
}
// Check collision with hoop - ball must hit from above
if (!self.hasScored && self.velocityY > 0) {
var hoopLeft = hoop.x - 100;
var hoopRight = hoop.x + 100;
var hoopTop = hoop.y - 20;
// Track if ball was above hoop in previous frame
if (self.lastY === undefined) self.lastY = self.y;
// Check if ball hits the top of the hoop (was above hoop, now at hoop level)
if (self.x > hoopLeft && self.x < hoopRight && self.lastY <= hoopTop && self.y >= hoopTop) {
// Score!
LK.setScore(LK.getScore() + 1);
pointsThisLevel++;
scoreTxt.setText(LK.getScore());
self.hasScored = true;
LK.getSound('score').play();
// Flash effect
LK.effects.flashObject(hoop, 0x00ff00, 500);
// Return ball to character after short delay
LK.setTimeout(function () {
character.catchBall(self);
}, 1000);
// Check level progression
if (pointsThisLevel >= pointsToNextLevel) {
currentLevel++;
storage.level = currentLevel;
pointsThisLevel = 0;
pointsToNextLevel = 8 + currentLevel * 2;
hoop.speed = 6 + currentLevel * 2; // Update hoop speed
LK.effects.flashScreen(0x00ff00, 1000); // Level up flash
}
// Check win condition (level 10)
if (currentLevel >= 10) {
LK.showYouWin();
}
}
// Update last position for next frame
self.lastY = self.y;
}
};
return self;
});
var Character = Container.expand(function () {
var self = Container.call(this);
var characterGraphics = self.attachAsset('character', {
anchorX: 0.5,
anchorY: 0.5
});
self.isHoldingBall = true;
self.ball = null;
self.moveSpeed = 8;
self.throwBall = function (targetX, targetY) {
if (!self.isHoldingBall || !self.ball) return;
self.isHoldingBall = false;
self.ball["throw"](targetX, targetY);
};
self.catchBall = function (ball) {
if (self.isHoldingBall) return;
self.isHoldingBall = true;
ball.reset();
ball.x = self.x;
ball.y = self.y - 50;
};
self.update = function () {
if (self.isHoldingBall && self.ball) {
self.ball.x = self.x;
self.ball.y = self.y - 50;
}
};
return self;
});
var Hoop = Container.expand(function () {
var self = Container.call(this);
// Create backboard
var backboard = self.attachAsset('backboard', {
anchorX: 0.5,
anchorY: 0.5,
x: 110,
y: -40
});
// Create hoop
var hoopGraphics = self.attachAsset('hoop', {
anchorX: 0.5,
anchorY: 0.5
});
// Create net
var net = self.attachAsset('net', {
anchorX: 0.5,
anchorY: 0,
y: 20,
alpha: 0.3
});
self.direction = 1;
self.speed = 6 + currentLevel * 2; // Speed increases with level
self.update = function () {
// Move hoop horizontally with faster speed
self.x += self.speed * self.direction;
// Bounce off screen edges
if (self.x <= 200) {
self.x = 200;
self.direction = 1;
}
if (self.x >= 1848) {
self.x = 1848;
self.direction = -1;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Game variables
var missedShots = 0;
var maxMisses = 3; // Fixed at 3 misses for game over
var currentLevel = storage.level || 1;
var pointsThisLevel = 0;
var pointsToNextLevel = 8 + currentLevel * 2; // More points needed for higher levels
// Create score display
var scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Create missed shots display
var missedTxt = new Text2('Misses: 0/' + maxMisses, {
size: 80,
fill: 0xFFFFFF
});
missedTxt.anchor.set(0, 0);
missedTxt.x = 50;
missedTxt.y = 50;
LK.gui.topLeft.addChild(missedTxt);
// Create level display
var levelTxt = new Text2('Level: ' + currentLevel, {
size: 80,
fill: 0xFFD700
});
levelTxt.anchor.set(1, 0);
levelTxt.x = -50;
levelTxt.y = 50;
LK.gui.topRight.addChild(levelTxt);
// Create progress display
var progressTxt = new Text2('Progress: 0/' + pointsToNextLevel, {
size: 60,
fill: 0xFFFFFF
});
progressTxt.anchor.set(0.5, 0);
progressTxt.y = 150;
LK.gui.top.addChild(progressTxt);
// Create instructions
var instructionTxt = new Text2('Drag character to move, tap far to throw ball!', {
size: 60,
fill: 0xFFFFFF
});
instructionTxt.anchor.set(0.5, 1);
LK.gui.bottom.addChild(instructionTxt);
// Create game objects
var hoop = game.addChild(new Hoop());
hoop.x = 1024;
hoop.y = 2400;
var character = game.addChild(new Character());
character.x = 1024;
character.y = 600;
var ball = game.addChild(new Ball());
character.ball = ball;
ball.reset();
// Touch controls for character movement and ball throwing
var isDragging = false;
game.down = function (x, y, obj) {
isDragging = true;
if (character.isHoldingBall) {
// If tapping far from character, throw ball
var distanceFromCharacter = Math.sqrt((x - character.x) * (x - character.x) + (y - character.y) * (y - character.y));
if (distanceFromCharacter > 150) {
character.throwBall(x, y);
isDragging = false;
}
}
};
game.move = function (x, y, obj) {
if (isDragging && character.isHoldingBall) {
character.x = x;
if (character.x < 100) character.x = 100;
if (character.x > 1948) character.x = 1948;
}
};
game.up = function (x, y, obj) {
isDragging = false;
};
// Main game loop
game.update = function () {
// Update missed shots display
missedTxt.setText('Misses: ' + missedShots + '/' + maxMisses);
// Update level display
levelTxt.setText('Level: ' + currentLevel);
// Update progress display
progressTxt.setText('Progress: ' + pointsThisLevel + '/' + pointsToNextLevel);
// Check game over condition
if (missedShots >= maxMisses) {
LK.showGameOver();
}
// Update score display
scoreTxt.setText(LK.getScore());
};