/****
* 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());
};