This repository has been archived by the owner on Jan 18, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Collisions.elm
86 lines (77 loc) · 3.57 KB
/
Collisions.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
module Collisions exposing (collide)
import List exposing (map, concat, concatMap, any)
import Random exposing (Seed)
import State exposing (..)
import Segment exposing (..)
import Triangle
import Player exposing (Player)
import Asteroids exposing (Asteroid, liesInside, split)
import Bullets exposing (Bullet)
import SegmentParticles exposing (SegmentParticle, segmentParticles)
import Ship
collide : Maybe Player -> List Asteroid -> List Bullet -> State Seed (List Asteroid, List Bullet, List SegmentParticle, Int, Bool)
collide player asteroids bullets =
collideAsteroidsBullets asteroids bullets >>= \(asteroids', bullets', particles, score) ->
case player of
Just player' ->
collidePlayerAsteroids player' asteroids' >>= \(hitPlayer, particles') ->
return (asteroids', bullets', particles ++ particles', score, hitPlayer)
_ -> return (asteroids', bullets', particles, score, False)
collideAsteroidsBullets : List Asteroid -> List Bullet -> State Seed (List Asteroid, List Bullet, List SegmentParticle, Int)
collideAsteroidsBullets asteroids bullets =
collideAsteroidsBullets' asteroids bullets >>= \(asteroids, bullets', particles, score) ->
return (concat asteroids, bullets', concat particles, score)
collideAsteroidsBullets' : List Asteroid -> List Bullet -> State Seed (List (List Asteroid), List Bullet, List (List SegmentParticle), Int)
collideAsteroidsBullets' asteroids bullets =
case asteroids of
[] -> return ([], bullets, [], 0)
x::xs ->
collideAsteroidBullet x bullets >>= \(asteroids', bullets', particles, score) ->
collideAsteroidsBullets' xs bullets' >>= \(xs', bullets'', particles', score') ->
return (asteroids' :: xs', bullets'', particles :: particles', score + score')
collideAsteroidBullet : Asteroid -> List Bullet -> State Seed (List Asteroid, List Bullet, List SegmentParticle, Int)
collideAsteroidBullet asteroid bullets =
case bullets of
[] -> return ([asteroid], [], [], 0)
x::xs ->
if liesInside x.position asteroid then
split asteroid >>= \(asteroids, particles) ->
return (asteroids, xs, particles, 100)
else
collideAsteroidBullet asteroid xs >>= \(asteroids, xs', particles, score) ->
return (asteroids, x :: xs', particles, score)
collidePlayerAsteroids : Player -> List Asteroid -> State Seed (Bool, List SegmentParticle)
collidePlayerAsteroids player asteroids =
case asteroids of
[] -> return (False, [])
x::xs ->
collidePlayerAsteroid player x >>= \(hitPlayer, particles) ->
if hitPlayer then
return (True, particles)
else
collidePlayerAsteroids player xs
collidePlayerAsteroid : Player -> Asteroid -> State Seed (Bool, List SegmentParticle)
collidePlayerAsteroid player asteroid =
let
shipTriangles = Ship.triangle player.position player.rotation |> Triangle.wrap
shipSegments = concatMap Triangle.segments shipTriangles
asteroidSegments = Asteroids.wrappedSegments asteroid
segmentPairs = pairs shipSegments asteroidSegments
liesInside' x = Asteroids.liesInside x asteroid
in
if
any (\(x, y) -> intersect x y) segmentPairs
|| any (\t -> liesInside' t.a || liesInside' t.b || liesInside' t.c) shipTriangles then
segmentParticles player.velocity shipSegments >>= \particles ->
return (True, particles)
else return (False, [])
pairs : List a -> List b -> List (a, b)
pairs a b =
case a of
[] -> []
x::xs -> pairs' x b ++ pairs xs b
pairs' : a -> List b -> List (a, b)
pairs' x b =
case b of
[] -> []
y::ys -> (x, y) :: pairs' x ys