/**** * Plugins ****/ var tween = LK.import("@upit/tween.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.isMoving = false; self.friction = 0.98; self.bounceDelay = 0; self.update = function () { if (self.isMoving) { self.x += self.velocityX; self.y += self.velocityY; // Apply friction self.velocityX *= self.friction; self.velocityY *= self.friction; // Handle bouncing delay if (self.bounceDelay > 0) { self.bounceDelay--; } // Stop if velocity is very low if (Math.abs(self.velocityX) < 0.5 && Math.abs(self.velocityY) < 0.5) { self.velocityX = 0; self.velocityY = 0; self.isMoving = false; } // Boundary bouncing if (self.x <= 30 || self.x >= 2018) { if (self.bounceDelay <= 0) { self.velocityX *= -0.8; self.x = Math.max(30, Math.min(2018, self.x)); self.bounceDelay = 5; LK.getSound('bounce').play(); } } if (self.y <= 30) { if (self.bounceDelay <= 0) { self.velocityY *= -0.8; self.y = Math.max(30, self.y); self.bounceDelay = 5; LK.getSound('bounce').play(); } } // Reset if ball goes off bottom if (self.y > 2732 + 100) { self.resetPosition(); } } }; self.shoot = function (targetX, targetY, power) { var deltaX = targetX - self.x; var deltaY = targetY - self.y; var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); self.velocityX = deltaX / distance * power; self.velocityY = deltaY / distance * power; self.isMoving = true; LK.getSound('kick').play(); }; self.resetPosition = function () { self.x = 1024; self.y = 2500; self.velocityX = 0; self.velocityY = 0; self.isMoving = false; }; return self; }); var Goalkeeper = Container.expand(function () { var self = Container.call(this); var keeperGraphics = self.attachAsset('goalkeeper', { anchorX: 0.5, anchorY: 0.5 }); self.direction = 1; self.speed = 2; self.minX = 824; self.maxX = 1224; self.update = function () { self.x += self.speed * self.direction; if (self.x <= self.minX || self.x >= self.maxX) { self.direction *= -1; } }; return self; }); var Obstacle = Container.expand(function () { var self = Container.call(this); var obstacleGraphics = self.attachAsset('obstacle', { anchorX: 0.5, anchorY: 0.5 }); self.direction = 1; self.speed = 1; self.minX = 100; self.maxX = 1948; self.update = function () { self.x += self.speed * self.direction; if (self.x <= self.minX || self.x >= self.maxX) { self.direction *= -1; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x228b22 }); /**** * Game Code ****/ // Game variables var ball; var goalkeeper; var goal; var obstacles = []; var isDragging = false; var dragStartX = 0; var dragStartY = 0; var aimLine; var currentLevel = 1; var isGameActive = true; // UI elements var scoreTxt = new Text2('Score: 0', { size: 80, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); var levelTxt = new Text2('Level: 1', { size: 60, fill: 0xFFFFFF }); levelTxt.anchor.set(1, 0); LK.gui.topRight.addChild(levelTxt); // Create field background var field = game.addChild(LK.getAsset('field', { anchorX: 0, anchorY: 1, x: 0, y: 2732 })); // Create goal goal = game.addChild(LK.getAsset('goal', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 200 })); // Create ball ball = game.addChild(new Ball()); ball.resetPosition(); // Create goalkeeper goalkeeper = game.addChild(new Goalkeeper()); goalkeeper.x = 1024; goalkeeper.y = 250; // Create aim line (initially hidden) aimLine = game.addChild(LK.getAsset('aimLine', { anchorX: 0.5, anchorY: 0, alpha: 0 })); // Initialize first level obstacles function createObstacles() { // Clear existing obstacles for (var i = obstacles.length - 1; i >= 0; i--) { obstacles[i].destroy(); obstacles.splice(i, 1); } // Create obstacles based on level var numObstacles = Math.min(currentLevel + 1, 5); for (var i = 0; i < numObstacles; i++) { var obstacle = game.addChild(new Obstacle()); obstacle.x = 300 + i * 350; obstacle.y = 800 + i % 2 * 400; obstacle.speed = 1 + currentLevel * 0.5; obstacles.push(obstacle); } // Increase goalkeeper speed goalkeeper.speed = 2 + currentLevel * 0.3; } createObstacles(); // Handle ball collision with obstacles function checkCollisions() { if (!ball.isMoving) return; // Check collision with obstacles for (var i = 0; i < obstacles.length; i++) { if (ball.intersects(obstacles[i]) && ball.bounceDelay <= 0) { // Simple bounce calculation var deltaX = ball.x - obstacles[i].x; var deltaY = ball.y - obstacles[i].y; var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); if (distance > 0) { ball.velocityX = deltaX / distance * Math.abs(ball.velocityX) * 0.8; ball.velocityY = deltaY / distance * Math.abs(ball.velocityY) * 0.8; ball.bounceDelay = 10; LK.getSound('bounce').play(); } } } // Check collision with goalkeeper if (ball.intersects(goalkeeper) && ball.bounceDelay <= 0) { var deltaX = ball.x - goalkeeper.x; var deltaY = ball.y - goalkeeper.y; var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); if (distance > 0) { ball.velocityX = deltaX / distance * Math.abs(ball.velocityX) * 0.9; ball.velocityY = deltaY / distance * Math.abs(ball.velocityY) * 0.9; ball.bounceDelay = 10; LK.getSound('bounce').play(); } } } // Check for goal function checkGoal() { if (!ball.isMoving) return; if (ball.intersects(goal)) { // Goal scored! LK.setScore(LK.getScore() + 10 * currentLevel); scoreTxt.setText('Score: ' + LK.getScore()); currentLevel++; levelTxt.setText('Level: ' + currentLevel); LK.getSound('goal').play(); LK.effects.flashScreen(0x00ff00, 500); // Check win condition if (LK.getScore() >= 500) { LK.showYouWin(); return; } // Reset for next level ball.resetPosition(); createObstacles(); } } // Game controls game.down = function (x, y, obj) { if (!isGameActive || ball.isMoving) return; isDragging = true; dragStartX = x; dragStartY = y; aimLine.alpha = 0.7; }; game.move = function (x, y, obj) { if (!isDragging || !isGameActive) return; // Update aim line var deltaX = x - ball.x; var deltaY = y - ball.y; var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); if (distance > 0) { aimLine.x = ball.x; aimLine.y = ball.y; aimLine.rotation = Math.atan2(deltaY, deltaX) + Math.PI / 2; aimLine.height = Math.min(distance, 300); } }; game.up = function (x, y, obj) { if (!isDragging || !isGameActive) return; isDragging = false; aimLine.alpha = 0; // Calculate power and shoot var deltaX = x - dragStartX; var deltaY = y - dragStartY; var power = Math.min(Math.sqrt(deltaX * deltaX + deltaY * deltaY) * 0.3, 20); if (power > 2) { ball.shoot(x, y, power); } }; // Main game loop game.update = function () { if (!isGameActive) return; checkCollisions(); checkGoal(); // Reset ball if it stops in a bad position if (!ball.isMoving && ball.y < 2000) { var resetTimer = LK.setTimeout(function () { ball.resetPosition(); }, 2000); } // Game over condition - if ball is stuck for too long if (!ball.isMoving && ball.y > 2600 && LK.ticks % 300 === 0) { // Check if no progress has been made if (LK.getScore() === 0 && LK.ticks > 1800) { // 30 seconds with no score LK.showGameOver(); } } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.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.isMoving = false;
self.friction = 0.98;
self.bounceDelay = 0;
self.update = function () {
if (self.isMoving) {
self.x += self.velocityX;
self.y += self.velocityY;
// Apply friction
self.velocityX *= self.friction;
self.velocityY *= self.friction;
// Handle bouncing delay
if (self.bounceDelay > 0) {
self.bounceDelay--;
}
// Stop if velocity is very low
if (Math.abs(self.velocityX) < 0.5 && Math.abs(self.velocityY) < 0.5) {
self.velocityX = 0;
self.velocityY = 0;
self.isMoving = false;
}
// Boundary bouncing
if (self.x <= 30 || self.x >= 2018) {
if (self.bounceDelay <= 0) {
self.velocityX *= -0.8;
self.x = Math.max(30, Math.min(2018, self.x));
self.bounceDelay = 5;
LK.getSound('bounce').play();
}
}
if (self.y <= 30) {
if (self.bounceDelay <= 0) {
self.velocityY *= -0.8;
self.y = Math.max(30, self.y);
self.bounceDelay = 5;
LK.getSound('bounce').play();
}
}
// Reset if ball goes off bottom
if (self.y > 2732 + 100) {
self.resetPosition();
}
}
};
self.shoot = function (targetX, targetY, power) {
var deltaX = targetX - self.x;
var deltaY = targetY - self.y;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
self.velocityX = deltaX / distance * power;
self.velocityY = deltaY / distance * power;
self.isMoving = true;
LK.getSound('kick').play();
};
self.resetPosition = function () {
self.x = 1024;
self.y = 2500;
self.velocityX = 0;
self.velocityY = 0;
self.isMoving = false;
};
return self;
});
var Goalkeeper = Container.expand(function () {
var self = Container.call(this);
var keeperGraphics = self.attachAsset('goalkeeper', {
anchorX: 0.5,
anchorY: 0.5
});
self.direction = 1;
self.speed = 2;
self.minX = 824;
self.maxX = 1224;
self.update = function () {
self.x += self.speed * self.direction;
if (self.x <= self.minX || self.x >= self.maxX) {
self.direction *= -1;
}
};
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
self.direction = 1;
self.speed = 1;
self.minX = 100;
self.maxX = 1948;
self.update = function () {
self.x += self.speed * self.direction;
if (self.x <= self.minX || self.x >= self.maxX) {
self.direction *= -1;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x228b22
});
/****
* Game Code
****/
// Game variables
var ball;
var goalkeeper;
var goal;
var obstacles = [];
var isDragging = false;
var dragStartX = 0;
var dragStartY = 0;
var aimLine;
var currentLevel = 1;
var isGameActive = true;
// UI elements
var scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var levelTxt = new Text2('Level: 1', {
size: 60,
fill: 0xFFFFFF
});
levelTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(levelTxt);
// Create field background
var field = game.addChild(LK.getAsset('field', {
anchorX: 0,
anchorY: 1,
x: 0,
y: 2732
}));
// Create goal
goal = game.addChild(LK.getAsset('goal', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 200
}));
// Create ball
ball = game.addChild(new Ball());
ball.resetPosition();
// Create goalkeeper
goalkeeper = game.addChild(new Goalkeeper());
goalkeeper.x = 1024;
goalkeeper.y = 250;
// Create aim line (initially hidden)
aimLine = game.addChild(LK.getAsset('aimLine', {
anchorX: 0.5,
anchorY: 0,
alpha: 0
}));
// Initialize first level obstacles
function createObstacles() {
// Clear existing obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
obstacles[i].destroy();
obstacles.splice(i, 1);
}
// Create obstacles based on level
var numObstacles = Math.min(currentLevel + 1, 5);
for (var i = 0; i < numObstacles; i++) {
var obstacle = game.addChild(new Obstacle());
obstacle.x = 300 + i * 350;
obstacle.y = 800 + i % 2 * 400;
obstacle.speed = 1 + currentLevel * 0.5;
obstacles.push(obstacle);
}
// Increase goalkeeper speed
goalkeeper.speed = 2 + currentLevel * 0.3;
}
createObstacles();
// Handle ball collision with obstacles
function checkCollisions() {
if (!ball.isMoving) return;
// Check collision with obstacles
for (var i = 0; i < obstacles.length; i++) {
if (ball.intersects(obstacles[i]) && ball.bounceDelay <= 0) {
// Simple bounce calculation
var deltaX = ball.x - obstacles[i].x;
var deltaY = ball.y - obstacles[i].y;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
if (distance > 0) {
ball.velocityX = deltaX / distance * Math.abs(ball.velocityX) * 0.8;
ball.velocityY = deltaY / distance * Math.abs(ball.velocityY) * 0.8;
ball.bounceDelay = 10;
LK.getSound('bounce').play();
}
}
}
// Check collision with goalkeeper
if (ball.intersects(goalkeeper) && ball.bounceDelay <= 0) {
var deltaX = ball.x - goalkeeper.x;
var deltaY = ball.y - goalkeeper.y;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
if (distance > 0) {
ball.velocityX = deltaX / distance * Math.abs(ball.velocityX) * 0.9;
ball.velocityY = deltaY / distance * Math.abs(ball.velocityY) * 0.9;
ball.bounceDelay = 10;
LK.getSound('bounce').play();
}
}
}
// Check for goal
function checkGoal() {
if (!ball.isMoving) return;
if (ball.intersects(goal)) {
// Goal scored!
LK.setScore(LK.getScore() + 10 * currentLevel);
scoreTxt.setText('Score: ' + LK.getScore());
currentLevel++;
levelTxt.setText('Level: ' + currentLevel);
LK.getSound('goal').play();
LK.effects.flashScreen(0x00ff00, 500);
// Check win condition
if (LK.getScore() >= 500) {
LK.showYouWin();
return;
}
// Reset for next level
ball.resetPosition();
createObstacles();
}
}
// Game controls
game.down = function (x, y, obj) {
if (!isGameActive || ball.isMoving) return;
isDragging = true;
dragStartX = x;
dragStartY = y;
aimLine.alpha = 0.7;
};
game.move = function (x, y, obj) {
if (!isDragging || !isGameActive) return;
// Update aim line
var deltaX = x - ball.x;
var deltaY = y - ball.y;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
if (distance > 0) {
aimLine.x = ball.x;
aimLine.y = ball.y;
aimLine.rotation = Math.atan2(deltaY, deltaX) + Math.PI / 2;
aimLine.height = Math.min(distance, 300);
}
};
game.up = function (x, y, obj) {
if (!isDragging || !isGameActive) return;
isDragging = false;
aimLine.alpha = 0;
// Calculate power and shoot
var deltaX = x - dragStartX;
var deltaY = y - dragStartY;
var power = Math.min(Math.sqrt(deltaX * deltaX + deltaY * deltaY) * 0.3, 20);
if (power > 2) {
ball.shoot(x, y, power);
}
};
// Main game loop
game.update = function () {
if (!isGameActive) return;
checkCollisions();
checkGoal();
// Reset ball if it stops in a bad position
if (!ball.isMoving && ball.y < 2000) {
var resetTimer = LK.setTimeout(function () {
ball.resetPosition();
}, 2000);
}
// Game over condition - if ball is stuck for too long
if (!ball.isMoving && ball.y > 2600 && LK.ticks % 300 === 0) {
// Check if no progress has been made
if (LK.getScore() === 0 && LK.ticks > 1800) {
// 30 seconds with no score
LK.showGameOver();
}
}
};