User prompt
Make the background new asset
User prompt
Add a background
User prompt
Don't let AI follow us and try to score a goal. Let him try to throw it to the one below.
User prompt
Let the AI try to throw the player red in green
Code edit (1 edits merged)
Please save this source code
User prompt
Car Football Frenzy
Initial prompt
Make me a car football game
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Ball class var Ball = Container.expand(function () { var self = Container.call(this); self.ballSprite = self.attachAsset('football', { anchorX: 0.5, anchorY: 0.5 }); self.width = self.ballSprite.width; self.height = self.ballSprite.height; self.vx = 0; self.vy = 0; self.friction = 0.98; self.maxSpeed = 38; self.update = function () { // Move ball self.x += self.vx; self.y += self.vy; // Friction self.vx *= self.friction; self.vy *= self.friction; // Clamp speed var speed = Math.sqrt(self.vx * self.vx + self.vy * self.vy); if (speed > self.maxSpeed) { self.vx *= self.maxSpeed / speed; self.vy *= self.maxSpeed / speed; } // Bounce off walls if (self.x < self.width / 2) { self.x = self.width / 2; self.vx = -self.vx * 0.7; } if (self.x > 2048 - self.width / 2) { self.x = 2048 - self.width / 2; self.vx = -self.vx * 0.7; } if (self.y < self.height / 2) { self.y = self.height / 2; self.vy = -self.vy * 0.7; } if (self.y > 2732 - self.height / 2) { self.y = 2732 - self.height / 2; self.vy = -self.vy * 0.7; } }; return self; }); // Car class (for both player and AI) var Car = Container.expand(function () { var self = Container.call(this); // Attach car asset (default to player car) self.carSprite = self.attachAsset('car', { anchorX: 0.5, anchorY: 0.5 }); self.width = self.carSprite.width; self.height = self.carSprite.height; self.speed = 0; self.maxSpeed = 32; self.acceleration = 2.2; self.friction = 0.95; self.angle = 0; // radians self.turnSpeed = 0.09; self.boosting = false; self.boostPower = 48; self.boostCooldown = 0; self.isAI = false; // For AI self.targetX = 0; self.targetY = 0; self.update = function () { // AI logic if (self.isAI) { // Always try to push the ball into the player's (bottom/green) goal var dx = ball.x - self.x; var dy = ball.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); // Target: aim for the ball, but bias target slightly toward the player's goal var goalBias = 180; var targetGoalX = goalPlayer.x; var targetGoalY = goalPlayer.y; // Calculate a point between the ball and the center of the player's goal self.targetX = ball.x + (targetGoalX - ball.x) * 0.18; self.targetY = ball.y + (targetGoalY - ball.y) * 0.18; // Turn towards target var desiredAngle = Math.atan2(self.targetY - self.y, self.targetX - self.x); var angleDiff = desiredAngle - self.angle; while (angleDiff > Math.PI) angleDiff -= Math.PI * 2; while (angleDiff < -Math.PI) angleDiff += Math.PI * 2; if (angleDiff > 0.1) self.angle += self.turnSpeed;else if (angleDiff < -0.1) self.angle -= self.turnSpeed; // Accelerate if facing target if (Math.abs(angleDiff) < 0.5) { self.speed += self.acceleration * 0.7; } // AI boost if close to ball and facing it if (dist < 400 && Math.abs(angleDiff) < 0.3 && self.boostCooldown <= 0) { self.boosting = true; } } // Boost logic if (self.boosting && self.boostCooldown <= 0) { self.speed = self.boostPower; self.boostCooldown = 60; // 1 second cooldown self.boosting = false; } if (self.boostCooldown > 0) self.boostCooldown--; // Clamp speed if (self.speed > self.maxSpeed) self.speed = self.maxSpeed; if (self.speed < -self.maxSpeed / 2) self.speed = -self.maxSpeed / 2; // Move car self.x += Math.cos(self.angle) * self.speed; self.y += Math.sin(self.angle) * self.speed; // Friction self.speed *= self.friction; // Keep in bounds if (self.x < self.width / 2) self.x = self.width / 2; if (self.x > 2048 - self.width / 2) self.x = 2048 - self.width / 2; if (self.y < self.height / 2) self.y = self.height / 2; if (self.y > 2732 - self.height / 2) self.y = 2732 - self.height / 2; // Rotate sprite self.carSprite.rotation = self.angle; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x222222 }); /**** * Game Code ****/ // Game state // Car asset (player) // Car asset (AI) // Ball asset // Goal asset (player) // Goal asset (AI) var playerScore = 0; var aiScore = 0; var matchTime = 60; // seconds var timeLeft = matchTime; var gameActive = true; // Add background image var background = LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366, scaleX: 1, scaleY: 1 }); game.addChild(background); // Create goals var goalPlayer = LK.getAsset('goal_player', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 2732 - 80 }); var goalAI = LK.getAsset('goal_ai', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 80 }); game.addChild(goalPlayer); game.addChild(goalAI); // Create ball var ball = new Ball(); game.addChild(ball); // Create player car var playerCar = new Car(); playerCar.x = 1024; playerCar.y = 2732 - 400; playerCar.angle = -Math.PI / 2; game.addChild(playerCar); // Create AI car var aiCar = new Car(); aiCar.carSprite.destroy(); aiCar.carSprite = aiCar.attachAsset('car_ai', { anchorX: 0.5, anchorY: 0.5 }); aiCar.isAI = true; aiCar.x = 1024; aiCar.y = 400; aiCar.angle = Math.PI / 2; game.addChild(aiCar); // Score display var scoreTxt = new Text2('0 : 0', { size: 120, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Timer display var timerTxt = new Text2('60', { size: 90, fill: 0xFFFF00 }); timerTxt.anchor.set(0.5, 0); LK.gui.top.addChild(timerTxt); timerTxt.y = 120; // Helper: Reset ball and cars to center function resetPositions(scoredBy) { ball.x = 1024; ball.y = 1366; ball.vx = 0; ball.vy = 0; playerCar.x = 1024; playerCar.y = 2732 - 400; playerCar.angle = -Math.PI / 2; playerCar.speed = 0; aiCar.x = 1024; aiCar.y = 400; aiCar.angle = Math.PI / 2; aiCar.speed = 0; // Small pause after goal gameActive = false; tween(ball, { alpha: 0.2 }, { duration: 200, onFinish: function onFinish() { tween(ball, { alpha: 1 }, { duration: 200, onFinish: function onFinish() { gameActive = true; } }); } }); } // Touch controls var touchActive = false; var touchStartX = 0, touchStartY = 0; var touchCurX = 0, touchCurY = 0; var boostActive = false; // Touch: steer by dragging, boost by double tap or long press game.down = function (x, y, obj) { // Ignore if not active if (!gameActive) return; // Don't allow touch in top left 100x100 if (x < 100 && y < 100) return; touchActive = true; touchStartX = x; touchStartY = y; touchCurX = x; touchCurY = y; boostActive = false; // Detect long press for boost playerCar.boosting = false; playerCar._boostTimeout = LK.setTimeout(function () { boostActive = true; playerCar.boosting = true; }, 400); }; game.move = function (x, y, obj) { if (!gameActive) return; if (!touchActive) return; touchCurX = x; touchCurY = y; // Steer: angle towards drag direction var dx = touchCurX - playerCar.x; var dy = touchCurY - playerCar.y; var desiredAngle = Math.atan2(dy, dx); var angleDiff = desiredAngle - playerCar.angle; while (angleDiff > Math.PI) angleDiff -= Math.PI * 2; while (angleDiff < -Math.PI) angleDiff += Math.PI * 2; if (angleDiff > 0.1) playerCar.angle += playerCar.turnSpeed;else if (angleDiff < -0.1) playerCar.angle -= playerCar.turnSpeed; // Accelerate if facing drag direction if (Math.abs(angleDiff) < 0.5) { playerCar.speed += playerCar.acceleration; } // Clamp if (playerCar.speed > playerCar.maxSpeed) playerCar.speed = playerCar.maxSpeed; }; game.up = function (x, y, obj) { touchActive = false; if (playerCar._boostTimeout) { LK.clearTimeout(playerCar._boostTimeout); playerCar._boostTimeout = null; } if (boostActive) { boostActive = false; } }; // Double tap for boost var lastTap = 0; game.down = function (origDown) { return function (x, y, obj) { var now = Date.now(); if (now - lastTap < 350) { // Double tap: boost playerCar.boosting = true; } lastTap = now; origDown.call(game, x, y, obj); }; }(game.down); // Physics: Car-ball collision function carBallCollision(car, ball) { var dx = ball.x - car.x; var dy = ball.y - car.y; var dist = Math.sqrt(dx * dx + dy * dy); var minDist = (car.width / 2 + ball.width / 2) * 0.8; if (dist < minDist) { // Push ball away var nx = dx / (dist || 1); var ny = dy / (dist || 1); var overlap = minDist - dist; ball.x += nx * overlap / 2; ball.y += ny * overlap / 2; // Ball velocity: add car's speed var impact = Math.max(8, car.speed * 1.2); ball.vx += nx * impact; ball.vy += ny * impact; // Car bounces a bit car.speed *= 0.7; } } // Physics: Car-car collision function carCarCollision(car1, car2) { var dx = car2.x - car1.x; var dy = car2.y - car1.y; var dist = Math.sqrt(dx * dx + dy * dy); var minDist = (car1.width / 2 + car2.width / 2) * 0.9; if (dist < minDist) { var nx = dx / (dist || 1); var ny = dy / (dist || 1); var overlap = minDist - dist; car1.x -= nx * overlap / 2; car1.y -= ny * overlap / 2; car2.x += nx * overlap / 2; car2.y += ny * overlap / 2; // Exchange some speed var temp = car1.speed; car1.speed = car2.speed * 0.7; car2.speed = temp * 0.7; } } // Goal detection function checkGoal() { // Player goal (top) if (ball.y - ball.height / 2 < goalAI.y + goalAI.height / 2 && ball.x > goalAI.x - goalAI.width / 2 && ball.x < goalAI.x + goalAI.width / 2) { playerScore++; scoreTxt.setText(playerScore + " : " + aiScore); LK.effects.flashScreen(0x00ff00, 500); resetPositions('player'); } // AI goal (bottom) if (ball.y + ball.height / 2 > goalPlayer.y - goalPlayer.height / 2 && ball.x > goalPlayer.x - goalPlayer.width / 2 && ball.x < goalPlayer.x + goalPlayer.width / 2) { aiScore++; scoreTxt.setText(playerScore + " : " + aiScore); LK.effects.flashScreen(0xff0000, 500); resetPositions('ai'); } } // Timer var timerInterval = LK.setInterval(function () { if (!gameActive) return; if (timeLeft > 0) { timeLeft--; timerTxt.setText(timeLeft + ""); if (timeLeft <= 10) timerTxt.setText(timeLeft + "!"); } if (timeLeft <= 0) { // End game gameActive = false; if (playerScore > aiScore) { LK.showYouWin(); } else if (aiScore > playerScore) { LK.showGameOver(); } else { // Draw: treat as loss for now LK.showGameOver(); } } }, 1000); // Main update loop game.update = function () { if (!gameActive) return; // Update cars and ball playerCar.update(); aiCar.update(); ball.update(); // Collisions carBallCollision(playerCar, ball); carBallCollision(aiCar, ball); carCarCollision(playerCar, aiCar); // Goal check checkGoal(); }; // Initial positions resetPositions(); /* End of game code */
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Ball class
var Ball = Container.expand(function () {
var self = Container.call(this);
self.ballSprite = self.attachAsset('football', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = self.ballSprite.width;
self.height = self.ballSprite.height;
self.vx = 0;
self.vy = 0;
self.friction = 0.98;
self.maxSpeed = 38;
self.update = function () {
// Move ball
self.x += self.vx;
self.y += self.vy;
// Friction
self.vx *= self.friction;
self.vy *= self.friction;
// Clamp speed
var speed = Math.sqrt(self.vx * self.vx + self.vy * self.vy);
if (speed > self.maxSpeed) {
self.vx *= self.maxSpeed / speed;
self.vy *= self.maxSpeed / speed;
}
// Bounce off walls
if (self.x < self.width / 2) {
self.x = self.width / 2;
self.vx = -self.vx * 0.7;
}
if (self.x > 2048 - self.width / 2) {
self.x = 2048 - self.width / 2;
self.vx = -self.vx * 0.7;
}
if (self.y < self.height / 2) {
self.y = self.height / 2;
self.vy = -self.vy * 0.7;
}
if (self.y > 2732 - self.height / 2) {
self.y = 2732 - self.height / 2;
self.vy = -self.vy * 0.7;
}
};
return self;
});
// Car class (for both player and AI)
var Car = Container.expand(function () {
var self = Container.call(this);
// Attach car asset (default to player car)
self.carSprite = self.attachAsset('car', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = self.carSprite.width;
self.height = self.carSprite.height;
self.speed = 0;
self.maxSpeed = 32;
self.acceleration = 2.2;
self.friction = 0.95;
self.angle = 0; // radians
self.turnSpeed = 0.09;
self.boosting = false;
self.boostPower = 48;
self.boostCooldown = 0;
self.isAI = false;
// For AI
self.targetX = 0;
self.targetY = 0;
self.update = function () {
// AI logic
if (self.isAI) {
// Always try to push the ball into the player's (bottom/green) goal
var dx = ball.x - self.x;
var dy = ball.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
// Target: aim for the ball, but bias target slightly toward the player's goal
var goalBias = 180;
var targetGoalX = goalPlayer.x;
var targetGoalY = goalPlayer.y;
// Calculate a point between the ball and the center of the player's goal
self.targetX = ball.x + (targetGoalX - ball.x) * 0.18;
self.targetY = ball.y + (targetGoalY - ball.y) * 0.18;
// Turn towards target
var desiredAngle = Math.atan2(self.targetY - self.y, self.targetX - self.x);
var angleDiff = desiredAngle - self.angle;
while (angleDiff > Math.PI) angleDiff -= Math.PI * 2;
while (angleDiff < -Math.PI) angleDiff += Math.PI * 2;
if (angleDiff > 0.1) self.angle += self.turnSpeed;else if (angleDiff < -0.1) self.angle -= self.turnSpeed;
// Accelerate if facing target
if (Math.abs(angleDiff) < 0.5) {
self.speed += self.acceleration * 0.7;
}
// AI boost if close to ball and facing it
if (dist < 400 && Math.abs(angleDiff) < 0.3 && self.boostCooldown <= 0) {
self.boosting = true;
}
}
// Boost logic
if (self.boosting && self.boostCooldown <= 0) {
self.speed = self.boostPower;
self.boostCooldown = 60; // 1 second cooldown
self.boosting = false;
}
if (self.boostCooldown > 0) self.boostCooldown--;
// Clamp speed
if (self.speed > self.maxSpeed) self.speed = self.maxSpeed;
if (self.speed < -self.maxSpeed / 2) self.speed = -self.maxSpeed / 2;
// Move car
self.x += Math.cos(self.angle) * self.speed;
self.y += Math.sin(self.angle) * self.speed;
// Friction
self.speed *= self.friction;
// Keep in bounds
if (self.x < self.width / 2) self.x = self.width / 2;
if (self.x > 2048 - self.width / 2) self.x = 2048 - self.width / 2;
if (self.y < self.height / 2) self.y = self.height / 2;
if (self.y > 2732 - self.height / 2) self.y = 2732 - self.height / 2;
// Rotate sprite
self.carSprite.rotation = self.angle;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222222
});
/****
* Game Code
****/
// Game state
// Car asset (player)
// Car asset (AI)
// Ball asset
// Goal asset (player)
// Goal asset (AI)
var playerScore = 0;
var aiScore = 0;
var matchTime = 60; // seconds
var timeLeft = matchTime;
var gameActive = true;
// Add background image
var background = LK.getAsset('background', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366,
scaleX: 1,
scaleY: 1
});
game.addChild(background);
// Create goals
var goalPlayer = LK.getAsset('goal_player', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 2732 - 80
});
var goalAI = LK.getAsset('goal_ai', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 80
});
game.addChild(goalPlayer);
game.addChild(goalAI);
// Create ball
var ball = new Ball();
game.addChild(ball);
// Create player car
var playerCar = new Car();
playerCar.x = 1024;
playerCar.y = 2732 - 400;
playerCar.angle = -Math.PI / 2;
game.addChild(playerCar);
// Create AI car
var aiCar = new Car();
aiCar.carSprite.destroy();
aiCar.carSprite = aiCar.attachAsset('car_ai', {
anchorX: 0.5,
anchorY: 0.5
});
aiCar.isAI = true;
aiCar.x = 1024;
aiCar.y = 400;
aiCar.angle = Math.PI / 2;
game.addChild(aiCar);
// Score display
var scoreTxt = new Text2('0 : 0', {
size: 120,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Timer display
var timerTxt = new Text2('60', {
size: 90,
fill: 0xFFFF00
});
timerTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(timerTxt);
timerTxt.y = 120;
// Helper: Reset ball and cars to center
function resetPositions(scoredBy) {
ball.x = 1024;
ball.y = 1366;
ball.vx = 0;
ball.vy = 0;
playerCar.x = 1024;
playerCar.y = 2732 - 400;
playerCar.angle = -Math.PI / 2;
playerCar.speed = 0;
aiCar.x = 1024;
aiCar.y = 400;
aiCar.angle = Math.PI / 2;
aiCar.speed = 0;
// Small pause after goal
gameActive = false;
tween(ball, {
alpha: 0.2
}, {
duration: 200,
onFinish: function onFinish() {
tween(ball, {
alpha: 1
}, {
duration: 200,
onFinish: function onFinish() {
gameActive = true;
}
});
}
});
}
// Touch controls
var touchActive = false;
var touchStartX = 0,
touchStartY = 0;
var touchCurX = 0,
touchCurY = 0;
var boostActive = false;
// Touch: steer by dragging, boost by double tap or long press
game.down = function (x, y, obj) {
// Ignore if not active
if (!gameActive) return;
// Don't allow touch in top left 100x100
if (x < 100 && y < 100) return;
touchActive = true;
touchStartX = x;
touchStartY = y;
touchCurX = x;
touchCurY = y;
boostActive = false;
// Detect long press for boost
playerCar.boosting = false;
playerCar._boostTimeout = LK.setTimeout(function () {
boostActive = true;
playerCar.boosting = true;
}, 400);
};
game.move = function (x, y, obj) {
if (!gameActive) return;
if (!touchActive) return;
touchCurX = x;
touchCurY = y;
// Steer: angle towards drag direction
var dx = touchCurX - playerCar.x;
var dy = touchCurY - playerCar.y;
var desiredAngle = Math.atan2(dy, dx);
var angleDiff = desiredAngle - playerCar.angle;
while (angleDiff > Math.PI) angleDiff -= Math.PI * 2;
while (angleDiff < -Math.PI) angleDiff += Math.PI * 2;
if (angleDiff > 0.1) playerCar.angle += playerCar.turnSpeed;else if (angleDiff < -0.1) playerCar.angle -= playerCar.turnSpeed;
// Accelerate if facing drag direction
if (Math.abs(angleDiff) < 0.5) {
playerCar.speed += playerCar.acceleration;
}
// Clamp
if (playerCar.speed > playerCar.maxSpeed) playerCar.speed = playerCar.maxSpeed;
};
game.up = function (x, y, obj) {
touchActive = false;
if (playerCar._boostTimeout) {
LK.clearTimeout(playerCar._boostTimeout);
playerCar._boostTimeout = null;
}
if (boostActive) {
boostActive = false;
}
};
// Double tap for boost
var lastTap = 0;
game.down = function (origDown) {
return function (x, y, obj) {
var now = Date.now();
if (now - lastTap < 350) {
// Double tap: boost
playerCar.boosting = true;
}
lastTap = now;
origDown.call(game, x, y, obj);
};
}(game.down);
// Physics: Car-ball collision
function carBallCollision(car, ball) {
var dx = ball.x - car.x;
var dy = ball.y - car.y;
var dist = Math.sqrt(dx * dx + dy * dy);
var minDist = (car.width / 2 + ball.width / 2) * 0.8;
if (dist < minDist) {
// Push ball away
var nx = dx / (dist || 1);
var ny = dy / (dist || 1);
var overlap = minDist - dist;
ball.x += nx * overlap / 2;
ball.y += ny * overlap / 2;
// Ball velocity: add car's speed
var impact = Math.max(8, car.speed * 1.2);
ball.vx += nx * impact;
ball.vy += ny * impact;
// Car bounces a bit
car.speed *= 0.7;
}
}
// Physics: Car-car collision
function carCarCollision(car1, car2) {
var dx = car2.x - car1.x;
var dy = car2.y - car1.y;
var dist = Math.sqrt(dx * dx + dy * dy);
var minDist = (car1.width / 2 + car2.width / 2) * 0.9;
if (dist < minDist) {
var nx = dx / (dist || 1);
var ny = dy / (dist || 1);
var overlap = minDist - dist;
car1.x -= nx * overlap / 2;
car1.y -= ny * overlap / 2;
car2.x += nx * overlap / 2;
car2.y += ny * overlap / 2;
// Exchange some speed
var temp = car1.speed;
car1.speed = car2.speed * 0.7;
car2.speed = temp * 0.7;
}
}
// Goal detection
function checkGoal() {
// Player goal (top)
if (ball.y - ball.height / 2 < goalAI.y + goalAI.height / 2 && ball.x > goalAI.x - goalAI.width / 2 && ball.x < goalAI.x + goalAI.width / 2) {
playerScore++;
scoreTxt.setText(playerScore + " : " + aiScore);
LK.effects.flashScreen(0x00ff00, 500);
resetPositions('player');
}
// AI goal (bottom)
if (ball.y + ball.height / 2 > goalPlayer.y - goalPlayer.height / 2 && ball.x > goalPlayer.x - goalPlayer.width / 2 && ball.x < goalPlayer.x + goalPlayer.width / 2) {
aiScore++;
scoreTxt.setText(playerScore + " : " + aiScore);
LK.effects.flashScreen(0xff0000, 500);
resetPositions('ai');
}
}
// Timer
var timerInterval = LK.setInterval(function () {
if (!gameActive) return;
if (timeLeft > 0) {
timeLeft--;
timerTxt.setText(timeLeft + "");
if (timeLeft <= 10) timerTxt.setText(timeLeft + "!");
}
if (timeLeft <= 0) {
// End game
gameActive = false;
if (playerScore > aiScore) {
LK.showYouWin();
} else if (aiScore > playerScore) {
LK.showGameOver();
} else {
// Draw: treat as loss for now
LK.showGameOver();
}
}
}, 1000);
// Main update loop
game.update = function () {
if (!gameActive) return;
// Update cars and ball
playerCar.update();
aiCar.update();
ball.update();
// Collisions
carBallCollision(playerCar, ball);
carBallCollision(aiCar, ball);
carCarCollision(playerCar, aiCar);
// Goal check
checkGoal();
};
// Initial positions
resetPositions();
/* End of game code */