/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
// Ball class
var Ball = Container.expand(function () {
var self = Container.call(this);
var ballAsset = self.attachAsset('football', {
anchorX: 0.5,
anchorY: 0.5
});
// Ball state
self.isMoving = false;
self.vx = 0;
self.vy = 0;
self.targetX = 0;
self.targetY = 0;
self.speed = 60; // pixels per tick
// Called every tick
self.update = function () {
if (self.isMoving) {
// Move towards target
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < self.speed || dist === 0) {
self.x = self.targetX;
self.y = self.targetY;
self.isMoving = false;
// Ball reached target (goal line or missed)
onBallStopped();
} else {
self.x += self.vx;
self.y += self.vy;
}
}
};
// Start moving towards (tx, ty)
self.shootTo = function (tx, ty) {
var dx = tx - self.x;
var dy = ty - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist === 0) {
self.vx = 0;
self.vy = 0;
} else {
self.vx = self.speed * dx / dist;
self.vy = self.speed * dy / dist;
}
self.targetX = tx;
self.targetY = ty;
self.isMoving = true;
};
return self;
});
// Goalkeeper class
var Goalkeeper = Container.expand(function () {
var self = Container.call(this);
var keeperAsset = self.attachAsset('goalkeeper', {
anchorX: 0.5,
anchorY: 0.5
});
// Movement boundaries (goal area)
self.leftLimit = 2048 / 2 - 450 + 110;
self.rightLimit = 2048 / 2 + 450 - 110;
self.y = 600; // Goal line y
// Move to a random x within limits
self.moveToRandom = function () {
var newX = self.leftLimit + Math.random() * (self.rightLimit - self.leftLimit);
var duration = 600 + Math.random() * 700; // 0.6s to 1.3s
tween(self, {
x: newX
}, {
duration: duration,
easing: tween.cubicInOut
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2e7d32 // Green pitch
});
/****
* Game Code
****/
// Penalty spot
// Goal area (for visual reference)
// Goalkeeper
// Football (ball)
// Game constants
var GOAL_Y = 600;
var PENALTY_SPOT_Y = 1800;
var PENALTY_SPOT_X = 2048 / 2;
var GOAL_WIDTH = 900;
var GOAL_LEFT = 2048 / 2 - GOAL_WIDTH / 2;
var GOAL_RIGHT = 2048 / 2 + GOAL_WIDTH / 2;
var MAX_SHOTS = 5;
// Game state
var shotsTaken = 0;
var goalsScored = 0;
var isShooting = false;
var ball = null;
var goalkeeper = null;
var dragStart = null;
var dragEnd = null;
var canShoot = true;
var highScore = storage.highScore || 0;
// UI
var scoreTxt = new Text2('0/' + MAX_SHOTS, {
size: 120,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var highScoreTxt = new Text2('Best: ' + highScore, {
size: 60,
fill: 0xFFFF00
});
highScoreTxt.anchor.set(0.5, 0);
LK.gui.topRight.addChild(highScoreTxt);
// Draw goal area
var goalAsset = LK.getAsset('goal', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: GOAL_Y
});
game.addChild(goalAsset);
// Draw penalty spot
var spotAsset = LK.getAsset('spot', {
anchorX: 0.5,
anchorY: 0.5,
x: PENALTY_SPOT_X,
y: PENALTY_SPOT_Y
});
game.addChild(spotAsset);
// Create goalkeeper
goalkeeper = new Goalkeeper();
goalkeeper.x = 2048 / 2;
goalkeeper.y = GOAL_Y;
game.addChild(goalkeeper);
// Create ball
function resetBall() {
if (ball) {
ball.destroy();
}
ball = new Ball();
ball.x = PENALTY_SPOT_X;
ball.y = PENALTY_SPOT_Y;
game.addChild(ball);
}
resetBall();
// Helper: update score UI
function updateScoreUI() {
scoreTxt.setText(goalsScored + '/' + MAX_SHOTS);
if (goalsScored > highScore) {
highScore = goalsScored;
storage.highScore = highScore;
highScoreTxt.setText('Best: ' + highScore);
}
}
// Helper: check if ball scored
function isGoal(ballX) {
// Ball must be within goal posts (allow some margin for ball width)
var margin = 60;
return ballX > GOAL_LEFT + margin && ballX < GOAL_RIGHT - margin;
}
// Called when ball stops moving (goal line or missed)
function onBallStopped() {
isShooting = false;
canShoot = false;
shotsTaken += 1;
// Check for collision with goalkeeper
var ballRect = new Rectangle(ball.x - 60, ball.y - 60, 120, 120);
var keeperRect = new Rectangle(goalkeeper.x - 110, goalkeeper.y - 40, 220, 80);
var hitKeeper = rectsIntersect(ballRect, keeperRect);
var scored = false;
if (!hitKeeper && isGoal(ball.x) && ball.y <= GOAL_Y + 20) {
// Goal!
goalsScored += 1;
scored = true;
LK.effects.flashObject(ball, 0x00ff00, 600);
} else if (hitKeeper && ball.y <= GOAL_Y + 40) {
// Saved!
LK.effects.flashObject(goalkeeper, 0xff0000, 600);
} else {
// Missed
LK.effects.flashObject(ball, 0xffff00, 600);
}
updateScoreUI();
// Next shot or end game
LK.setTimeout(function () {
if (shotsTaken >= MAX_SHOTS) {
// Game over
LK.showGameOver();
} else {
resetBall();
canShoot = true;
goalkeeper.moveToRandom();
}
}, 900);
}
// Rectangle intersection helper
function rectsIntersect(r1, r2) {
return !(r2.x > r1.x + r1.width || r2.x + r2.width < r1.x || r2.y > r1.y + r1.height || r2.y + r2.height < r1.y);
}
// Drag/swipe to shoot
dragStart = null;
dragEnd = null;
// Only allow shooting if not already shooting and not waiting for next shot
game.down = function (x, y, obj) {
if (!canShoot || isShooting) return;
// Only allow starting drag near the ball
var dx = x - ball.x;
var dy = y - ball.y;
if (dx * dx + dy * dy < 120 * 120) {
dragStart = {
x: x,
y: y
};
dragEnd = null;
}
};
game.move = function (x, y, obj) {
if (!canShoot || isShooting) return;
if (dragStart) {
dragEnd = {
x: x,
y: y
};
// Optionally, show a line or indicator (not implemented due to asset limitations)
}
};
game.up = function (x, y, obj) {
if (!canShoot || isShooting) return;
if (dragStart && dragEnd) {
// Calculate direction
var dx = dragEnd.x - dragStart.x;
var dy = dragEnd.y - dragStart.y;
// Only allow upward shots (towards goal)
if (dy < -60) {
// Normalize direction, set target at goal line
var ratio = (PENALTY_SPOT_Y - GOAL_Y) / -dy;
var targetX = ball.x + dx * ratio;
// Clamp targetX within goal area
if (targetX < GOAL_LEFT + 60) targetX = GOAL_LEFT + 60;
if (targetX > GOAL_RIGHT - 60) targetX = GOAL_RIGHT - 60;
var targetY = GOAL_Y + 10;
isShooting = true;
ball.shootTo(targetX, targetY);
}
}
dragStart = null;
dragEnd = null;
};
// Main update loop
game.update = function () {
if (ball) ball.update();
// Move goalkeeper if not tweening
if (!isShooting && canShoot && LK.ticks % 60 === 0) {
goalkeeper.moveToRandom();
}
};
// Reset game state on new game
function resetGameState() {
shotsTaken = 0;
goalsScored = 0;
isShooting = false;
canShoot = true;
updateScoreUI();
resetBall();
goalkeeper.x = 2048 / 2;
goalkeeper.y = GOAL_Y;
goalkeeper.moveToRandom();
}
resetGameState();
// When game is reset (after game over), re-initialize state
LK.on('gameStart', function () {
resetGameState();
}); ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,290 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1");
+
+/****
+* Classes
+****/
+// Ball class
+var Ball = Container.expand(function () {
+ var self = Container.call(this);
+ var ballAsset = self.attachAsset('football', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Ball state
+ self.isMoving = false;
+ self.vx = 0;
+ self.vy = 0;
+ self.targetX = 0;
+ self.targetY = 0;
+ self.speed = 60; // pixels per tick
+ // Called every tick
+ self.update = function () {
+ if (self.isMoving) {
+ // Move towards target
+ var dx = self.targetX - self.x;
+ var dy = self.targetY - self.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist < self.speed || dist === 0) {
+ self.x = self.targetX;
+ self.y = self.targetY;
+ self.isMoving = false;
+ // Ball reached target (goal line or missed)
+ onBallStopped();
+ } else {
+ self.x += self.vx;
+ self.y += self.vy;
+ }
+ }
+ };
+ // Start moving towards (tx, ty)
+ self.shootTo = function (tx, ty) {
+ var dx = tx - self.x;
+ var dy = ty - self.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist === 0) {
+ self.vx = 0;
+ self.vy = 0;
+ } else {
+ self.vx = self.speed * dx / dist;
+ self.vy = self.speed * dy / dist;
+ }
+ self.targetX = tx;
+ self.targetY = ty;
+ self.isMoving = true;
+ };
+ return self;
+});
+// Goalkeeper class
+var Goalkeeper = Container.expand(function () {
+ var self = Container.call(this);
+ var keeperAsset = self.attachAsset('goalkeeper', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Movement boundaries (goal area)
+ self.leftLimit = 2048 / 2 - 450 + 110;
+ self.rightLimit = 2048 / 2 + 450 - 110;
+ self.y = 600; // Goal line y
+ // Move to a random x within limits
+ self.moveToRandom = function () {
+ var newX = self.leftLimit + Math.random() * (self.rightLimit - self.leftLimit);
+ var duration = 600 + Math.random() * 700; // 0.6s to 1.3s
+ tween(self, {
+ x: newX
+ }, {
+ duration: duration,
+ easing: tween.cubicInOut
+ });
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
+ backgroundColor: 0x2e7d32 // Green pitch
+});
+
+/****
+* Game Code
+****/
+// Penalty spot
+// Goal area (for visual reference)
+// Goalkeeper
+// Football (ball)
+// Game constants
+var GOAL_Y = 600;
+var PENALTY_SPOT_Y = 1800;
+var PENALTY_SPOT_X = 2048 / 2;
+var GOAL_WIDTH = 900;
+var GOAL_LEFT = 2048 / 2 - GOAL_WIDTH / 2;
+var GOAL_RIGHT = 2048 / 2 + GOAL_WIDTH / 2;
+var MAX_SHOTS = 5;
+// Game state
+var shotsTaken = 0;
+var goalsScored = 0;
+var isShooting = false;
+var ball = null;
+var goalkeeper = null;
+var dragStart = null;
+var dragEnd = null;
+var canShoot = true;
+var highScore = storage.highScore || 0;
+// UI
+var scoreTxt = new Text2('0/' + MAX_SHOTS, {
+ size: 120,
+ fill: 0xFFFFFF
+});
+scoreTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(scoreTxt);
+var highScoreTxt = new Text2('Best: ' + highScore, {
+ size: 60,
+ fill: 0xFFFF00
+});
+highScoreTxt.anchor.set(0.5, 0);
+LK.gui.topRight.addChild(highScoreTxt);
+// Draw goal area
+var goalAsset = LK.getAsset('goal', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 2048 / 2,
+ y: GOAL_Y
+});
+game.addChild(goalAsset);
+// Draw penalty spot
+var spotAsset = LK.getAsset('spot', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: PENALTY_SPOT_X,
+ y: PENALTY_SPOT_Y
+});
+game.addChild(spotAsset);
+// Create goalkeeper
+goalkeeper = new Goalkeeper();
+goalkeeper.x = 2048 / 2;
+goalkeeper.y = GOAL_Y;
+game.addChild(goalkeeper);
+// Create ball
+function resetBall() {
+ if (ball) {
+ ball.destroy();
+ }
+ ball = new Ball();
+ ball.x = PENALTY_SPOT_X;
+ ball.y = PENALTY_SPOT_Y;
+ game.addChild(ball);
+}
+resetBall();
+// Helper: update score UI
+function updateScoreUI() {
+ scoreTxt.setText(goalsScored + '/' + MAX_SHOTS);
+ if (goalsScored > highScore) {
+ highScore = goalsScored;
+ storage.highScore = highScore;
+ highScoreTxt.setText('Best: ' + highScore);
+ }
+}
+// Helper: check if ball scored
+function isGoal(ballX) {
+ // Ball must be within goal posts (allow some margin for ball width)
+ var margin = 60;
+ return ballX > GOAL_LEFT + margin && ballX < GOAL_RIGHT - margin;
+}
+// Called when ball stops moving (goal line or missed)
+function onBallStopped() {
+ isShooting = false;
+ canShoot = false;
+ shotsTaken += 1;
+ // Check for collision with goalkeeper
+ var ballRect = new Rectangle(ball.x - 60, ball.y - 60, 120, 120);
+ var keeperRect = new Rectangle(goalkeeper.x - 110, goalkeeper.y - 40, 220, 80);
+ var hitKeeper = rectsIntersect(ballRect, keeperRect);
+ var scored = false;
+ if (!hitKeeper && isGoal(ball.x) && ball.y <= GOAL_Y + 20) {
+ // Goal!
+ goalsScored += 1;
+ scored = true;
+ LK.effects.flashObject(ball, 0x00ff00, 600);
+ } else if (hitKeeper && ball.y <= GOAL_Y + 40) {
+ // Saved!
+ LK.effects.flashObject(goalkeeper, 0xff0000, 600);
+ } else {
+ // Missed
+ LK.effects.flashObject(ball, 0xffff00, 600);
+ }
+ updateScoreUI();
+ // Next shot or end game
+ LK.setTimeout(function () {
+ if (shotsTaken >= MAX_SHOTS) {
+ // Game over
+ LK.showGameOver();
+ } else {
+ resetBall();
+ canShoot = true;
+ goalkeeper.moveToRandom();
+ }
+ }, 900);
+}
+// Rectangle intersection helper
+function rectsIntersect(r1, r2) {
+ return !(r2.x > r1.x + r1.width || r2.x + r2.width < r1.x || r2.y > r1.y + r1.height || r2.y + r2.height < r1.y);
+}
+// Drag/swipe to shoot
+dragStart = null;
+dragEnd = null;
+// Only allow shooting if not already shooting and not waiting for next shot
+game.down = function (x, y, obj) {
+ if (!canShoot || isShooting) return;
+ // Only allow starting drag near the ball
+ var dx = x - ball.x;
+ var dy = y - ball.y;
+ if (dx * dx + dy * dy < 120 * 120) {
+ dragStart = {
+ x: x,
+ y: y
+ };
+ dragEnd = null;
+ }
+};
+game.move = function (x, y, obj) {
+ if (!canShoot || isShooting) return;
+ if (dragStart) {
+ dragEnd = {
+ x: x,
+ y: y
+ };
+ // Optionally, show a line or indicator (not implemented due to asset limitations)
+ }
+};
+game.up = function (x, y, obj) {
+ if (!canShoot || isShooting) return;
+ if (dragStart && dragEnd) {
+ // Calculate direction
+ var dx = dragEnd.x - dragStart.x;
+ var dy = dragEnd.y - dragStart.y;
+ // Only allow upward shots (towards goal)
+ if (dy < -60) {
+ // Normalize direction, set target at goal line
+ var ratio = (PENALTY_SPOT_Y - GOAL_Y) / -dy;
+ var targetX = ball.x + dx * ratio;
+ // Clamp targetX within goal area
+ if (targetX < GOAL_LEFT + 60) targetX = GOAL_LEFT + 60;
+ if (targetX > GOAL_RIGHT - 60) targetX = GOAL_RIGHT - 60;
+ var targetY = GOAL_Y + 10;
+ isShooting = true;
+ ball.shootTo(targetX, targetY);
+ }
+ }
+ dragStart = null;
+ dragEnd = null;
+};
+// Main update loop
+game.update = function () {
+ if (ball) ball.update();
+ // Move goalkeeper if not tweening
+ if (!isShooting && canShoot && LK.ticks % 60 === 0) {
+ goalkeeper.moveToRandom();
+ }
+};
+// Reset game state on new game
+function resetGameState() {
+ shotsTaken = 0;
+ goalsScored = 0;
+ isShooting = false;
+ canShoot = true;
+ updateScoreUI();
+ resetBall();
+ goalkeeper.x = 2048 / 2;
+ goalkeeper.y = GOAL_Y;
+ goalkeeper.moveToRandom();
+}
+resetGameState();
+// When game is reset (after game over), re-initialize state
+LK.on('gameStart', function () {
+ resetGameState();
});
\ No newline at end of file
A football player named Ercan Kara. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
draw a soccer ball use a light gray and black. 2d. High contrast. No shadows
gray bar . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
gray iron bar. In-Game asset. High contrast. No shadows