-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.elm
183 lines (141 loc) · 4.12 KB
/
main.elm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
module Main exposing (..)
import Keyboard.Extra as Keyboard
import Time exposing (Time)
import Html exposing (Html, div)
import Html.Attributes exposing (style)
import Html.App exposing (program)
import Sprite exposing (..)
import Map
import AnimationFrame
-- MODEL
{-| Model contains the x,y coordinates of the sprite
as well as the velocity and direction.
-}
type alias Model =
{ sprite : Sprite.Model
, map : Map.Model
, keyboard : Keyboard.Model
}
initialModel : Keyboard.Model -> Model
initialModel keyboard =
Model Sprite.init Map.init keyboard
-- UPDATE
type Msg
= Tick Time
| KeyPress Keyboard.Msg
| Nothing
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
Tick timeDelta ->
( model
|> updateMap timeDelta
|> updateSprite (Sprite.Tick timeDelta)
, Cmd.none
)
KeyPress key ->
let
( keyboard, _ ) =
Keyboard.update key model.keyboard
direction =
Keyboard.arrows keyboard
in
( { model | keyboard = keyboard }
|> updateSprite (Sprite.Direction direction)
, Cmd.none
)
Nothing ->
( model, Cmd.none )
updateSprite : Sprite.Msg -> Model -> Model
updateSprite msg model =
let
sprite' =
Sprite.update msg model.sprite
in
{ model | sprite = sprite' }
updateMap : Time -> Model -> Model
updateMap dt model =
let
( x, y, vx, vy, map ) =
( model.sprite.x, model.sprite.y, model.sprite.vx, model.sprite.vy, model.map )
( bottomWall, leftWall, rightWall, topWall ) =
( 0, 0, Map.width, Map.height )
( movingUp, movingDown, movingRight, movingLeft ) =
( vy > 0, vy < 0, vx > 0, vx < 0 )
action : Map.Action
action =
if x == leftWall && movingLeft then
Map.HorizontalScroll (round (dt * vx))
else if (x + 32) == rightWall && movingRight then
Map.HorizontalScroll (round (dt * vx))
else if y == topWall && movingUp then
Map.VerticalScroll (round (dt * vy))
else if (y - 32) == bottomWall && movingDown then
Map.VerticalScroll (round (dt * vy))
else
Map.HorizontalScroll 0
in
{ model
| map = Map.update action map
}
-- VIEW
view : Model -> Html Msg
view model =
let
bee =
Html.App.map (\_ -> Nothing) (Sprite.view model.sprite)
-- outer, middle, inner is for vertical & horizontal centering
outer =
div
[ style
[ ( "display", "table" )
, ( "position", "absolute" )
, ( "height", "100%" )
, ( "width", "100%" )
]
]
[ middle ]
middle =
div
[ style
[ ( "display", "table-cell" )
, ( "vertical-align", "middle" )
]
]
[ inner ]
inner =
div
[ style
[ ( "margin-left", "auto" )
, ( "margin-right", "auto" )
, ( "width", (toString Map.width) ++ "px" )
]
]
[ Html.App.map (\_ -> Nothing) (Map.view model.map)
, bee
]
in
outer
-- SUBSCRIPTIONS
subs : Sub Msg
subs =
Sub.batch
[ Sub.map KeyPress Keyboard.subscriptions
, AnimationFrame.diffs Tick
]
-- MAIN
main : Program Never
main =
let
( initialKeyboard, keyboardCmd ) =
Keyboard.init
in
program
{ init =
( (initialModel initialKeyboard)
, Cmd.map KeyPress keyboardCmd
)
, update = update
, subscriptions = always subs
, view = view
}