aboutsummaryrefslogtreecommitdiff
path: root/Demos
diff options
context:
space:
mode:
Diffstat (limited to 'Demos')
-rw-r--r--Demos/Pong/Pong.hs59
1 files changed, 37 insertions, 22 deletions
diff --git a/Demos/Pong/Pong.hs b/Demos/Pong/Pong.hs
index fd7fbeb..0e24a42 100644
--- a/Demos/Pong/Pong.hs
+++ b/Demos/Pong/Pong.hs
@@ -16,18 +16,15 @@ import Spear.Step
16 16
17-- Configuration 17-- Configuration
18 18
19padSize = vec2 0.05 0.02 19padSize = vec2 0.07 0.02
20 20ballSize = 0.012
21ballSize = 0.01 21ballSpeed = 0.6
22 22initialBallVelocity = vec2 1 1
23ballVelocity = vec2 0.3 0.3 23maxBounceAngle = 65 * pi/180
24 24playerSpeed = 1.0
25playerSpeed = 0.7 25enemySpeed = 1.5
26
27initialEnemyPos = vec2 0.5 0.9 26initialEnemyPos = vec2 0.5 0.9
28
29initialPlayerPos = vec2 0.5 0.1 27initialPlayerPos = vec2 0.5 0.1
30
31initialBallPos = vec2 0.5 0.5 28initialBallPos = vec2 0.5 0.5
32 29
33-- Game events 30-- Game events
@@ -66,7 +63,7 @@ padBox = AABB2 (-padSize) padSize
66obj2 = obj2FromVectors unitx2 unity2 63obj2 = obj2FromVectors unitx2 unity2
67 64
68newWorld = 65newWorld =
69 [ GameObject ballBox (obj2 initialBallPos) $ stepBall ballVelocity, 66 [ GameObject ballBox (obj2 initialBallPos) $ stepBall initialBallVelocity,
70 GameObject padBox (obj2 initialEnemyPos) stepEnemy, 67 GameObject padBox (obj2 initialEnemyPos) stepEnemy,
71 GameObject padBox (obj2 initialPlayerPos) stepPlayer 68 GameObject padBox (obj2 initialPlayerPos) stepPlayer
72 ] 69 ]
@@ -75,19 +72,37 @@ newWorld =
75 72
76stepBall vel = collideBall vel .> moveBall 73stepBall vel = collideBall vel .> moveBall
77 74
75-- TODO: in collideBall and paddleBounce, we should an apply an offset to the
76-- ball when collision is detected.
78collideBall :: Vector2 -> Step [GameObject] e GameObject (Vector2, GameObject) 77collideBall :: Vector2 -> Step [GameObject] e GameObject (Vector2, GameObject)
79collideBall vel = step $ \_ dt gos _ ball -> 78collideBall vel = step $ \_ dt gos _ ball ->
80 let (AABB2 pmin pmax) = aabb ball `aabbAdd` pos ball 79 let (AABB2 pmin pmax) = aabb ball `aabbAdd` pos ball
81 collideCol = x pmin < 0 || x pmax > 1 80 collideSide = x pmin < 0 || x pmax > 1
82 collideRow = y pmin < 0 || y pmax > 1 || any (collide ball) (tail gos) 81 collideBack = y pmin < 0 || y pmax > 1
83 negx v@(Vector2 x y) = if collideCol then vec2 (-x) y else v 82 collidePaddle = any (collide ball) (tail gos)
84 negy v@(Vector2 x y) = if collideRow then vec2 x (-y) else v 83 flipX v@(Vector2 x y) = if collideSide then vec2 (-x) y else v
85 vel' = negx . negy $ vel 84 flipY v@(Vector2 x y) = if collideBack then vec2 x (-y) else v
86 delta = dt -- A small delta to apply when collision occurs. 85 vel' = normalise . (\v -> foldl (paddleBounce ball) v (tail gos)) . flipX . flipY $ vel
87 adjustX = if collideCol then scale delta (vec2 (x vel) 0) else vec2 0 0 86 -- A small delta to apply when collision occurs.
88 adjustY = if collideRow then scale delta (vec2 0 (y vel)) else vec2 0 0 87 delta = 1 + if collideSide || collideBack || collidePaddle then 2*dt else 0
89 in ((vel' + adjustX + adjustY, ball), collideBall vel') 88 in ((scale ballSpeed (scale delta vel'), ball), collideBall vel')
90 89
90paddleBounce :: GameObject -> Vector2 -> GameObject -> Vector2
91paddleBounce ball v paddle =
92 if collide ball paddle
93 then
94 let (AABB2 pmin pmax) = aabb paddle `aabbAdd` pos paddle
95 center = (x pmin + x pmax) / 2
96 -- Normalized offset of the ball from the paddle's center, [-1, +1].
97 -- It's outside the [-1, +1] range if there is no collision.
98 offset = (x (pos ball) - center) / ((x pmax - x pmin) / 2)
99 angle = offset * maxBounceAngle
100 -- When it bounces off of a paddle, y vel is flipped.
101 ysign = -(signum (y v))
102 in vec2 (sin angle) (ysign * cos angle)
103 else v
104
105collide :: GameObject -> GameObject -> Bool
91collide go1 go2 = 106collide go1 go2 =
92 let (AABB2 (Vector2 xmin1 ymin1) (Vector2 xmax1 ymax1)) = 107 let (AABB2 (Vector2 xmin1 ymin1) (Vector2 xmax1 ymax1)) =
93 aabb go1 `aabbAdd` pos go1 108 aabb go1 `aabbAdd` pos go1
@@ -112,7 +127,7 @@ movePad :: Step s e GameObject GameObject
112movePad = step $ \elapsed _ _ _ pad -> 127movePad = step $ \elapsed _ _ _ pad ->
113 let p = vec2 px 0.9 128 let p = vec2 px 0.9
114 px = 129 px =
115 double2Float (sin elapsed * 0.5 + 0.5) 130 double2Float (sin (elapsed * enemySpeed) * 0.5 + 0.5)
116 * (1 - 2 * x padSize) 131 * (1 - 2 * x padSize)
117 + x padSize 132 + x padSize
118 in (setPos p pad, movePad) 133 in (setPos p pad, movePad)