PixelChipCode

Circle Pack Push in GameMaker

Oct 24th, 2024 (edited)
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JavaScript 4.27 KB | Source Code | 0 0
  1. // Circle pack-push in GameMaker by oliver @pixelchipcode
  2.  
  3. // obj_packer: Create Event
  4. circles = [];
  5. path_points = [];
  6. is_drawing = false;
  7. max_radius = 20;
  8. min_radius = 2;
  9. spawn_interval = 10;
  10. last_spawn_x = 0;
  11. last_spawn_y = 0;
  12.  
  13. // Physics constants - tweaked for smoother motion with arrays
  14. spring_strength = .4;
  15. damping = 0.8;
  16. min_push_distance = 0.1;
  17.  
  18. // obj_packer: Step Event
  19. // Handle mouse input and drawing
  20. if (mouse_check_button_pressed(mb_left)) {
  21.     is_drawing = true;
  22.     circles = [];  // Clear arrays
  23.     path_points = [];
  24.     array_push(path_points, [mouse_x, mouse_y]);
  25.     last_spawn_x = mouse_x;
  26.     last_spawn_y = mouse_y;
  27. }
  28.  
  29. if (mouse_check_button(mb_left) && is_drawing) {
  30.     // Add new mouse position if moved
  31.     var path_len = array_length(path_points);
  32.     var last_point = path_points[path_len - 1];
  33.     if (point_distance(mouse_x, mouse_y, last_point[0], last_point[1]) > 5) {
  34.         array_push(path_points, [mouse_x, mouse_y]);
  35.     }
  36.    
  37.     // Spawn new circles along the line
  38.     var dist = point_distance(last_spawn_x, last_spawn_y, mouse_x, mouse_y);
  39.    
  40.     if (dist >= spawn_interval) {
  41.         var dir = point_direction(last_spawn_x, last_spawn_y, mouse_x, mouse_y);
  42.         var steps = floor(dist / spawn_interval);
  43.        
  44.         for (var i = 0; i < steps; i++) {
  45.             var spawn_x = last_spawn_x + lengthdir_x(spawn_interval * (i + 1), dir);
  46.             var spawn_y = last_spawn_y + lengthdir_y(spawn_interval * (i + 1), dir);
  47.            
  48.             // [x, y, vx, vy, radius, target_radius, growing, hue]
  49.             array_push(circles, [
  50.                 spawn_x,                    // x
  51.                 spawn_y,                    // y
  52.                 0,                          // vx
  53.                 0,                          // vy
  54.                 1,                          // radius
  55.                 random_range(min_radius, max_radius), // target_radius
  56.                 1,                          // growing (1 = true, 0 = false)
  57.                 (point_distance(spawn_x, spawn_y, room_width/2, room_height/2) /
  58.                  point_distance(0, 0, room_width/2, room_height/2)) * 255 // hue
  59.             ]);
  60.         }
  61.        
  62.         last_spawn_x = spawn_x;
  63.         last_spawn_y = spawn_y;
  64.     }
  65. }
  66.  
  67. if (mouse_check_button_released(mb_left)) {
  68.     is_drawing = false;
  69. }
  70.  
  71. // Update circles with physics
  72. var circle_count = array_length(circles);
  73. for (var i = 0; i < circle_count; i++) {
  74.     var circle = circles[i];
  75.    
  76.     // Grow circles
  77.     if (circle[6] && circle[4] < circle[5]) {  // if growing and radius < target_radius
  78.         circle[4] += 0.5;  // increase radius
  79.         if (circle[4] >= circle[5]) {
  80.             circle[4] = circle[5];
  81.             circle[6] = 0;  // stop growing
  82.         }
  83.     }
  84.    
  85.     // Calculate spring forces between circles
  86.     var total_force_x = 0;
  87.     var total_force_y = 0;
  88.    
  89.     for (var j = 0; j < circle_count; j++) {
  90.         if (i == j) continue;
  91.        
  92.         var o = circles[j];
  93.         var dist = point_distance(circle[0], circle[1], o[0], o[1]);
  94.         var min_dist = circle[4] + o[4];  // sum of radii
  95.        
  96.         if (dist < min_dist && dist > 0) {
  97.             var overlap = min_dist - dist;
  98.             var angle = point_direction(o[0], o[1], circle[0], circle[1]);
  99.            
  100.             // Calculate spring force
  101.             var force = overlap * spring_strength;
  102.             total_force_x += lengthdir_x(force, angle);
  103.             total_force_y += lengthdir_y(force, angle);
  104.         }
  105.     }
  106.    
  107.     // Apply forces and update velocity
  108.     circle[2] += total_force_x;  // vx
  109.     circle[3] += total_force_y;  // vy
  110.    
  111.     // Apply damping
  112.     circle[2] *= damping;
  113.     circle[3] *= damping;
  114.    
  115.     // Update position if movement is significant
  116.     if (abs(circle[2]) > min_push_distance || abs(circle[3]) > min_push_distance) {
  117.         circle[0] += circle[2];  // x += vx
  118.         circle[1] += circle[3];  // y += vy
  119.     }
  120. }
  121.  
  122. // Draw circles with gradient effect
  123. var circle_count = array_length(circles);
  124. for (var i = 0; i < circle_count; i++) {
  125.     var circle = circles[i];
  126.     if(circle[4] < 5){
  127.             draw_circle(circle[0], circle[1], circle[4],false)
  128.     } else{
  129.     draw_circle(circle[0], circle[1], circle[4],true)
  130.     }
  131. }
Tags: gml gameMaker
Advertisement
Add Comment
Please, Sign In to add comment