/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Goalkeeper = Container.expand(function () {
var self = Container.call(this);
var keeperGraphics = self.attachAsset('goalkeeper', {
anchorX: 0.5,
anchorY: 1.0
});
self.minX = 0;
self.maxX = 0;
self.isDiving = false;
self.dive = function (direction) {
if (!self.isDiving) {
self.isDiving = true;
var targetX = direction > 0 ? self.maxX : self.minX;
tween(self, {
x: targetX,
scaleX: direction > 0 ? 1.2 : -1.2
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 1
}, {
duration: 200
});
self.isDiving = false;
}
});
}
};
return self;
});
var SoccerBall = Container.expand(function () {
var self = Container.call(this);
var ballGraphics = self.attachAsset('soccerBall', {
anchorX: 0.5,
anchorY: 0.5
});
self.speedX = 0;
self.speedY = 0;
self.isActive = true;
self.update = function () {
if (self.isActive) {
self.x += self.speedX;
self.y += self.speedY;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x4CAF50
});
/****
* Game Code
****/
// Game variables
var goalkeeper;
var soccerBalls = [];
var goalsAllowed = 0;
var maxGoals = 5;
var consecutiveSaves = 0;
var ballSpawnCounter = 0;
var ballSpawnRate = 120; // frames between balls
var gameSpeed = 1;
var isDragging = false;
// Create goal structure
var goalBackground = game.addChild(LK.getAsset('goal', {
anchorX: 0.5,
anchorY: 1.0,
alpha: 0.3
}));
goalBackground.x = 2048 / 2;
goalBackground.y = 2732 - 200;
// Goal posts
var leftPost = game.addChild(LK.getAsset('goalPost', {
anchorX: 0.5,
anchorY: 1.0
}));
leftPost.x = 2048 / 2 - 400;
leftPost.y = 2732 - 200;
var rightPost = game.addChild(LK.getAsset('goalPost', {
anchorX: 0.5,
anchorY: 1.0
}));
rightPost.x = 2048 / 2 + 400;
rightPost.y = 2732 - 200;
// Goal line
var goalLine = game.addChild(LK.getAsset('goalLine', {
anchorX: 0.5,
anchorY: 0.5
}));
goalLine.x = 2048 / 2;
goalLine.y = 2732 - 200;
// Create goalkeeper
goalkeeper = game.addChild(new Goalkeeper());
goalkeeper.x = 2048 / 2;
goalkeeper.y = 2732 - 200;
goalkeeper.minX = 2048 / 2 - 350;
goalkeeper.maxX = 2048 / 2 + 350;
// UI Elements
var scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var goalsTxt = new Text2('Goals: 0/5', {
size: 60,
fill: 0xFFFFFF
});
goalsTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(goalsTxt);
var streakTxt = new Text2('Saves: 0', {
size: 50,
fill: 0xFFFF00
});
streakTxt.anchor.set(0, 0);
LK.gui.left.addChild(streakTxt);
// Touch/drag controls
game.down = function (x, y, obj) {
isDragging = true;
var clampedX = Math.max(goalkeeper.minX, Math.min(goalkeeper.maxX, x));
goalkeeper.x = clampedX;
};
game.move = function (x, y, obj) {
if (isDragging) {
var clampedX = Math.max(goalkeeper.minX, Math.min(goalkeeper.maxX, x));
goalkeeper.x = clampedX;
}
};
game.up = function (x, y, obj) {
isDragging = false;
};
// Spawn soccer ball
function spawnSoccerBall() {
var ball = new SoccerBall();
// Random spawn position along top of screen
ball.x = Math.random() * 1848 + 100;
ball.y = 100;
// Calculate trajectory toward goal
var targetX = 2048 / 2 + (Math.random() - 0.5) * 600;
var targetY = 2732 - 250;
var distance = Math.sqrt(Math.pow(targetX - ball.x, 2) + Math.pow(targetY - ball.y, 2));
var speed = 8 + Math.random() * 4 * gameSpeed;
ball.speedX = (targetX - ball.x) / distance * speed;
ball.speedY = (targetY - ball.y) / distance * speed;
ball.lastY = ball.y;
ball.lastActive = true;
soccerBalls.push(ball);
game.addChild(ball);
}
// Main game update loop
game.update = function () {
// Update ball spawn counter
ballSpawnCounter++;
if (ballSpawnCounter >= ballSpawnRate) {
spawnSoccerBall();
ballSpawnCounter = 0;
// Increase difficulty over time
if (ballSpawnRate > 60) {
ballSpawnRate = Math.max(60, ballSpawnRate - 1);
}
gameSpeed += 0.01;
}
// Update soccer balls
for (var i = soccerBalls.length - 1; i >= 0; i--) {
var ball = soccerBalls[i];
if (!ball.isActive) continue;
// Check if ball went off screen (missed goal)
if (ball.lastY < 2732 - 180 && ball.y >= 2732 - 180 && ball.isActive) {
// Check if ball is within goal area
if (ball.x > 2048 / 2 - 400 && ball.x < 2048 / 2 + 400) {
// Check if goalkeeper saved it
if (ball.intersects(goalkeeper)) {
// SAVE!
ball.isActive = false;
LK.setScore(LK.getScore() + 10);
consecutiveSaves++;
// Bonus points for consecutive saves
if (consecutiveSaves > 1) {
LK.setScore(LK.getScore() + consecutiveSaves * 5);
}
// Diving save bonus
if (goalkeeper.isDiving) {
LK.setScore(LK.getScore() + 20);
LK.effects.flashObject(goalkeeper, 0xffff00, 500);
}
LK.getSound('save').play();
LK.effects.flashObject(ball, 0x00ff00, 300);
// Trigger goalkeeper dive animation
var direction = ball.x > goalkeeper.x ? 1 : -1;
goalkeeper.dive(direction);
} else {
// GOAL!
goalsAllowed++;
consecutiveSaves = 0;
LK.getSound('goal').play();
LK.effects.flashScreen(0xff0000, 500);
if (goalsAllowed >= maxGoals) {
LK.getSound('whistle').play();
LK.showGameOver();
return;
}
}
// Remove ball
ball.destroy();
soccerBalls.splice(i, 1);
continue;
}
}
// Remove balls that go completely off screen
if (ball.y > 2732 + 100 || ball.x < -100 || ball.x > 2148) {
ball.destroy();
soccerBalls.splice(i, 1);
continue;
}
// Update last position
ball.lastY = ball.y;
}
// Update UI
scoreTxt.setText('Score: ' + LK.getScore());
goalsTxt.setText('Goals: ' + goalsAllowed + '/' + maxGoals);
streakTxt.setText('Saves: ' + consecutiveSaves);
}; ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,237 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+var Goalkeeper = Container.expand(function () {
+ var self = Container.call(this);
+ var keeperGraphics = self.attachAsset('goalkeeper', {
+ anchorX: 0.5,
+ anchorY: 1.0
+ });
+ self.minX = 0;
+ self.maxX = 0;
+ self.isDiving = false;
+ self.dive = function (direction) {
+ if (!self.isDiving) {
+ self.isDiving = true;
+ var targetX = direction > 0 ? self.maxX : self.minX;
+ tween(self, {
+ x: targetX,
+ scaleX: direction > 0 ? 1.2 : -1.2
+ }, {
+ duration: 300,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ tween(self, {
+ scaleX: 1
+ }, {
+ duration: 200
+ });
+ self.isDiving = false;
+ }
+ });
+ }
+ };
+ return self;
+});
+var SoccerBall = Container.expand(function () {
+ var self = Container.call(this);
+ var ballGraphics = self.attachAsset('soccerBall', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speedX = 0;
+ self.speedY = 0;
+ self.isActive = true;
+ self.update = function () {
+ if (self.isActive) {
+ self.x += self.speedX;
+ self.y += self.speedY;
+ }
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x4CAF50
+});
+
+/****
+* Game Code
+****/
+// Game variables
+var goalkeeper;
+var soccerBalls = [];
+var goalsAllowed = 0;
+var maxGoals = 5;
+var consecutiveSaves = 0;
+var ballSpawnCounter = 0;
+var ballSpawnRate = 120; // frames between balls
+var gameSpeed = 1;
+var isDragging = false;
+// Create goal structure
+var goalBackground = game.addChild(LK.getAsset('goal', {
+ anchorX: 0.5,
+ anchorY: 1.0,
+ alpha: 0.3
+}));
+goalBackground.x = 2048 / 2;
+goalBackground.y = 2732 - 200;
+// Goal posts
+var leftPost = game.addChild(LK.getAsset('goalPost', {
+ anchorX: 0.5,
+ anchorY: 1.0
+}));
+leftPost.x = 2048 / 2 - 400;
+leftPost.y = 2732 - 200;
+var rightPost = game.addChild(LK.getAsset('goalPost', {
+ anchorX: 0.5,
+ anchorY: 1.0
+}));
+rightPost.x = 2048 / 2 + 400;
+rightPost.y = 2732 - 200;
+// Goal line
+var goalLine = game.addChild(LK.getAsset('goalLine', {
+ anchorX: 0.5,
+ anchorY: 0.5
+}));
+goalLine.x = 2048 / 2;
+goalLine.y = 2732 - 200;
+// Create goalkeeper
+goalkeeper = game.addChild(new Goalkeeper());
+goalkeeper.x = 2048 / 2;
+goalkeeper.y = 2732 - 200;
+goalkeeper.minX = 2048 / 2 - 350;
+goalkeeper.maxX = 2048 / 2 + 350;
+// UI Elements
+var scoreTxt = new Text2('Score: 0', {
+ size: 80,
+ fill: 0xFFFFFF
+});
+scoreTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(scoreTxt);
+var goalsTxt = new Text2('Goals: 0/5', {
+ size: 60,
+ fill: 0xFFFFFF
+});
+goalsTxt.anchor.set(1, 0);
+LK.gui.topRight.addChild(goalsTxt);
+var streakTxt = new Text2('Saves: 0', {
+ size: 50,
+ fill: 0xFFFF00
+});
+streakTxt.anchor.set(0, 0);
+LK.gui.left.addChild(streakTxt);
+// Touch/drag controls
+game.down = function (x, y, obj) {
+ isDragging = true;
+ var clampedX = Math.max(goalkeeper.minX, Math.min(goalkeeper.maxX, x));
+ goalkeeper.x = clampedX;
+};
+game.move = function (x, y, obj) {
+ if (isDragging) {
+ var clampedX = Math.max(goalkeeper.minX, Math.min(goalkeeper.maxX, x));
+ goalkeeper.x = clampedX;
+ }
+};
+game.up = function (x, y, obj) {
+ isDragging = false;
+};
+// Spawn soccer ball
+function spawnSoccerBall() {
+ var ball = new SoccerBall();
+ // Random spawn position along top of screen
+ ball.x = Math.random() * 1848 + 100;
+ ball.y = 100;
+ // Calculate trajectory toward goal
+ var targetX = 2048 / 2 + (Math.random() - 0.5) * 600;
+ var targetY = 2732 - 250;
+ var distance = Math.sqrt(Math.pow(targetX - ball.x, 2) + Math.pow(targetY - ball.y, 2));
+ var speed = 8 + Math.random() * 4 * gameSpeed;
+ ball.speedX = (targetX - ball.x) / distance * speed;
+ ball.speedY = (targetY - ball.y) / distance * speed;
+ ball.lastY = ball.y;
+ ball.lastActive = true;
+ soccerBalls.push(ball);
+ game.addChild(ball);
+}
+// Main game update loop
+game.update = function () {
+ // Update ball spawn counter
+ ballSpawnCounter++;
+ if (ballSpawnCounter >= ballSpawnRate) {
+ spawnSoccerBall();
+ ballSpawnCounter = 0;
+ // Increase difficulty over time
+ if (ballSpawnRate > 60) {
+ ballSpawnRate = Math.max(60, ballSpawnRate - 1);
+ }
+ gameSpeed += 0.01;
+ }
+ // Update soccer balls
+ for (var i = soccerBalls.length - 1; i >= 0; i--) {
+ var ball = soccerBalls[i];
+ if (!ball.isActive) continue;
+ // Check if ball went off screen (missed goal)
+ if (ball.lastY < 2732 - 180 && ball.y >= 2732 - 180 && ball.isActive) {
+ // Check if ball is within goal area
+ if (ball.x > 2048 / 2 - 400 && ball.x < 2048 / 2 + 400) {
+ // Check if goalkeeper saved it
+ if (ball.intersects(goalkeeper)) {
+ // SAVE!
+ ball.isActive = false;
+ LK.setScore(LK.getScore() + 10);
+ consecutiveSaves++;
+ // Bonus points for consecutive saves
+ if (consecutiveSaves > 1) {
+ LK.setScore(LK.getScore() + consecutiveSaves * 5);
+ }
+ // Diving save bonus
+ if (goalkeeper.isDiving) {
+ LK.setScore(LK.getScore() + 20);
+ LK.effects.flashObject(goalkeeper, 0xffff00, 500);
+ }
+ LK.getSound('save').play();
+ LK.effects.flashObject(ball, 0x00ff00, 300);
+ // Trigger goalkeeper dive animation
+ var direction = ball.x > goalkeeper.x ? 1 : -1;
+ goalkeeper.dive(direction);
+ } else {
+ // GOAL!
+ goalsAllowed++;
+ consecutiveSaves = 0;
+ LK.getSound('goal').play();
+ LK.effects.flashScreen(0xff0000, 500);
+ if (goalsAllowed >= maxGoals) {
+ LK.getSound('whistle').play();
+ LK.showGameOver();
+ return;
+ }
+ }
+ // Remove ball
+ ball.destroy();
+ soccerBalls.splice(i, 1);
+ continue;
+ }
+ }
+ // Remove balls that go completely off screen
+ if (ball.y > 2732 + 100 || ball.x < -100 || ball.x > 2148) {
+ ball.destroy();
+ soccerBalls.splice(i, 1);
+ continue;
+ }
+ // Update last position
+ ball.lastY = ball.y;
+ }
+ // Update UI
+ scoreTxt.setText('Score: ' + LK.getScore());
+ goalsTxt.setText('Goals: ' + goalsAllowed + '/' + maxGoals);
+ streakTxt.setText('Saves: ' + consecutiveSaves);
+};
\ No newline at end of file