User prompt
when ball stuck ai try hit another part of hım
User prompt
When ball is gone corner ai try hit another side
User prompt
Ai also can try to goal and defend the goal
User prompt
Ai try dont eat a goal
User prompt
Ai hit every side
User prompt
Remove the old command
User prompt
Ai not allow hit ın front of also hit every side
User prompt
Ball can Bounce the corner
User prompt
Create a scoreboard for 2 teams
User prompt
Get ai smart
User prompt
Remove all scoreboard codes
User prompt
Make a score board
User prompt
Make ai smart but sometimes is move randomly
User prompt
Make ai little bit stupid
User prompt
When ball go other Side ball go Faster
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'y')' in or related to this line: 'timerTxt.y = blueScoreTxt.y - 10; // Place timer just above the scoreboard' Line Number: 34
User prompt
Timer get middle top on screen
User prompt
Make a timer
User prompt
Make score board for 2 teams
User prompt
Make score board
User prompt
Ball can touch the goal is the score
User prompt
When teams player touch ball ball is Faster than old ball
User prompt
Make half line ın the half
User prompt
Ball wanna go Faster
User prompt
Ball can move
/****
* 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;
;
var draggingPlayer = null;
// 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) {
// 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) {
draggingPlayer = player;
}
// No-op: Remove red player drag logic, opponent is now AI controlled
};
// Handle touch/mouse move: move player if dragging
game.move = function (x, y, obj) {
if (draggingPlayer) {
// Blue player (left side) - only blue player can be dragged
if (draggingPlayer === player) {
var minX = field.x - field.width / 2 + player.width / 2;
var maxX = field.x; // Center line is the max for left player
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));
}
}
// Remove red player drag logic: opponent is now AI controlled
};
// Handle touch/mouse up: stop dragging
game.up = function (x, y, obj) {
draggingPlayer = null;
};
;
;
// 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);
}
}
// --- AI for red opponent ---
if (typeof opponent.aiTargetX === "undefined") {
opponent.aiTargetX = opponent.x;
opponent.aiTargetY = opponent.y;
}
var aiSpeed = 18;
var minX2 = field.x; // Center line is the min for right player
var maxX2 = field.x + field.width / 2 - opponent.width / 2;
var minY2 = field.y - field.height / 2 + opponent.height / 2;
var maxY2 = field.y + field.height / 2 - opponent.height / 2;
// AI logic: decide between attacking and defending
var rightGoalX = rightGoal.x;
var rightGoalY = rightGoal.y;
var leftGoalX = leftGoal.x;
var leftGoalY = leftGoal.y;
var defendZoneX = field.x + field.width * 0.18; // 18% from center, a bit in front of goal
// If the ball is close to the AI's goal, defend. Otherwise, try to attack.
var ballIsThreatening = ball.x > field.x + field.width * 0.35; // Ball is deep in AI's half
var aiHasBall = Math.abs(ball.x - opponent.x) < 200 && Math.abs(ball.y - opponent.y) < 200;
if (ballIsThreatening) {
// DEFEND: Place between ball and right goal, but not too far from goal
var defendX = Math.max(defendZoneX, Math.min(maxX2, ball.x - 80));
var defendY = Math.max(minY2, Math.min(maxY2, ball.y));
opponent.aiTargetX = defendX;
opponent.aiTargetY = defendY;
} else if (aiHasBall || ball.x > field.x) {
// ATTACK: Move toward ball, then toward left goal if close to ball
if (aiHasBall) {
// If close to ball, try to "shoot" toward left goal
// Aim slightly offset from center to avoid always straight shots
var offsetY = (Math.random() - 0.5) * 100;
opponent.aiTargetX = Math.max(minX2, Math.min(maxX2, leftGoalX + 60));
opponent.aiTargetY = Math.max(minY2, Math.min(maxY2, leftGoalY + offsetY));
} else {
// Move toward ball
opponent.aiTargetX = Math.max(minX2, Math.min(maxX2, ball.x));
opponent.aiTargetY = Math.max(minY2, Math.min(maxY2, ball.y));
}
} else {
// Idle near center of right half
opponent.aiTargetX = field.x + field.width * 0.25;
opponent.aiTargetY = field.y;
}
// Move opponent toward target
var odx = opponent.aiTargetX - opponent.x;
var ody = opponent.aiTargetY - opponent.y;
var odist = Math.sqrt(odx * odx + ody * ody) || 1;
if (odist > 1) {
opponent.x += odx / odist * Math.min(aiSpeed, odist);
opponent.y += ody / odist * Math.min(aiSpeed, odist);
}
// 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)) {
// Vector from opponent to ball
var dxr = ball.x - opponent.x;
var dyr = ball.y - opponent.y;
var distr = Math.sqrt(dxr * dxr + dyr * dyr) || 1;
// Allow AI to hit from any side
ball.vx = dxr / distr * 50;
ball.vy = dyr / distr * 50;
LK.effects.flashObject(ball, 0xd32f2f, 200);
}
// Move the ball if it has velocity
if (typeof ball.vx === "number" && typeof ball.vy === "number") {
// 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;
}
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
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;
}
}
// Stop if very slow
if (Math.abs(ball.vx) < 0.2) ball.vx = 0;
if (Math.abs(ball.vy) < 0.2) ball.vy = 0;
// 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)
var field = LK.getAsset('field', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2
});
game.addChild(field);
// Draw center line
var centerLine = LK.getAsset('centerLine', {
anchorX: 0.5,
anchorY: 0.5,
width: 10,
// thin vertical line
height: 1200,
// match field height
x: 2048 / 2,
y: 2732 / 2
});
game.addChild(centerLine);
// Draw 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)
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
});
game.addChild(leftGoal);
// Draw right goal (real-life: tall, slim, at field edge, centered vertically)
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
});
game.addChild(rightGoal);
// 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 left side (blue)
var player = LK.getAsset('playerBlue', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 - 500,
y: 2732 / 2
});
game.addChild(player);
// Draw opponent at right side (red)
var opponent = LK.getAsset('playerRed', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 + 500,
y: 2732 / 2
});
game.addChild(opponent);
; ===================================================================
--- original.js
+++ change.js
@@ -87,27 +87,43 @@
if (typeof opponent.aiTargetX === "undefined") {
opponent.aiTargetX = opponent.x;
opponent.aiTargetY = opponent.y;
}
- // AI DEFENSE: Try to block ball from entering right goal
var aiSpeed = 18;
var minX2 = field.x; // Center line is the min for right player
var maxX2 = field.x + field.width / 2 - opponent.width / 2;
var minY2 = field.y - field.height / 2 + opponent.height / 2;
var maxY2 = field.y + field.height / 2 - opponent.height / 2;
- // Defensive logic: If ball is on AI's half, position between ball and right goal
+ // AI logic: decide between attacking and defending
var rightGoalX = rightGoal.x;
var rightGoalY = rightGoal.y;
+ var leftGoalX = leftGoal.x;
+ var leftGoalY = leftGoal.y;
var defendZoneX = field.x + field.width * 0.18; // 18% from center, a bit in front of goal
- if (ball.x > field.x) {
- // Place between ball and right goal, but not too far from goal
+ // If the ball is close to the AI's goal, defend. Otherwise, try to attack.
+ var ballIsThreatening = ball.x > field.x + field.width * 0.35; // Ball is deep in AI's half
+ var aiHasBall = Math.abs(ball.x - opponent.x) < 200 && Math.abs(ball.y - opponent.y) < 200;
+ if (ballIsThreatening) {
+ // DEFEND: Place between ball and right goal, but not too far from goal
var defendX = Math.max(defendZoneX, Math.min(maxX2, ball.x - 80));
- // Try to align vertically with ball, but clamp to field
var defendY = Math.max(minY2, Math.min(maxY2, ball.y));
opponent.aiTargetX = defendX;
opponent.aiTargetY = defendY;
+ } else if (aiHasBall || ball.x > field.x) {
+ // ATTACK: Move toward ball, then toward left goal if close to ball
+ if (aiHasBall) {
+ // If close to ball, try to "shoot" toward left goal
+ // Aim slightly offset from center to avoid always straight shots
+ var offsetY = (Math.random() - 0.5) * 100;
+ opponent.aiTargetX = Math.max(minX2, Math.min(maxX2, leftGoalX + 60));
+ opponent.aiTargetY = Math.max(minY2, Math.min(maxY2, leftGoalY + offsetY));
+ } else {
+ // Move toward ball
+ opponent.aiTargetX = Math.max(minX2, Math.min(maxX2, ball.x));
+ opponent.aiTargetY = Math.max(minY2, Math.min(maxY2, ball.y));
+ }
} else {
- // Ball is on player's half, idle near center of right half
+ // Idle near center of right half
opponent.aiTargetX = field.x + field.width * 0.25;
opponent.aiTargetY = field.y;
}
// Move opponent toward target