User prompt
Ai do sometimes random move
User prompt
Red can move and ai get starter
User prompt
Red is ai controled
User prompt
Please fix the bug: 'ReferenceError: leftGoal is not defined' in or related to this line: 'var inLeftGoal = ball.intersects(leftGoal);' Line Number: 340
User prompt
Remove all horizantal
User prompt
Please fix the bug: 'ReferenceError: leftGoalPostLeft is not defined' in or related to this line: 'var leftLeftNow = ball.intersects(leftGoalPostLeft);' Line Number: 226
User prompt
Make horizontal
User prompt
Make horizon talep
User prompt
2 players can touch the screen
User prompt
Remove ai and the game play 2 players
User prompt
When ball stucks red give up and game finish
User prompt
When ball touch goal post ball Bounce that
User prompt
Get smallee
User prompt
Narrow the goal post and get symetri goal
User prompt
A little bit go big goal post
User prompt
Goal post make slim and near the goal
User prompt
Greater goal post ın goal left and right side
User prompt
Make goal post
User prompt
Ball stop the when the game start but whoever touch the ball, ball cant stop anymore and go Faster
User prompt
Ball cant stop
User prompt
Ai get smartter
User prompt
Ball cant stop
User prompt
When ball stuck he try hit right side
User prompt
Ai target for oppenets side not own
User prompt
Ai cant try score own goal
/**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1976d2 // Blue field background }); /**** * Game Code ****/ ; // --- Timer --- var timerSeconds = 0; var timerRunning = true; var timerTxt = new Text2('0:00', { size: 90, fill: 0xffffff, font: "Impact, Arial Black, Tahoma" }); timerTxt.anchor.set(0.5, 1); timerTxt.x = LK.gui.width / 2; // Place timer at top center LK.gui.top.addChild(timerTxt); timerTxt.y = 0; ; // Track dragging state for both players by touchId var draggingPlayers = {}; // { touchId: player } // Convert global (event) coordinates to local game coordinates function toGameCoords(x, y) { // LK events provide coordinates in game space already return { x: x, y: y }; } // Handle touch/mouse down: start dragging if on player game.down = function (x, y, obj) { // Use obj.event.identifier for multi-touch, fallback to 0 for mouse var touchId = obj && obj.event && typeof obj.event.identifier !== "undefined" ? obj.event.identifier : 0; // Check if the down event is on the blue player var dx = x - player.x; var dy = y - player.y; var r = player.width / 2; if (dx * dx + dy * dy <= r * r) { draggingPlayers[touchId] = player; return; } // Check if the down event is on the red player (opponent) var dx2 = x - opponent.x; var dy2 = y - opponent.y; var r2 = opponent.width / 2; if (dx2 * dx2 + dy2 * dy2 <= r2 * r2) { draggingPlayers[touchId] = opponent; return; } }; // Handle touch/mouse move: move player if dragging game.move = function (x, y, obj) { // Use obj.event.identifier for multi-touch, fallback to 0 for mouse var touchId = obj && obj.event && typeof obj.event.identifier !== "undefined" ? obj.event.identifier : 0; var draggingPlayer = draggingPlayers[touchId]; if (draggingPlayer) { if (draggingPlayer === player) { // Blue player (top side) var minX = field.x - field.width / 2 + player.width / 2; var maxX = field.x + field.width / 2 - player.width / 2; var minY = field.y - field.height / 2 + player.height / 2; var maxY = field.y; // Center line is the max for top player draggingPlayer.x = Math.max(minX, Math.min(maxX, x)); draggingPlayer.y = Math.max(minY, Math.min(maxY - player.height / 2, y)); } else if (draggingPlayer === opponent) { // Red player (bottom side) var minX2 = field.x - field.width / 2 + opponent.width / 2; var maxX2 = field.x + field.width / 2 - opponent.width / 2; var minY2 = field.y; // Center line is the min for bottom player var maxY2 = field.y + field.height / 2 - opponent.height / 2; draggingPlayer.x = Math.max(minX2, Math.min(maxX2, x)); draggingPlayer.y = Math.max(minY2 + opponent.height / 2, Math.min(maxY2, y)); } } }; // Handle touch/mouse up: stop dragging game.up = function (x, y, obj) { // Use obj.event.identifier for multi-touch, fallback to 0 for mouse var touchId = obj && obj.event && typeof obj.event.identifier !== "undefined" ? obj.event.identifier : 0; delete draggingPlayers[touchId]; }; ; ; // Track last intersection state between player and ball var lastPlayerBallIntersecting = false; // Update loop to check for player touching ball game.update = function () { // --- Timer update --- if (timerRunning) { if (typeof game._lastTimerTick === "undefined") { game._lastTimerTick = Date.now(); } var now = Date.now(); if (now - game._lastTimerTick >= 1000) { timerSeconds += 1; game._lastTimerTick += 1000; // Format as M:SS var min = Math.floor(timerSeconds / 60); var sec = timerSeconds % 60; timerTxt.setText(min + ":" + (sec < 10 ? "0" : "") + sec); } } // No AI logic: opponent is now player 2 and is controlled by drag/touch // Check if player is touching the ball (collision/intersection) var isIntersecting = player.intersects(ball); // Detect the exact moment player starts touching the ball if (!lastPlayerBallIntersecting && isIntersecting) { // Calculate direction from player to ball var dx = ball.x - player.x; var dy = ball.y - player.y; var dist = Math.sqrt(dx * dx + dy * dy) || 1; // Give the ball a velocity away from the player (EVEN FASTER than before) ball.vx = dx / dist * 70; ball.vy = dy / dist * 70; LK.effects.flashObject(ball, 0x1976d2, 200); } // AI: Red player can also kick the ball if touching, from any side if (opponent.intersects(ball)) { // Check if ball is in a corner var minBallX = field.x - field.width / 2 + ball.width / 2; var maxBallX = field.x + field.width / 2 - ball.width / 2; var minBallY = field.y - field.height / 2 + ball.height / 2; var maxBallY = field.y + field.height / 2 - ball.height / 2; var atLeft = ball.x <= minBallX + 1; var atRight = ball.x >= maxBallX - 1; var atTop = ball.y <= minBallY + 1; var atBottom = ball.y >= maxBallY - 1; // --- Ball stuck detection --- if (typeof ball.stuckFrames === "undefined") ball.stuckFrames = 0; if (typeof ball.lastStuckX === "undefined") ball.lastStuckX = ball.x; if (typeof ball.lastStuckY === "undefined") ball.lastStuckY = ball.y; // If the ball hasn't moved much in 10 frames, consider it stuck var stuckThreshold = 6; if (Math.abs(ball.x - ball.lastStuckX) < stuckThreshold && Math.abs(ball.y - ball.lastStuckY) < stuckThreshold) { ball.stuckFrames++; } else { ball.stuckFrames = 0; ball.lastStuckX = ball.x; ball.lastStuckY = ball.y; } // If the ball is stuck for too long, red gives up and the game finishes if (ball.stuckFrames > 90) { // 90 frames ~1.5 seconds at 60fps timerRunning = false; LK.effects.flashScreen(0xff0000, 600); LK.showGameOver(); return; } var dxr, dyr; if ((atLeft || atRight) && (atTop || atBottom)) { // Ball is in a corner, AI tries to hit it toward the center of the field dxr = field.x - ball.x; dyr = field.y - ball.y; } else if (ball.stuckFrames > 12) { // Ball is stuck: AI tries to hit the right side of the ball // Always aim to the right (positive X direction) dxr = 1; dyr = 0; // Add a little bias toward the field center to avoid infinite right wall hits dxr += (field.x - ball.x) * 0.005; dyr += (field.y - ball.y) * 0.01; } else { // Normal: hit from AI to ball direction dxr = ball.x - opponent.x; dyr = ball.y - opponent.y; } var distr = Math.sqrt(dxr * dxr + dyr * dyr) || 1; ball.vx = dxr / distr * 50; ball.vy = dyr / distr * 50; LK.effects.flashObject(ball, 0xd32f2f, 200); } // Ball activation: Ball is stopped at start, but after first touch, it never stops and goes faster if (typeof ball.activated === "undefined") ball.activated = false; if (!ball.activated && (player.intersects(ball) || opponent.intersects(ball))) { ball.activated = true; // Give a small nudge in a random direction if ball is perfectly still if (ball.vx === 0 && ball.vy === 0) { var angle = Math.random() * Math.PI * 2; ball.vx = Math.cos(angle) * 18; ball.vy = Math.sin(angle) * 18; } } // Move the ball if it has velocity if (typeof ball.vx === "number" && typeof ball.vy === "number") { // --- Ball bounce off goal posts (horizontal) --- // Track last intersection for each post if (typeof ball.lastLeftGoalPostLeftIntersect === "undefined") ball.lastLeftGoalPostLeftIntersect = false; if (typeof ball.lastLeftGoalPostRightIntersect === "undefined") ball.lastLeftGoalPostRightIntersect = false; if (typeof ball.lastRightGoalPostLeftIntersect === "undefined") ball.lastRightGoalPostLeftIntersect = false; if (typeof ball.lastRightGoalPostRightIntersect === "undefined") ball.lastRightGoalPostRightIntersect = false; // Left goal post left var leftLeftNow = ball.intersects(leftGoalPostLeft); if (!ball.lastLeftGoalPostLeftIntersect && leftLeftNow) { // Bounce: reflect velocity, add a little randomness var dx = ball.x - (leftGoalPostLeft.x - leftGoalPostLeft.width / 2); var dy = ball.y - leftGoalPostLeft.y; var dist = Math.sqrt(dx * dx + dy * dy) || 1; ball.vx = dx / dist * Math.max(Math.abs(ball.vx), 30); ball.vy = dy / dist * Math.max(Math.abs(ball.vy), 30); LK.effects.flashObject(ball, 0xffff00, 120); } ball.lastLeftGoalPostLeftIntersect = leftLeftNow; // Left goal post right var leftRightNow = ball.intersects(leftGoalPostRight); if (!ball.lastLeftGoalPostRightIntersect && leftRightNow) { var dx = ball.x - (leftGoalPostRight.x + leftGoalPostRight.width / 2); var dy = ball.y - leftGoalPostRight.y; var dist = Math.sqrt(dx * dx + dy * dy) || 1; ball.vx = dx / dist * Math.max(Math.abs(ball.vx), 30); ball.vy = dy / dist * Math.max(Math.abs(ball.vy), 30); LK.effects.flashObject(ball, 0xffff00, 120); } ball.lastLeftGoalPostRightIntersect = leftRightNow; // Right goal post left var rightLeftNow = ball.intersects(rightGoalPostLeft); if (!ball.lastRightGoalPostLeftIntersect && rightLeftNow) { var dx = ball.x - (rightGoalPostLeft.x - rightGoalPostLeft.width / 2); var dy = ball.y - rightGoalPostLeft.y; var dist = Math.sqrt(dx * dx + dy * dy) || 1; ball.vx = dx / dist * Math.max(Math.abs(ball.vx), 30); ball.vy = dy / dist * Math.max(Math.abs(ball.vy), 30); LK.effects.flashObject(ball, 0xffff00, 120); } ball.lastRightGoalPostLeftIntersect = rightLeftNow; // Right goal post right var rightRightNow = ball.intersects(rightGoalPostRight); if (!ball.lastRightGoalPostRightIntersect && rightRightNow) { var dx = ball.x - (rightGoalPostRight.x + rightGoalPostRight.width / 2); var dy = ball.y - rightGoalPostRight.y; var dist = Math.sqrt(dx * dx + dy * dy) || 1; ball.vx = dx / dist * Math.max(Math.abs(ball.vx), 30); ball.vy = dy / dist * Math.max(Math.abs(ball.vy), 30); LK.effects.flashObject(ball, 0xffff00, 120); } ball.lastRightGoalPostRightIntersect = rightRightNow; // Track lastX for side detection if (typeof ball.lastX === "undefined") ball.lastX = ball.x; // Detect crossing from left to right side (player to opponent) var centerX = field.x; if (ball.lastX <= centerX && ball.x > centerX) { // Ball just crossed to right side, speed up! ball.vx *= 1.25; ball.vy *= 1.25; } // Detect crossing from right to left side (opponent to player) if (ball.lastX >= centerX && ball.x < centerX) { // Ball just crossed to left side, speed up! ball.vx *= 1.25; ball.vy *= 1.25; } if (ball.activated) { ball.x += ball.vx; ball.y += ball.vy; } // Friction ball.vx *= 0.96; ball.vy *= 0.96; // Clamp to field bounds and bounce off corners (horizontal) var minBallX = field.x - field.width / 2 + ball.width / 2; var maxBallX = field.x + field.width / 2 - ball.width / 2; var minBallY = field.y - field.height / 2 + ball.height / 2; var maxBallY = field.y + field.height / 2 - ball.height / 2; // Detect if ball is in a corner (within 1px of both X and Y bounds) var atLeft = ball.x <= minBallX + 1; var atRight = ball.x >= maxBallX - 1; var atTop = ball.y <= minBallY + 1; var atBottom = ball.y >= maxBallY - 1; // Bounce off corners: if at a corner, reflect both vx and vy if (atLeft && atTop || atLeft && atBottom || atRight && atTop || atRight && atBottom) { // Snap to corner ball.x = atLeft ? minBallX : maxBallX; ball.y = atTop ? minBallY : maxBallY; ball.vx *= -0.5; ball.vy *= -0.5; } else { // Bounce off left/right walls if (ball.x < minBallX) { ball.x = minBallX; ball.vx *= -0.5; } if (ball.x > maxBallX) { ball.x = maxBallX; ball.vx *= -0.5; } // Bounce off top/bottom walls if (ball.y < minBallY) { ball.y = minBallY; ball.vy *= -0.5; } if (ball.y > maxBallY) { ball.y = maxBallY; ball.vy *= -0.5; } } // --- Goal detection (horizontal) --- // If ball intersects leftGoal or rightGoal, score! // Only trigger on the exact frame the ball enters the goal (use lastBallInLeftGoal/lastBallInRightGoal) if (typeof ball.lastInLeftGoal === "undefined") ball.lastInLeftGoal = false; if (typeof ball.lastInRightGoal === "undefined") ball.lastInRightGoal = false; var inLeftGoal = ball.intersects(leftGoal); var inRightGoal = ball.intersects(rightGoal); // Score for blue (player) if ball enters bottom goal if (!ball.lastInRightGoal && inRightGoal) { timerRunning = false; LK.effects.flashScreen(0x00ff00, 600); LK.showYouWin(); return; } // Score for red (opponent) if ball enters top goal if (!ball.lastInLeftGoal && inLeftGoal) { timerRunning = false; LK.effects.flashScreen(0xff0000, 600); LK.showGameOver(); return; } ball.lastInLeftGoal = inLeftGoal; ball.lastInRightGoal = inRightGoal; // Prevent the ball from ever stopping: enforce a minimum velocity if it's moving var minBallSpeed = ball.activated ? 8 : 1.2; if (typeof ball.vx === "number" && typeof ball.vy === "number") { var speed = Math.sqrt(ball.vx * ball.vx + ball.vy * ball.vy); if (speed < minBallSpeed) { if (speed === 0) { // If completely stopped, nudge in a random direction var angle = Math.random() * Math.PI * 2; ball.vx = Math.cos(angle) * minBallSpeed; ball.vy = Math.sin(angle) * minBallSpeed; } else { // If moving but too slow, scale up to minimum speed ball.vx = ball.vx / (speed || 1) * minBallSpeed; ball.vy = ball.vy / (speed || 1) * minBallSpeed; } } } // Never allow the ball to stop: if both vx and vy are 0, nudge in a random direction if (ball.activated && typeof ball.vx === "number" && typeof ball.vy === "number" && ball.vx === 0 && ball.vy === 0) { var angle = Math.random() * Math.PI * 2; ball.vx = Math.cos(angle) * minBallSpeed; ball.vy = Math.sin(angle) * minBallSpeed; } // Update lastX for next frame ball.lastX = ball.x; // --- Goal detection --- // If ball intersects leftGoal or rightGoal, score! // Only trigger on the exact frame the ball enters the goal (use lastBallInLeftGoal/lastBallInRightGoal) if (typeof ball.lastInLeftGoal === "undefined") ball.lastInLeftGoal = false; if (typeof ball.lastInRightGoal === "undefined") ball.lastInRightGoal = false; var inLeftGoal = ball.intersects(leftGoal); var inRightGoal = ball.intersects(rightGoal); // Score for blue (player) if ball enters right goal if (!ball.lastInRightGoal && inRightGoal) { timerRunning = false; LK.effects.flashScreen(0x00ff00, 600); LK.showYouWin(); return; } // Score for red (opponent) if ball enters left goal if (!ball.lastInLeftGoal && inLeftGoal) { timerRunning = false; LK.effects.flashScreen(0xff0000, 600); LK.showGameOver(); return; } ball.lastInLeftGoal = inLeftGoal; ball.lastInRightGoal = inRightGoal; } // Update last intersection state lastPlayerBallIntersecting = isIntersecting; }; // Futsal ball (white) // Center circle (white, ellipse) // Center line (white, box) // Main field (futsal green) // Goal area (penalty box, white) // Goal (yellow, box) // Player (blue, ellipse) // --- HORIZONTAL FIELD (landscape) --- // Field: centered, wide, short var field = LK.getAsset('field', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 }); game.addChild(field); // Center line: horizontal var centerLine = LK.getAsset('centerLine', { anchorX: 0.5, anchorY: 0.5, width: 1900, // match field width height: 10, // thin horizontal line x: 2048 / 2, y: 2732 / 2 }); game.addChild(centerLine); // Center circle var centerCircle = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 }); game.addChild(centerCircle); // Draw top goal (left in landscape) var leftGoal = LK.getAsset('goal', { anchorX: 0.5, anchorY: 0.5, width: 400, //{2g} // wide height: 40, //{2h} // short x: 2048 / 2, y: (2732 - 1200) / 2 + 20 // flush with top field edge }); game.addChild(leftGoal); // Left goal posts (left and right) - horizontal orientation var goalPostWidth = 70; var goalPostHeight = 12; var goalPostOffsetY = leftGoal.height / 2 - goalPostHeight / 2; var leftGoalPostLeft = LK.getAsset('goal', { anchorX: 1.0, anchorY: 0.5, width: goalPostWidth, height: goalPostHeight, x: leftGoal.x - leftGoal.width / 2, // left edge of goal y: leftGoal.y - goalPostOffsetY // near the left of the goal }); game.addChild(leftGoalPostLeft); var leftGoalPostRight = LK.getAsset('goal', { anchorX: 0.0, anchorY: 0.5, width: goalPostWidth, height: goalPostHeight, x: leftGoal.x + leftGoal.width / 2, // right edge of goal y: leftGoal.y - goalPostOffsetY // near the right of the goal }); game.addChild(leftGoalPostRight); // Draw bottom goal (right in landscape) var rightGoal = LK.getAsset('goal', { anchorX: 0.5, anchorY: 0.5, width: 400, height: 40, x: 2048 / 2, y: (2732 + 1200) / 2 - 20 // flush with bottom field edge }); game.addChild(rightGoal); // Right goal posts (left and right) - horizontal orientation var rightGoalPostLeft = LK.getAsset('goal', { anchorX: 1.0, anchorY: 0.5, width: goalPostWidth, height: goalPostHeight, x: rightGoal.x - rightGoal.width / 2, // left edge of goal y: rightGoal.y + goalPostOffsetY // near the left of the goal }); game.addChild(rightGoalPostLeft); var rightGoalPostRight = LK.getAsset('goal', { anchorX: 0.0, anchorY: 0.5, width: goalPostWidth, height: goalPostHeight, x: rightGoal.x + rightGoal.width / 2, // right edge of goal y: rightGoal.y + goalPostOffsetY // near the right of the goal }); game.addChild(rightGoalPostRight); // Draw ball at center var ball = LK.getAsset('ball', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 }); ball.vx = 0; ball.vy = 0; game.addChild(ball); // Draw player at top side (blue) var player = LK.getAsset('playerBlue', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 - 350 // above center }); game.addChild(player); // Draw opponent at bottom side (red) var opponent = LK.getAsset('playerRed', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 + 350 // below center }); game.addChild(opponent); ;
===================================================================
--- original.js
+++ change.js
@@ -60,23 +60,23 @@
var touchId = obj && obj.event && typeof obj.event.identifier !== "undefined" ? obj.event.identifier : 0;
var draggingPlayer = draggingPlayers[touchId];
if (draggingPlayer) {
if (draggingPlayer === player) {
- // Blue player (left side)
+ // Blue player (top side)
var minX = field.x - field.width / 2 + player.width / 2;
- var maxX = field.x; // Center line is the max for left player
+ var maxX = field.x + field.width / 2 - player.width / 2;
var minY = field.y - field.height / 2 + player.height / 2;
- var maxY = field.y + field.height / 2 - player.height / 2;
- draggingPlayer.x = Math.max(minX, Math.min(maxX - player.width / 2, x));
- draggingPlayer.y = Math.max(minY, Math.min(maxY, y));
+ var maxY = field.y; // Center line is the max for top player
+ draggingPlayer.x = Math.max(minX, Math.min(maxX, x));
+ draggingPlayer.y = Math.max(minY, Math.min(maxY - player.height / 2, y));
} else if (draggingPlayer === opponent) {
- // Red player (right side)
- var minX2 = field.x; // Center line is the min for right player
+ // Red player (bottom side)
+ var minX2 = field.x - field.width / 2 + opponent.width / 2;
var maxX2 = field.x + field.width / 2 - opponent.width / 2;
- var minY2 = field.y - field.height / 2 + opponent.height / 2;
+ var minY2 = field.y; // Center line is the min for bottom player
var maxY2 = field.y + field.height / 2 - opponent.height / 2;
- draggingPlayer.x = Math.max(minX2 + opponent.width / 2, Math.min(maxX2, x));
- draggingPlayer.y = Math.max(minY2, Math.min(maxY2, y));
+ draggingPlayer.x = Math.max(minX2, Math.min(maxX2, x));
+ draggingPlayer.y = Math.max(minY2 + opponent.height / 2, Math.min(maxY2, y));
}
}
};
// Handle touch/mouse up: stop dragging
@@ -187,59 +187,59 @@
}
}
// Move the ball if it has velocity
if (typeof ball.vx === "number" && typeof ball.vy === "number") {
- // --- Ball bounce off goal posts ---
+ // --- Ball bounce off goal posts (horizontal) ---
// Track last intersection for each post
- if (typeof ball.lastLeftGoalPostTopIntersect === "undefined") ball.lastLeftGoalPostTopIntersect = false;
- if (typeof ball.lastLeftGoalPostBottomIntersect === "undefined") ball.lastLeftGoalPostBottomIntersect = false;
- if (typeof ball.lastRightGoalPostTopIntersect === "undefined") ball.lastRightGoalPostTopIntersect = false;
- if (typeof ball.lastRightGoalPostBottomIntersect === "undefined") ball.lastRightGoalPostBottomIntersect = false;
- // Left goal post top
- var leftTopNow = ball.intersects(leftGoalPostTop);
- if (!ball.lastLeftGoalPostTopIntersect && leftTopNow) {
+ if (typeof ball.lastLeftGoalPostLeftIntersect === "undefined") ball.lastLeftGoalPostLeftIntersect = false;
+ if (typeof ball.lastLeftGoalPostRightIntersect === "undefined") ball.lastLeftGoalPostRightIntersect = false;
+ if (typeof ball.lastRightGoalPostLeftIntersect === "undefined") ball.lastRightGoalPostLeftIntersect = false;
+ if (typeof ball.lastRightGoalPostRightIntersect === "undefined") ball.lastRightGoalPostRightIntersect = false;
+ // Left goal post left
+ var leftLeftNow = ball.intersects(leftGoalPostLeft);
+ if (!ball.lastLeftGoalPostLeftIntersect && leftLeftNow) {
// Bounce: reflect velocity, add a little randomness
- var dx = ball.x - leftGoalPostTop.x;
- var dy = ball.y - (leftGoalPostTop.y - leftGoalPostTop.height / 2);
+ var dx = ball.x - (leftGoalPostLeft.x - leftGoalPostLeft.width / 2);
+ var dy = ball.y - leftGoalPostLeft.y;
var dist = Math.sqrt(dx * dx + dy * dy) || 1;
ball.vx = dx / dist * Math.max(Math.abs(ball.vx), 30);
ball.vy = dy / dist * Math.max(Math.abs(ball.vy), 30);
LK.effects.flashObject(ball, 0xffff00, 120);
}
- ball.lastLeftGoalPostTopIntersect = leftTopNow;
- // Left goal post bottom
- var leftBottomNow = ball.intersects(leftGoalPostBottom);
- if (!ball.lastLeftGoalPostBottomIntersect && leftBottomNow) {
- var dx = ball.x - leftGoalPostBottom.x;
- var dy = ball.y - (leftGoalPostBottom.y + leftGoalPostBottom.height / 2);
+ ball.lastLeftGoalPostLeftIntersect = leftLeftNow;
+ // Left goal post right
+ var leftRightNow = ball.intersects(leftGoalPostRight);
+ if (!ball.lastLeftGoalPostRightIntersect && leftRightNow) {
+ var dx = ball.x - (leftGoalPostRight.x + leftGoalPostRight.width / 2);
+ var dy = ball.y - leftGoalPostRight.y;
var dist = Math.sqrt(dx * dx + dy * dy) || 1;
ball.vx = dx / dist * Math.max(Math.abs(ball.vx), 30);
ball.vy = dy / dist * Math.max(Math.abs(ball.vy), 30);
LK.effects.flashObject(ball, 0xffff00, 120);
}
- ball.lastLeftGoalPostBottomIntersect = leftBottomNow;
- // Right goal post top
- var rightTopNow = ball.intersects(rightGoalPostTop);
- if (!ball.lastRightGoalPostTopIntersect && rightTopNow) {
- var dx = ball.x - rightGoalPostTop.x;
- var dy = ball.y - (rightGoalPostTop.y - rightGoalPostTop.height / 2);
+ ball.lastLeftGoalPostRightIntersect = leftRightNow;
+ // Right goal post left
+ var rightLeftNow = ball.intersects(rightGoalPostLeft);
+ if (!ball.lastRightGoalPostLeftIntersect && rightLeftNow) {
+ var dx = ball.x - (rightGoalPostLeft.x - rightGoalPostLeft.width / 2);
+ var dy = ball.y - rightGoalPostLeft.y;
var dist = Math.sqrt(dx * dx + dy * dy) || 1;
ball.vx = dx / dist * Math.max(Math.abs(ball.vx), 30);
ball.vy = dy / dist * Math.max(Math.abs(ball.vy), 30);
LK.effects.flashObject(ball, 0xffff00, 120);
}
- ball.lastRightGoalPostTopIntersect = rightTopNow;
- // Right goal post bottom
- var rightBottomNow = ball.intersects(rightGoalPostBottom);
- if (!ball.lastRightGoalPostBottomIntersect && rightBottomNow) {
- var dx = ball.x - rightGoalPostBottom.x;
- var dy = ball.y - (rightGoalPostBottom.y + rightGoalPostBottom.height / 2);
+ ball.lastRightGoalPostLeftIntersect = rightLeftNow;
+ // Right goal post right
+ var rightRightNow = ball.intersects(rightGoalPostRight);
+ if (!ball.lastRightGoalPostRightIntersect && rightRightNow) {
+ var dx = ball.x - (rightGoalPostRight.x + rightGoalPostRight.width / 2);
+ var dy = ball.y - rightGoalPostRight.y;
var dist = Math.sqrt(dx * dx + dy * dy) || 1;
ball.vx = dx / dist * Math.max(Math.abs(ball.vx), 30);
ball.vy = dy / dist * Math.max(Math.abs(ball.vy), 30);
LK.effects.flashObject(ball, 0xffff00, 120);
}
- ball.lastRightGoalPostBottomIntersect = rightBottomNow;
+ ball.lastRightGoalPostRightIntersect = rightRightNow;
// Track lastX for side detection
if (typeof ball.lastX === "undefined") ball.lastX = ball.x;
// Detect crossing from left to right side (player to opponent)
var centerX = field.x;
@@ -260,9 +260,9 @@
}
// Friction
ball.vx *= 0.96;
ball.vy *= 0.96;
- // Clamp to field bounds and bounce off corners
+ // Clamp to field bounds and bounce off corners (horizontal)
var minBallX = field.x - field.width / 2 + ball.width / 2;
var maxBallX = field.x + field.width / 2 - ball.width / 2;
var minBallY = field.y - field.height / 2 + ball.height / 2;
var maxBallY = field.y + field.height / 2 - ball.height / 2;
@@ -297,8 +297,31 @@
ball.y = maxBallY;
ball.vy *= -0.5;
}
}
+ // --- Goal detection (horizontal) ---
+ // If ball intersects leftGoal or rightGoal, score!
+ // Only trigger on the exact frame the ball enters the goal (use lastBallInLeftGoal/lastBallInRightGoal)
+ if (typeof ball.lastInLeftGoal === "undefined") ball.lastInLeftGoal = false;
+ if (typeof ball.lastInRightGoal === "undefined") ball.lastInRightGoal = false;
+ var inLeftGoal = ball.intersects(leftGoal);
+ var inRightGoal = ball.intersects(rightGoal);
+ // Score for blue (player) if ball enters bottom goal
+ if (!ball.lastInRightGoal && inRightGoal) {
+ timerRunning = false;
+ LK.effects.flashScreen(0x00ff00, 600);
+ LK.showYouWin();
+ return;
+ }
+ // Score for red (opponent) if ball enters top goal
+ if (!ball.lastInLeftGoal && inLeftGoal) {
+ timerRunning = false;
+ LK.effects.flashScreen(0xff0000, 600);
+ LK.showGameOver();
+ return;
+ }
+ ball.lastInLeftGoal = inLeftGoal;
+ ball.lastInRightGoal = inRightGoal;
// Prevent the ball from ever stopping: enforce a minimum velocity if it's moving
var minBallSpeed = ball.activated ? 8 : 1.2;
if (typeof ball.vx === "number" && typeof ball.vy === "number") {
var speed = Math.sqrt(ball.vx * ball.vx + ball.vy * ball.vy);
@@ -356,101 +379,104 @@
// Main field (futsal green)
// Goal area (penalty box, white)
// Goal (yellow, box)
// Player (blue, ellipse)
+// --- HORIZONTAL FIELD (landscape) ---
+// Field: centered, wide, short
var field = LK.getAsset('field', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2
});
game.addChild(field);
-// Draw center line
+// Center line: horizontal
var centerLine = LK.getAsset('centerLine', {
anchorX: 0.5,
anchorY: 0.5,
- width: 10,
- // thin vertical line
- height: 1200,
- // match field height
+ width: 1900,
+ // match field width
+ height: 10,
+ // thin horizontal line
x: 2048 / 2,
y: 2732 / 2
});
game.addChild(centerLine);
-// Draw center circle
+// Center circle
var centerCircle = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2
});
game.addChild(centerCircle);
-// Draw left goal (real-life: tall, slim, at field edge, centered vertically)
+// Draw top goal (left in landscape)
var leftGoal = LK.getAsset('goal', {
anchorX: 0.5,
- // center anchor for easier placement
anchorY: 0.5,
- width: 40,
- // slim width
- height: 400,
- // tall height
- x: (2048 - 1900) / 2 + 20,
- // flush with left field edge
- y: 2732 / 2
+ width: 400,
+ //{2g} // wide
+ height: 40,
+ //{2h} // short
+ x: 2048 / 2,
+ y: (2732 - 1200) / 2 + 20 // flush with top field edge
});
game.addChild(leftGoal);
-// Left goal posts (top and bottom) - narrower and symmetric to right side
-var goalPostWidth = 12;
-var goalPostHeight = 70;
-var goalPostOffsetX = leftGoal.width / 2 - goalPostWidth / 2;
-var leftGoalPostTop = LK.getAsset('goal', {
- anchorX: 0.5,
- anchorY: 1.0,
+// Left goal posts (left and right) - horizontal orientation
+var goalPostWidth = 70;
+var goalPostHeight = 12;
+var goalPostOffsetY = leftGoal.height / 2 - goalPostHeight / 2;
+var leftGoalPostLeft = LK.getAsset('goal', {
+ anchorX: 1.0,
+ anchorY: 0.5,
width: goalPostWidth,
height: goalPostHeight,
- x: leftGoal.x - goalPostOffsetX,
- y: leftGoal.y - leftGoal.height / 2 // near the top of the goal
+ x: leftGoal.x - leftGoal.width / 2,
+ // left edge of goal
+ y: leftGoal.y - goalPostOffsetY // near the left of the goal
});
-game.addChild(leftGoalPostTop);
-var leftGoalPostBottom = LK.getAsset('goal', {
- anchorX: 0.5,
- anchorY: 0.0,
+game.addChild(leftGoalPostLeft);
+var leftGoalPostRight = LK.getAsset('goal', {
+ anchorX: 0.0,
+ anchorY: 0.5,
width: goalPostWidth,
height: goalPostHeight,
- x: leftGoal.x - goalPostOffsetX,
- y: leftGoal.y + leftGoal.height / 2 // near the bottom of the goal
+ x: leftGoal.x + leftGoal.width / 2,
+ // right edge of goal
+ y: leftGoal.y - goalPostOffsetY // near the right of the goal
});
-game.addChild(leftGoalPostBottom);
-// Draw right goal (real-life: tall, slim, at field edge, centered vertically)
+game.addChild(leftGoalPostRight);
+// Draw bottom goal (right in landscape)
var rightGoal = LK.getAsset('goal', {
anchorX: 0.5,
anchorY: 0.5,
- width: 40,
- height: 400,
- x: (2048 + 1900) / 2 - 20,
- // flush with right field edge
- y: 2732 / 2
+ width: 400,
+ height: 40,
+ x: 2048 / 2,
+ y: (2732 + 1200) / 2 - 20 // flush with bottom field edge
});
game.addChild(rightGoal);
-// Right goal posts (top and bottom) - narrower and symmetric to left side
-var rightGoalPostTop = LK.getAsset('goal', {
- anchorX: 0.5,
- anchorY: 1.0,
+// Right goal posts (left and right) - horizontal orientation
+var rightGoalPostLeft = LK.getAsset('goal', {
+ anchorX: 1.0,
+ anchorY: 0.5,
width: goalPostWidth,
height: goalPostHeight,
- x: rightGoal.x + goalPostOffsetX,
- y: rightGoal.y - rightGoal.height / 2 // near the top of the goal
+ x: rightGoal.x - rightGoal.width / 2,
+ // left edge of goal
+ y: rightGoal.y + goalPostOffsetY // near the left of the goal
});
-game.addChild(rightGoalPostTop);
-var rightGoalPostBottom = LK.getAsset('goal', {
- anchorX: 0.5,
- anchorY: 0.0,
+game.addChild(rightGoalPostLeft);
+var rightGoalPostRight = LK.getAsset('goal', {
+ anchorX: 0.0,
+ anchorY: 0.5,
width: goalPostWidth,
height: goalPostHeight,
- x: rightGoal.x + goalPostOffsetX,
- y: rightGoal.y + rightGoal.height / 2 // near the bottom of the goal
+ x: rightGoal.x + rightGoal.width / 2,
+ // right edge of goal
+ y: rightGoal.y + goalPostOffsetY // near the right of the goal
});
-game.addChild(rightGoalPostBottom);
+game.addChild(rightGoalPostRight);
// Draw ball at center
var ball = LK.getAsset('ball', {
anchorX: 0.5,
anchorY: 0.5,
@@ -459,21 +485,21 @@
});
ball.vx = 0;
ball.vy = 0;
game.addChild(ball);
-// Draw player at left side (blue)
+// Draw player at top side (blue)
var player = LK.getAsset('playerBlue', {
anchorX: 0.5,
anchorY: 0.5,
- x: 2048 / 2 - 500,
- y: 2732 / 2
+ x: 2048 / 2,
+ y: 2732 / 2 - 350 // above center
});
game.addChild(player);
-// Draw opponent at right side (red)
+// Draw opponent at bottom side (red)
var opponent = LK.getAsset('playerRed', {
anchorX: 0.5,
anchorY: 0.5,
- x: 2048 / 2 + 500,
- y: 2732 / 2
+ x: 2048 / 2,
+ y: 2732 / 2 + 350 // below center
});
game.addChild(opponent);
;
\ No newline at end of file