Используя Haskell's Gloss library, я пытаюсь имитировать звездное поле. Визуальный аспект (рисование «звезд» с различными скоростями и размерами на экране) работает. Однако по какой-то причине звезды не распределяются случайным образом, что приводит к моделированию, которое имеет шаблон. У меня также есть эта проблема с симуляцией взрыва, но для простоты я оставлю это на время. Это упрощенная версия моего кода до сих пор:Haskell Gloss: случайное звездное поле не случайное?
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)
Примечание: velPart
, speedPart
и т.д. являются функциями, чтобы получить свойство из данной частицы. Опять же, рисунок работает отлично, поэтому я оставлю этот код. updateParticlePosition
просто добавляет скорость к текущему положению звезды.
Я думаю, что проблема связана с тем, что мои случайные генераторы не прошли должным образом, но я слишком смущен, чтобы придумать решение ... Любая помощь очень ценится!
Помните, что все функции в Haskell являются * чистый *. Имея это в виду, как ожидается, что «randomFloat :: StdGen -> Float -> Float -> Float' даст разные результаты от вызова? – gspr
Я думал, что он должен давать разные результаты, если ему передается уникальный генератор для каждого вызова. По крайней мере, это то, что я пытаюсь сделать. – Felix
Отбрасывает новое состояние генератора, отбрасывая вторую половину значения, возвращаемого из 'randomR'. – gspr