fork download
  1. import System.Exit
  2. import Graphics.UI.GLUT
  3. import Control.Monad
  4. import Control.Applicative
  5. import Control.Arrow
  6. import Control.Concurrent
  7. import Graphics.Rendering.OpenGL
  8. import Data.IORef
  9. import Data.List
  10. import Data.Maybe
  11. initial = ((0,0),(0.005,-0.03),(0,0),([(-0.4,-0.9),(-0.4,-0.85),(0.4,-0.85),(0.4,-0.9),(-0.4,-0.9)],(0,0)),liftM2 (,) [-0.9,-0.7..0.9] [0.5,0.7,0.9])
  12. ws = dzip [(-1,-1),(-1,1),(1,1),(1,-1)] ; r = 0.1 :: GLfloat
  13. main = initialWindowSize $= Size 777 777 >> initialWindowPosition $= Position 100 100 >> initialDisplayMode $= [DoubleBuffered] >> createWindow "ursula" >>
  14. newIORef initial >>= \ior -> keyboardMouseCallback $= Just (kbd ior) >> displayCallback $= dlay ior >> idleCallback $= Just (anime ior) >> mainLoop
  15. dlay ior = clearColor $= Color4 1 1 1 1 >> clear [ColorBuffer] >> readIORef ior >>= drawDoxyq >> swapBuffers
  16. kbd _ (Char 'q') Down _ _ = exitWith ExitSuccess
  17. kbd s (Char x) Down _ _ = modifyIORef' s $ \(a,b,t,(d,e),cs) -> (a,b,t,(d,(if x == '[' then -0.05 else if x == ']' then 0.05 else fst e,0)),cs)
  18. kbd _ _ _ _ _ = return ()
  19. draw c = renderPrimitive c . mapM_ (vertex . uncurry Vertex2)
  20. touch xy s xy' = guard ((xy ==== xy') <= r+r && (s .*. (xy.-.xy')) <= 0) >> Just (xy.-.xy')
  21. drawDoxyq ((x,y),_,(t,_),(bd,_),cs) = currentColor $= Color4 0.3 0.4 0.8 0 >> mapM_ (mapM_ (draw LineLoop) . sta) cs >>
  22. currentColor $= Color4 0.7 0.1 0.2 1 >> mapM_ (draw LineStrip) swa >> currentColor $= Color4 0 0 0 1 >> draw Polygon bd where
  23. swa = [[(x,y),(x + r/1.8*cos (th+pi/4),y + r/1.8*sin (th+pi/4)),(x + r/1.2*cos th,y + r/1.2*sin th)] | th <- [t,t+pi/2..t+1.6*pi]]
  24. sta (x,y) = [[(x,y+r/2),(x-r/2,y-r/2),(x+r/2,y-r/2)],[(x+r/2,y+r/2-0.03),(x-r/2,y+r/2-0.03),(x,y-r/2-0.03)]]
  25. frame (xy,v,(tt,tr),(b,s),cs) = if snd xy <= r-0.99 || null cs then error "GAME OVER" else (xy.+.v',v',(tt+tr',tr'),(b',s'),cs') where
  26. v' = listy v (\us -> rV (2*negv v .>. foldl1' (.+.) us + tr/11) $ negv v) $ mapMaybe (cutSect xy v) (ws ++ dzip b') ++ mapMaybe (touch xy v) cs
  27. s' = 0.93 *. if any ((1<=) . (*signum (fst s)) . fst) b then negv s else s
  28. b' = map (.+.s') b ; cs' = filter (isNothing . touch xy v) cs
  29. tr' = if v .=. v' then tr else (v' .>. v)/19
  30. listy d f x = if null x then d else f x
  31. rV t (x,y) = (x*cos t - y*sin t,y*cos t + x*sin t)
  32. anime ior = modifyIORef' ior frame >> threadDelay 30000 >> postRedisplay Nothing
  33. cutSect xy s c@(u,v) = guard (xy ./ l <= r && w `oncut` c && (s .*. (xy.-.w)) <= 0) >> Just (xy.-.w) where
  34. l = ln u (u.-.v) ; w = xy .-| l
  35. oncut u (v,w) = 0 <= (u.-.v) .*. (w.-.u) && 0 <= (u.-.w) .*. (u.-.w) && ((u.-.w) .<>. (v.-.w)) # 0
  36. ln xy w = (snd w,-fst w,w.<>.xy)
  37. (x,y) .-| (a,b,c) = ((b^2*x - a*c - a*b*y)/(a^2 + b^2),-(b*c + a*b*x - a^2*y)/(a^2 + b^2))
  38. p ./ ln = p ==== p .-| ln ; pop f (a,b) (c,d) = (f a c,f b d)
  39. (.+.) = pop (+) ; (.-.) = pop (-) ; (.=.) = (uncurry (&&) .) . pop (#)
  40. (*.) = tmap . (*) ; (.*.) = (uncurry (+) .) . pop (*)
  41. (.<>.) = (uncurry (-) .) . (. uncurry (flip (,))) . pop (*) ; v .>. u = atan2 (v .<>. u) (v .*. u)
  42. norm = sqrt . join (.*.) ; a ==== b = norm $ a.-.b ; negv = tmap negate
  43. infix 4 #,*. ; infix 3 .+.,==== ; infix 8 .>.
  44. x # y = abs (x-y) < 0.00001 ; tmap = join (***)
  45. dzipWith = (<*> drop 1) . zipWith ; dzip = dzipWith (,)
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.hs:7:8:
    Could not find module `Graphics.Rendering.OpenGL'
    Use -v to see a list of the files searched for.
stdout
Standard output is empty