User prompt
make particules bigger
User prompt
make background is dark black
User prompt
make particules more faster
User prompt
make follow more faster
User prompt
particules are following mouse with like a snake
User prompt
make a better optimization
User prompt
fix the fps problem
User prompt
make all particles same color and color are always changing
User prompt
add it more shapes
User prompt
make particles cant get out of the screen
User prompt
solve the fps problem
User prompt
add more particles and make physics
Code edit (1 edits merged)
Please save this source code
User prompt
Million Particle Swarm
Initial prompt
make a particles game and make it million particles are following mouse and being cool shapes
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Particle class: represents a single particle in the swarm. var Particle = Container.expand(function () { var self = Container.call(this); // Attach the particle asset, centered var gfx = self.attachAsset('particle', { anchorX: 0.5, anchorY: 0.5 }); // Particle properties self.vx = 0; self.vy = 0; self.tx = 0; // target x self.ty = 0; // target y self.speed = 0.55 + Math.random() * 0.15; // much faster following self.color = 0xffffff; gfx.tint = self.color; // Animate color change self.setColor = function (newColor) { var startColor = gfx.tint; // Use a short duration for smooth, fast color transitions tween(gfx, { tint: newColor }, { duration: 200, easing: tween.cubicOut }); self.color = newColor; }; // Update method: move towards target self.update = function () { // Move towards target (tx, ty) with some inertia var dx = self.tx - self.x; var dy = self.ty - self.y; self.vx += dx * self.speed * 0.12; self.vy += dy * self.speed * 0.12; // --- Simple physics additions --- // Gravity (downwards) self.vy += 0.02; // Removed neighbor repulsion for performance // Damping for smoothness self.vx *= 0.85; self.vy *= 0.85; self.x += self.vx; self.y += self.vy; // Clamp position to stay within screen bounds if (self.x < 0) { self.x = 0; self.vx = 0; } if (self.x > 2048) { self.x = 2048; self.vx = 0; } if (self.y < 0) { self.y = 0; self.vy = 0; } if (self.y > 2732) { self.y = 2732; self.vy = 0; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 // Pure black background }); /**** * Game Code ****/ // We'll use the tween plugin for smooth color transitions. // We'll use simple colored ellipses for particles, and a background color for the game. // Number of particles: balance between performance and visual density var PARTICLE_COUNT = 800; // Lowered to 800 for much better performance on all devices // Particle storage var particles = []; // Swarm target position (where particles move towards) var swarmTarget = { x: 1024, y: 1366 }; // Start at center // Shape morphing: list of shape functions var shapes = [ // Circle function (i, N) { var angle = i / N * Math.PI * 2; var radius = 600; return { x: 1024 + Math.cos(angle) * radius, y: 1366 + Math.sin(angle) * radius }; }, // Horizontal wave function (i, N) { var x = 300 + i / N * 1448; var y = 1366 + Math.sin(i / N * Math.PI * 4 + LK.ticks * 0.01) * 400; return { x: x, y: y }; }, // Heart shape function (i, N) { var t = i / N * Math.PI * 2; var scale = 400; var x = 1024 + scale * 16 * Math.pow(Math.sin(t), 3); var y = 1200 - scale * (13 * Math.cos(t) - 5 * Math.cos(2 * t) - 2 * Math.cos(3 * t) - Math.cos(4 * t)); return { x: x, y: y }; }, // Spiral function (i, N) { var t = i / N * Math.PI * 8; var r = 80 + 500 * (i / N); var x = 1024 + Math.cos(t) * r; var y = 1366 + Math.sin(t) * r; return { x: x, y: y }; }, // Random cloud function (i, N) { var angle = i / N * Math.PI * 2; var radius = 400 + Math.sin(LK.ticks * 0.01 + i) * 120 + Math.random() * 40; return { x: 1024 + Math.cos(angle) * radius, y: 1366 + Math.sin(angle) * radius }; }, // Star shape function (i, N) { var angle = i / N * Math.PI * 2; var spikes = 5; var outerRadius = 600; var innerRadius = 250; var spike = Math.floor(i / (N / (spikes * 2))); var r = spike % 2 === 0 ? outerRadius : innerRadius; return { x: 1024 + Math.cos(angle) * r, y: 1366 + Math.sin(angle) * r }; }, // Square function (i, N) { var side = Math.floor(i / (N / 4)); var pos = i % (N / 4) / (N / 4); var size = 900; if (side === 0) { return { x: 1024 - size / 2 + pos * size, y: 1366 - size / 2 }; } else if (side === 1) { return { x: 1024 + size / 2, y: 1366 - size / 2 + pos * size }; } else if (side === 2) { return { x: 1024 + size / 2 - pos * size, y: 1366 + size / 2 }; } else { return { x: 1024 - size / 2, y: 1366 + size / 2 - pos * size }; } }, // Infinity (lemniscate) function (i, N) { var t = i / N * Math.PI * 2; var a = 350; var x = 1024 + a * Math.cos(t) / (1 + Math.sin(t) * Math.sin(t)); var y = 1366 + a * Math.sin(t) * Math.cos(t) / (1 + Math.sin(t) * Math.sin(t)); return { x: x, y: y }; }, // Flower (petals) function (i, N) { var angle = i / N * Math.PI * 2; var petals = 7; var r = 400 + 180 * Math.sin(petals * angle + LK.ticks * 0.01); return { x: 1024 + Math.cos(angle) * r, y: 1366 + Math.sin(angle) * r }; }]; // Current shape index and morph progress var currentShape = 0; var nextShape = 1; var morphProgress = 0; // 0 to 1 // Morph every X seconds var MORPH_TIME = 240; // frames (4 seconds) var morphTimer = 0; // Precompute target positions for shapes var shapeTargets = [[], []]; // Initialize particles for (var i = 0; i < PARTICLE_COUNT; i++) { var p = new Particle(); // Start at random position near center p.x = 1024 + (Math.random() - 0.5) * 200; p.y = 1366 + (Math.random() - 0.5) * 200; p.tx = p.x; p.ty = p.y; p._particleIndex = i; // Assign index for neighbor repulsion particles.push(p); game.addChild(p); } // Function to update shape targets function updateShapeTargets() { var N = PARTICLE_COUNT; for (var s = 0; s < 2; s++) { var shapeFn = shapes[s === 0 ? currentShape : nextShape]; for (var i = 0; i < N; i++) { shapeTargets[s][i] = shapeFn(i, N); } } } updateShapeTargets(); // Touch/mouse handling var isTouching = false; var lastTouch = { x: 1024, y: 1366 }; // Move handler: update swarm target to touch position function handleMove(x, y, obj) { // Clamp to game area if (x < 0) x = 0; if (x > 2048) x = 2048; if (y < 0) y = 0; if (y > 2732) y = 2732; swarmTarget.x = x; swarmTarget.y = y; lastTouch.x = x; lastTouch.y = y; isTouching = true; } game.move = handleMove; // Down handler: start following touch game.down = function (x, y, obj) { handleMove(x, y, obj); isTouching = true; }; // Up handler: stop following touch, revert to shape morphing game.up = function (x, y, obj) { isTouching = false; }; // (morphColors function removed, color is now global and animated in game.update) // Main update loop game.update = function () { // Shape morphing logic morphTimer++; if (morphTimer >= MORPH_TIME) { morphTimer = 0; currentShape = nextShape; nextShape = (nextShape + 1) % shapes.length; morphProgress = 0; updateShapeTargets(); // morphColors(); // Remove per-particle color morphing } if (!isTouching) { morphProgress += 1 / MORPH_TIME; if (morphProgress > 1) morphProgress = 1; } else { morphProgress = 0; } // Calculate a global color that changes over time var t = LK.ticks * 0.015; var r = Math.floor(180 + Math.sin(t) * 75); var g = Math.floor(180 + Math.sin(t + 2) * 75); var b = Math.floor(180 + Math.sin(t + 4) * 75); var globalColor = r << 16 | g << 8 | b; // For each particle, set its target and color for (var i = 0; i < particles.length; i++) { var p = particles[i]; // Only update if on screen (skip if far outside, for extra FPS) if (p.x > -32 && p.x < 2080 && p.y > -32 && p.y < 2764) { if (isTouching) { // Snake-like following: first particle follows touch, each next follows previous if (i === 0) { p.tx = swarmTarget.x; p.ty = swarmTarget.y; } else { // Follow previous particle with a delay/lag for snake effect var prev = particles[i - 1]; // Distance between particles in the chain var followDist = 12; var dx = prev.x - p.x; var dy = prev.y - p.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > followDist) { // Move target to a point followDist behind the previous particle var t = followDist / dist; p.tx = p.x + dx * t; p.ty = p.y + dy * t; } else { // Stay in place if close enough p.tx = p.x; p.ty = p.y; } } } else { // Morph between shapes var t0 = shapeTargets[0][i]; var t1 = shapeTargets[1][i]; var tMorph = morphProgress; p.tx = t0.x * (1 - tMorph) + t1.x * tMorph; p.ty = t0.y * (1 - tMorph) + t1.y * tMorph; } // Set all particles to the same color, but only tween the first particle and copy the tint to others for performance if (i === 0) { if (i === 0) { p.setColor(globalColor); var batchedTint = p.children[0].tint; } if (i > 0 && typeof batchedTint !== "undefined") { p.children[0].tint = batchedTint; } var batchedTint = p.children[0].tint; } if (i > 0 && typeof batchedTint !== "undefined") { p.children[0].tint = batchedTint; } p.update(); } else if (i % 8 === LK.ticks % 8) { // For offscreen particles, update less frequently (every 8th frame) p.update(); } } }; // No GUI or score, as this is a pure interactive art experience.
===================================================================
--- original.js
+++ change.js