-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathhackman.elm
141 lines (108 loc) · 3.85 KB
/
hackman.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
module Hackman where
import Keyboard
import Window
import Debug
import Text
-- INPUT:
-- The information we need to represent all relevant user input.
-- {{{
-- +---------------------------+
-- | Keys Used |
-- +---------+-----------------+
-- | KEY | EFFECT |
-- +---------+-----------------+
-- | [space] | up |
-- | a | left |
-- | d | right |
-- | s | down (Not used) |
-- +---------+-----------------+
--}}}
-- MODEL:
-- The information we need to represent the entire game.
-- {{{
type Object a = { a | x:Float -- x coordinate
, y:Float -- y coordinate
, vx:Float -- x velocity
, vy:Float } -- y velocity
type Rectangle a = { a | x:Float -- top left corner x coordinate
, y:Float -- top left corner y coordinate
, w:Float -- width
, l:Float } -- length
type Player = Object {}
type Platform = Rectangle {}
data State = Play | Pause | Win
-- A game has a state, a player, and a number of platforms greater than or
-- equal to zero.
type Game = { state:State, player:Player, platforms:[Platform] }
defaultGame : Game
defaultGame =
{ state = Pause
, player = { x = 0
, y = 0
, vx = 0
, vy = 0}
, platforms = []
}
-- }}}
-- UPDATE:
-- How the game steps from one state to another based on user input.
-- {{{
within : Player -> -- The platform we're testing whether our player is within
Platform -> -- Our glorious hero
Bool -- Whether our glorious hero is within the platform
within player platform =
((player.x > platform.x - 8) && -- we're not to the left
(player.x < (platform.x + platform.w) + 8)) && -- or to the right
((player.y < platform.y + 8) && -- or on top
(player.y > platform.y)) -- or below
-- Note: this is using 8 as a tolerance because it feels pretty good.
-- Feel free to change this.
stepV : Float -> -- Our velocity vector
Bool -> -- Whether there is an lower-bound collision
Bool -> -- Whether there is an upper-bound collision
Float -- New velocity vector
stepV v lowerCollision upperCollision =
if | lowerCollision -> abs v
| upperCollision -> 0 - (abs v)
| otherwise -> v
stepObj : Time ->
Object a -> -- Original object
Object a -- Object after time
stepObj t ({x,y,vx,vy} as obj) =
{ obj | x <- x + (vx * t)
, y <- y + (vy * t) }
jump {y} g h =
if (any (within h) g.platforms)
then { h | vy <- 5 }
else h
gravity t g h = if not (any (within h) g.platforms) then { h | vy <- h.vy - t/4 } else h
physics t g h = { h | x <- h.x + t*h.vx , y <- max 0 (h.y + t*h.vy) }
walk {x} g h = { h | vx <- toFloat x
, dir <- if | x < 0 -> "left"
| x > 0 -> "right"
| otherwise -> h.dir }
-- }}}
-- VIEW:
-- How the game state is displayed to the user.
-- {{{
-- Useful Colors
-- R G B
backgroundGrey = rgb 149 165 166
platformGrey = rgb 44 62 80
textBlue = rgb 41 128 185
-- Formats text to look pretty
txt f = leftAligned << f << monospace << Text.color textBlue << toText
displayPlatform : Platform ->
Form
displayPlatform {x,y,w,l} = move (x, y) (filled platformGrey (rect w l))
-- Where the magic happens
display : (Int, Int) ->
Game ->
Element
display (w,h) {state, player, platforms} = container w h middle <|
collage 600 400
([ filled backgroundGrey (rect 600 400)
, toForm (image 10 10 "/img/Player/standing.png")
]
++ (map displayPlatform platforms))
-- }}}