-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGameSkeleton.elm
134 lines (90 loc) · 3.5 KB
/
GameSkeleton.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
import Color (..)
import Graphics.Collage (..)
import Graphics.Element (..)
import Keyboard
import Signal (..)
import Time (fps, inSeconds, Time)
import Window
import Text
import List
{-- Part 1: Model the user input ----------------------------------------------
What information do you need to represent all relevant user input?
Task: Redefine `UserInput` to include all of the information you need.
Redefine `userInput` to be a signal that correctly models the user
input as described by `UserInput`.
------------------------------------------------------------------------------}
type alias UserInput = {}
userInput : Signal UserInput
userInput = constant {}
type alias Input =
{ delta : Float
, userInput : UserInput
}
{-- Part 2: Model the game ----------------------------------------------------
What information do you need to represent the entire game?
Tasks: Redefine `GameState` to represent your particular game.
Redefine `defaultGame` to represent your initial game state.
For example, if you want to represent many objects that just have a position,
your GameState might just be a list of coordinates and your default game might
be an empty list (no objects at the start):
type GameState = { objects : [(Float,Float)] }
defaultGame = { objects = [] }
------------------------------------------------------------------------------}
type alias GameState = {}
defaultGame : GameState
defaultGame =
{}
{-- Part 3: Update the game ---------------------------------------------------
How does the game step from one state to another based on user input?
Task: redefine `stepGame` to use the UserInput and GameState
you defined in parts 1 and 2. Maybe use some helper functions
to break up the work, stepping smaller parts of the game.
------------------------------------------------------------------------------}
stepGame : Input -> GameState -> GameState
stepGame {delta,userInput} ({ball,blocks,player} as gameState) =
let
ball' = ball
blocks' = blocks
player' = player
in
{ gameState | ball <- ball'
, blocks <- blocks'
, player <- player'
}
near k c n = n >= k-c && n <= k+c
within ball box = (ball.x |> near box.x (ball.r + box.w / 2))
&& (ball.y |> near box.y (ball.r + box.h / 2))
stepV v lowerCollision upperCollision =
if | lowerCollision -> abs v
| upperCollision -> 0 - abs v
| otherwise -> v
stepObj t ({x,y,vx,vy} as obj) =
{ obj |
x <- x + vx * t,
y <- y + vy * t
}
{-- Part 4: Display the game --------------------------------------------------
How should the GameState be displayed to the user?
Task: redefine `display` to use the GameState you defined in part 2.
------------------------------------------------------------------------------}
display : (Int,Int) -> GameState -> Element
display (w,h) ({ball,player,blocks} as gameState) =
container w h middle <|
Text.asText gameState
make obj shape =
shape
|> filled white
|> move (obj.x, obj.y)
{-- That's all folks! ---------------------------------------------------------
The following code puts it all together and shows it on screen.
------------------------------------------------------------------------------}
input : Signal Input
input =
let
delta = inSeconds <~ fps 30
in
sampleOn delta (Input <~ delta ~ userInput)
gameState : Signal GameState
gameState = foldp stepGame defaultGame input
main : Signal Element
main = display <~ Window.dimensions ~ gameState