diff options
Diffstat (limited to 'Demos/Pong/Main.hs')
-rw-r--r-- | Demos/Pong/Main.hs | 84 |
1 files changed, 47 insertions, 37 deletions
diff --git a/Demos/Pong/Main.hs b/Demos/Pong/Main.hs index d51a324..22b1021 100644 --- a/Demos/Pong/Main.hs +++ b/Demos/Pong/Main.hs | |||
@@ -1,3 +1,5 @@ | |||
1 | {-# LANGUAGE MultiParamTypeClasses #-} | ||
2 | |||
1 | module Main where | 3 | module Main where |
2 | 4 | ||
3 | import Pong | 5 | import Pong |
@@ -5,52 +7,62 @@ import Pong | |||
5 | import Spear.App | 7 | import Spear.App |
6 | import Spear.Game | 8 | import Spear.Game |
7 | import Spear.Math.AABB | 9 | import Spear.Math.AABB |
8 | import Spear.Math.Matrix4 as Matrix4 hiding (position) | 10 | import Spear.Math.Matrix4 as Matrix4 |
9 | import Spear.Math.Spatial | 11 | import Spear.Math.Spatial |
10 | import Spear.Math.Spatial2 | 12 | import Spear.Math.Spatial2 |
11 | import Spear.Math.Vector | 13 | import Spear.Math.Vector |
14 | import Spear.Physics.Collision | ||
12 | import Spear.Render.Core.Pipeline | 15 | import Spear.Render.Core.Pipeline |
13 | import Spear.Render.Core.State | 16 | import Spear.Render.Core.State |
14 | import Spear.Render.Immediate | 17 | import Spear.Render.Immediate |
18 | import Spear.Sound.Sound | ||
19 | import Spear.Sound.State | ||
15 | import Spear.Window | 20 | import Spear.Window |
16 | 21 | ||
17 | import Control.Monad (when) | 22 | import Control.Monad (when) |
18 | import Data.Maybe (mapMaybe) | ||
19 | 23 | ||
20 | 24 | ||
21 | data GameState = GameState | 25 | data Pong = Pong |
22 | { window :: Window | 26 | { viewProjection :: Matrix4 |
23 | , renderCoreState :: RenderCoreState | 27 | , backgroundMusic :: SoundSource |
24 | , immRenderState :: ImmRenderState | ||
25 | , viewProjection :: Matrix4 | ||
26 | , world :: [GameObject] | 28 | , world :: [GameObject] |
27 | } | 29 | } |
28 | 30 | ||
29 | app = App defaultAppOptions step render resize | 31 | type GameState = AppState Pong |
32 | |||
33 | |||
34 | options = defaultAppOptions { title = "Pong" } | ||
35 | |||
36 | app = App options initGame endGame step render resize | ||
37 | |||
30 | 38 | ||
31 | main = | 39 | main :: IO () |
32 | withWindow (1920, 1200) (Just "Pong") initGame endGame $ | 40 | main = runApp app |
33 | loop app | ||
34 | 41 | ||
35 | initGame :: Window -> Game () GameState | 42 | initGame :: Game AppContext Pong |
36 | initGame window = do | 43 | initGame = do |
37 | (immRenderState, renderCoreState) <- runSiblingGame newImmRenderer newRenderCoreState | 44 | music <- siblingGame $ do |
38 | return $ GameState window renderCoreState immRenderState Matrix4.id newWorld | 45 | musicBuffer <- loadAudioFile "/home/jeanne/Casual Tiki Party Main.wav" |
46 | music <- makeSoundSource | ||
47 | setSoundSourceBuffer music musicBuffer | ||
48 | setSoundLoopMode music Loop | ||
49 | playSounds [music] | ||
50 | return music | ||
51 | return $ Pong Matrix4.id music newWorld | ||
39 | 52 | ||
40 | endGame :: Game GameState () | 53 | endGame :: Game GameState () |
41 | endGame = do | 54 | endGame = return () |
42 | game <- getGameState | 55 | |
43 | runSubGame' (deleteImmRenderer $ immRenderState game) (renderCoreState game) | ||
44 | 56 | ||
45 | step :: Elapsed -> Dt -> [InputEvent] -> Game GameState Bool | 57 | step :: Elapsed -> Dt -> [InputEvent] -> Game GameState Bool |
46 | step elapsed dt inputEvents = do | 58 | step elapsed dt inputEvents = do |
47 | gs <- getGameState | 59 | appState <- get |
48 | events <- processInput (window gs) | 60 | gameState <- getGameState |
49 | --when (events /= []) $ gameIO . putStrLn $ show events | 61 | events <- processInput (appWindow appState) |
50 | modifyGameState $ \gs -> | 62 | --when (events /= []) $ liftIO . putStrLn $ show events |
51 | gs | 63 | modifyGameState $ \pong -> pong |
52 | { world = stepWorld (realToFrac elapsed) (realToFrac dt) events (world gs) | 64 | { world = stepWorld (realToFrac elapsed) (realToFrac dt) events (world gameState) |
53 | } | 65 | } |
54 | return (not $ exitRequested inputEvents) | 66 | return (not $ exitRequested inputEvents) |
55 | 67 | ||
56 | processInput :: Window -> Game GameState [GameEvent] | 68 | processInput :: Window -> Game GameState [GameEvent] |
@@ -61,20 +73,19 @@ processInput window = processKeys window | |||
61 | 73 | ||
62 | exitRequested = elem (KeyDown KEY_ESC) | 74 | exitRequested = elem (KeyDown KEY_ESC) |
63 | 75 | ||
76 | |||
64 | render :: Game GameState () | 77 | render :: Game GameState () |
65 | render = do | 78 | render = do |
66 | gameState <- getGameState | 79 | gameState <- getGameState |
67 | immRenderState' <- flip execSubGame (immRenderState gameState) $ do | 80 | siblingGame $ do |
68 | immStart | 81 | immStart |
69 | immSetViewProjectionMatrix (viewProjection gameState) | 82 | immSetViewProjectionMatrix (viewProjection gameState) |
70 | -- Clear the background to a different colour than the playable area to make | 83 | -- Clear the background to a different colour than the playable area to make |
71 | -- the latter distinguishable. | 84 | -- the latter distinguishable. |
72 | gameIO $ do | 85 | setClearColour (0.2, 0.2, 0.2, 0.0) |
73 | setClearColour (0.2, 0.2, 0.2, 0.0) | 86 | clearBuffers [ColourBuffer] |
74 | clearBuffers [ColourBuffer] | ||
75 | render' $ world gameState | 87 | render' $ world gameState |
76 | immEnd | 88 | immEnd |
77 | saveGameState $ gameState { immRenderState = immRenderState' } | ||
78 | 89 | ||
79 | render' :: [GameObject] -> Game ImmRenderState () | 90 | render' :: [GameObject] -> Game ImmRenderState () |
80 | render' world = do | 91 | render' world = do |
@@ -97,17 +108,16 @@ renderBackground = | |||
97 | ,vec2 pmin pmax)] | 108 | ,vec2 pmin pmax)] |
98 | 109 | ||
99 | renderGO :: GameObject -> Game ImmRenderState () | 110 | renderGO :: GameObject -> Game ImmRenderState () |
100 | renderGO go = do | 111 | renderGO go = |
101 | let (AABB2 (Vector2 xmin ymin) (Vector2 xmax ymax)) = aabb go | 112 | let (AABB2Volume (AABB2 (Vector2 xmin ymin) (Vector2 xmax ymax))) = boundingVolume go |
102 | (Vector2 xcenter ycenter) = position go | 113 | in |
103 | immPreservingMatrix $ do | ||
104 | immTranslate (vec3 xcenter ycenter 0) | ||
105 | immDrawQuads2d [ | 114 | immDrawQuads2d [ |
106 | (vec2 xmin ymin | 115 | (vec2 xmin ymin |
107 | ,vec2 xmax ymin | 116 | ,vec2 xmax ymin |
108 | ,vec2 xmax ymax | 117 | ,vec2 xmax ymax |
109 | ,vec2 xmin ymax)] | 118 | ,vec2 xmin ymax)] |
110 | 119 | ||
120 | |||
111 | resize :: WindowEvent -> Game GameState () | 121 | resize :: WindowEvent -> Game GameState () |
112 | resize (ResizeEvent w h) = | 122 | resize (ResizeEvent w h) = |
113 | let r = fromIntegral w / fromIntegral h | 123 | let r = fromIntegral w / fromIntegral h |
@@ -117,7 +127,7 @@ resize (ResizeEvent w h) = | |||
117 | bottom = if r > 1 then 0 else -pad | 127 | bottom = if r > 1 then 0 else -pad |
118 | top = if r > 1 then 1 else 1 + pad | 128 | top = if r > 1 then 1 else 1 + pad |
119 | in do | 129 | in do |
120 | gameIO $ setViewport 0 0 w h | 130 | setViewport 0 0 w h |
121 | modifyGameState $ \state -> state { | 131 | modifyGameState $ \pong -> pong { |
122 | viewProjection = Matrix4.ortho left right bottom top (-1) 1 | 132 | viewProjection = Matrix4.ortho left right bottom top (-1) 1 |
123 | } | 133 | } |