Iceandele
Iceandele

Reputation: 660

Animating With Gloss in Haskell

Here's my code for a little pattern that looks something like this. (Not the most efficient code I know). Now, I want to make stars rotate using animate. but I'm not sure how to use display and animate together in one program. Any help would be appreciated. Thanks.

Gloss Image

import Graphics.Gloss

main = display (InWindow "Gloss" (700,700) (0,0))
           black (picture 100)
picture :: Float -> Picture
picture 0 = text "Value cannot be 0"
picture number = scale 6.5 6.5 (color rose $ drawpicture number)

orangered, orangered2, orangered3 :: Color
orangered = makeColor 1.0 0.251 0.0 0.7
orangered2 = makeColor 1.0 0.251 0.0 0.5
orangered3 = makeColor 1.0 0.251 0.0 0.3

intervalsmall = [0,11.25,22.5,33.75,45,56.25,67.5,78.75]
intervalbig = [0,22.5,45,67.5,90,112.5,135,157.5,180,202.5,225,247.5,270,292.5,315,337.5]
xlist = [2,4..50]
ylist = [0,2..48]

squares = pictures[rotate x (line [(-50,0),(0,50),(50,0),(0,-50),(-50,0)]) | x <- intervalsmall]
stars = pictures[rotate x ((pictures [line [(-8.5,0),(0,50),(8.5,0)],line[(0,50),(0,0)]])) | x <- intervalbig]
grid = pictures[line [(0,y),(x,50)] | x <- xlist, y <- ylist, x-y==2]
insidegrid = pictures[
    translate 0 (-50) grid,
    rotate 90 (translate 0 (-50) grid),
    rotate 180 (translate 0 (-50) grid),
    rotate 270 (translate 0 (-50) grid)]

drawpicture :: Float -> Picture
drawpicture number = pictures [
    color red (pictures [circle 50,circle 8.5]),
    line [(-50,-50),(-50,50),(50,50),(50,-50),(-50,-50)],
    squares,
    scale 0.7 0.7 squares,
    scale 0.49 0.49 squares,
    scale 0.347 0.347 squares,
    scale 0.242 0.242 squares,
    color orange stars,
    color orange (scale 0.178 0.178 stars),
    rotate 11.25 (scale 0.178 0.178 stars), 
    translate (-50) 0 grid,
    rotate 90 (Translate (-50) 0 grid),
    rotate 180 (Translate (-50) 0 grid),
    rotate 270 (Translate (-50) 0 grid),
    color orangered insidegrid,
    color orangered2 (rotate 45 insidegrid),
    color orangered3 (rotate 22.5 insidegrid),
    color orangered3 (rotate 67.5 insidegrid)
    ]

Upvotes: 5

Views: 4261

Answers (2)

Thomas M. DuBuisson
Thomas M. DuBuisson

Reputation: 64740

It's easier if you have separate draw functions for each visual element, but the basic answer is: to animate it just use the animate function and rotate the image components you desire to "move":

import Graphics.Gloss

main = animate (InWindow "Gloss" (700,700) (0,0))
           black picture

picture :: Float -> Picture
picture 0 = text "Value cannot be 0"
picture number = scale 6.5 6.5 (color rose $ drawpicture number)

orangered, orangered2, orangered3 :: Color
orangered = makeColor 1.0 0.251 0.0 0.7
orangered2 = makeColor 1.0 0.251 0.0 0.5
orangered3 = makeColor 1.0 0.251 0.0 0.3

intervalsmall = [0,11.25,22.5,33.75,45,56.25,67.5,78.75]
intervalbig = [0,22.5,45,67.5,90,112.5,135,157.5,180,202.5,225,247.5,270,292.5,315,337.5]
xlist = [2,4..50]
ylist = [0,2..48]

squares = pictures[rotate x (line [(-50,0),(0,50),(50,0),(0,-50),(-50,0)]) | x <- intervalsmall]
stars = pictures[rotate x ((pictures [line [(-8.5,0),(0,50),(8.5,0)],line[(0,50),(0,0)]])) | x <- intervalbig]
grid = pictures[line [(0,y),(x,50)] | x <- xlist, y <- ylist, x-y==2]
insidegrid = pictures[
    translate 0 (-50) grid,
    rotate 90 (translate 0 (-50) grid),
    rotate 180 (translate 0 (-50) grid),
    rotate 270 (translate 0 (-50) grid)]

rotVal :: Float -> Float
rotVal x = x - (x / (2*pi))

drawpicture :: Float -> Picture
drawpicture number = pictures [
    rot $ color red (pictures [circle 50,circle 8.5]),
    line [(-50,-50),(-50,50),(50,50),(50,-50),(-50,-50)],
    rot $ squares,
    rot $ scale 0.7 0.7 squares,
    rot $ scale 0.49 0.49 squares,
    rot $ scale 0.347 0.347 squares,
    rot $ scale 0.242 0.242 squares,
    rot $ color orange stars,
    rot (color orange (scale 0.178 0.178 stars)),
    rot (rotate 11.25 (scale 0.178 0.178 stars)),
    translate (-50) 0 grid,
    rotate 90 (Translate (-50) 0 grid),
    rotate 180 (Translate (-50) 0 grid),
    rotate 270 (Translate (-50) 0 grid),
    rot $ color orangered insidegrid,
    rot $ color orangered2 (rotate 45 insidegrid),
    rot $ color orangered3 (rotate 22.5 insidegrid),
    rot $ color orangered3 (rotate 67.5 insidegrid)
    ]
  where rot = rotate (rotVal number)

Upvotes: 4

DiegoNolan
DiegoNolan

Reputation: 3766

It is too much to write out all for you but you just have to add another argument to your picture function that is a Float and represents time. So display would be replaced by animate. So.

main = animate (InWindow "Gloss" (700,700) (0,0))
           black (picture 100)

picture :: Float -> Float -> Picture
picture number time = -- whatever you have to do

You'll have to change your helping drawing functions to take this time param. Let's say you want to rotate the whole think once ever 5 seconds you can just multiply this time coming in and get an angle angle = time*(pi*2/5) then you can use this angle for trig functions to calculate new x and y positions from the center.

Upvotes: 0

Related Questions