/**** * 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 = 2200; // Bottom of field where player stands 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 = 2300; // Bottom of field }; 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: 2300 }, { 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
@@ -1,6 +1,613 @@
-/****
+/****
+* 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 = 2200; // Bottom of field where player stands
+ 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 = 2300; // Bottom of field
+ };
+ 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: 2300
+ }, {
+ 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: 0x000000
-});
\ No newline at end of file
+ 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();
\ No newline at end of file
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