vendredi 28 octobre 2016

Haskell Gloss: random starfield not random?

Using Haskell’s Gloss library, I’m trying to simulate a starfield. The visual aspect (drawing ‘stars’ with various speeds and sizes to the screen) is working. However, for some reason the stars aren’t being randomly distributed, resulting in a simulation which has a pattern. I also have this problem with an explosion simulation, but for simplicity’s sake, I’ll leave that one out for now. This is a simplified version of my code so far:

type Position       = (Float, Float)
type Velocity       = (Float, Float)
type Size           = Float
type Speed          = Float
type Drag           = Float
type Life           = Int

type Particle       = (Position, Velocity, Speed, Drag, Life, Size)

-- timeHandler is called every frame by the gloss ‘Play’ function. It's being passed
-- the delta time and the world it needs to update.
timeHandler dt world = world {rndGen = mkStdGen (timer world),
                              timer  = (timer world) + 1,
                              stars  = spawnParticle world (rndGen world) : updateParticles (stars world) dt world}

randomFloat :: StdGen -> Float -> Float -> Float
randomFloat rand min max = fst $ randomR (min, max) rand

spawnParticle :: World -> StdGen -> Particle
spawnParticle world gen = ((pos, (1 * speed, 0), speed, 1, 0, size), snd (split gen))
where pos   = (px', py')
      px'   = randomFloat gen (-600) (-500)
      py'   = randomFloat gen (-250) 250
      speed = size * (randomFloat gen 100 300) -- the smaller a particle, the slower 
      size  = randomFloat gen 0.1 1.3

updateParticles :: [Particle] -> Float -> World -> [Particle]
updateParticles []     _  _     = []
updateParticles (x:xs) dt world | fst(posPart x) > 500 = updateParticles xs dt world
                                | otherwise            = updatedPart : updateParticles xs dt world
    where pos'        = updateParticlePosition dt x world
          updatedPart = (pos', velPart x, speedPart x, 1, 0, sizePart x)

Note: velPart, speedPart etc. are functions to get a property out of a given particle. Again, drawing works fine, so I’ll leave that code out. updateParticlePosition simply adds the velocity to the current position of a star.

I think the problem has something to do with the fact that my random generators are not passed properly, but I’m too confused to come up with a solution… Any help is much appreciated!




Aucun commentaire:

Enregistrer un commentaire