User prompt
Add a 1vs1 mode where you face a bot, the first one to score or stop 5 goals wins ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add another mode where you have to stop goals that are increasingly difficult, unpredictable, and fast. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
After that, you have a menu with three difficulties: Easy, you only have to stop 25 slow goals, Normal, you have to stop 50 fast goals, and Hard, you have to stop 100 very fast goals.
Remix started
Copy Goalkeeper Hero
/****
* 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.targetX = 1024; // Center of goal
self.moveSpeed = 15;
self.update = function () {
// Smooth movement toward target position
var dx = self.targetX - self.x;
if (Math.abs(dx) > 5) {
self.x += dx * 0.2;
}
};
self.setTarget = function (x) {
// Keep goalkeeper within goal bounds
var goalLeft = 424;
var goalRight = 1624;
self.targetX = Math.max(goalLeft, Math.min(goalRight, x));
};
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.active = true;
self.update = function () {
if (!self.active) return;
self.x += self.speedX;
self.y += self.speedY;
// Add slight gravity effect
self.speedY += 0.2;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Game variables
var goalkeeper;
var balls = [];
var ballSpawnTimer = 0;
var ballSpawnInterval = 120; // 2 seconds at 60fps
var difficulty = 1;
var saves = 0;
var gameSpeed = 1;
var gameStarted = false;
var selectedDifficulty = null;
var difficultySettings = {
easy: {
goalTarget: 25,
ballSpeed: 1,
spawnRate: 150,
name: "Easy"
},
normal: {
goalTarget: 50,
ballSpeed: 1.5,
spawnRate: 120,
name: "Normal"
},
hard: {
goalTarget: 100,
ballSpeed: 2.5,
spawnRate: 90,
name: "Hard"
}
};
// Create field
var field = game.addChild(LK.getAsset('field', {
anchorX: 0,
anchorY: 1,
x: 0,
y: 2732
}));
// Create goal structure
var goalNet = game.addChild(LK.getAsset('goalNet', {
width: 1200,
anchorX: 0.5,
anchorY: 1,
x: 1024,
y: 2732
}));
goalNet.alpha = 0.3;
var leftPost = game.addChild(LK.getAsset('goalPost', {
anchorX: 0.5,
anchorY: 1,
x: 424,
y: 2732
}));
var rightPost = game.addChild(LK.getAsset('goalPost', {
anchorX: 0.5,
anchorY: 1,
x: 1624,
y: 2732
}));
// Create goalkeeper
goalkeeper = game.addChild(new Goalkeeper());
goalkeeper.x = 1024;
goalkeeper.y = 2732;
// Create UI
var scoreTxt = new Text2('Saves: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Create difficulty selection menu
var menuContainer = new Container();
game.addChild(menuContainer);
var titleText = new Text2('Select Difficulty', {
size: 120,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 800;
menuContainer.addChild(titleText);
// Easy button
var easyButton = new Container();
var easyBg = LK.getAsset('goalPost', {
width: 400,
height: 120,
anchorX: 0.5,
anchorY: 0.5,
color: 0x00ff00
});
var easyText = new Text2('Easy - 25 Goals', {
size: 60,
fill: 0x000000
});
easyText.anchor.set(0.5, 0.5);
easyButton.addChild(easyBg);
easyButton.addChild(easyText);
easyButton.x = 1024;
easyButton.y = 1200;
menuContainer.addChild(easyButton);
// Normal button
var normalButton = new Container();
var normalBg = LK.getAsset('goalPost', {
width: 400,
height: 120,
anchorX: 0.5,
anchorY: 0.5,
color: 0xffff00
});
var normalText = new Text2('Normal - 50 Goals', {
size: 60,
fill: 0x000000
});
normalText.anchor.set(0.5, 0.5);
normalButton.addChild(normalBg);
normalButton.addChild(normalText);
normalButton.x = 1024;
normalButton.y = 1400;
menuContainer.addChild(normalButton);
// Hard button
var hardButton = new Container();
var hardBg = LK.getAsset('goalPost', {
width: 400,
height: 120,
anchorX: 0.5,
anchorY: 0.5,
color: 0xff0000
});
var hardText = new Text2('Hard - 100 Goals', {
size: 60,
fill: 0x000000
});
hardText.anchor.set(0.5, 0.5);
hardButton.addChild(hardBg);
hardButton.addChild(hardText);
hardButton.x = 1024;
hardButton.y = 1600;
menuContainer.addChild(hardButton);
// Button click handlers
easyButton.down = function (x, y, obj) {
startGame('easy');
};
normalButton.down = function (x, y, obj) {
startGame('normal');
};
hardButton.down = function (x, y, obj) {
startGame('hard');
};
// Function to start game with selected difficulty
function startGame(difficultyLevel) {
selectedDifficulty = difficultyLevel;
gameStarted = true;
menuContainer.visible = false;
var settings = difficultySettings[difficultyLevel];
gameSpeed = settings.ballSpeed;
ballSpawnInterval = settings.spawnRate;
scoreTxt.setText('Saves: 0/' + settings.goalTarget + ' (' + settings.name + ')');
}
// Ball spawning function
function spawnBall() {
var ball = new SoccerBall();
// Random spawn position across the field width
ball.x = Math.random() * 1600 + 224;
ball.y = 100;
// Calculate trajectory toward goal
var targetX = Math.random() * 1200 + 424; // Random point in goal area
var targetY = 2732 - 100; // Goal height
var distance = Math.sqrt(Math.pow(targetX - ball.x, 2) + Math.pow(targetY - ball.y, 2));
var speed = 3 * gameSpeed;
ball.speedX = (targetX - ball.x) / distance * speed;
ball.speedY = (targetY - ball.y) / distance * speed;
balls.push(ball);
game.addChild(ball);
LK.getSound('kick').play();
}
// Touch controls
var isDragging = false;
game.down = function (x, y, obj) {
isDragging = true;
goalkeeper.setTarget(x);
};
game.move = function (x, y, obj) {
if (isDragging) {
goalkeeper.setTarget(x);
}
};
game.up = function (x, y, obj) {
isDragging = false;
};
// Main game loop
game.update = function () {
// Don't run game logic until difficulty is selected
if (!gameStarted) return;
// Spawn balls
ballSpawnTimer++;
if (ballSpawnTimer >= ballSpawnInterval) {
spawnBall();
ballSpawnTimer = 0;
}
// Update and check balls
for (var i = balls.length - 1; i >= 0; i--) {
var ball = balls[i];
if (!ball.active) continue;
// Check if ball went past goal line (goal scored)
if (ball.y > 2732) {
LK.getSound('goal').play();
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
return;
}
// Check for save (collision with goalkeeper)
if (ball.intersects(goalkeeper) && ball.active) {
ball.active = false;
saves++;
LK.setScore(saves);
var settings = difficultySettings[selectedDifficulty];
scoreTxt.setText('Saves: ' + saves + '/' + settings.goalTarget + ' (' + settings.name + ')');
// Visual feedback for save
LK.effects.flashObject(goalkeeper, 0x00ff00, 500);
tween(goalkeeper, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(goalkeeper, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeIn
});
}
});
LK.getSound('save').play();
// Remove ball
ball.destroy();
balls.splice(i, 1);
continue;
}
// Remove balls that went off screen (missed)
if (ball.y < -100 || ball.x < -100 || ball.x > 2148) {
ball.destroy();
balls.splice(i, 1);
continue;
}
// Check if ball is out of bounds horizontally (safe)
if ((ball.x < 424 || ball.x > 1624) && ball.y > 2332) {
ball.active = false;
ball.destroy();
balls.splice(i, 1);
continue;
}
}
// Win condition - based on selected difficulty
var settings = difficultySettings[selectedDifficulty];
if (saves >= settings.goalTarget) {
LK.showYouWin();
}
};
// LK engine handles pause/play functionality automatically through built-in systems ===================================================================
--- original.js
+++ change.js
@@ -65,8 +65,30 @@
var ballSpawnInterval = 120; // 2 seconds at 60fps
var difficulty = 1;
var saves = 0;
var gameSpeed = 1;
+var gameStarted = false;
+var selectedDifficulty = null;
+var difficultySettings = {
+ easy: {
+ goalTarget: 25,
+ ballSpeed: 1,
+ spawnRate: 150,
+ name: "Easy"
+ },
+ normal: {
+ goalTarget: 50,
+ ballSpeed: 1.5,
+ spawnRate: 120,
+ name: "Normal"
+ },
+ hard: {
+ goalTarget: 100,
+ ballSpeed: 2.5,
+ spawnRate: 90,
+ name: "Hard"
+ }
+};
// Create field
var field = game.addChild(LK.getAsset('field', {
anchorX: 0,
anchorY: 1,
@@ -104,8 +126,96 @@
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
+// Create difficulty selection menu
+var menuContainer = new Container();
+game.addChild(menuContainer);
+var titleText = new Text2('Select Difficulty', {
+ size: 120,
+ fill: 0xFFFFFF
+});
+titleText.anchor.set(0.5, 0.5);
+titleText.x = 1024;
+titleText.y = 800;
+menuContainer.addChild(titleText);
+// Easy button
+var easyButton = new Container();
+var easyBg = LK.getAsset('goalPost', {
+ width: 400,
+ height: 120,
+ anchorX: 0.5,
+ anchorY: 0.5,
+ color: 0x00ff00
+});
+var easyText = new Text2('Easy - 25 Goals', {
+ size: 60,
+ fill: 0x000000
+});
+easyText.anchor.set(0.5, 0.5);
+easyButton.addChild(easyBg);
+easyButton.addChild(easyText);
+easyButton.x = 1024;
+easyButton.y = 1200;
+menuContainer.addChild(easyButton);
+// Normal button
+var normalButton = new Container();
+var normalBg = LK.getAsset('goalPost', {
+ width: 400,
+ height: 120,
+ anchorX: 0.5,
+ anchorY: 0.5,
+ color: 0xffff00
+});
+var normalText = new Text2('Normal - 50 Goals', {
+ size: 60,
+ fill: 0x000000
+});
+normalText.anchor.set(0.5, 0.5);
+normalButton.addChild(normalBg);
+normalButton.addChild(normalText);
+normalButton.x = 1024;
+normalButton.y = 1400;
+menuContainer.addChild(normalButton);
+// Hard button
+var hardButton = new Container();
+var hardBg = LK.getAsset('goalPost', {
+ width: 400,
+ height: 120,
+ anchorX: 0.5,
+ anchorY: 0.5,
+ color: 0xff0000
+});
+var hardText = new Text2('Hard - 100 Goals', {
+ size: 60,
+ fill: 0x000000
+});
+hardText.anchor.set(0.5, 0.5);
+hardButton.addChild(hardBg);
+hardButton.addChild(hardText);
+hardButton.x = 1024;
+hardButton.y = 1600;
+menuContainer.addChild(hardButton);
+// Button click handlers
+easyButton.down = function (x, y, obj) {
+ startGame('easy');
+};
+normalButton.down = function (x, y, obj) {
+ startGame('normal');
+};
+hardButton.down = function (x, y, obj) {
+ startGame('hard');
+};
+// Function to start game with selected difficulty
+function startGame(difficultyLevel) {
+ selectedDifficulty = difficultyLevel;
+ gameStarted = true;
+ menuContainer.visible = false;
+ var settings = difficultySettings[difficultyLevel];
+ gameSpeed = settings.ballSpeed;
+ ballSpawnInterval = settings.spawnRate;
+ scoreTxt.setText('Saves: 0/' + settings.goalTarget + ' (' + settings.name + ')');
+}
// Ball spawning function
function spawnBall() {
var ball = new SoccerBall();
// Random spawn position across the field width
@@ -114,9 +224,9 @@
// Calculate trajectory toward goal
var targetX = Math.random() * 1200 + 424; // Random point in goal area
var targetY = 2732 - 100; // Goal height
var distance = Math.sqrt(Math.pow(targetX - ball.x, 2) + Math.pow(targetY - ball.y, 2));
- var speed = (3 + difficulty) * gameSpeed;
+ var speed = 3 * gameSpeed;
ball.speedX = (targetX - ball.x) / distance * speed;
ball.speedY = (targetY - ball.y) / distance * speed;
balls.push(ball);
game.addChild(ball);
@@ -137,21 +247,15 @@
isDragging = false;
};
// Main game loop
game.update = function () {
+ // Don't run game logic until difficulty is selected
+ if (!gameStarted) return;
// Spawn balls
ballSpawnTimer++;
if (ballSpawnTimer >= ballSpawnInterval) {
spawnBall();
ballSpawnTimer = 0;
- // Increase difficulty over time
- if (ballSpawnInterval > 60) {
- ballSpawnInterval -= 2;
- }
- if (LK.ticks % 600 === 0) {
- // Every 10 seconds
- difficulty += 0.2;
- }
}
// Update and check balls
for (var i = balls.length - 1; i >= 0; i--) {
var ball = balls[i];
@@ -167,9 +271,10 @@
if (ball.intersects(goalkeeper) && ball.active) {
ball.active = false;
saves++;
LK.setScore(saves);
- scoreTxt.setText('Saves: ' + saves);
+ var settings = difficultySettings[selectedDifficulty];
+ scoreTxt.setText('Saves: ' + saves + '/' + settings.goalTarget + ' (' + settings.name + ')');
// Visual feedback for save
LK.effects.flashObject(goalkeeper, 0x00ff00, 500);
tween(goalkeeper, {
scaleX: 1.3,
@@ -206,10 +311,11 @@
balls.splice(i, 1);
continue;
}
}
- // Win condition - 50 saves
- if (saves >= 50) {
+ // Win condition - based on selected difficulty
+ var settings = difficultySettings[selectedDifficulty];
+ if (saves >= settings.goalTarget) {
LK.showYouWin();
}
};
// LK engine handles pause/play functionality automatically through built-in systems
\ No newline at end of file
A common soccer ball made of leather. In-Game asset. 2d. High contrast. No shadows. Cartoon
5-year-old boy with his back turned wearing a worn t-shirt and work gloves. In-Game asset. 2d. High contrast. No shadows. Cartoon
A religious street area. In-Game asset. 2d. High contrast. No shadows
Goal net. In-Game asset. 2d. High contrast. No shadows