]> gitweb.factorcode.org Git - factor.git/blob - extra/jamshred/player/player.factor
jamshred: Don't (move-player) in a tight loop.
[factor.git] / extra / jamshred / player / player.factor
1 ! Copyright (C) 2007, 2008 Alex Chapman
2 ! See http://factorcode.org/license.txt for BSD license.
3
4 USING: accessors colors combinators jamshred.log jamshred.oint
5 jamshred.sound jamshred.tunnel kernel locals math math.constants
6 math.order ranges math.vectors math.matrices sequences shuffle
7 specialized-arrays strings system ;
8
9 QUALIFIED-WITH: alien.c-types c
10 SPECIALIZED-ARRAY: c:float
11 IN: jamshred.player
12
13 TUPLE: player < oint
14     { name string }
15     { sounds sounds }
16     tunnel
17     nearest-segment
18     { last-move integer }
19     { speed float } ;
20
21 ! speeds are in GL units / second
22 CONSTANT: default-speed 1.0
23 CONSTANT: max-speed 30.0
24
25 : <player> ( name sounds -- player )
26     [ float-array{ 0 0 5 } float-array{ 0 0 -1 } float-array{ 0 1 0 } float-array{ -1 0 0 } ] 2dip
27     f f 0 default-speed player boa ;
28
29 : turn-player ( player x-radians y-radians -- )
30     overd left-pivot up-pivot ;
31
32 : roll-player ( player z-radians -- )
33     forward-pivot ;
34
35 : to-tunnel-start ( player -- )
36     dup tunnel>> first
37     [ >>nearest-segment ]
38     [ location>> >>location ] bi drop ;
39
40 : play-in-tunnel ( player segments -- )
41     >>tunnel to-tunnel-start ;
42
43 : update-time ( player -- seconds-passed )
44     nano-count swap [ last-move>> - 1,000,000,000 / ] [ last-move<< ] 2bi ;
45
46 : moved ( player -- ) nano-count swap last-move<< ;
47
48 : speed-range ( -- range )
49     max-speed [0..b] ;
50
51 : change-player-speed ( inc player -- )
52     [ + 0 max-speed clamp ] change-speed drop ;
53
54 : multiply-player-speed ( n player -- )
55     [ * 0 max-speed clamp ] change-speed drop ;
56
57 : distance-to-move ( seconds-passed player -- distance )
58     speed>> * ;
59
60 : bounce ( d-left player -- d-left' player )
61     {
62         [ dup nearest-segment>> bounce-off-wall ]
63         [ sounds>> bang ]
64         [ 3/4 swap multiply-player-speed ]
65         [ ]
66     } cleave ;
67
68 :: (distance) ( heading player -- current next location heading )
69     player nearest-segment>>
70     player [ tunnel>> ] [ nearest-segment>> ] bi heading heading-segment
71     player location>> heading ;
72
73 : distance-to-heading-segment ( heading player -- distance )
74     (distance) distance-to-next-segment ;
75
76 : distance-to-heading-segment-area ( heading player -- distance )
77     (distance) distance-to-next-segment-area ;
78
79 : distance-to-collision ( player -- distance )
80     dup nearest-segment>> (distance-to-collision) ;
81
82 : almost-to-collision ( player -- distance )
83     distance-to-collision 0.1 - dup 0 < [ drop 0 ] when ;
84
85 : from ( player -- radius distance-from-centre )
86     [ nearest-segment>> dup radius>> swap ] [ location>> ] bi
87     distance-from-centre ;
88
89 : distance-from-wall ( player -- distance ) from - ;
90 : fraction-from-centre ( player -- fraction ) from swap / ;
91 : fraction-from-wall ( player -- fraction )
92     fraction-from-centre 1 swap - ;
93
94 : update-nearest-segment2 ( heading player -- )
95     2dup distance-to-heading-segment-area 0 <= [
96         [ tunnel>> ] [ nearest-segment>> rot heading-segment ]
97         [ nearest-segment<< ] tri
98     ] [
99         2drop
100     ] if ;
101
102 :: move-player-on-heading ( d-left player distance heading -- d-left' player )
103     d-left distance min :> d-to-move
104     d-to-move heading n*v :> move-v
105
106     move-v player location+
107     heading player update-nearest-segment2
108     d-left d-to-move - player ;
109
110 : distance-to-move-freely ( player -- distance )
111     [ almost-to-collision ]
112     [ [ forward>> ] keep distance-to-heading-segment-area ] bi min ;
113
114 : ?move-player-freely ( d-left player -- d-left' player )
115     over 0 > [
116         ! must make sure we are moving a significant distance, otherwise
117         ! we can recurse endlessly due to floating-point imprecision.
118         ! (at least I /think/ that's what causes it...)
119         dup distance-to-move-freely dup 0.1 > [
120             over forward>> move-player-on-heading ?move-player-freely
121         ] [ drop ] if
122     ] when ;
123
124 : drag-heading ( player -- heading )
125     [ forward>> ] [ nearest-segment>> forward>> proj ] bi ;
126
127 : drag-player ( d-left player -- d-left' player )
128     dup [ [ drag-heading ] keep distance-to-heading-segment-area ]
129     [ drag-heading move-player-on-heading ] bi ;
130
131 : (move-player) ( d-left player -- d-left' player )
132     ?move-player-freely over 0 > [
133         ! bounce
134         drag-player
135     ] when ;
136
137 : move-player ( player -- )
138     [ update-time ] [ distance-to-move ] [ (move-player) 2drop ] tri ;
139
140 : update-player ( player -- )
141     [ move-player ] [ nearest-segment>> COLOR: white swap color<< ] bi ;