Changeset 20156
- Timestamp:
- 09/28/08 19:48:28 (5 years ago)
- Location:
- lang/haskell/nario
- Files:
-
- 3 modified
Legend:
- Unmodified
- Added
- Removed
-
lang/haskell/nario/Main.hs
r20045 r20156 1 2 1 -- Nario 3 2 … … 5 4 6 5 import Multimedia.SDL 7 import Control.Monad (when)8 import Data.IORef (newIORef, readIORef, writeIORef, modifyIORef)6 import System.IO.Unsafe (unsafeInterleaveIO) 7 import Control.Concurrent (threadDelay) 9 8 10 import SDLUtil 11 import Util 9 --import Control.Exception 10 12 11 import Player 13 12 import Field 14 import Const13 import Util 15 14 16 ----------------------------------- 17 -- システム周り 18 ----------------------------------- 19 20 -- 種種の定義 21 22 wndTitle = "Nario in Haskell" 23 wndSize = sz 256 240 15 wndTitle = "delayed-stream test" 16 wndWidth = 256 17 wndHeight = 240 18 wndBpp = 32 24 19 25 20 frameRate = 60 26 21 27 22 -- 背景色 28 backColor = 0x2891ff -- 青23 backColor = 0x2891ff 29 24 25 -- 描画コマンド 26 type Scr = Surface -> IO () 30 27 28 -- エントリ 29 main :: IO () 30 main = do 31 sdlInit [VIDEO] 32 setCaption wndTitle wndTitle 33 sur <- setVideoMode wndWidth wndHeight wndBpp [HWSURFACE, DOUBLEBUF, ANYFORMAT] 34 do 35 strm <- delayedStream (1000000 `div` frameRate) fetch 36 scrs <- process $ map snd $ takeWhile notQuit strm 37 mapM_ (\scr -> scr sur) scrs 38 sdlQuit 31 39 40 where 41 -- 環境のフェッチ 42 fetch = do 43 quit <- checkSDLEvent 44 ks <- getKeyState 45 return (quit, ks) 46 notQuit = not . fst 32 47 33 -- メインループ 48 -- 遅延ストリーム 49 -- microsec 秒ごとに func を実行したアクションの結果をリストとして返す 50 delayedStream :: Int -> IO a -> IO [a] 51 delayedStream microsec func = unsafeInterleaveIO $ do 52 threadDelay microsec 53 x <- func 54 xs <- delayedStream microsec func 55 return $ x:xs 34 56 35 main :: IO () 36 main = sdlStart [VIDEO] wndTitle wndSize $ \sur -> do 37 gs <- newIORef =<< initState 38 imgres <- loadImageResource 39 40 et <- elapseTime frameRate 41 loop et gs onProcess (onDraw sur imgres) [] 42 43 loop et gs op od bef = do 44 quit <- checkEvent 45 when (not quit) $ do 46 ks <- getKeyState 47 modifyIORef gs $ op $ keyProc bef ks 48 st <- readIORef gs 49 (fps, draw) <- et 50 when draw $ od st 51 loop et gs op od ks 52 53 checkEvent = do 57 -- SDL のイベントを処理 58 -- 終了イベントがきたら True を返す 59 checkSDLEvent = do 54 60 ev <- pollEvent 55 61 case ev of … … 57 63 Just (KeyboardEvent { kbPress = True, kbKeysym = Keysym { ksSym = ks, ksMod = km } }) 58 64 | ks == SDLK_ESCAPE -> return True 59 | ks == SDLK_F4 && (KMOD_LALT `elem` km || 60 KMOD_RALT `elem` km) -> return True 65 | ks == SDLK_F4 && (KMOD_LALT `elem` km || KMOD_RALT `elem` km) -> return True 61 66 Nothing -> return False 62 _ -> check Event67 _ -> checkSDLEvent 63 68 64 sdlStart fs title (Size w h) p = do 65 True <- sdlInit fs 66 setCaption title title 67 sur <- setVideoMode w h 32 [HWSURFACE, DOUBLEBUF, ANYFORMAT] 68 p sur 69 sdlQuit 69 ---- 70 70 71 72 -- ゲームの状態 73 data GameState = 74 GameState { 75 pl :: Player, 76 fld :: Field 71 -- 状態 72 data GameState = GameState { 73 pl :: Player, 74 fld :: Field 77 75 } 78 76 79 77 -- 開始状態 80 init State = do78 initialState = do 81 79 fldmap <- loadField stage 82 80 return GameState { … … 87 85 stage = 0 88 86 87 -- キー入力を処理して描画コマンドを返す 88 process :: [[SDLKey]] -> IO [Scr] 89 process kss = do 90 imgres <- loadImageResource 91 st <- initialState 92 return $ map (\scr -> scr imgres) $ loop [] st kss 93 where 94 loop :: [SDLKey] -> GameState -> [[SDLKey]] -> [(ImageResource -> Scr)] 95 loop _ _ [] = [] 96 loop bef gs (ks:kss) = scr' : loop ks gs' kss 97 where 98 (scr', gs') = update kp gs 99 kp = keyProc bef ks 89 100 90 -- 毎フレームの処理 91 onProcess :: KeyProc -> GameState -> GameState 92 onProcess kp gs 93 | otherwise = gs { pl = updatePlayer kp (fld gs) (pl gs) } 101 -- 更新 102 update :: KeyProc -> GameState -> (ImageResource -> Scr, GameState) 103 update kp gs = (render gs', gs') 104 where 105 gs' = gs { pl = updatePlayer kp (fld gs) (pl gs) } 94 106 95 96 -- 描画処理 97 onDraw :: Surface -> ImageResource -> GameState -> IO () 98 onDraw sur imgres gs = do 107 -- 描画 108 render :: GameState -> ImageResource -> Scr 109 render gs imgres sur = do 99 110 fillRect sur Nothing backColor 100 111 … … 106 117 flipSurface sur 107 118 return () 108 -
lang/haskell/nario/Player.hs
r20086 r20156 168 168 moveY $ checkX fld $ moveX kp player 169 169 where 170 moveY 171 | stand player = doJump kp . checkFloor fld . fall 172 | otherwise = checkCeil fld . checkFloor fld . fall 170 moveY = doJump kp . checkFloor fld . checkCeil fld . fall 173 171 174 172 -- スクロール位置取得 -
lang/haskell/nario/Util.hs
r20086 r20156 2 2 3 3 import System.Time (getClockTime, diffClockTimes, noTimeDiff, tdMin, tdSec, tdPicosec) 4 import Data.IORef (newIORef, readIORef, writeIORef, modifyIORef)5 4 import Control.Concurrent (threadDelay) 6 5 import Data.Maybe (fromJust) … … 67 66 mapPhyKey PadB = [SDLK_LSHIFT, SDLK_RSHIFT] 68 67 69 -- 時間調節70 71 elapseTime :: Integer -> IO (IO (Int,Bool))72 elapseTime fps = do73 let frametime = picosec `div` fps74 tm <- getClockTime75 st <- newIORef ((0,0,noTimeDiff), (1,tm))76 return $ do77 ((bef,cur,fdt), (cnt,bt)) <- readIORef st78 ct <- getClockTime79 let dt = diffClockTimes ct bt80 ndt = diffClockTimes ct tm81 adj = frametime*cnt - toPsec dt82 nc = if cnt==fps then (1,ct) else (cnt+1,bt)83 (nbef,ncur) = if tdSec fdt /= tdSec ndt then (cur,0) else (bef,cur)84 if adj < 0 then do85 writeIORef st ((nbef,ncur,ndt), nc)86 return (bef, False)87 else do88 writeIORef st ((nbef,ncur+1,ndt), nc)89 threadDelay $ fromInteger $ min 16666 $ adj `div` 100000090 return (bef, True)91 where92 toPsec dt = toInteger (tdMin dt * 60 + tdSec dt) * picosec + tdPicosec dt93 picosec = 100000000000094 95 68 96 69
![(please configure the [header_logo] section in trac.ini)](/share/chrome/site/your_project_logo.png)