From a9fc5f24f66d49da647fe67b76d80f28f120d9cb Mon Sep 17 00:00:00 2001 From: nek0 Date: Thu, 21 Dec 2017 05:21:20 +0100 Subject: [PATCH] playable! --- assets/haskelloid.png | Bin 6424 -> 6774 bytes src/InGame.hs | 117 +++++++++++++++++++++++++++++++++++++----- src/Main.hs | 3 +- src/StateMachine.hs | 2 +- src/Types.hs | 2 +- 5 files changed, 107 insertions(+), 17 deletions(-) diff --git a/assets/haskelloid.png b/assets/haskelloid.png index f633deb21ea3235c53516c2757796e5c2187fdd0..a4b7813034d80262afc6b147a6d6b3a1e4271e32 100644 GIT binary patch literal 6774 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 literal 6424 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 CA_}Mg diff --git a/src/InGame.hs b/src/InGame.hs index 1815bd9..1eefe50 100644 --- a/src/InGame.hs +++ b/src/InGame.hs @@ -5,30 +5,40 @@ import Affection as A import qualified SDL import qualified Data.Set as S -import Data.Maybe (isNothing) +import Data.Maybe (isNothing, catMaybes) import Control.Monad (when, unless) import Control.Monad.IO.Class (liftIO) +import System.Random (randomRIO) + import Linear import NanoVG hiding (V2(..)) +import Foreign.C.Types (CFloat(..)) + import Types import Commons dVel :: Float dVel = 100 +pewVel :: Float +pewVel = 200 + +pewTTL :: Double +pewTTL = 10 + dRot :: Float dRot = 150 -loadGame :: Affection UserData () -> Affection UserData () -loadGame stateChange = do +loadGame :: Affection UserData () -> Affection UserData () -> Affection UserData () +loadGame stateChange clean = do liftIO $ logIO A.Debug "loading game" ud <- getAffection nhs <- newHaskelloids - kid <- partSubscribe (subKeyboard $ subsystems ud) (handleGameKeys stateChange) + kid <- partSubscribe (subKeyboard $ subsystems ud) (handleGameKeys stateChange clean) putAffection ud { stateUUIDs = UUIDClean [] [kid] , haskelloids = nhs @@ -42,18 +52,17 @@ loadGame stateChange = do , wonlost = Nothing } -handleGameKeys :: Affection UserData () -> KeyboardMessage -> Affection UserData () -handleGameKeys stateChange kbdev = when (msgKbdKeyMotion kbdev == SDL.Pressed) $ +handleGameKeys :: Affection UserData () -> Affection UserData () -> KeyboardMessage -> Affection UserData () +handleGameKeys stateChange clean kbdev = when (msgKbdKeyMotion kbdev == SDL.Pressed) $ case SDL.keysymKeycode (msgKbdKeysym kbdev) of SDL.KeycodeSpace -> unless (msgKbdKeyRepeat kbdev) $ do - liftIO $ logIO A.Debug "TODO: PEW!" + liftIO $ logIO A.Debug "PEW!" + shoot SDL.KeycodeR -> unless (msgKbdKeyRepeat kbdev) $ do ud <- getAffection - liftIO $ logIO A.Debug "Reloading" - putAffection ud - { stateUUIDs = UUIDClean [] [] - } - loadGame stateChange + unless (isNothing $ wonlost ud) $ do + liftIO $ logIO A.Debug "Reloading" + clean SDL.KeycodeEscape -> do liftIO $ logIO A.Debug "Leave to Menu" stateChange @@ -63,6 +72,17 @@ handleGameKeys stateChange kbdev = when (msgKbdKeyMotion kbdev == SDL.Pressed) $ SDL.KeycodeD -> rotateShip (-dRot) _ -> return () +shoot :: Affection UserData () +shoot = do + ud <- getAffection + let Ship{..} = ship ud + npew = Pew ppos pVel pewTTL + ppos = sPos + ((V2 0 25) `rotVec` sRot) + pVel = sVel + ((V2 0 pewVel) `rotVec` sRot) + putAffection ud + { shots = npew : shots ud + } + accelShip :: Float -> Affection UserData () accelShip vel = do ud <- getAffection @@ -96,10 +116,13 @@ updateGame :: Double -> Affection UserData () updateGame sec = do ud <- getAffection let nhs = map (updateHaskelloid sec) (haskelloids ud) + npews = filter (\p -> pTTL p > 0) $ map (updatePew sec) (shots ud) putAffection ud { haskelloids = nhs + , shots = npews , ship = updateShip sec (ship ud) } + checkShotDown ud2 <- getAffection when ( ( any (checkCollision (ship ud2)) (haskelloids ud2) @@ -111,6 +134,51 @@ updateGame sec = do { wonlost = Just Lost } ) + when (isNothing (wonlost ud2) && null (haskelloids ud2)) + (putAffection ud2 + { wonlost = Just Won + } + ) + +checkShotDown :: Affection UserData () +checkShotDown = + do + ud <- getAffection + let shoots = shots ud + hasks = haskelloids ud + pairs = catMaybes $ concatMap (crossOut hasks) shoots + deadHasks = map fst pairs + nhask = foldl (\acc a -> filter (\x -> a /= x) acc) hasks deadHasks + npews = foldl (\acc a -> filter (\x -> a /= x) acc) shoots (map snd pairs) + children <- liftIO $ concat <$> mapM (\Haskelloid{..} -> do + n1velx <- randomRIO (-10, 10) + n1vely <- randomRIO (-10, 10) + n1rot <- randomRIO (-180, 180) + n1pitch <- randomRIO (-pi, pi) + n2velx <- randomRIO (-10, 10) + n2vely <- randomRIO (-10, 10) + n2rot <- randomRIO (-180, 180) + n2pitch <- randomRIO (-pi, pi) + let ndiv = hDiv + 1 + if ndiv > 5 + then return [] + else return $ + [ Haskelloid hPos (V2 n1velx n1vely) n1rot n1pitch ndiv hImg + , Haskelloid hPos (V2 n2velx n2vely) n2rot n2pitch ndiv hImg + ] + ) deadHasks + putAffection ud + { shots = npews + , haskelloids = nhask ++ children + } + where + crossOut :: [Haskelloid] -> Pew -> [Maybe (Haskelloid, Pew)] + crossOut hs p = + foldl (\acc h -> + if distance (pPos p) (hPos h) < (50 / fromIntegral (hDiv h)) + then Just (h, p) : acc + else Nothing : acc + ) [] hs checkCollision :: Ship -> Haskelloid -> Bool checkCollision s h = @@ -129,10 +197,19 @@ updateShip ddt s@Ship{..} = s where dt = realToFrac ddt +updatePew :: Double -> Pew -> Pew +updatePew ddt p@Pew{..} = p + { pPos = wrapAround (pPos + fmap (dt *) pVel) 0 + , pTTL = pTTL - ddt + } + where + dt = realToFrac ddt + drawGame :: Affection UserData () drawGame = do ud <- getAffection mapM_ drawHaskelloid (haskelloids ud) + mapM_ drawPew (shots ud) case wonlost ud of Just Lost -> liftIO $ do let ctx = nano ud @@ -154,9 +231,9 @@ drawGame = do textAlign ctx (S.fromList [AlignCenter,AlignTop]) fillColor ctx (rgba 255 255 255 255) textBox ctx 0 200 800 "YOU WON!" - fillColor ctx (rgba 255 128 0 255) + fillColor ctx (rgba 128 255 0 255) fontSize ctx 40 - textBox ctx 0 350 800 "Press [Esc] to exit" + textBox ctx 0 350 800 "Press [Esc] to exit\nPress [R] to try again" restore ctx Nothing -> drawShip (ship ud) @@ -166,3 +243,15 @@ drawShip Ship{..} = do liftIO $ drawImage ctx (sImg) (sPos - fmap (/2) dim) dim sRot 255 where dim = V2 40 40 + +drawPew :: Pew -> Affection UserData () +drawPew Pew{..} = do + ctx <- nano <$> getAffection + liftIO $ do + let (V2 x y) = fmap CFloat pPos + save ctx + beginPath ctx + fillColor ctx (rgba 255 128 0 255) + circle ctx x y 2 + fill ctx + restore ctx diff --git a/src/Main.hs b/src/Main.hs index 41560e6..41171b4 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -31,7 +31,7 @@ main = do , windowConfig = SDL.defaultWindow { SDL.windowOpenGL = Just SDL.defaultOpenGL { SDL.glProfile = SDL.Core SDL.Normal 3 2 - -- , SDL.glColorPrecision = V4 0 8 8 8 + , SDL.glColorPrecision = V4 8 8 8 1 } } , initScreenMode = SDL.Windowed @@ -61,6 +61,7 @@ pre = do SDL.KeycodeF -> do dt <- getDelta liftIO $ logIO A.Debug $ "FPS: " ++ show (1/dt) + SDL.KeycodeO -> toggleScreen _ -> return () return () diff --git a/src/StateMachine.hs b/src/StateMachine.hs index 3e784e7..946da7b 100644 --- a/src/StateMachine.hs +++ b/src/StateMachine.hs @@ -11,7 +11,7 @@ import Menu instance StateMachine State UserData where smLoad Menu = loadMenu (smClean Menu >> smLoad InGame) - smLoad InGame = loadGame (smClean InGame >> smLoad Menu) + smLoad InGame = loadGame (smClean InGame >> smLoad Menu) (smClean InGame >> smLoad InGame) smUpdate Menu = updateMenu diff --git a/src/Types.hs b/src/Types.hs index 4f424bf..4ec6ede 100644 --- a/src/Types.hs +++ b/src/Types.hs @@ -37,7 +37,7 @@ data Pew = Pew { pPos :: V2 Float , pVel :: V2 Float , pTTL :: Double - } + } deriving (Eq) data Haskelloid = Haskelloid { hPos :: V2 Float