/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { playerScore: 0, computerScore: 0, currentRound: 1, totalRounds: 5, difficulty: 1 }); /**** * Classes ****/ var Ball = Container.expand(function () { var self = Container.call(this); var ballGraphics = self.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 0; self.direction = { x: 0, y: 0 }; self.isMoving = false; self.curveFactor = 0; self.reset = function () { self.x = 1024; // Center of field horizontally self.y = 1700; // Moved ball closer to the goal self.isMoving = false; self.speed = 0; self.direction = { x: 0, y: 0 }; self.curveFactor = 0; self.scaleX = 1; self.scaleY = 1; }; self.shoot = function (targetX, targetY, power, curve) { if (self.isMoving) return; // Calculate direction vector self.direction.x = targetX - self.x; self.direction.y = targetY - self.y; // Normalize direction vector var length = Math.sqrt(self.direction.x * self.direction.x + self.direction.y * self.direction.y); self.direction.x /= length; self.direction.y /= length; // Set speed based on power (0-100) self.speed = 5 + power * 15 / 100; // Set curve factor (-1 to 1) self.curveFactor = curve; self.isMoving = true; // Play kick sound LK.getSound('kick').play(); }; self.update = function () { if (!self.isMoving) return; // Apply curve to direction (simulating curved shot) if (self.curveFactor !== 0) { var perpX = -self.direction.y; var perpY = self.direction.x; self.direction.x += perpX * self.curveFactor * 0.01; self.direction.y += perpY * self.curveFactor * 0.01; // Renormalize direction after applying curve var length = Math.sqrt(self.direction.x * self.direction.x + self.direction.y * self.direction.y); self.direction.x /= length; self.direction.y /= length; } // Move ball self.x += self.direction.x * self.speed; self.y += self.direction.y * self.speed; // Simulate perspective by scaling the ball as it moves away var scaleFactor = 1 - (2732 - self.y) / 2732 * 0.5; self.scaleX = scaleFactor; self.scaleY = scaleFactor; // Apply gravity effect to slow down the ball self.speed *= 0.99; // Stop the ball if it's moving too slowly if (self.speed < 0.5) { self.isMoving = false; } }; self.reset(); return self; }); var GameState = Container.expand(function () { var self = Container.call(this); self.STATES = { AIMING: 'aiming', POWER: 'power', SHOOTING: 'shooting', SAVING: 'saving', RESULT: 'result', GAME_OVER: 'gameOver' }; self.currentState = self.STATES.AIMING; self.playerTurn = true; self.setState = function (newState) { self.currentState = newState; }; self.nextState = function () { switch (self.currentState) { case self.STATES.AIMING: self.setState(self.STATES.POWER); break; case self.STATES.POWER: self.setState(self.STATES.SHOOTING); break; case self.STATES.SHOOTING: self.setState(self.STATES.RESULT); break; case self.STATES.SAVING: self.setState(self.STATES.RESULT); break; case self.STATES.RESULT: if (storage.currentRound >= storage.totalRounds) { self.setState(self.STATES.GAME_OVER); } else { self.switchTurn(); self.setState(self.STATES.AIMING); } break; } }; self.switchTurn = function () { self.playerTurn = !self.playerTurn; // Increment round when both players had their turn if (self.playerTurn) { storage.currentRound++; } }; return self; }); var Goal = Container.expand(function () { var self = Container.call(this); var goalGraphics = self.attachAsset('goal', { anchorX: 0.5, anchorY: 0.5 }); self.width = 800; self.height = 300; self.reset = function () { self.x = 1024; // Center of field horizontally self.y = 500; // Top of field }; self.isInGoal = function (x, y) { return x >= self.x - self.width / 2 && x <= self.x + self.width / 2 && y >= self.y - self.height / 2 && y <= self.y + self.height / 2; }; self.reset(); return self; }); var Goalkeeper = Container.expand(function () { var self = Container.call(this); var goalkeeperGraphics = self.attachAsset('goalkeeper', { anchorX: 0.5, anchorY: 0.5 }); self.targetX = 0; self.targetY = 0; self.speed = 15; self.diving = false; self.diveDirection = 0; // -1 left, 0 center, 1 right self.difficulty = 1; self.reset = function () { self.x = 1024; // Center of goal horizontally self.y = 650; // Goal line self.diving = false; self.diveDirection = 0; goalkeeperGraphics.rotation = 0; }; self.dive = function (direction) { if (self.diving) return; self.diving = true; self.diveDirection = direction; // Rotate goalkeeper based on dive direction if (direction < 0) { goalkeeperGraphics.rotation = -Math.PI / 4; // 45 degrees left } else if (direction > 0) { goalkeeperGraphics.rotation = Math.PI / 4; // 45 degrees right } }; self.computerMove = function (ballX, ballY, difficulty) { if (self.diving) return; var predictAccuracy = Math.min(0.5 + difficulty * 0.1, 0.9); // Higher difficulty = better prediction var randomFactor = Math.random(); if (randomFactor < predictAccuracy) { // AI predicts correctly where the ball will go self.targetX = ballX; } else { // AI makes a random guess self.targetX = 1024 + (Math.random() * 600 - 300); } // Determine dive direction var diveDirection = 0; if (self.targetX < self.x - 100) diveDirection = -1;else if (self.targetX > self.x + 100) diveDirection = 1; // Dive after a short reaction time based on difficulty var reactionTime = Math.max(300 - difficulty * 30, 100); LK.setTimeout(function () { self.dive(diveDirection); }, reactionTime); }; self.update = function () { if (!self.diving) return; // Move goalkeeper during dive self.x += self.speed * self.diveDirection; // Limit goalkeeper movement within goal area if (self.x < 700) self.x = 700; if (self.x > 1348) self.x = 1348; }; self.reset(); return self; }); var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.reset = function () { self.x = 1024; // Center of field horizontally self.y = 1800; // Moved player closer to the goal }; self.celebrate = function () { // Make player jump in celebration tween(self, { y: self.y - 100 }, { duration: 400, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { y: 1800 }, { duration: 400, easing: tween.easeIn }); } }); }; self.disappointment = function () { // Make player slump down in disappointment tween(self, { scaleY: 0.8 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { scaleY: 1 }, { duration: 500, easing: tween.easeIn }); } }); }; self.reset(); return self; }); var PowerMeter = Container.expand(function () { var self = Container.call(this); var background = self.attachAsset('power_meter', { anchorX: 0.5, anchorY: 0.5 }); var indicator = self.attachAsset('power_indicator', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 140 // Start at bottom of power meter }); self.power = 0; self.increasing = true; self.active = false; self.startMeter = function () { self.power = 0; self.increasing = true; self.active = true; indicator.y = 140; // Reset to bottom }; self.stopMeter = function () { self.active = false; return self.power; }; self.update = function () { if (!self.active) return; if (self.increasing) { self.power += 2; if (self.power >= 100) { self.power = 100; self.increasing = false; } } else { self.power -= 2; if (self.power <= 0) { self.power = 0; self.increasing = true; } } // Update indicator position indicator.y = 140 - self.power * 280 / 100; }; self.reset = function () { self.x = 200; self.y = 1366; // Center vertically self.power = 0; self.active = false; indicator.y = 140; // Reset to bottom }; self.reset(); return self; }); var ScoreDisplay = Container.expand(function () { var self = Container.call(this); // Score text self.scoreText = new Text2('0 - 0', { size: 100, fill: 0xFFFFFF }); self.scoreText.anchor.set(0.5, 0); self.addChild(self.scoreText); // Round text self.roundText = new Text2('Round 1/5', { size: 60, fill: 0xFFFFFF }); self.roundText.anchor.set(0.5, 0); self.roundText.y = 120; self.addChild(self.roundText); self.updateScore = function (playerScore, computerScore) { self.scoreText.setText(playerScore + ' - ' + computerScore); }; self.updateRound = function (currentRound, totalRounds) { self.roundText.setText('Round ' + currentRound + '/' + totalRounds); }; return self; }); var Target = Container.expand(function () { var self = Container.call(this); var targetGraphics = self.attachAsset('target', { anchorX: 0.5, anchorY: 0.5 }); self.visible = false; self.show = function (x, y) { self.x = x; self.y = y; self.visible = true; // Pulse animation self.scale.set(0.7, 0.7); tween(self.scale, { x: 1, y: 1 }, { duration: 300, easing: tween.easeOut }); }; self.hide = function () { self.visible = false; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x33AA33 }); /**** * Game Code ****/ // Play background crowd noise LK.playMusic('background_crowd', { volume: 0.3 }); // Create background field var background = LK.getAsset('bg_field', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366 }); game.addChild(background); // Create game objects var gameState = new GameState(); var ball = new Ball(); var goalkeeper = new Goalkeeper(); var goal = new Goal(); var player = new Player(); var powerMeter = new PowerMeter(); var target = new Target(); // Add objects to game game.addChild(goal); game.addChild(goalkeeper); game.addChild(player); game.addChild(ball); game.addChild(powerMeter); game.addChild(target); // Create UI score display var scoreDisplay = new ScoreDisplay(); LK.gui.top.addChild(scoreDisplay); scoreDisplay.updateScore(storage.playerScore, storage.computerScore); scoreDisplay.updateRound(storage.currentRound, storage.totalRounds); // Game status text var statusText = new Text2('Tap where you want to aim', { size: 60, fill: 0xFFFFFF }); statusText.anchor.set(0.5, 0); LK.gui.center.addChild(statusText); statusText.y = -200; // Instructions text var instructionText = new Text2('', { size: 50, fill: 0xFFFF00 }); instructionText.anchor.set(0.5, 0); LK.gui.center.addChild(instructionText); instructionText.y = -120; // Reset the game and prepare for a new round function resetRound() { ball.reset(); goalkeeper.reset(); player.reset(); powerMeter.reset(); target.hide(); if (gameState.playerTurn) { // Player is shooter statusText.setText('Tap where you want to aim'); instructionText.setText('Choose a spot inside the goal'); gameState.setState(gameState.STATES.AIMING); } else { // Player is goalkeeper statusText.setText('Get ready to save!'); instructionText.setText('Swipe in the direction you want to dive'); gameState.setState(gameState.STATES.SAVING); // Computer shoots after a delay LK.setTimeout(function () { if (gameState.currentState === gameState.STATES.SAVING) { computerShoot(); } }, 2000); } scoreDisplay.updateScore(storage.playerScore, storage.computerScore); scoreDisplay.updateRound(storage.currentRound, storage.totalRounds); } // Computer AI shoots the ball function computerShoot() { // Computer chooses a random target inside the goal var targetX = goal.x + (Math.random() * 600 - 300); var targetY = goal.y + (Math.random() * 200 - 100); // Calculate a random power between var power = 50 + Math.random() * 40; // Calculate a random curve factor var curve = Math.random() * 0.6 - 0.3; // Show target briefly target.show(targetX, targetY); // Shoot the ball ball.shoot(targetX, targetY, power, curve); statusText.setText('Try to save it!'); instructionText.setText('Swipe left or right to dive'); } // Check if the ball is saved by the goalkeeper function checkSave() { // Calculate distance between ball and goalkeeper var dx = ball.x - goalkeeper.x; var dy = ball.y - goalkeeper.y; var distance = Math.sqrt(dx * dx + dy * dy); // Check if goalkeeper saved the ball (within his reach) var saved = distance < 150; if (saved) { // Play save sound LK.getSound('save').play(); // Flash effect to show the save LK.effects.flashObject(goalkeeper, 0xFFFFFF, 500); statusText.setText('SAVED!'); if (gameState.playerTurn) { // Computer saved player's shot instructionText.setText('The goalkeeper saved your shot!'); } else { // Player saved computer's shot instructionText.setText('Great save!'); storage.playerScore++; } } else if (goal.isInGoal(ball.x, ball.y)) { // Ball went in the goal - it's a score! LK.getSound('goal').play(); statusText.setText('GOAL!'); if (gameState.playerTurn) { // Player scored instructionText.setText('You scored!'); storage.playerScore++; player.celebrate(); } else { // Computer scored instructionText.setText('They scored past you!'); storage.computerScore++; } } else { // Ball missed the goal LK.getSound('miss').play(); statusText.setText('MISSED!'); if (gameState.playerTurn) { // Player missed instructionText.setText('Your shot went wide!'); player.disappointment(); } else { // Computer missed instructionText.setText('Their shot went wide!'); } } // Update score display scoreDisplay.updateScore(storage.playerScore, storage.computerScore); // Move to next state after a delay LK.setTimeout(function () { gameState.nextState(); if (gameState.currentState === gameState.STATES.GAME_OVER) { endGame(); } else { resetRound(); } }, 2000); } // End the game and show final result function endGame() { var resultText = ''; if (storage.playerScore > storage.computerScore) { resultText = 'You Win! ' + storage.playerScore + ' - ' + storage.computerScore; LK.showYouWin(); } else if (storage.playerScore < storage.computerScore) { resultText = 'You Lose! ' + storage.playerScore + ' - ' + storage.computerScore; LK.showGameOver(); } else { resultText = 'It\'s a Draw! ' + storage.playerScore + ' - ' + storage.computerScore; LK.showYouWin(); } statusText.setText(resultText); instructionText.setText('Game Over'); // Reset game for next round storage.playerScore = 0; storage.computerScore = 0; storage.currentRound = 1; } // Game click/tap handler game.down = function (x, y, obj) { if (gameState.currentState === gameState.STATES.AIMING && gameState.playerTurn) { // Only allow aiming inside the goal if (goal.isInGoal(x, y)) { target.show(x, y); statusText.setText('Set your power'); instructionText.setText('Tap to stop the power meter'); gameState.nextState(); powerMeter.startMeter(); } } else if (gameState.currentState === gameState.STATES.POWER && gameState.playerTurn) { var power = powerMeter.stopMeter(); statusText.setText('Shooting!'); instructionText.setText(''); // Shoot the ball with random curve var curve = Math.random() * 0.4 - 0.2; ball.shoot(target.x, target.y, power, curve); // Computer goalkeeper tries to save goalkeeper.computerMove(target.x, target.y, storage.difficulty); gameState.nextState(); } else if (gameState.currentState === gameState.STATES.SAVING && !gameState.playerTurn) { // Record start of swipe for goalkeeper dive game.swipeStartX = x; game.swipeStartY = y; } }; // Game drag release handler game.up = function (x, y, obj) { if (gameState.currentState === gameState.STATES.SAVING && !gameState.playerTurn && game.swipeStartX) { // Calculate swipe direction var swipeDx = x - game.swipeStartX; var swipeThreshold = 50; var diveDirection = 0; if (swipeDx < -swipeThreshold) diveDirection = -1;else if (swipeDx > swipeThreshold) diveDirection = 1; // Make goalkeeper dive goalkeeper.dive(diveDirection); // Reset swipe tracking game.swipeStartX = null; } }; // Main game update loop game.update = function () { // Update game objects ball.update(); goalkeeper.update(); powerMeter.update(); // Handle state-specific logic if (gameState.currentState === gameState.STATES.SHOOTING || gameState.currentState === gameState.STATES.SAVING) { // Check if ball has stopped moving if (ball.isMoving === false && ball.y < 1000) { gameState.setState(gameState.STATES.RESULT); checkSave(); } // Check if ball has gone far off screen if (ball.y < -200 || ball.x < -200 || ball.x > 2248) { ball.isMoving = false; gameState.setState(gameState.STATES.RESULT); checkSave(); } } }; // Initialize the game with first round resetRound();
===================================================================
--- original.js
+++ change.js
@@ -27,9 +27,9 @@
self.isMoving = false;
self.curveFactor = 0;
self.reset = function () {
self.x = 1024; // Center of field horizontally
- self.y = 2200; // Bottom of field where player stands
+ self.y = 1700; // Moved ball closer to the goal
self.isMoving = false;
self.speed = 0;
self.direction = {
x: 0,
@@ -220,9 +220,9 @@
anchorY: 0.5
});
self.reset = function () {
self.x = 1024; // Center of field horizontally
- self.y = 2300; // Bottom of field
+ self.y = 1800; // Moved player closer to the goal
};
self.celebrate = function () {
// Make player jump in celebration
tween(self, {
@@ -231,9 +231,9 @@
duration: 400,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
- y: 2300
+ y: 1800
}, {
duration: 400,
easing: tween.easeIn
});
soccer ball 2d ingame asset high contrast no shadows. In-Game asset. 2d. High contrast. No shadows
soccer goal 2d ingame asset high contrast no shadows. In-Game asset. 2d. High contrast. No shadows
male soccer goalkeeper with hands up and not holding ball 2d ingame asset high contrast no shadows. In-Game asset. 2d. High contrast. No shadows
target logo 2d ingame asset high contrast no shadows. In-Game asset. 2d. High contrast. No shadows
soccer field 2d ingame asset high contrast no shadows. In-Game asset. 2d. High contrast. No shadows
male soccer striker not holding ball 2d ingame asset high contrast no shadows. In-Game asset. 2d. High contrast. No shadows
spectator character 2d in game asset high contrast no shadows. In-Game asset. 2d. High contrast. No shadows