1- module Game where
2- import Time exposing ( .. )
1+ import Time exposing (..)
2+ import List exposing (.. )
33import AnimationFrame
4- import Keyboard
4+ import Keyboard.Extra as Keyboard
55import Window
6- import Graphics. Collage exposing (..)
7- import Graphics. Element exposing (..)
6+ import Collage exposing (..)
7+ import Element exposing (..)
88import Color exposing (..)
9-
9+ import Html.App as App
10+ import Html
1011-- MODEL
1112
13+
14+
15+ type Msg
16+ = Step Time
17+ | KeyboardExtraMsg Keyboard . Msg
18+ | Noop
19+
1220type alias Player =
1321 { angle: Float }
1422
15- type alias Input =
16- { space : Bool
17- , dir : Int
18- }
19-
2023type alias Game =
2124 {
2225 player : Player
26+ , direction : Int
27+ , keyboardModel : Keyboard . Model
2328 }
2429
2530( gameWidth, gameHeight) = ( 1024 , 576 ) -- 16:9
@@ -29,13 +34,6 @@ type alias Game =
2934playerRadius : Float
3035playerRadius = gameWidth / 10.0
3136
32- -- The global game state
33-
34- defaultGame : Game
35- defaultGame =
36- {
37- player = Player ( degrees 30 )
38- }
3937
4038-- UPDATE
4139
@@ -51,20 +49,45 @@ updatePlayerAngle angle dir =
5149 else
5250 newAngle
5351
54- updatePlayer : Input -> Game -> Player
55- updatePlayer { dir} { player} =
52+ updatePlayer : Int -> Game -> Player
53+ updatePlayer dir { player} =
5654 let
5755 newAngle = updatePlayerAngle player. angle dir
5856 in
5957 { player | angle = newAngle }
6058
61- -- Game loop: Transition from one state to the next.
62- update : (Time , Input ) -> Game -> Game
63- update ( timestamp, input) game =
64-
65- { game |
66- player = updatePlayer input game
67- }
59+
60+ {- | Updates the game state on a keyboard command -}
61+ onUserInput : Keyboard .Msg -> Game -> (Game , Cmd Msg )
62+ onUserInput keyMsg game =
63+ let
64+ ( keyboardModel, keyboardCmd ) =
65+ Keyboard . update keyMsg game. keyboardModel
66+ in
67+ ( { game | keyboardModel = keyboardModel
68+ , direction = ( Keyboard . arrows keyboardModel) . x
69+ }
70+ , Cmd . map KeyboardExtraMsg keyboardCmd )
71+
72+ {- | Updates the game state on every frame -}
73+ onFrame : Time -> Game -> (Game , Cmd Msg )
74+ onFrame time game =
75+ let
76+ nextCmd = Cmd . none
77+ in
78+ ( { game |
79+ player = updatePlayer game. direction game
80+ }, nextCmd )
81+
82+
83+ {- | Game loop: Transition from one state to the next. -}
84+ update : Msg -> Game -> (Game , Cmd Msg )
85+ update msg game =
86+ case msg of
87+ KeyboardExtraMsg keyMsg -> onUserInput keyMsg game
88+ Step time -> onFrame time game
89+ _ -> ( game, Cmd . none)
90+
6891
6992-- VIEW
7093
@@ -86,33 +109,50 @@ makePlayer player =
86109 |> moveRadial angle ( playerRadius - 10 )
87110 |> rotate angle
88111
89- view : (Int ,Int ) -> Game -> Element
90- view ( w, h) game =
91- container w h middle <|
92- collage gameWidth gameHeight
93- [ rect gameWidth gameHeight
94- |> filled bgBlack
95- , makePlayer game. player
96- ]
112+ view : Game -> Html .Html Msg
113+ view game =
114+ let
115+ bg = rect gameWidth gameHeight |> filled bgBlack
116+ field = makePlayer game. player
117+ in
118+ toHtml <|
119+ container gameWidth gameHeight middle <|
120+ collage gameWidth gameHeight
121+ [ bg
122+ , field
123+ ]
124+
125+ -- SUBSCRIPTIONS
126+
127+ subscriptions : Game -> Sub Msg
128+ subscriptions game =
129+ Sub . batch [
130+ AnimationFrame . times ( \ time -> Step time) ,
131+ Sub . map KeyboardExtraMsg Keyboard . subscriptions
132+ ]
133+
134+
135+ -- INIT
136+
137+ init : (Game , Cmd Msg )
138+ init =
139+ let
140+ ( keyboardModel, keyboardCmd ) = Keyboard . init
141+ in
142+ ( { player = Player ( degrees 30 )
143+ , keyboardModel = keyboardModel
144+ , direction = 0
145+ }
146+ , Cmd . batch
147+ [ Cmd . map KeyboardExtraMsg keyboardCmd
148+ ]
149+ )
97150
98- -- SIGNALS
99151
100- main : Signal Element
101152main =
102- Signal . map2 view Window . dimensions gameState
103-
104- gameState : Signal Game
105- gameState =
106- Signal . foldp update defaultGame input
107-
108- -- Creates an event stream from the keyboard inputs and is
109- -- updated by AnimationFrame.
110- input : Signal (Time , Input )
111- input =
112- Signal . map2 Input
113- Keyboard . space
114- ( Signal . map . x Keyboard . arrows)
115- -- only update on a new frame
116- |> Signal . sampleOn AnimationFrame . frame
117- |> Time . timestamp
153+ App . program
154+ { init = init
155+ , update = update
156+ , view = view
157+ , subscriptions = subscriptions }
118158
0 commit comments