Advertisement
KrYn0MoRe

particle simulator

Oct 2nd, 2023 (edited)
1,049
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.84 KB | None | 0 0
  1. local part = Instance.new("Part")
  2. part.Size = Vector3.new(10,10,1)
  3. part.Position = Vector3.new(0,10,20)
  4. part.Anchored = true
  5. part.CanCollide = false
  6. part.Parent = script
  7.  
  8. local surface = Instance.new("SurfaceGui")
  9. surface.SizingMode = Enum.SurfaceGuiSizingMode.PixelsPerStud
  10. surface.PixelsPerStud = 50
  11. surface.Parent = part
  12.  
  13. local main = Instance.new("Frame")
  14. main.Size = UDim2.new(1,0,1,0)
  15. main.BorderSizePixel = 0
  16. main.BackgroundColor3 = Color3.new(0,0,0)
  17. main.ClipsDescendants = true
  18. main.Parent = surface
  19.  
  20. local particle_list = {}
  21. local groups = {}
  22. local particle_data = {}
  23.  
  24. local scale = 10 -- size and velocity scaling
  25. local mas = main.AbsoluteSize
  26.  
  27. function create_particle(x,y)
  28.     x = x or 0
  29.     y = y or 0
  30.    
  31.     local p = Instance.new("Frame")
  32.     p.Size = UDim2.new(0,scale,0,scale)
  33.     p.Position = UDim2.new(0,mas.X/2,0,mas.Y/2)+UDim2.new(0,x*scale,0,y*scale)
  34.     p.BackgroundColor3 = Color3.new(1,1,1)
  35.     p.Name = #particle_list+1
  36.     p.BorderSizePixel = 0
  37.     p.Parent = main
  38.    
  39.     particle_data[p] = {}
  40.     particle_data[p].force = Vector2.new(0,0)
  41.     particle_data[p].position = Vector2.new(p.Position.X.Offset,p.Position.Y.Offset)
  42.     particle_data[p].mass = 1
  43.    
  44.     table.insert(particle_list,p)
  45. end
  46.  
  47. function update_divs(divs)
  48.     for _,div in pairs(divs) do
  49.         for x = 0,div do
  50.             groups[div][x] = {}
  51.  
  52.             for y = 0,div do
  53.                 groups[div][x][y] = 0
  54.  
  55.                 local visualize = false
  56.  
  57.                 if visualize then
  58.                     local p = Instance.new("Frame")
  59.                     p.Size = UDim2.new(3,0,0,1)
  60.                     p.Position = UDim2.new(0,mas.X/div*x,0,mas.Y/div*y)
  61.                     p.BackgroundColor3 = Color3.new(1,1,1)
  62.                     p.BackgroundTransparency = .9
  63.                     p.BorderSizePixel = 0
  64.                     p.Parent = main
  65.  
  66.                     local p = Instance.new("Frame")
  67.                     p.Size = UDim2.new(0,1,3,0)
  68.                     p.Position = UDim2.new(0,mas.X/div*x,0,mas.Y/div*y)
  69.                     p.BackgroundColor3 = Color3.new(1,1,1)
  70.                     p.BackgroundTransparency = .9
  71.                     p.BorderSizePixel = 0
  72.                     p.Parent = main
  73.                 end
  74.             end
  75.         end
  76.     end
  77.     for i,v in ipairs(particle_list) do -- first establish group population
  78.         local pos = v.Position
  79.         for _,div in pairs(divs) do
  80.             local x = math.floor(pos.X.Offset/mas.X*div)
  81.             local y = math.floor(pos.Y.Offset/mas.Y*div)
  82.            
  83.             if div > x and div > y and x > 0 and y > 0 then
  84.                 groups[div][x][y] += 1 -- increase population in group area
  85.             end
  86.         end
  87.     end
  88. end
  89.  
  90. function update_groups()
  91.     local divs = {60,40,20}
  92.     local total_div = 0
  93.    
  94.     for _,div in pairs(divs) do
  95.         total_div += div
  96.         groups[div] = {}
  97.     end
  98.     update_divs(divs)
  99.    
  100.     for i,v in ipairs(particle_list) do -- update colors
  101.         local pos = v.Position
  102.        
  103.         local pop = 0
  104.        
  105.         for _,div in pairs(divs) do
  106.             local x = math.floor(pos.X.Offset/mas.X*div)
  107.             local y = math.floor(pos.Y.Offset/mas.Y*div)
  108.  
  109.             if div > x and div > y and x > 0 and y > 0 then
  110.                 local divpop = groups[div][x][y]
  111.                 pop += divpop^2/(mas.X/div)
  112.             end
  113.         end
  114.  
  115.         local radiance = pop
  116.         v.BackgroundColor3 = Color3.new(radiance,radiance,radiance)
  117.         --v.BackgroundColor3 = Color3.new(0.4+radiance*0.4,0.8-radiance*0.4,0.8-radiance*0.4)
  118.     end
  119.    
  120.     --[[ -- supposed to update gravity with large amounts of particles but im lazy to add
  121.     for _,p in ipairs(particle_list) do -- update gravity
  122.         local pos = p.Position
  123.        
  124.         local force = 0
  125.        
  126.         for _,div in pairs(divs) do
  127.             local x = math.floor(pos.X.Offset/mas.X*div)
  128.             local y = math.floor(pos.Y.Offset/mas.Y*div)
  129.            
  130.             if div > x and div > y and x > 0 and y > 0 then
  131.                 local divpop = groups[div][x][y]
  132.                 force += divpop/(mas.X/div) -- all the particles have mass of 1, no extra steps
  133.             end
  134.         end
  135.  
  136.         local p_vec = Vector2.new(p.Position.X.Offset,p.Position.Y.Offset)
  137.         local new_vec = p_vec+force
  138.  
  139.         p.Position = UDim2.new(0,new_vec.X,0,new_vec.Y)
  140.     end
  141.     ]]
  142. end
  143.  
  144. function update_particle(p)
  145.     local G = 6.67408 * 10^-4--1/1000
  146.     for i,v in ipairs(particle_list) do
  147.         if v ~= p then
  148.             local m1 = particle_data[p].mass
  149.             local m2 = particle_data[v].mass
  150.             local p_vec = particle_data[p].position
  151.             local v_vec = particle_data[v].position
  152.             local force_vec = v_vec-p_vec
  153.             local r = force_vec.Magnitude
  154.             local F = G*(m1*m2)/r^2
  155.             local A = F/m1
  156.             if r > 0 then
  157.                 force_vec = force_vec*A
  158.             end
  159.             force_vec = particle_data[p].force+force_vec
  160.             particle_data[p].force = force_vec
  161.  
  162.             local new_vec = p_vec+force_vec
  163.             particle_data[p].position = new_vec
  164.             --p.Position = UDim2.new(0,new_vec.X,0,new_vec.Y)
  165.         end
  166.     end
  167. end
  168.  
  169. function update_sim()
  170.     for _,p in ipairs(particle_list) do
  171.         update_particle(p)
  172.     end
  173.     for _,p in ipairs(particle_list) do
  174.         local new_vec = particle_data[p].position
  175.         p.Position = UDim2.new(0,new_vec.X,0,new_vec.Y)
  176.     end
  177.     update_groups()
  178. end
  179.  
  180. local mx = 10
  181. local my = 10
  182.  
  183. for x = 1,mx do
  184.     for y = 1,my do
  185.         create_particle((-mx*2/2)+x*2,(-my*2/2)+y*2)
  186.     end
  187. end
  188.  
  189. update_groups()
  190.  
  191. task.wait(3)
  192.  
  193. while true do
  194.     update_sim()
  195.     task.wait()
  196. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement