/**** * 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); self.hasScored = false; self.hasBounced = false; var ballGraphics = LK.getAsset('ball', { anchorX: 0.5, anchorY: 0.5 }); self.addChild(ballGraphics); self.speed = { x: 0, y: 0 }; self.hasThrown = false; self._move_migrated = function () { self.speed.y += 3.2; self.x += self.speed.x; self.y += self.speed.y; self.rotation += self.speed.x * 0.01; if (self.hasThrown) { var targetScale = 0.8; self.scale.x += (targetScale - self.scale.x) * 0.05; self.scale.y += (targetScale - self.scale.y) * 0.05; } if (self.hasScored) { self.alpha -= 0.15; } else { self.alpha += 0.15; if (self.alpha > 1) { self.alpha = 1; } } }; self.bounceOffPoint = function (x, y, elasticity) { var dx = self.x - x; var dy = self.y - y; var angle = Math.atan2(dy, dx); var speed = Math.sqrt(self.speed.x * self.speed.x + self.speed.y * self.speed.y); self.speed.x = Math.cos(angle) * speed * elasticity; self.speed.y = Math.sin(angle) * speed * elasticity; }; self.angleTo = function (x, y) { var dx = self.x - x; var dy = self.y - y; return Math.atan2(dy, dx); }; self.distanceTo = function (x, y) { var dx = self.x - x; var dy = self.y - y; return Math.sqrt(dx * dx + dy * dy); }; self.moveToDistance = function (x, y, distance) { var angle = self.angleTo(x, y); self.x = x + Math.cos(angle) * (distance * 1.05); self.y = y + Math.sin(angle) * (distance * 1.05); }; }); var Hoop = Container.expand(function () { var self = Container.call(this); self.setScore = function (score) { self.scoreLabel.setText(score.toString()); }; self.moveTo = function (newX, newY, hoopRim) { var dx = (newX - self.x) / 60; var dy = (newY - self.y) / 60; var steps = 0; var interval = LK.setInterval(function () { self.x += dx; self.y += dy; hoopRim.x = self.x; hoopRim.y = self.y + self.children[1].y - 250; steps++; if (steps >= 60) { LK.clearInterval(interval); } }); }; var backboardGraphics = LK.getAsset('backboard', { anchorX: 0.5, anchorY: 0.5 }); backboardGraphics.y -= 250; self.addChild(backboardGraphics); self.hoopRimGraphics = LK.getAsset('hoopRim', { anchorX: 0.5, anchorY: 0.5 }); self.hoopRimGraphics.y = backboardGraphics.height / 2 - 550 + 20 + 120 + 150 + 100; self.hoopRimGraphics.alpha = 0; self.addChild(self.hoopRimGraphics); self.leftElement = LK.getAsset('leftElement', { anchorX: 0.5, anchorY: 0.5 }); self.leftElement.x = self.hoopRimGraphics.x - self.hoopRimGraphics.width / 2 + self.leftElement.width / 2 - 50; self.leftElement.y = self.hoopRimGraphics.y - 250; self.leftElement.alpha = 0; self.addChild(self.leftElement); self.rightElement = LK.getAsset('rightElement', { anchorX: 0.5, anchorY: 0.5 }); self.rightElement.x = self.hoopRimGraphics.x + self.hoopRimGraphics.width / 2 - self.rightElement.width / 2 + 50; self.rightElement.y = self.hoopRimGraphics.y - 250; self.rightElement.alpha = 0; self.addChild(self.rightElement); self.hoopOutlineGraphics = LK.getAsset('hoopOutline', { anchorX: 1, anchorY: 0.5 }); self.hoopOutlineGraphics.y = self.hoopRimGraphics.y - 230; self.hoopOutlineGraphics.alpha = 1; self.hoopOutlineGraphics.tint = 0xbb502e; self.hoopOutlineGraphics.rotation = Math.PI / 2; self.addChild(self.hoopOutlineGraphics); self.multiplierLabel = new Text2('', { size: 200, fill: '#8d4529', font: 'Impact' }); self.multiplierLabel.anchor.set(.5, 1); self.multiplierLabel.x = self.hoopRimGraphics.x; self.multiplierLabel.y = self.hoopRimGraphics.y - 250 - 50 + 30; self.addChild(self.multiplierLabel); self.scoreLabel = new Text2('0', { size: 270, fill: '#4b190c', font: 'Impact' }); self.scoreLabel.anchor.set(.5, .5); self.scoreLabel.x = self.hoopRimGraphics.x; self.scoreLabel.y = self.hoopRimGraphics.y - 250 - 20 - 420; self.addChild(self.scoreLabel); }); var HoopRim = Container.expand(function () { var self = Container.call(this); var hoopRimGraphics = LK.getAsset('hoopRimSeparate', { anchorX: 0.5, anchorY: 0.5 }); self.addChild(hoopRimGraphics); }); var Particle = Container.expand(function () { var self = Container.call(this); self.interactive = false; var particleGraphics = self.attachAsset('fireParticle', { anchorX: 0.5, anchorY: 0.5 }); particleGraphics.blendMode = 1; self.lifeSpan = 60; self.speed = { x: (Math.random() - 0.5) * 2, y: (Math.random() - 0.5) * 2 }; self.scale.set(Math.random() * 0.6 + 0.2); self.rotation = Math.random() * Math.PI * 2; self._move_migrated = function () { self.x += self.speed.x; self.y += self.speed.y; self.alpha -= 0.03; if (self.alpha <= 0) { self.destroy(); } }; }); var Timer = Container.expand(function () { var self = Container.call(this); self.timerLabel = new Text2('120', { size: 150, fill: '#ffffff', font: 'Impact' }); self.timerLabel.anchor.set(0.5, 0.5); self.addChild(self.timerLabel); self.timeLeft = 120; self.gameEnded = false; self.setTime = function (time) { self.timeLeft = time; self.timerLabel.setText(Math.ceil(self.timeLeft).toString()); // Flash red when time is low if (self.timeLeft <= 10) { tween(self.timerLabel, { tint: 0xff0000 }, { duration: 200, onFinish: function onFinish() { tween(self.timerLabel, { tint: 0xffffff }, { duration: 200 }); } }); } }; self.update = function () { if (self.timeLeft > 0 && !self.gameEnded) { self.timeLeft -= 1 / 60; // Decrease by 1 second every 60 frames self.setTime(self.timeLeft); if (self.timeLeft <= 0) { self.gameEnded = true; // Save high score if (score > (storage.highScore || 0)) { storage.highScore = score; } LK.showGameOver(); } } }; return self; }); var TitleText = Container.expand(function () { var self = Container.call(this); self.titleLabel = new Text2("TIME ATTACK!", { size: 200, fill: 0x0, font: "Impact" }); self.titleLabel.anchor.set(0.5, 0.5); self.addChild(self.titleLabel); self.subtitleLabel = new Text2("Throw ball to start", { size: 100, fill: 0x0, font: "Impact" }); self.subtitleLabel.anchor.set(0.5, 0.5); self.subtitleLabel.y = self.titleLabel.y + 150; self.addChild(self.subtitleLabel); self.fadeOut = function () { tween(self, { alpha: 0 }, { duration: 500, onFinish: function onFinish() { self.visible = false; } }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x477096 }); /**** * Game Code ****/ // Import plugins var bg = LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5 }); bg.x = 2048 / 2; bg.y = 2732 / 2 + 150; bg.alpha = 0.7; game.addChild(bg); // Play background music LK.playMusic('basketball', { fade: { start: 0, end: 1, duration: 1000 } }); var hoop = game.addChild(new Hoop()); var score = 0; var scoreMultiplier = 1; // Create title screen var titleScreen = new TitleText(); titleScreen.x = 2048 / 2; titleScreen.y = 2732 / 2 - 300; game.addChild(titleScreen); // Create timer var timer = new Timer(); timer.x = 2048 / 2; timer.y = 150; timer.timeLeft = 120; // Set initial time to 120 seconds timer.gameEnded = true; // Pause timer initially until first throw game.addChild(timer); // Display high score var highScoreLabel = new Text2('Best: ' + (storage.highScore || 0), { size: 80, fill: '#ffffff', font: 'Impact' }); highScoreLabel.anchor.set(1, 0); highScoreLabel.x = 2048 - 40; highScoreLabel.y = 40; game.addChild(highScoreLabel); var ballShadow = LK.getAsset('ballShadow', { anchorX: 0.5, anchorY: 0.5 }); ballShadow.alpha = 0.5; game.addChild(ballShadow); var ball = game.addChild(new Ball()); var hoopRim = game.addChild(new HoopRim()); ball.hitElement = ''; hoop.x = 2048 / 2; hoop.y = 2732 / 2; hoopRim.x = hoop.x; hoopRim.y = hoop.y + hoop.children[1].y - 250; ball.x = 2048 / 2; ball.on('down', function (x, y, obj) { if (!ball.hasThrown) { var event = obj; dragStart = game.toLocal(event.global); } }); var dragStart = null; game.on('move', function (x, y, obj) { var event = obj; var pos = game.toLocal(event.global); if (dragStart !== null && ball.distanceTo(pos.x, pos.y) > 400) { game.fireBall(obj); } }); game.fireBall = function (obj) { if (dragStart !== null) { var event = obj.event; var pos = game.toLocal(event.global); var dx = pos.x - dragStart.x; var dy = pos.y - dragStart.y; var angle = Math.atan2(dy, dx); ball.speed.x = Math.cos(angle) * 72 * 1.76 * 0.9 / 3; ball.speed.y = Math.sin(angle) * 72 * 1.76 * 0.9; ball.hasThrown = true; ball.hitElement = ''; game.removeChild(ball); game.addChild(ball); dragStart = null; // Play throw sound LK.getSound('throwSound').play(); // Start timer on first throw if it's not already running if (timer.gameEnded) { timer.gameEnded = false; timer.timeLeft = 120; // Reset to ensure full 120 seconds timer.setTime(timer.timeLeft); titleScreen.fadeOut(); // Hide the title screen } } }; game.on('up', function (x, y, obj) { if (dragStart !== null) { var event = obj; var pos = game.toLocal(event.global); var distance = Math.sqrt(Math.pow(pos.x - dragStart.x, 2) + Math.pow(pos.y - dragStart.y, 2)); if (distance > 150) { game.fireBall(obj); } } dragStart = null; }); var floorY = 2732 - 40 + 900 * (ball.scale.y - 1); ball.y = floorY - ball.height; LK.on('tick', function () { // Update timer timer.update(); if (scoreMultiplier === 3) { for (var i = 0; i < 2; i++) { var particle = new Particle(); particle.alpha = ball.alpha; var angle = Math.random() * Math.PI * 2; var radius = ball.width * 0.5 * Math.sqrt(Math.random()); particle.x = ball.x + Math.cos(angle) * radius; particle.y = ball.y + Math.sin(angle) * radius; game.addChild(particle); } } game.children.forEach(function (child) { if (child instanceof Particle) { child._move_migrated(); } }); var floorY = 2732 - 40 + 900 * (ball.scale.y - 1); ball._move_migrated(); if (ball.speed.y > 0) { game.removeChild(hoopRim); game.addChild(hoopRim); if (ball.distanceTo(hoop.x + hoop.leftElement.x, hoop.y + hoop.leftElement.y) < ball.width / 2 + hoop.leftElement.width / 2) { ball.moveToDistance(hoop.x + hoop.leftElement.x, hoop.y + hoop.leftElement.y, ball.width / 2 + hoop.leftElement.width / 2 + 1); ball.bounceOffPoint(hoop.x + hoop.leftElement.x, hoop.y + hoop.leftElement.y, 0.5); ball.hitElement = 'left'; } if (ball.distanceTo(hoop.x + hoop.rightElement.x, hoop.y + hoop.rightElement.y) < ball.width / 2 + hoop.rightElement.width / 2) { ball.moveToDistance(hoop.x + hoop.rightElement.x, hoop.y + hoop.rightElement.y, ball.width / 2 + hoop.rightElement.width / 2 + 1); ball.bounceOffPoint(hoop.x + hoop.rightElement.x, hoop.y + hoop.rightElement.y, 0.5); ball.hitElement = 'right'; } } ballShadow.x = ball.x; ballShadow.y = 1800 + ball.height / 2 + 500 * ball.scale.x; var scale = (1 - 2 * (ball.y - 2732 + ball.height) / 2732) * ball.scale.x; ballShadow.scale.set(scale); ballShadow.alpha = (1 - scale + 1) / 2 * ball.alpha; if (ball.y + ball.height > floorY) { ball.y = floorY - ball.height; ball.speed.y *= -0.75; ballShadow.x = ball.x; ballShadow.visible = true; if (ball.hasThrown && !ball.hasScored) { if (!ball.hasBounced) { ball.hasBounced = true; } else if (timer.timeLeft <= 0) { LK.showGameOver(); } else { // Play miss sound LK.getSound('missSound').play(); // Create a new ball after it has bounced without scoring ball.x = 2048 / 2; ball.y = 2532 - ball.height; ball.speed.x = 0; ball.speed.y = 0; ball.hasThrown = false; ball.hasScored = false; ball.hasBounced = false; ball.scale.x = 1; ball.scale.y = 1; ball.alpha = 1; ball.hitElement = ''; scoreMultiplier = 1; hoop.multiplierLabel.setText(''); // Play whistle sound when new ball is ready LK.getSound('whistleSound').play(); } } else if (ball.hasScored) { ball.x = 2048 / 2; ball.y = 2532 - ball.height; ball.speed.x = 0; ball.speed.y = 0; ball.hasThrown = false; ball.hasScored = false; ball.hasBounced = false; ball.scale.x = 1; ball.scale.y = 1; if (ball.hitElement === '') { if (scoreMultiplier < 3) { scoreMultiplier++; } } else { scoreMultiplier = 1; } if (scoreMultiplier > 1) { hoop.multiplierLabel.setText('x' + scoreMultiplier); } else { hoop.multiplierLabel.setText(''); } ball.hitElement = ''; // Play whistle sound when new ball is ready after scoring LK.getSound('whistleSound').play(); hoop.moveTo(Math.random() * (2048 - 1000) + 500, Math.random() * (2732 - 2000) + 1000, hoopRim); } } if (ball.x + ball.width / 2 < 0 || ball.x - ball.width / 2 > 2048) { if (timer.timeLeft <= 0) { LK.showGameOver(); } else { // Play miss sound for out of bounds LK.getSound('missSound').play(); // Create a new ball if the ball goes out of bounds ball.x = 2048 / 2; ball.y = 2532 - ball.height; ball.speed.x = 0; ball.speed.y = 0; ball.hasThrown = false; ball.hasScored = false; ball.hasBounced = false; ball.scale.x = 1; ball.scale.y = 1; ball.alpha = 1; ball.hitElement = ''; scoreMultiplier = 1; hoop.multiplierLabel.setText(''); // Play whistle sound when new ball is ready after going out of bounds LK.getSound('whistleSound').play(); } } else if (ball.intersects(hoop.hoopRimGraphics) && ball.speed.y > 0 && !ball.hasScored && !ball.hasBounced && ball.x > hoop.x + hoop.leftElement.x && ball.x < hoop.x + hoop.rightElement.x) { ball.hasScored = true; score += scoreMultiplier; LK.setScore(score); hoop.scoreLabel.setText(score.toString()); // Play score sound LK.getSound('scoreSound').play(); // Update high score display if needed if (score > (storage.highScore || 0)) { storage.highScore = score; highScoreLabel.setText('Best: ' + score); // Animate high score update tween(highScoreLabel, { scaleX: 1.3, scaleY: 1.3 }, { duration: 300, onFinish: function onFinish() { tween(highScoreLabel, { scaleX: 1, scaleY: 1 }, { duration: 300 }); } }); } } });
/****
* 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);
self.hasScored = false;
self.hasBounced = false;
var ballGraphics = LK.getAsset('ball', {
anchorX: 0.5,
anchorY: 0.5
});
self.addChild(ballGraphics);
self.speed = {
x: 0,
y: 0
};
self.hasThrown = false;
self._move_migrated = function () {
self.speed.y += 3.2;
self.x += self.speed.x;
self.y += self.speed.y;
self.rotation += self.speed.x * 0.01;
if (self.hasThrown) {
var targetScale = 0.8;
self.scale.x += (targetScale - self.scale.x) * 0.05;
self.scale.y += (targetScale - self.scale.y) * 0.05;
}
if (self.hasScored) {
self.alpha -= 0.15;
} else {
self.alpha += 0.15;
if (self.alpha > 1) {
self.alpha = 1;
}
}
};
self.bounceOffPoint = function (x, y, elasticity) {
var dx = self.x - x;
var dy = self.y - y;
var angle = Math.atan2(dy, dx);
var speed = Math.sqrt(self.speed.x * self.speed.x + self.speed.y * self.speed.y);
self.speed.x = Math.cos(angle) * speed * elasticity;
self.speed.y = Math.sin(angle) * speed * elasticity;
};
self.angleTo = function (x, y) {
var dx = self.x - x;
var dy = self.y - y;
return Math.atan2(dy, dx);
};
self.distanceTo = function (x, y) {
var dx = self.x - x;
var dy = self.y - y;
return Math.sqrt(dx * dx + dy * dy);
};
self.moveToDistance = function (x, y, distance) {
var angle = self.angleTo(x, y);
self.x = x + Math.cos(angle) * (distance * 1.05);
self.y = y + Math.sin(angle) * (distance * 1.05);
};
});
var Hoop = Container.expand(function () {
var self = Container.call(this);
self.setScore = function (score) {
self.scoreLabel.setText(score.toString());
};
self.moveTo = function (newX, newY, hoopRim) {
var dx = (newX - self.x) / 60;
var dy = (newY - self.y) / 60;
var steps = 0;
var interval = LK.setInterval(function () {
self.x += dx;
self.y += dy;
hoopRim.x = self.x;
hoopRim.y = self.y + self.children[1].y - 250;
steps++;
if (steps >= 60) {
LK.clearInterval(interval);
}
});
};
var backboardGraphics = LK.getAsset('backboard', {
anchorX: 0.5,
anchorY: 0.5
});
backboardGraphics.y -= 250;
self.addChild(backboardGraphics);
self.hoopRimGraphics = LK.getAsset('hoopRim', {
anchorX: 0.5,
anchorY: 0.5
});
self.hoopRimGraphics.y = backboardGraphics.height / 2 - 550 + 20 + 120 + 150 + 100;
self.hoopRimGraphics.alpha = 0;
self.addChild(self.hoopRimGraphics);
self.leftElement = LK.getAsset('leftElement', {
anchorX: 0.5,
anchorY: 0.5
});
self.leftElement.x = self.hoopRimGraphics.x - self.hoopRimGraphics.width / 2 + self.leftElement.width / 2 - 50;
self.leftElement.y = self.hoopRimGraphics.y - 250;
self.leftElement.alpha = 0;
self.addChild(self.leftElement);
self.rightElement = LK.getAsset('rightElement', {
anchorX: 0.5,
anchorY: 0.5
});
self.rightElement.x = self.hoopRimGraphics.x + self.hoopRimGraphics.width / 2 - self.rightElement.width / 2 + 50;
self.rightElement.y = self.hoopRimGraphics.y - 250;
self.rightElement.alpha = 0;
self.addChild(self.rightElement);
self.hoopOutlineGraphics = LK.getAsset('hoopOutline', {
anchorX: 1,
anchorY: 0.5
});
self.hoopOutlineGraphics.y = self.hoopRimGraphics.y - 230;
self.hoopOutlineGraphics.alpha = 1;
self.hoopOutlineGraphics.tint = 0xbb502e;
self.hoopOutlineGraphics.rotation = Math.PI / 2;
self.addChild(self.hoopOutlineGraphics);
self.multiplierLabel = new Text2('', {
size: 200,
fill: '#8d4529',
font: 'Impact'
});
self.multiplierLabel.anchor.set(.5, 1);
self.multiplierLabel.x = self.hoopRimGraphics.x;
self.multiplierLabel.y = self.hoopRimGraphics.y - 250 - 50 + 30;
self.addChild(self.multiplierLabel);
self.scoreLabel = new Text2('0', {
size: 270,
fill: '#4b190c',
font: 'Impact'
});
self.scoreLabel.anchor.set(.5, .5);
self.scoreLabel.x = self.hoopRimGraphics.x;
self.scoreLabel.y = self.hoopRimGraphics.y - 250 - 20 - 420;
self.addChild(self.scoreLabel);
});
var HoopRim = Container.expand(function () {
var self = Container.call(this);
var hoopRimGraphics = LK.getAsset('hoopRimSeparate', {
anchorX: 0.5,
anchorY: 0.5
});
self.addChild(hoopRimGraphics);
});
var Particle = Container.expand(function () {
var self = Container.call(this);
self.interactive = false;
var particleGraphics = self.attachAsset('fireParticle', {
anchorX: 0.5,
anchorY: 0.5
});
particleGraphics.blendMode = 1;
self.lifeSpan = 60;
self.speed = {
x: (Math.random() - 0.5) * 2,
y: (Math.random() - 0.5) * 2
};
self.scale.set(Math.random() * 0.6 + 0.2);
self.rotation = Math.random() * Math.PI * 2;
self._move_migrated = function () {
self.x += self.speed.x;
self.y += self.speed.y;
self.alpha -= 0.03;
if (self.alpha <= 0) {
self.destroy();
}
};
});
var Timer = Container.expand(function () {
var self = Container.call(this);
self.timerLabel = new Text2('120', {
size: 150,
fill: '#ffffff',
font: 'Impact'
});
self.timerLabel.anchor.set(0.5, 0.5);
self.addChild(self.timerLabel);
self.timeLeft = 120;
self.gameEnded = false;
self.setTime = function (time) {
self.timeLeft = time;
self.timerLabel.setText(Math.ceil(self.timeLeft).toString());
// Flash red when time is low
if (self.timeLeft <= 10) {
tween(self.timerLabel, {
tint: 0xff0000
}, {
duration: 200,
onFinish: function onFinish() {
tween(self.timerLabel, {
tint: 0xffffff
}, {
duration: 200
});
}
});
}
};
self.update = function () {
if (self.timeLeft > 0 && !self.gameEnded) {
self.timeLeft -= 1 / 60; // Decrease by 1 second every 60 frames
self.setTime(self.timeLeft);
if (self.timeLeft <= 0) {
self.gameEnded = true;
// Save high score
if (score > (storage.highScore || 0)) {
storage.highScore = score;
}
LK.showGameOver();
}
}
};
return self;
});
var TitleText = Container.expand(function () {
var self = Container.call(this);
self.titleLabel = new Text2("TIME ATTACK!", {
size: 200,
fill: 0x0,
font: "Impact"
});
self.titleLabel.anchor.set(0.5, 0.5);
self.addChild(self.titleLabel);
self.subtitleLabel = new Text2("Throw ball to start", {
size: 100,
fill: 0x0,
font: "Impact"
});
self.subtitleLabel.anchor.set(0.5, 0.5);
self.subtitleLabel.y = self.titleLabel.y + 150;
self.addChild(self.subtitleLabel);
self.fadeOut = function () {
tween(self, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
self.visible = false;
}
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x477096
});
/****
* Game Code
****/
// Import plugins
var bg = LK.getAsset('background', {
anchorX: 0.5,
anchorY: 0.5
});
bg.x = 2048 / 2;
bg.y = 2732 / 2 + 150;
bg.alpha = 0.7;
game.addChild(bg);
// Play background music
LK.playMusic('basketball', {
fade: {
start: 0,
end: 1,
duration: 1000
}
});
var hoop = game.addChild(new Hoop());
var score = 0;
var scoreMultiplier = 1;
// Create title screen
var titleScreen = new TitleText();
titleScreen.x = 2048 / 2;
titleScreen.y = 2732 / 2 - 300;
game.addChild(titleScreen);
// Create timer
var timer = new Timer();
timer.x = 2048 / 2;
timer.y = 150;
timer.timeLeft = 120; // Set initial time to 120 seconds
timer.gameEnded = true; // Pause timer initially until first throw
game.addChild(timer);
// Display high score
var highScoreLabel = new Text2('Best: ' + (storage.highScore || 0), {
size: 80,
fill: '#ffffff',
font: 'Impact'
});
highScoreLabel.anchor.set(1, 0);
highScoreLabel.x = 2048 - 40;
highScoreLabel.y = 40;
game.addChild(highScoreLabel);
var ballShadow = LK.getAsset('ballShadow', {
anchorX: 0.5,
anchorY: 0.5
});
ballShadow.alpha = 0.5;
game.addChild(ballShadow);
var ball = game.addChild(new Ball());
var hoopRim = game.addChild(new HoopRim());
ball.hitElement = '';
hoop.x = 2048 / 2;
hoop.y = 2732 / 2;
hoopRim.x = hoop.x;
hoopRim.y = hoop.y + hoop.children[1].y - 250;
ball.x = 2048 / 2;
ball.on('down', function (x, y, obj) {
if (!ball.hasThrown) {
var event = obj;
dragStart = game.toLocal(event.global);
}
});
var dragStart = null;
game.on('move', function (x, y, obj) {
var event = obj;
var pos = game.toLocal(event.global);
if (dragStart !== null && ball.distanceTo(pos.x, pos.y) > 400) {
game.fireBall(obj);
}
});
game.fireBall = function (obj) {
if (dragStart !== null) {
var event = obj.event;
var pos = game.toLocal(event.global);
var dx = pos.x - dragStart.x;
var dy = pos.y - dragStart.y;
var angle = Math.atan2(dy, dx);
ball.speed.x = Math.cos(angle) * 72 * 1.76 * 0.9 / 3;
ball.speed.y = Math.sin(angle) * 72 * 1.76 * 0.9;
ball.hasThrown = true;
ball.hitElement = '';
game.removeChild(ball);
game.addChild(ball);
dragStart = null;
// Play throw sound
LK.getSound('throwSound').play();
// Start timer on first throw if it's not already running
if (timer.gameEnded) {
timer.gameEnded = false;
timer.timeLeft = 120; // Reset to ensure full 120 seconds
timer.setTime(timer.timeLeft);
titleScreen.fadeOut(); // Hide the title screen
}
}
};
game.on('up', function (x, y, obj) {
if (dragStart !== null) {
var event = obj;
var pos = game.toLocal(event.global);
var distance = Math.sqrt(Math.pow(pos.x - dragStart.x, 2) + Math.pow(pos.y - dragStart.y, 2));
if (distance > 150) {
game.fireBall(obj);
}
}
dragStart = null;
});
var floorY = 2732 - 40 + 900 * (ball.scale.y - 1);
ball.y = floorY - ball.height;
LK.on('tick', function () {
// Update timer
timer.update();
if (scoreMultiplier === 3) {
for (var i = 0; i < 2; i++) {
var particle = new Particle();
particle.alpha = ball.alpha;
var angle = Math.random() * Math.PI * 2;
var radius = ball.width * 0.5 * Math.sqrt(Math.random());
particle.x = ball.x + Math.cos(angle) * radius;
particle.y = ball.y + Math.sin(angle) * radius;
game.addChild(particle);
}
}
game.children.forEach(function (child) {
if (child instanceof Particle) {
child._move_migrated();
}
});
var floorY = 2732 - 40 + 900 * (ball.scale.y - 1);
ball._move_migrated();
if (ball.speed.y > 0) {
game.removeChild(hoopRim);
game.addChild(hoopRim);
if (ball.distanceTo(hoop.x + hoop.leftElement.x, hoop.y + hoop.leftElement.y) < ball.width / 2 + hoop.leftElement.width / 2) {
ball.moveToDistance(hoop.x + hoop.leftElement.x, hoop.y + hoop.leftElement.y, ball.width / 2 + hoop.leftElement.width / 2 + 1);
ball.bounceOffPoint(hoop.x + hoop.leftElement.x, hoop.y + hoop.leftElement.y, 0.5);
ball.hitElement = 'left';
}
if (ball.distanceTo(hoop.x + hoop.rightElement.x, hoop.y + hoop.rightElement.y) < ball.width / 2 + hoop.rightElement.width / 2) {
ball.moveToDistance(hoop.x + hoop.rightElement.x, hoop.y + hoop.rightElement.y, ball.width / 2 + hoop.rightElement.width / 2 + 1);
ball.bounceOffPoint(hoop.x + hoop.rightElement.x, hoop.y + hoop.rightElement.y, 0.5);
ball.hitElement = 'right';
}
}
ballShadow.x = ball.x;
ballShadow.y = 1800 + ball.height / 2 + 500 * ball.scale.x;
var scale = (1 - 2 * (ball.y - 2732 + ball.height) / 2732) * ball.scale.x;
ballShadow.scale.set(scale);
ballShadow.alpha = (1 - scale + 1) / 2 * ball.alpha;
if (ball.y + ball.height > floorY) {
ball.y = floorY - ball.height;
ball.speed.y *= -0.75;
ballShadow.x = ball.x;
ballShadow.visible = true;
if (ball.hasThrown && !ball.hasScored) {
if (!ball.hasBounced) {
ball.hasBounced = true;
} else if (timer.timeLeft <= 0) {
LK.showGameOver();
} else {
// Play miss sound
LK.getSound('missSound').play();
// Create a new ball after it has bounced without scoring
ball.x = 2048 / 2;
ball.y = 2532 - ball.height;
ball.speed.x = 0;
ball.speed.y = 0;
ball.hasThrown = false;
ball.hasScored = false;
ball.hasBounced = false;
ball.scale.x = 1;
ball.scale.y = 1;
ball.alpha = 1;
ball.hitElement = '';
scoreMultiplier = 1;
hoop.multiplierLabel.setText('');
// Play whistle sound when new ball is ready
LK.getSound('whistleSound').play();
}
} else if (ball.hasScored) {
ball.x = 2048 / 2;
ball.y = 2532 - ball.height;
ball.speed.x = 0;
ball.speed.y = 0;
ball.hasThrown = false;
ball.hasScored = false;
ball.hasBounced = false;
ball.scale.x = 1;
ball.scale.y = 1;
if (ball.hitElement === '') {
if (scoreMultiplier < 3) {
scoreMultiplier++;
}
} else {
scoreMultiplier = 1;
}
if (scoreMultiplier > 1) {
hoop.multiplierLabel.setText('x' + scoreMultiplier);
} else {
hoop.multiplierLabel.setText('');
}
ball.hitElement = '';
// Play whistle sound when new ball is ready after scoring
LK.getSound('whistleSound').play();
hoop.moveTo(Math.random() * (2048 - 1000) + 500, Math.random() * (2732 - 2000) + 1000, hoopRim);
}
}
if (ball.x + ball.width / 2 < 0 || ball.x - ball.width / 2 > 2048) {
if (timer.timeLeft <= 0) {
LK.showGameOver();
} else {
// Play miss sound for out of bounds
LK.getSound('missSound').play();
// Create a new ball if the ball goes out of bounds
ball.x = 2048 / 2;
ball.y = 2532 - ball.height;
ball.speed.x = 0;
ball.speed.y = 0;
ball.hasThrown = false;
ball.hasScored = false;
ball.hasBounced = false;
ball.scale.x = 1;
ball.scale.y = 1;
ball.alpha = 1;
ball.hitElement = '';
scoreMultiplier = 1;
hoop.multiplierLabel.setText('');
// Play whistle sound when new ball is ready after going out of bounds
LK.getSound('whistleSound').play();
}
} else if (ball.intersects(hoop.hoopRimGraphics) && ball.speed.y > 0 && !ball.hasScored && !ball.hasBounced && ball.x > hoop.x + hoop.leftElement.x && ball.x < hoop.x + hoop.rightElement.x) {
ball.hasScored = true;
score += scoreMultiplier;
LK.setScore(score);
hoop.scoreLabel.setText(score.toString());
// Play score sound
LK.getSound('scoreSound').play();
// Update high score display if needed
if (score > (storage.highScore || 0)) {
storage.highScore = score;
highScoreLabel.setText('Best: ' + score);
// Animate high score update
tween(highScoreLabel, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 300,
onFinish: function onFinish() {
tween(highScoreLabel, {
scaleX: 1,
scaleY: 1
}, {
duration: 300
});
}
});
}
}
});
Basketball, cartoon style Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
4:3 Simple rectangle white outline. Black background
Skull explosion
Wide Single Orange metal bar lying down Single Game Texture. In-Game asset. 2d. Pixelart. White background. Blank background. Low detail. High contrast. —ar 2:1
https://kagi.com/proxy/basketball_backboard.png?c=iNrrnnUOe99nVfDGJsYBLujiaX2Hu-zxBFRkvLEyXdRnJ8cU3RjcAYbR-o12E923qVNGy1CEGrQG87ogCD3yUarJdZYt5R03mmEMb7Jrh-8%3D blank backboard Single Game Texture. In-Game asset. 2d. Pixelart. White background. Blank background. Low detail. High contrast.
Indoor stadium seen from court Single Game Texture. In-Game asset. 2d. Pixelart. White background. Blank background. Low detail. High contrast. --no goal