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 ****/ // Goal asset (AI) // Goal asset (player) // Ball asset // Car asset (AI) // Car asset (player) // Game state var playerScore = 0; var aiScore = 0; var matchTime = 60; // seconds var timeLeft = matchTime; var gameActive = true; // 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 */
===================================================================
--- original.js
+++ change.js
@@ -77,60 +77,33 @@
self.targetY = 0;
self.update = function () {
// AI logic
if (self.isAI) {
- // If the player car is above the halfway line, try to push the player into the green goal
- if (playerCar.y > 1366) {
- // Target just behind the player car, so AI can push it toward the green goal
- var dx = playerCar.x - self.x;
- var dy = playerCar.y - self.y;
- var dist = Math.sqrt(dx * dx + dy * dy);
- // Aim for a point slightly behind the player car (towards the green goal)
- var pushDist = 120;
- var pushAngle = Math.atan2(playerCar.y - goalPlayer.y, playerCar.x - goalPlayer.x);
- self.targetX = playerCar.x + Math.cos(pushAngle) * pushDist;
- self.targetY = playerCar.y + Math.sin(pushAngle) * pushDist;
- // If close to player and facing, boost
- 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;
- if (Math.abs(angleDiff) < 0.5) {
- self.speed += self.acceleration * 0.7;
- }
- if (dist < 350 && Math.abs(angleDiff) < 0.3 && self.boostCooldown <= 0) {
- self.boosting = true;
- }
- } else {
- // Default: try to push the ball toward the player goal
- var dx = ball.x - self.x;
- var dy = ball.y - self.y;
- var dist = Math.sqrt(dx * dx + dy * dy);
- // Target: If ball is on AI's side, go for ball, else defend
- if (ball.y < 1366) {
- self.targetX = ball.x;
- self.targetY = ball.y + 120;
- } else {
- // Defend goal
- self.targetX = 1024;
- self.targetY = 220;
- }
- // 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;
- }
+ // 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;
@@ -166,14 +139,14 @@
/****
* Game Code
****/
-// Game state
-// Car asset (player)
-// Car asset (AI)
-// Ball asset
-// Goal asset (player)
// Goal asset (AI)
+// Goal asset (player)
+// Ball asset
+// Car asset (AI)
+// Car asset (player)
+// Game state
var playerScore = 0;
var aiScore = 0;
var matchTime = 60; // seconds
var timeLeft = matchTime;