66module Main where
77
88import Aztecs
9- import Aztecs.GL
9+ import Aztecs.GL.D2
10+ import Aztecs.GL.Text
1011import Aztecs.GLFW
1112import Control.Monad
1213import Control.Monad.IO.Class
1314import Control.Monad.State.Strict
1415import Data.Time.Clock
15- import System.IO
1616import Prelude hiding (lookup )
1717
18+ -- Configuration options
19+
1820windowW , windowH :: Int
1921windowW = 800
2022windowH = 600
@@ -36,9 +38,10 @@ ballInitSpeedY = 200
3638paddleMargin :: Float
3739paddleMargin = 40
3840
39- newtype GameState = GameState { gsLastTime :: UTCTime }
40- deriving ( Show )
41+ -- Current game state
42+ newtype GameState = GameState { lastTime :: UTCTime }
4143
44+ -- Game monad
4245type GameM = StateT GameState IO
4346
4447-- Paddle component
@@ -58,12 +61,12 @@ instance (Monad m) => Component m Ball
5861main :: IO ()
5962main = do
6063 now <- getCurrentTime
61- let initialState = GameState {gsLastTime = now}
62- (_, _) <- runStateT (runAccess_ setupAndRun ) initialState
64+ let initialState = GameState {lastTime = now}
65+ (_, _) <- runStateT (runAccess_ run ) initialState
6366 putStrLn " Game ended!"
6467
65- setupAndRun :: Access GameM ()
66- setupAndRun = do
68+ run :: Access GameM ()
69+ run = do
6770 -- Spawn the window
6871 windowEntity <-
6972 spawn $
@@ -106,26 +109,59 @@ setupAndRun = do
106109 <> bundle (Parent windowEntity)
107110 <> bundle (Ball ballInitSpeedX ballInitSpeedY)
108111
112+ -- Spawn font and score labels
113+ font <- spawn . bundle $ Font " assets/Montserrat-VariableFont_wght.ttf"
114+
115+ leftScoreLabelE <-
116+ spawn $
117+ bundle (Label " 0" font defaultLabelStyle {labelFontSize = 48 , labelColor = V4 1 1 1 1 })
118+ <> bundle (transform2d {transformTranslation = V2 (round (centerX - 60 )) (round (fromIntegral windowH - 50 :: Float ))} :: Transform2D )
119+ <> bundle (Parent windowEntity)
120+
121+ rightScoreLabelE <-
122+ spawn $
123+ bundle (Label " 0" font defaultLabelStyle {labelFontSize = 48 , labelColor = V4 1 1 1 1 })
124+ <> bundle (transform2d {transformTranslation = V2 (round (centerX + 40 )) (round (fromIntegral windowH - 50 :: Float ))} :: Transform2D )
125+ <> bundle (Parent windowEntity)
126+
109127 -- Run the game loop
110- runAccessGLFW $ run windowEntity leftPaddleE rightPaddleE ballE
128+ let rs =
129+ Loop
130+ { window = windowEntity,
131+ leftPaddle = leftPaddleE,
132+ rightPaddle = rightPaddleE,
133+ ball = ballE,
134+ leftScoreLabel = leftScoreLabelE,
135+ rightScoreLabel = rightScoreLabelE
136+ }
137+ runAccessGLFW $ loop rs
138+
139+ data Loop = Loop
140+ { window :: EntityID ,
141+ leftPaddle :: EntityID ,
142+ rightPaddle :: EntityID ,
143+ ball :: EntityID ,
144+ leftScoreLabel :: EntityID ,
145+ rightScoreLabel :: EntityID
146+ }
111147
112- run :: EntityID -> EntityID -> EntityID -> EntityID -> Access GameM Bool
113- run windowE leftE rightE ballE = do
148+ loop :: Loop -> Access GameM Bool
149+ loop rs = do
114150 now <- liftIO getCurrentTime
115- lastTime <- lift $ gets gsLastTime
116- let dt = realToFrac (diffUTCTime now lastTime ) :: Float
151+ lt <- lift $ gets lastTime
152+ let dt = realToFrac (diffUTCTime now lt ) :: Float
117153 dt' = min dt 0.1
118- lift . modify' $ \ gs -> gs {gsLastTime = now}
154+ lift . modify' $ \ gs -> gs {lastTime = now}
119155
120- mKeys <- lookup @ _ @ Keys windowE
156+ mKeys <- lookup @ _ @ Keys (window rs)
121157 case mKeys of
122158 Just keys -> do
123159 if keyJustPressed Key'Escape keys
124160 then return True
125161 else do
126- updatePaddle leftE keys Key'W Key'S dt'
127- updatePaddle rightE keys Key'Up Key'Down dt'
128- updateBall dt' ballE leftE rightE
162+ updatePaddle (leftPaddle rs) keys Key'W Key'S dt'
163+ updatePaddle (rightPaddle rs) keys Key'Up Key'Down dt'
164+ updateBall dt' rs
129165 render
130166 return False
131167 Nothing -> do
@@ -149,18 +185,21 @@ updatePaddle paddleE keys upKey downKey dt = do
149185 $ bundle (t {transformTranslation = V2 x (round newY)} :: Transform2D )
150186 Nothing -> return ()
151187
152- updateBall :: Float -> EntityID -> EntityID -> EntityID -> Access GameM ()
153- updateBall dt ballE leftE rightE = do
188+ updateBall :: Float -> Loop -> Access GameM ()
189+ updateBall dt rs = do
190+ let ballE = ball rs
191+ leftE = leftPaddle rs
192+ rightE = rightPaddle rs
154193 mBallT <- lookup @ _ @ Transform2D ballE
155194 mBall <- lookup @ _ @ Ball ballE
156195 mLeftT <- lookup @ _ @ Transform2D leftE
157196 mRightT <- lookup @ _ @ Transform2D rightE
158197
159198 case (mBallT, mBall, mLeftT, mRightT) of
160- (Just ballT, Just ball, Just leftT, Just rightT) -> do
199+ (Just ballT, Just ball' , Just leftT, Just rightT) -> do
161200 -- Get current velocity from Ball component
162- let velX = ballVelX ball
163- velY = ballVelY ball
201+ let velX = ballVelX ball'
202+ velY = ballVelY ball'
164203
165204 let V2 bx by = transformTranslation ballT
166205 V2 _ ly = transformTranslation leftT
@@ -210,24 +249,26 @@ updateBall dt ballE leftE rightE = do
210249 then (Nothing , rightPaddleX - paddleW / 2 - ballR, clampedBy, - (abs velX))
211250 else
212251 if newBx + ballR < 0
213- then do
214- (Just (rightE, " Right" ), centerX, centerY, ballInitSpeedX)
252+ then (Just (rightE, False ), centerX, centerY, ballInitSpeedX)
215253 else
216254 if newBx - ballR > fromIntegral windowW
217- then (Just (leftE, " Left " ), centerX, centerY, - ballInitSpeedX)
255+ then (Just (leftE, True ), centerX, centerY, - ballInitSpeedX)
218256 else (Nothing , newBx, clampedBy, velX)
219257
220258 -- Scoring
221259 case res of
222- Just (e, s ) -> do
260+ Just (e, isLeft ) -> do
223261 mPaddle <- lookup @ _ @ Paddle e
224262 let ! score = case mPaddle of
225263 Just p -> paddleScore p + 1
226264 Nothing -> 1
227265 insert e . bundle $ Paddle score
228- liftIO $ do
229- putStrLn $ s ++ " scores! Score: " ++ show score
230- hFlush stdout
266+ -- Update the appropriate score label
267+ let labelE = if isLeft then leftScoreLabel rs else rightScoreLabel rs
268+ mLabel <- lookup @ _ @ Label labelE
269+ case mLabel of
270+ Just lbl -> insert labelE . bundle $ lbl {labelText = show score}
271+ Nothing -> return ()
231272 Nothing -> return ()
232273
233274 -- Update ball transform and velocity
0 commit comments