module Space(newStdShipEntity,
playerShipColor,
enemyShipColor,
width,
height,
drawGLScreen,
drawEntity,
collides2d,
getShipBox,
angleFromTo,
angleFromToRad,
randPos
)
where
import System.Random
import Data.Foldable
import Prelude hiding (mapM_)
import Graphics.Rendering.OpenGL as OpenGL
import Graphics.UI.SDL as SDL
import OpenGLUtils
import Entity
import AObject
import Tree
import Utils
import Collision
newStdShipEntity :: GLvector3 -> Color4 GLfloat -> GLdouble -> Entity
newStdShipEntity pos c rot = newEntity pos rot c TriangleFan trianglePoints glVector3AllUnit
playerShipColor, enemyShipColor :: Color4 GLfloat
playerShipColor = Color4 0.0 0.5 0.0 1.0
enemyShipColor = Color4 0.5 0.0 0.0 1.0
width :: (Num a) => a
width = 800
height :: (Num a) => a
height = 600
drawEntity :: Maybe GLdouble -> Entity -> IO ()
drawEntity mconstsize ent = do
loadIdentity
translate $ (\(x,y,z) -> Vector3 x y z) (Entity.position ent)
rotate (Entity.rotation ent) $ Vector3 0 0 (1 :: GLdouble)
case mconstsize of
Nothing -> (\(x,y,z) -> OpenGL.scale x y z) (Entity.scale ent)
Just n -> uniformScale n
currentColor $= (Entity.color ent)
renderPrimitive (primitive ent) $ forM_ (vertices ent) $ \(x,y,z) -> do
vertex $ Vertex3 x y z
drawAObject :: Maybe GLdouble -> AObject -> IO ()
drawAObject mconstsize aobj = preservingMatrix $ do
translate $ vecToVec $ AObject.getPosition aobj
uniformScale $ case mconstsize of
Nothing -> size aobj
Just s -> s
currentColor $= (AObject.color aobj)
renderPrimitive Polygon $ forM_ aobjPoints $ \(x,y,z) -> do
vertex $ Vertex3 x y z
drawAObjTree :: Maybe GLdouble -> AObjTree -> IO ()
drawAObjTree mconstsize (Leaf aobj) = do
drawAObject mconstsize aobj
drawOrbit (orbitRadius aobj) (barycenter aobj)
drawAObjTree mconstsize (Node (_, rad) objs) = preservingMatrix $ do
mapM_ (drawAObjTree mconstsize) objs
drawOrbit rad glVector3Null
drawOrbit :: GLdouble -> GLvector3 -> IO ()
drawOrbit rad bary = preservingMatrix $ do
translate $ vecToVec $ bary
uniformScale rad
currentColor $= aorbitColor
renderPrimitive LineLoop $ forM_ aorbitPoints $ \(x,y,z) -> do
vertex $ Vertex3 x y z
drawGLScreen :: Maybe GLdouble -> [Entity] -> AObjTree -> IO ()
drawGLScreen mconstsize ents objs = do
clear [ColorBuffer,DepthBuffer]
lineWidth $= 5
forM_ ents (drawEntity mconstsize)
lineWidth $= 1
loadIdentity
drawAObjTree mconstsize objs
glSwapBuffers
angleFromTo :: (RealFloat t) => (t, t, t)
-> (t, t, t)
-> t
angleFromTo a b = radToDeg $ angleFromToRad a b
angleFromToRad :: (RealFloat t) => (t, t, t)
-> (t, t, t)
-> t
angleFromToRad (ax, ay, _) (bx, by, _) =
atan2 (by - ay) (bx - ax)
randPos :: ((Int, Int), (Int, Int)) -> IO GLvector3
randPos ((minx, miny), (maxx, maxy)) = do
x <- fromIntegral `fmap` randomRIO (minx, maxx)
y <- fromIntegral `fmap` randomRIO (miny, maxy)
return (x, y, 0)
getShipBox
:: Entity -> ((GLdouble, GLdouble), (GLdouble, GLdouble))
getShipBox e =
let (x, y, _) = Entity.position e
in boxArea (x, y) 1
trianglePoints :: [GLvector3]
trianglePoints =
[ (0, 1, 0)
,(0.9, -1, 0)
,(0.0, -0.7, 0)
,(-0.9,-1, 0)
]