Prexxo

Sand particle simulation

Apr 25th, 2022 (edited)
633
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 3.68 KB | None | 0 0
  1. local Vector2 = require"Vector2"
  2. local Grid = require"Grid"
  3. require"utility"
  4.  
  5. local particleSize = Vector2.new(2, 2)
  6. local gridSize = Vector2.new(600, 500)
  7. local gravity = Vector2.new(0, 30)
  8. local gridRoot = Vector2.new()
  9.  
  10. local particleGrid = Grid.new("static", gridRoot, particleSize, gridSize); particleGrid:outline()
  11. local gridCells = particleGrid.cells
  12.  
  13. local particleLists = {
  14.     ["solid"] = {length = 0},
  15.     ["liquid"] = {length = 0},
  16. }
  17.  
  18. local solidParticlesList = particleLists["solid"]
  19.  
  20. local numberOfParticles = 0 --// All together
  21.  
  22. local particleDatabase = {
  23.     ["sand"] = {
  24.         possibleColors = {
  25.             Color.new(255, 236, 26),
  26.             Color.new(255, 239, 115),
  27.             Color.new(255, 200, 61),
  28.             Color.new(255, 183, 74),
  29.  
  30.         },
  31.         type = "solid",
  32.  
  33.     }
  34. }
  35.  
  36. local function isCellEmpty(cell)
  37.     return cell and cell.particle == nil and cell
  38. end
  39.  
  40. local function moveParticle(particle, newCell)
  41.     local oldCell = particle.cell
  42.     oldCell.particle = nil
  43.  
  44.     particle.cell = newCell
  45.     newCell.particle = particle
  46. end
  47.  
  48. local function getRandomDirection()
  49.     local random = math.random()
  50.  
  51.     return random == 1 and 1 or -1
  52. end
  53.  
  54. local function getCell(x, y)
  55.     local cellX = gridCells[x]
  56.  
  57.     return cellX and cellX[y]
  58. end
  59.  
  60. local function simulateSolidParticles()
  61.     for i = solidParticlesList.length, 1, -1 do
  62.         local particle = solidParticlesList[i]
  63.         local cell = particle.cell
  64.         local cellPos = cell.pos
  65.         local freeFalling = particle.freeFalling
  66.  
  67.         local posX, posY = cellPos.x, cellPos.y
  68.  
  69.         local cellBellow = getCell(posX, posY+1)
  70.  
  71.         if isCellEmpty(cellBellow) then
  72.             moveParticle(particle, cellBellow)
  73.  
  74.             freeFalling = true
  75.         else
  76.             freeFalling = false
  77.             local diagonalCell = isCellEmpty(getCell(posX-1, posY+1)) or isCellEmpty(getCell(posX+1, posY+1))
  78.  
  79.             if diagonalCell then
  80.                 moveParticle(particle, diagonalCell)
  81.             end
  82.  
  83.         end
  84.  
  85.         ::continue::
  86.         particle.freeFalling = freeFalling
  87.     end
  88. end
  89.  
  90. local Particle = {
  91.     grid = particleGrid,
  92.     particleSize = particleSize,
  93.  
  94. }
  95.  
  96. function Particle.new(particleId, cellPos, ...)
  97.     local particleData = particleDatabase[particleId]
  98.     local particleType = particleData.type
  99.     local possibleColors = particleData.possibleColors
  100.  
  101.     local particle = {
  102.         type = particleType,
  103.         cell = particleGrid:getCell(cellPos),
  104.         color = possibleColors[math.random(1, #possibleColors)],
  105.  
  106.         freeFalling = true,
  107.     }
  108.  
  109.     local particleList = particleLists[particleType]
  110.     local listLength = particleList.length + 1; particleList.length = listLength
  111.  
  112.     --// insert into list for the particle to update
  113.     particleList[listLength] = particle
  114.    
  115.     numberOfParticles = numberOfParticles + 1
  116.  
  117.     return particle
  118. end
  119.  
  120. function Particle.update(timeElapsed)
  121.     simulateSolidParticles()
  122. end
  123.  
  124. function Particle.draw()
  125.     love.graphics.print("Particles: "..numberOfParticles, 10, gridSize.y +20, 0)
  126.     love.graphics.print("FPS: "..love.timer.getFPS(), 10, gridSize.y + 40, 0)
  127.  
  128.     for _, list in pairs(particleLists) do
  129.         for i = 1, list.length do
  130.             local particle = list[i]
  131.             local worldPos = particleGrid:cellToWorldPos(particle.cell.pos)
  132.             local color = particle.color
  133.    
  134.             love.graphics.setColor(color.r/255, color.g/255, color.b/255)
  135.             love.graphics.rectangle("fill", worldPos.x + particleSize.x/2, worldPos.y + particleSize.y/2, particleSize.x, particleSize.y)
  136.         end
  137.     end
  138. end
  139.  
  140. return Particle
Add Comment
Please, Sign In to add comment