/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Goalkeeper class
var Goalkeeper = Container.expand(function () {
var self = Container.call(this);
var keeper = self.attachAsset('goalkeeper', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8; // Initial speed
self.direction = 1; // 1: right, -1: left
// Update
self.update = function () {
self.x += self.speed * self.direction;
// Bounce off posts
if (self.x > goalRightX - keeper.width / 2) {
self.x = goalRightX - keeper.width / 2;
self.direction = -1;
}
if (self.x < goalLeftX + keeper.width / 2) {
self.x = goalLeftX + keeper.width / 2;
self.direction = 1;
}
};
// Increase speed
self.increaseSpeed = function () {
self.speed += 1.5;
if (self.speed > 22) self.speed = 22;
};
return self;
});
// Soccer Ball class
var SoccerBall = Container.expand(function () {
var self = Container.call(this);
// Shadow
var shadow = self.attachAsset('ballShadow', {
anchorX: 0.5,
anchorY: 0.5,
y: 80,
alpha: 0.4
});
// Ball
var ball = self.attachAsset('soccerBall', {
anchorX: 0.5,
anchorY: 0.5
});
self.vx = 0;
self.vy = 0;
self.isShot = false;
self.hasScored = false;
self.hasMissed = false;
// Feedback
self.showGoal = function () {
var goalFx = LK.getAsset('goalCircle', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.7
});
self.addChild(goalFx);
tween(goalFx, {
alpha: 0
}, {
duration: 600,
onFinish: function onFinish() {
goalFx.destroy();
}
});
};
self.showMiss = function () {
var missFx = LK.getAsset('missCircle', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.7
});
self.addChild(missFx);
tween(missFx, {
alpha: 0
}, {
duration: 600,
onFinish: function onFinish() {
missFx.destroy();
}
});
};
// Ball update
self.update = function () {
if (self.isShot) {
self.x += self.vx;
self.y += self.vy;
// Simulate friction/air resistance
self.vx *= 0.99;
self.vy *= 0.99;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a472a // Dark green pitch
});
/****
* Game Code
****/
// Goal feedback (yellow)
// Miss feedback (red)
// Net posts (gray)
// Ball shadow (gray)
// Goal area (light green)
// Goalkeeper (blue)
// Soccer ball (white)
// --- Game constants ---
var goalWidth = 900;
var goalHeight = 40;
var goalY = 420; // Y position of goal line
var goalX = (2048 - goalWidth) / 2;
var goalLeftX = goalX;
var goalRightX = goalX + goalWidth;
var goalPostHeight = 180;
var shotsTotal = 10;
// --- Game state ---
var balls = [];
var shotsLeft = shotsTotal;
var score = 0;
var isShooting = false;
var canShoot = true;
var swipeStart = null;
var swipeEnd = null;
var currentBall = null;
var goalkeeper = null;
var lastGoalkeeperSpeedupScore = 0;
// --- UI Elements ---
var scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFF700
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var shotsTxt = new Text2('Shots: ' + shotsLeft, {
size: 70,
fill: 0xFFFFFF
});
shotsTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(shotsTxt);
shotsTxt.y = 120;
// --- Draw goal area ---
var goalArea = LK.getAsset('goalArea', {
anchorX: 0,
anchorY: 0,
x: goalX,
y: goalY
});
game.addChild(goalArea);
// Goal posts
var leftPost = LK.getAsset('goalPost', {
anchorX: 0.5,
anchorY: 1,
x: goalLeftX,
y: goalY + goalPostHeight
});
var rightPost = LK.getAsset('goalPost', {
anchorX: 0.5,
anchorY: 1,
x: goalRightX,
y: goalY + goalPostHeight
});
game.addChild(leftPost);
game.addChild(rightPost);
// --- Add goalkeeper ---
goalkeeper = new Goalkeeper();
goalkeeper.x = 2048 / 2;
goalkeeper.y = goalY + 40;
game.addChild(goalkeeper);
// --- Ball spawn position ---
var ballStartX = 2048 / 2;
var ballStartY = 2732 - 320;
// --- Functions ---
function spawnBall() {
var ball = new SoccerBall();
ball.x = ballStartX;
ball.y = ballStartY;
balls.push(ball);
game.addChild(ball);
currentBall = ball;
isShooting = false;
canShoot = true;
}
function resetGame() {
// Remove all balls
for (var i = 0; i < balls.length; ++i) {
balls[i].destroy();
}
balls = [];
shotsLeft = shotsTotal;
score = 0;
lastGoalkeeperSpeedupScore = 0;
scoreTxt.setText(score);
shotsTxt.setText('Shots: ' + shotsLeft);
goalkeeper.speed = 8;
goalkeeper.x = 2048 / 2;
spawnBall();
}
function shootBall(vx, vy) {
if (!currentBall || !canShoot) return;
currentBall.vx = vx;
currentBall.vy = vy;
currentBall.isShot = true;
isShooting = true;
canShoot = false;
shotsLeft -= 1;
shotsTxt.setText('Shots: ' + shotsLeft);
}
// --- Input handling (swipe or tap) ---
game.down = function (x, y, obj) {
if (!canShoot) return;
// Only allow starting swipe/tap from lower half of screen
if (y < 1800) return;
swipeStart = {
x: x,
y: y
};
swipeEnd = null;
};
game.move = function (x, y, obj) {
if (!canShoot || !swipeStart) return;
swipeEnd = {
x: x,
y: y
};
};
game.up = function (x, y, obj) {
if (!canShoot || !swipeStart) return;
swipeEnd = {
x: x,
y: y
};
// Calculate direction and power
var dx = swipeEnd.x - swipeStart.x;
var dy = swipeEnd.y - swipeStart.y;
// Only allow upward swipes/taps
if (dy > -40) {
// Not enough upward movement, treat as tap
dx = 0;
dy = -900;
}
// Clamp power
var power = Math.sqrt(dx * dx + dy * dy);
if (power < 200) power = 200;
if (power > 1200) power = 1200;
// Normalize
var norm = Math.sqrt(dx * dx + dy * dy);
var vx = 0,
vy = 0;
if (norm > 0) {
vx = dx / norm * (power / 22);
vy = dy / norm * (power / 18);
} else {
vx = 0;
vy = -power / 18;
}
shootBall(vx, vy);
swipeStart = null;
swipeEnd = null;
};
// --- Main update loop ---
game.update = function () {
// Update goalkeeper
if (goalkeeper) goalkeeper.update();
// Update balls
for (var i = balls.length - 1; i >= 0; --i) {
var ball = balls[i];
ball.update();
// Only check for scoring/miss if ball is shot and not already scored/missed
if (ball.isShot && !ball.hasScored && !ball.hasMissed) {
// Check if ball crosses goal line (y <= goalY+goalHeight)
if (ball.y <= goalY + goalHeight / 2 && ball.y > goalY - 80) {
// Check if within goal posts
if (ball.x > goalLeftX + 60 && ball.x < goalRightX - 60) {
// Check collision with goalkeeper
var keeperRect = {
x: goalkeeper.x - 110,
y: goalkeeper.y - 40,
w: 220,
h: 80
};
var ballRect = {
x: ball.x - 60,
y: ball.y - 60,
w: 120,
h: 120
};
var intersects = !(keeperRect.x + keeperRect.w < ballRect.x || keeperRect.x > ballRect.x + ballRect.w || keeperRect.y + keeperRect.h < ballRect.y || keeperRect.y > ballRect.y + ballRect.h);
if (!intersects) {
// GOAL!
ball.hasScored = true;
score += 1;
scoreTxt.setText(score);
ball.showGoal();
// Speed up goalkeeper every 2 goals
if (score - lastGoalkeeperSpeedupScore >= 2) {
goalkeeper.increaseSpeed();
lastGoalkeeperSpeedupScore = score;
}
} else {
// Saved by keeper
ball.hasMissed = true;
ball.showMiss();
}
} else {
// Missed wide
ball.hasMissed = true;
ball.showMiss();
}
}
// Missed high
if (ball.y < goalY - 100) {
if (!ball.hasScored && !ball.hasMissed) {
ball.hasMissed = true;
ball.showMiss();
}
}
}
// Remove ball if out of bounds
if (ball.y < -200 || ball.x < -200 || ball.x > 2248) {
ball.destroy();
balls.splice(i, 1);
if (currentBall === ball) currentBall = null;
}
}
// After shot, wait for ball to stop or leave screen, then spawn next ball or end game
if (isShooting && !currentBall) {
if (shotsLeft > 0) {
spawnBall();
} else {
// Game over
LK.showGameOver();
}
isShooting = false;
}
// If current ball is shot and has scored/missed, and is slow or out of bounds, remove it
if (currentBall && currentBall.isShot && (currentBall.hasScored || currentBall.hasMissed)) {
var speed = Math.sqrt(currentBall.vx * currentBall.vx + currentBall.vy * currentBall.vy);
if (speed < 2 || currentBall.y < -200 || currentBall.x < -200 || currentBall.x > 2248) {
currentBall.destroy();
for (var j = 0; j < balls.length; ++j) {
if (balls[j] === currentBall) {
balls.splice(j, 1);
break;
}
}
currentBall = null;
}
}
// Win condition: score 10 goals
if (score >= 10) {
LK.showYouWin();
}
};
// --- Start game ---
resetGame(); ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,369 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+// Goalkeeper class
+var Goalkeeper = Container.expand(function () {
+ var self = Container.call(this);
+ var keeper = self.attachAsset('goalkeeper', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 8; // Initial speed
+ self.direction = 1; // 1: right, -1: left
+ // Update
+ self.update = function () {
+ self.x += self.speed * self.direction;
+ // Bounce off posts
+ if (self.x > goalRightX - keeper.width / 2) {
+ self.x = goalRightX - keeper.width / 2;
+ self.direction = -1;
+ }
+ if (self.x < goalLeftX + keeper.width / 2) {
+ self.x = goalLeftX + keeper.width / 2;
+ self.direction = 1;
+ }
+ };
+ // Increase speed
+ self.increaseSpeed = function () {
+ self.speed += 1.5;
+ if (self.speed > 22) self.speed = 22;
+ };
+ return self;
+});
+// Soccer Ball class
+var SoccerBall = Container.expand(function () {
+ var self = Container.call(this);
+ // Shadow
+ var shadow = self.attachAsset('ballShadow', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ y: 80,
+ alpha: 0.4
+ });
+ // Ball
+ var ball = self.attachAsset('soccerBall', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.vx = 0;
+ self.vy = 0;
+ self.isShot = false;
+ self.hasScored = false;
+ self.hasMissed = false;
+ // Feedback
+ self.showGoal = function () {
+ var goalFx = LK.getAsset('goalCircle', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ alpha: 0.7
+ });
+ self.addChild(goalFx);
+ tween(goalFx, {
+ alpha: 0
+ }, {
+ duration: 600,
+ onFinish: function onFinish() {
+ goalFx.destroy();
+ }
+ });
+ };
+ self.showMiss = function () {
+ var missFx = LK.getAsset('missCircle', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ alpha: 0.7
+ });
+ self.addChild(missFx);
+ tween(missFx, {
+ alpha: 0
+ }, {
+ duration: 600,
+ onFinish: function onFinish() {
+ missFx.destroy();
+ }
+ });
+ };
+ // Ball update
+ self.update = function () {
+ if (self.isShot) {
+ self.x += self.vx;
+ self.y += self.vy;
+ // Simulate friction/air resistance
+ self.vx *= 0.99;
+ self.vy *= 0.99;
+ }
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x1a472a // Dark green pitch
+});
+
+/****
+* Game Code
+****/
+// Goal feedback (yellow)
+// Miss feedback (red)
+// Net posts (gray)
+// Ball shadow (gray)
+// Goal area (light green)
+// Goalkeeper (blue)
+// Soccer ball (white)
+// --- Game constants ---
+var goalWidth = 900;
+var goalHeight = 40;
+var goalY = 420; // Y position of goal line
+var goalX = (2048 - goalWidth) / 2;
+var goalLeftX = goalX;
+var goalRightX = goalX + goalWidth;
+var goalPostHeight = 180;
+var shotsTotal = 10;
+// --- Game state ---
+var balls = [];
+var shotsLeft = shotsTotal;
+var score = 0;
+var isShooting = false;
+var canShoot = true;
+var swipeStart = null;
+var swipeEnd = null;
+var currentBall = null;
+var goalkeeper = null;
+var lastGoalkeeperSpeedupScore = 0;
+// --- UI Elements ---
+var scoreTxt = new Text2('0', {
+ size: 120,
+ fill: 0xFFF700
+});
+scoreTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(scoreTxt);
+var shotsTxt = new Text2('Shots: ' + shotsLeft, {
+ size: 70,
+ fill: 0xFFFFFF
+});
+shotsTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(shotsTxt);
+shotsTxt.y = 120;
+// --- Draw goal area ---
+var goalArea = LK.getAsset('goalArea', {
+ anchorX: 0,
+ anchorY: 0,
+ x: goalX,
+ y: goalY
+});
+game.addChild(goalArea);
+// Goal posts
+var leftPost = LK.getAsset('goalPost', {
+ anchorX: 0.5,
+ anchorY: 1,
+ x: goalLeftX,
+ y: goalY + goalPostHeight
+});
+var rightPost = LK.getAsset('goalPost', {
+ anchorX: 0.5,
+ anchorY: 1,
+ x: goalRightX,
+ y: goalY + goalPostHeight
+});
+game.addChild(leftPost);
+game.addChild(rightPost);
+// --- Add goalkeeper ---
+goalkeeper = new Goalkeeper();
+goalkeeper.x = 2048 / 2;
+goalkeeper.y = goalY + 40;
+game.addChild(goalkeeper);
+// --- Ball spawn position ---
+var ballStartX = 2048 / 2;
+var ballStartY = 2732 - 320;
+// --- Functions ---
+function spawnBall() {
+ var ball = new SoccerBall();
+ ball.x = ballStartX;
+ ball.y = ballStartY;
+ balls.push(ball);
+ game.addChild(ball);
+ currentBall = ball;
+ isShooting = false;
+ canShoot = true;
+}
+function resetGame() {
+ // Remove all balls
+ for (var i = 0; i < balls.length; ++i) {
+ balls[i].destroy();
+ }
+ balls = [];
+ shotsLeft = shotsTotal;
+ score = 0;
+ lastGoalkeeperSpeedupScore = 0;
+ scoreTxt.setText(score);
+ shotsTxt.setText('Shots: ' + shotsLeft);
+ goalkeeper.speed = 8;
+ goalkeeper.x = 2048 / 2;
+ spawnBall();
+}
+function shootBall(vx, vy) {
+ if (!currentBall || !canShoot) return;
+ currentBall.vx = vx;
+ currentBall.vy = vy;
+ currentBall.isShot = true;
+ isShooting = true;
+ canShoot = false;
+ shotsLeft -= 1;
+ shotsTxt.setText('Shots: ' + shotsLeft);
+}
+// --- Input handling (swipe or tap) ---
+game.down = function (x, y, obj) {
+ if (!canShoot) return;
+ // Only allow starting swipe/tap from lower half of screen
+ if (y < 1800) return;
+ swipeStart = {
+ x: x,
+ y: y
+ };
+ swipeEnd = null;
+};
+game.move = function (x, y, obj) {
+ if (!canShoot || !swipeStart) return;
+ swipeEnd = {
+ x: x,
+ y: y
+ };
+};
+game.up = function (x, y, obj) {
+ if (!canShoot || !swipeStart) return;
+ swipeEnd = {
+ x: x,
+ y: y
+ };
+ // Calculate direction and power
+ var dx = swipeEnd.x - swipeStart.x;
+ var dy = swipeEnd.y - swipeStart.y;
+ // Only allow upward swipes/taps
+ if (dy > -40) {
+ // Not enough upward movement, treat as tap
+ dx = 0;
+ dy = -900;
+ }
+ // Clamp power
+ var power = Math.sqrt(dx * dx + dy * dy);
+ if (power < 200) power = 200;
+ if (power > 1200) power = 1200;
+ // Normalize
+ var norm = Math.sqrt(dx * dx + dy * dy);
+ var vx = 0,
+ vy = 0;
+ if (norm > 0) {
+ vx = dx / norm * (power / 22);
+ vy = dy / norm * (power / 18);
+ } else {
+ vx = 0;
+ vy = -power / 18;
+ }
+ shootBall(vx, vy);
+ swipeStart = null;
+ swipeEnd = null;
+};
+// --- Main update loop ---
+game.update = function () {
+ // Update goalkeeper
+ if (goalkeeper) goalkeeper.update();
+ // Update balls
+ for (var i = balls.length - 1; i >= 0; --i) {
+ var ball = balls[i];
+ ball.update();
+ // Only check for scoring/miss if ball is shot and not already scored/missed
+ if (ball.isShot && !ball.hasScored && !ball.hasMissed) {
+ // Check if ball crosses goal line (y <= goalY+goalHeight)
+ if (ball.y <= goalY + goalHeight / 2 && ball.y > goalY - 80) {
+ // Check if within goal posts
+ if (ball.x > goalLeftX + 60 && ball.x < goalRightX - 60) {
+ // Check collision with goalkeeper
+ var keeperRect = {
+ x: goalkeeper.x - 110,
+ y: goalkeeper.y - 40,
+ w: 220,
+ h: 80
+ };
+ var ballRect = {
+ x: ball.x - 60,
+ y: ball.y - 60,
+ w: 120,
+ h: 120
+ };
+ var intersects = !(keeperRect.x + keeperRect.w < ballRect.x || keeperRect.x > ballRect.x + ballRect.w || keeperRect.y + keeperRect.h < ballRect.y || keeperRect.y > ballRect.y + ballRect.h);
+ if (!intersects) {
+ // GOAL!
+ ball.hasScored = true;
+ score += 1;
+ scoreTxt.setText(score);
+ ball.showGoal();
+ // Speed up goalkeeper every 2 goals
+ if (score - lastGoalkeeperSpeedupScore >= 2) {
+ goalkeeper.increaseSpeed();
+ lastGoalkeeperSpeedupScore = score;
+ }
+ } else {
+ // Saved by keeper
+ ball.hasMissed = true;
+ ball.showMiss();
+ }
+ } else {
+ // Missed wide
+ ball.hasMissed = true;
+ ball.showMiss();
+ }
+ }
+ // Missed high
+ if (ball.y < goalY - 100) {
+ if (!ball.hasScored && !ball.hasMissed) {
+ ball.hasMissed = true;
+ ball.showMiss();
+ }
+ }
+ }
+ // Remove ball if out of bounds
+ if (ball.y < -200 || ball.x < -200 || ball.x > 2248) {
+ ball.destroy();
+ balls.splice(i, 1);
+ if (currentBall === ball) currentBall = null;
+ }
+ }
+ // After shot, wait for ball to stop or leave screen, then spawn next ball or end game
+ if (isShooting && !currentBall) {
+ if (shotsLeft > 0) {
+ spawnBall();
+ } else {
+ // Game over
+ LK.showGameOver();
+ }
+ isShooting = false;
+ }
+ // If current ball is shot and has scored/missed, and is slow or out of bounds, remove it
+ if (currentBall && currentBall.isShot && (currentBall.hasScored || currentBall.hasMissed)) {
+ var speed = Math.sqrt(currentBall.vx * currentBall.vx + currentBall.vy * currentBall.vy);
+ if (speed < 2 || currentBall.y < -200 || currentBall.x < -200 || currentBall.x > 2248) {
+ currentBall.destroy();
+ for (var j = 0; j < balls.length; ++j) {
+ if (balls[j] === currentBall) {
+ balls.splice(j, 1);
+ break;
+ }
+ }
+ currentBall = null;
+ }
+ }
+ // Win condition: score 10 goals
+ if (score >= 10) {
+ LK.showYouWin();
+ }
+};
+// --- Start game ---
+resetGame();
\ No newline at end of file