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.12 + Math.random() * 0.08; // slightly varied speed for organic look self.color = 0xffffff; // Assign a random color on creation function randomColor() { // Generate a random pastel color var r = 180 + Math.floor(Math.random() * 75); var g = 180 + Math.floor(Math.random() * 75); var b = 180 + Math.floor(Math.random() * 75); return r << 16 | g << 8 | b; } self.color = randomColor(); gfx.tint = self.color; // Animate color change self.setColor = function (newColor) { var startColor = gfx.tint; tween(gfx, { tint: newColor }, { duration: 800, 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.05; self.vy += dy * self.speed * 0.05; // --- Simple physics additions --- // Gravity (downwards) self.vy += 0.02; // Repulsion from nearby particles (very basic, only for a few neighbors for perf) // This is a naive O(N) approach, but we only check a few random neighbors for speed var repulsionStrength = 0.2; var neighborCount = 3; for (var n = 0; n < neighborCount; n++) { var idx = (self._particleIndex + n * 997) % PARTICLE_COUNT; // pseudo-random neighbor if (typeof particles !== "undefined" && particles[idx] && particles[idx] !== self) { var other = particles[idx]; var rx = self.x - other.x; var ry = self.y - other.y; var distSq = rx * rx + ry * ry; if (distSq < 400) { // Only if very close var dist = Math.sqrt(distSq) + 0.01; var force = repulsionStrength / dist; self.vx += rx / dist * force; self.vy += ry / dist * force; } } } // Damping for smoothness self.vx *= 0.85; self.vy *= 0.85; self.x += self.vx; self.y += self.vy; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x181830 // Deep dark blue for contrast }); /**** * 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 = 10000; // Increased to 10,000 for a denser, more impressive effect // 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 }; }]; // 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; }; // Animate color palette on each morph function morphColors() { for (var i = 0; i < particles.length; i++) { var p = particles[i]; // Assign a new random pastel color var newColor = function () { var r = 180 + Math.floor(Math.random() * 75); var g = 180 + Math.floor(Math.random() * 75); var b = 180 + Math.floor(Math.random() * 75); return r << 16 | g << 8 | b; }(); p.setColor(newColor); } } // 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(); } if (!isTouching) { morphProgress += 1 / MORPH_TIME; if (morphProgress > 1) morphProgress = 1; } else { morphProgress = 0; } // For each particle, set its target for (var i = 0; i < particles.length; i++) { var p = particles[i]; if (isTouching) { // Swarm follows finger/touch, with some spread var angle = i / particles.length * Math.PI * 2; var spread = 80 + Math.sin(LK.ticks * 0.01 + i) * 30; p.tx = swarmTarget.x + Math.cos(angle) * spread; p.ty = swarmTarget.y + Math.sin(angle) * spread; } else { // Morph between shapes var t0 = shapeTargets[0][i]; var t1 = shapeTargets[1][i]; var t = morphProgress; p.tx = t0.x * (1 - t) + t1.x * t; p.ty = t0.y * (1 - t) + t1.y * t; } p.update(); } }; // No GUI or score, as this is a pure interactive art experience.
===================================================================
--- original.js
+++ change.js
@@ -48,8 +48,31 @@
var dx = self.tx - self.x;
var dy = self.ty - self.y;
self.vx += dx * self.speed * 0.05;
self.vy += dy * self.speed * 0.05;
+ // --- Simple physics additions ---
+ // Gravity (downwards)
+ self.vy += 0.02;
+ // Repulsion from nearby particles (very basic, only for a few neighbors for perf)
+ // This is a naive O(N) approach, but we only check a few random neighbors for speed
+ var repulsionStrength = 0.2;
+ var neighborCount = 3;
+ for (var n = 0; n < neighborCount; n++) {
+ var idx = (self._particleIndex + n * 997) % PARTICLE_COUNT; // pseudo-random neighbor
+ if (typeof particles !== "undefined" && particles[idx] && particles[idx] !== self) {
+ var other = particles[idx];
+ var rx = self.x - other.x;
+ var ry = self.y - other.y;
+ var distSq = rx * rx + ry * ry;
+ if (distSq < 400) {
+ // Only if very close
+ var dist = Math.sqrt(distSq) + 0.01;
+ var force = repulsionStrength / dist;
+ self.vx += rx / dist * force;
+ self.vy += ry / dist * force;
+ }
+ }
+ }
// Damping for smoothness
self.vx *= 0.85;
self.vy *= 0.85;
self.x += self.vx;
@@ -70,9 +93,9 @@
****/
// 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 = 1200; // For MVP, 1200 is performant and visually rich
+var PARTICLE_COUNT = 10000; // Increased to 10,000 for a denser, more impressive effect
// Particle storage
var particles = [];
// Swarm target position (where particles move towards)
var swarmTarget = {
@@ -146,8 +169,9 @@
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