User prompt
I can't see the palms
User prompt
What is happening with the palms? THey are stuck on the bottom! No! You spawn 1 palm in the center, goes left ind iagonal. Then you spawn another on the right, goes right on the diagonal. And that continuosly. And everytime a palm reaches the bottom, destroy it with .destroy() method! Keep references of them in an array!
Code edit (1 edits merged)
Please save this source code
User prompt
Are you even destroying the palms when they reach the bottom? We need to be performant and reduce memory issue!
Code edit (13 edits merged)
Please save this source code
User prompt
Ok that's a lot of palms, generate half that
User prompt
The palms - generate more, keep generating them!
User prompt
The palms should have all the same speed.
User prompt
Ok the palms move in diagonal and when they reach the bottom, they are destroyed! Also please keep continuosly generating palms!
User prompt
Ok, now the palms: 1. The should move in perspective. They start on the center of the screen, and then 1 goes left, next goes right, one left, one right, indifinitely. 2. Goes left means moving from the center of the screen to the bottom left corner. 3. Goes right means moving from the center of the screen to the bottom right corner. 4. Scale them as they move to simulate the pespective of looking from bottom center of the screen. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
User prompt
No! I want the lines starting super small like . and then growing until | but don't let them move x or y, just vertically down
User prompt
Ok but I need many more roadlines going left and right so that we simulate the separation of lanes
User prompt
Loading Ok now I want you to add perspective to those roadlines. My road is like this / \ and the road lines are / | \ but the further they are from the bottom, the smaller they are. The closer they get to the bottom the bigger.
User prompt
Ok let the lines start a liiitle bit below 50% on y, like 200 pixels below
Code edit (1 edits merged)
Please save this source code
User prompt
All the roadline should start at that position when spawned! Also don't stop spawning road lines continuosly, but always starting from 50% 50%
User prompt
Ok the roadlines, should start on 50% x and 50% height of the screen and then go down
Code edit (1 edits merged)
Please save this source code
User prompt
Implement this, but using mypalm and roadline asset and applied to my game engine and how I have my game now // Create Palms const palms = []; for (let i = 0; i < 8; i++) { const palm = new PIXI.Sprite(palmTexture); palm.anchor.set(0.5, 0.5); palm.x = (i % 2 === 0 ? 200 : 568) + Math.random() * 20 - 10; // Left/right side palm.y = 100 + i * 80; // Staggered vertically palm.scale.set(1 - i * 0.07); // Smaller if farther palm.originalX = palm.x; palms.push(palm); palmGroup.addChild(palm); } // Create Road Lines const roadLines = []; for (let i = 0; i < 10; i++) { const line = new PIXI.Sprite(roadLineTexture); line.anchor.set(0.5, 0.5); line.x = app.screen.width / 2; line.y = i * 80; line.scale.set(0.5, 1); roadLines.push(line); roadLineGroup.addChild(line); } // Sway parameters let swayCounter = 0; // Animation loop - maybe in the update? app.ticker.add((delta) => { swayCounter += delta * 0.1; // Move palms palms.forEach((palm, index) => { palm.y += (index < 3 ? 3 : 1) * delta; // Close palms move faster palm.x = palm.originalX + Math.sin(swayCounter + index) * 5; // Sway effect // Reset palms if (palm.y > app.screen.height + 100) { palm.y = -100; palm.originalX = (index % 2 === 0 ? 200 : 568) + Math.random() * 20 - 10; palm.scale.set(1 - Math.random() * 0.3); } }); // Move road lines roadLines.forEach((line) => { line.y += 5 * delta; if (line.y > app.screen.height) { line.y = -20; } }); }); ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Create a "palmGroup" container and a "roadLineGroup" container
User prompt
Do it
User prompt
Remove the game over conditions
User prompt
Instead of using the trafficCar asset, select randomly one from: trafficCar, trafficCar1, trafficCar2 or trafficCar3
Code edit (2 edits merged)
Please save this source code
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0
});
/****
* Classes
****/
var PlayerCar = Container.expand(function () {
var self = Container.call(this);
var carGraphics = self.attachAsset('playerCar', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = carGraphics.width;
self.height = carGraphics.height;
self.speed = 0;
self.maxSpeed = 15;
self.steering = 0;
self.crashed = false;
self.crash = function () {
if (!self.crashed) {
self.crashed = true;
LK.getSound('crash').play();
LK.effects.flashObject(self, 0xFF0000, 1000);
// Reduce speed on crash
self.speed = Math.max(0, self.speed - 5);
// Reset crash state after 1 second
LK.setTimeout(function () {
self.crashed = false;
}, 1000);
}
};
self.update = function () {
// Handle car physics
if (!self.crashed) {
self.speed = Math.min(self.maxSpeed, self.speed + 0.1);
}
// Apply steering if not crashed
if (!self.crashed) {
self.x += self.steering;
}
// Keep car within 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;
}
};
return self;
});
var TrafficCar = Container.expand(function () {
var self = Container.call(this);
// Randomly select one of the available traffic car assets
var carAssets = ['trafficCar', 'trafficCar2', 'trafficCar3', 'trafficCar4'];
var selectedCarAsset = carAssets[Math.floor(Math.random() * carAssets.length)];
var carGraphics = self.attachAsset(selectedCarAsset, {
anchorX: 0.5,
anchorY: 0.5
});
self.width = carGraphics.width;
self.height = carGraphics.height;
self.speed = 5;
self.direction = Math.random() > 0.5 ? 1 : -1; // Random direction: -1 = left, 1 = right
self.startY = 1700; // Starting Y position (further up the screen)
self.targetY = 2732 + self.height; // Y position when fully off-screen (bottom)
self.initialScale = 0.1;
self.targetScale = 2.0;
// Set target X position in one of the specified ranges
self.targetX = Math.random() > 0.5 ? Math.random() * 500 + 1500 : Math.random() * 300 + 200;
// Set initial scale
self.scale.set(self.initialScale);
self.update = function () {
// Calculate progress towards target Y
var progress = (self.y - self.startY) / (self.targetY - self.startY);
progress = Math.max(0, Math.min(1, progress)); // Clamp between 0 and 1
// Interpolate scale based on progress
var currentScale = self.initialScale + (self.targetScale - self.initialScale) * progress;
self.scale.set(currentScale);
// Calculate X position based on progress (linear interpolation)
var startX = 2048 / 2; // Center of screen
self.x = startX + (self.targetX - startX) * progress;
// Increase speed as car progresses - starting slow and getting faster
var speedMultiplier = 0.5 + progress * 5; // Starts at 0.5 when progress=0, ends at 3.0 when progress=1
// Update Y position with increasing speed
self.y += (gameSpeed - self.speed) * speedMultiplier;
// Destroy if off screen
if (self.y > self.targetY) {
// Check against targetY
// Find and remove self from trafficCars array
var index = trafficCars.indexOf(self);
if (index > -1) {
trafficCars.splice(index, 1);
}
self.destroy();
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Game state variables
var gameSpeed = 10;
var gameStarted = false;
var gameTime = 30; // Initial time in seconds
var distance = 0;
var level = 1;
var checkpointDistance = 500; // Distance between checkpoints
var nextCheckpointAt = checkpointDistance;
var trafficCars = [];
var obstacles = [];
var checkpoints = [];
var timeBonuses = [];
var difficultyTimer;
// Create container groups
var palmGroup = new Container();
var roadLineGroup = new Container();
// Create palm trees
var palms = [];
var centerX = 2048 / 2; // Center of screen X
var centerY = 2732 / 2; // Center of screen Y
for (var i = 0; i < 8; i++) {
var palm = LK.getAsset('palm', {
anchorX: 0.5,
anchorY: 0.5
});
palm.x = centerX; // Start at center
palm.y = centerY; // Start at center
palm.scale.set(0.2); // Start small
palm.lastY = palm.y;
palm.direction = i % 2 === 0 ? "left" : "right"; // Alternate left and right
palm.isMoving = false; // Flag to track if palm is currently animating
palms.push(palm);
palmGroup.addChild(palm);
}
// Create Road Lines
var roadLines = [];
for (var i = 0; i < 10; i++) {
var line = LK.getAsset('roadLine', {
anchorX: 0.5,
anchorY: 0.5
});
line.x = 2048 / 2; // Center of the screen (50% x)
line.y = 2732 / 2 + 200 + i * 200; // Start 200 pixels below the middle of the screen
// Initial scale based on position (start super small, grow as they move down)
var progress = i / 9; // 0 at top, 1 at bottom
var scaleX = 0.1 + progress * 2.9; // Width increases with progress (0.1 to 3)
var scaleY = 0.05 + progress * 2.0; // Height increases with progress (0.05 to 2.05)
line.scale.set(scaleX, scaleY);
line.lastY = line.y;
roadLines.push(line);
roadLineGroup.addChild(line);
}
// Sway parameters
var swayCounter = 0;
// Create road
var road = LK.getAsset('road', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2
});
game.addChild(road);
game.addChild(palmGroup);
game.addChild(roadLineGroup);
// Create player car
var player = new PlayerCar();
player.x = 2048 / 2;
player.y = 2732 - 300;
game.addChild(player);
// Create UI elements
var timeText = new Text2('Time: 30', {
size: 80,
fill: 0xFFFFFF
});
timeText.anchor.set(0, 0);
LK.gui.topRight.addChild(timeText);
timeText.x = -250; // Offset from right edge
var scoreText = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreText.anchor.set(0, 0);
LK.gui.top.addChild(scoreText);
var levelText = new Text2('Level: 1', {
size: 80,
fill: 0xFFFFFF
});
levelText.anchor.set(0, 0);
LK.gui.topRight.addChild(levelText);
levelText.y = 100; // Offset below time
levelText.x = -250; // Offset from right edge
var startText = new Text2('TAP TO START', {
size: 120,
fill: 0xFFFFFF
});
startText.anchor.set(0.5, 0.5);
LK.gui.center.addChild(startText);
// Functions to spawn game elements
function spawnTrafficCar() {
// Only spawn a new car if there are no cars on screen
if (trafficCars.length === 0) {
var car = new TrafficCar();
car.x = 2048 / 2; // Start in the middle of the screen
car.y = car.startY; // Start at the defined startY
car.speed = 3 + Math.random() * 5; // Random speed
trafficCars.push(car);
game.addChild(car);
}
// Schedule next check for spawning
var nextSpawnTime = 1000; // Check every second
LK.setTimeout(spawnTrafficCar, nextSpawnTime);
}
// Start game function
function startGame() {
gameStarted = true;
gameTime = 30;
distance = 0;
level = 1;
gameSpeed = 10;
nextCheckpointAt = checkpointDistance;
LK.setScore(0);
// Update UI
scoreText.setText('Score: 0');
timeText.setText('Time: ' + Math.ceil(gameTime));
levelText.setText('Level: ' + level);
// Remove start text
LK.gui.center.removeChild(startText);
// Start spawning game elements
spawnTrafficCar();
// Set timer to increase difficulty
difficultyTimer = LK.setInterval(function () {
if (gameStarted) {
level++;
gameSpeed += 1;
levelText.setText('Level: ' + level);
}
}, 30000); // Increase difficulty every 30 seconds
// Play background music
LK.playMusic('bgmusic');
// Initialize palm animations with staggered start
for (var i = 0; i < palms.length; i++) {
LK.setTimeout(function (index) {
return function () {
palms[index].isMoving = false; // This will trigger animation in update
};
}(i), i * 500); // Stagger by 500ms per palm
}
// Continuously spawn new palms
LK.setInterval(function () {
if (gameStarted && palms.length < 8) {
var newPalm = LK.getAsset('palm', {
anchorX: 0.5,
anchorY: 0.5
});
newPalm.x = centerX; // Start at center
newPalm.y = centerY; // Start at center
newPalm.scale.set(0.2); // Start small
newPalm.lastY = newPalm.y;
newPalm.direction = palms.length % 2 === 0 ? "left" : "right"; // Alternate left and right
newPalm.isMoving = false; // Flag to track if palm is currently animating
palms.push(newPalm);
palmGroup.addChild(newPalm);
}
}, 1000); // Check every second
}
// Handle touch input
game.down = function (x, y) {
if (!gameStarted) {
startGame();
return;
}
};
game.move = function (x, y) {
if (!gameStarted) {
return;
}
// Move player car directly to mouse X position
var targetX = x;
// Apply smooth movement by calculating the difference
var deltaX = targetX - player.x;
player.steering = deltaX * 0.1; // Smooth movement factor
};
game.up = function () {
if (gameStarted) {
// No need to reset steering as we'll continue to follow mouse
}
};
// Main game update function
game.update = function () {
if (!gameStarted) {
return;
}
// Update game time
gameTime -= 1 / 60; // Assuming 60 FPS
timeText.setText('Time: ' + Math.ceil(gameTime));
// Update distance
if (gameStarted) {
distance += gameSpeed;
LK.setScore(Math.floor(distance / 10));
scoreText.setText('Score: ' + LK.getScore());
// Update palms animations
for (var p = palms.length - 1; p >= 0; p--) {
var palm = palms[p];
palm.lastY = palm.y;
// Check if palm reached bottom of screen - destroy it
if (palm.y > 2732 + 100) {
palmGroup.removeChild(palm);
palms.splice(p, 1);
palm.destroy();
continue;
}
// Start a new palm animation if not already moving
if (!palm.isMoving) {
palm.isMoving = true;
// Set target position based on direction (left or right corner)
var targetX = palm.direction === "left" ? 100 : 2048 - 100; // Left or right edge
var targetY = 2732 + 100; // Below bottom of screen
var targetScale = 2.0; // End larger
// Create tween animation with perspective effect - use same duration for all palms
tween(palm, {
x: targetX,
y: targetY,
scaleX: targetScale,
scaleY: targetScale
}, {
duration: 3000,
// Same fixed duration for all palms: 3 seconds
easing: tween.easeIn
});
}
// Spawn new palms if we have less than 8
while (palms.length < 8) {
var newPalm = LK.getAsset('palm', {
anchorX: 0.5,
anchorY: 0.5
});
newPalm.x = centerX; // Start at center
newPalm.y = centerY; // Start at center
newPalm.scale.set(0.2); // Start small
newPalm.lastY = newPalm.y;
newPalm.direction = palms.length % 2 === 0 ? "left" : "right"; // Alternate left and right
newPalm.isMoving = false; // Flag to track if palm is currently animating
palms.push(newPalm);
palmGroup.addChild(newPalm);
}
}
// Move road lines
for (var r = 0; r < roadLines.length; r++) {
var line = roadLines[r];
line.lastY = line.y;
line.y += 5 * gameSpeed / 10;
if (line.y > 2732) {
line.x = 2048 / 2; // Center of the screen (50% x)
line.y = 2732 / 2 + 200; // 200 pixels below the middle of the screen
// Reset scale to smallest for lines that just respawned - start super small
line.scale.set(0.1, 0.35);
}
// Update scale based on Y position to create perspective
var progress = (line.y - (2732 / 2 + 200)) / (2732 - (2732 / 2 + 200));
progress = Math.max(0, Math.min(1, progress)); // Clamp between 0 and 1
// Scale increases with progress (tiny dot to full line)
var scaleY = 1 + progress * 3.0; // Height increases dramatically with progress
var scaleX = 0.1 + progress * 2.9; // Width increases with progress (0.1 to 3)
// Keep position fixed at center - no spreading
line.x = 2048 / 2; // Keep all lines at center
line.scale.set(scaleX, scaleY);
}
}
// Game will continue indefinitely - removed game over condition
gameTime = Math.max(gameTime, 0.1); // Keep time from reaching zero
// Check collisions with traffic cars but just trigger visual effect without ending game
for (var i = trafficCars.length - 1; i >= 0; i--) {
var car = trafficCars[i];
if (player.intersects(car) && !player.crashed) {
player.crash();
trafficCars.splice(i, 1);
car.destroy();
// Add small time bonus on collision instead of ending game
gameTime += 1;
}
}
};
function endGame() {
if (!gameStarted) {
return;
}
// Just save high score without ending the game
if (LK.getScore() > storage.highScore) {
storage.highScore = LK.getScore();
}
// Game continues - no game over screen
} ===================================================================
--- original.js
+++ change.js
@@ -329,17 +329,17 @@
// Set target position based on direction (left or right corner)
var targetX = palm.direction === "left" ? 100 : 2048 - 100; // Left or right edge
var targetY = 2732 + 100; // Below bottom of screen
var targetScale = 2.0; // End larger
- // Create tween animation with perspective effect
+ // Create tween animation with perspective effect - use same duration for all palms
tween(palm, {
x: targetX,
y: targetY,
scaleX: targetScale,
scaleY: targetScale
}, {
- duration: 4000,
- // 4 seconds
+ duration: 3000,
+ // Same fixed duration for all palms: 3 seconds
easing: tween.easeIn
});
}
// Spawn new palms if we have less than 8