8 #include <SDL_opengl.h>
13 void cave_gen(Cave
* cave
, Ship
* digger
)
15 // check if the digger advanced to the next segment
16 int i
= (cave
->i
-1+SEGMENT_COUNT
)%SEGMENT_COUNT
;
17 if( digger
->pos
[2] > digger
->start
+1 && digger
->pos
[2] - SEGMENT_LEN
< cave
->segs
[i
][0][2] )
20 // invalidate GL list for this segment
21 if(glIsList(cave
->gl_list
[cave
->i
]))
22 glDeleteLists(cave
->gl_list
[cave
->i
], 1);
23 cave
->gl_list
[cave
->i
] = 0;
25 if(glIsList(cave
->gl_wire_list
[cave
->i
]))
26 glDeleteLists(cave
->gl_wire_list
[cave
->i
], 1);
27 cave
->gl_wire_list
[cave
->i
] = 0;
29 // generate new segment
30 for( i
= 0; i
< SECTOR_COUNT
; ++i
) {
31 float a
= M_PI_2
+(i
-1)*M_PI
*2/SECTOR_COUNT
;
32 float r
= digger
->radius
;
33 SET(cave
->segs
[cave
->i
][i
],
34 digger
->pos
[0] + r
*cos(a
),
35 digger
->pos
[1] + r
*sin(a
),
36 ((int)(digger
->pos
[2]/SEGMENT_LEN
))*SEGMENT_LEN
40 // increment segment circular pointer
42 if( cave
->i
>= SEGMENT_COUNT
) {
46 cave
->monolith_x
= digger
->pos
[0] + (2*RAND
-1)*(digger
->radius
-MONOLITH_WIDTH
);
47 cave
->monolith_y
= digger
->pos
[1] + (2*RAND
-1)*(digger
->radius
-MONOLITH_HEIGHT
);
48 cave
->monolith_yaw
= atan2(digger
->vel
[0], digger
->vel
[2]);
52 void cave_init(Cave
* cave
, Ship
* digger
)
56 digger_control(digger
);
57 ship_move(digger
, 1./FPS
);
58 cave_gen(cave
, digger
);
63 void ship_init(Ship
* ship
, float radius
)
65 SET(ship
->pos
,0,0,ship
->start
);
66 SET(ship
->vel
,0,0,VELOCITY
);
67 SET(ship
->lookAt
,0,0,VELOCITY
);
68 ship
->radius
= radius
;
72 void ship_move(Ship
* ship
, float dt
)
78 Vec3 leftup
= {-a
,a
/2,0};
79 ADD(ship
->vel
, leftup
);
83 Vec3 rightup
= {+a
,a
/2,0};
84 ADD(ship
->vel
, rightup
);
87 ship
->vel
[1] -= GRAVITY
*dt
;
89 ADDSCALE(ship
->pos
, ship
->vel
, dt
);
93 float smoothness
= 0.2;
94 SUB2 (d
, ship
->vel
, ship
->lookAt
);
95 ADDSCALE (ship
->lookAt
, d
, smoothness
);
100 ship
->vel
[1] += THRUST
*dt
;
102 ship
->vel
[1] -= GRAVITY
*dt
;
104 ship
->pos
[1] += ship
->vel
[1]*dt
;
108 void digger_control(Ship
* ship
)
110 float twist_factor
= 500;
112 float twist
= 1-1/(1+ ship
->pos
[2]/twist_factor
);
120 ship
->vel
[1] > max_vel
[1] ||
121 ship
->vel
[1] < -max_vel
[1] ||
122 ship
->vel
[0] > max_vel
[0] ||
123 ship
->vel
[0] < -max_vel
[0] ||
128 ship
->lefton
= RAND
<twist
*noise
? rand()%2 :
129 ship
->vel
[1] < 0 || ship
->vel
[0] > +max_vel
[0];
132 ship
->righton
= RAND
<twist
*noise
? rand()%2 :
133 ship
->vel
[1] < 0 || ship
->vel
[0] < -max_vel
[0];
136 float scale
= 1-MIN(1,log(1+ship
->pos
[2])/log(1+MIN_CAVE_RADIUS_DEPTH
));
137 ship
->radius
= MIN_CAVE_RADIUS
+(MAX_CAVE_RADIUS
-MIN_CAVE_RADIUS
)*scale
+RAND
;
140 static float X(Cave
* cave
, int i
, float xn
, float yn
, int k0
, int k1
)
141 {// used by collision()
143 float x1
= cave
->segs
[i
][k0
][0];
144 float y1
= cave
->segs
[i
][k0
][1];
145 float x2
= cave
->segs
[i
][k1
][0];
146 float y2
= cave
->segs
[i
][k1
][1];
147 float t
= (yn
- y2
)/(y1
- y2
);
150 float x
= (x1
- xn
)*t
+ (x2
- xn
)*(1 - t
);
151 //printf("t(%f), x(%f)\n", t, x);
155 float collision(Cave
* cave
, Ship
* ship
)
159 // This method counts the number of intersections of a semi-line
160 // starting from the point being checked against the poligon,
161 // that in this case is the segment of the cave.
162 // If the number of intersections is odd, the point is inside.
164 // In fact we'll check four points around the center of the ship
165 // (to simulate a diamond-shaped bounding box).
167 // The return value is the distance from the ship to the cave.
169 int intersection_count
[4];
170 memset(intersection_count
, 0, sizeof(intersection_count
));
174 for( k
= 0; k
< SECTOR_COUNT
; ++k
) {
175 int i0
= (k
+0)%SECTOR_COUNT
;
176 int i1
= (k
+1)%SECTOR_COUNT
;
179 SUB2(dist
, ship
->pos
, cave
->segs
[i
][i0
]);
180 float len
= LEN(dist
);
185 if(cave
->segs
[i
][i0
][0] < ship
->pos
[0]-ship
->radius
&&
186 cave
->segs
[i
][i1
][0] < ship
->pos
[0]-ship
->radius
)
188 if(cave
->segs
[i
][i0
][1] > ship
->pos
[1]+ship
->radius
&&
189 cave
->segs
[i
][i1
][1] > ship
->pos
[1]+ship
->radius
)
191 if(cave
->segs
[i
][i0
][1] < ship
->pos
[1]-ship
->radius
&&
192 cave
->segs
[i
][i1
][1] < ship
->pos
[1]-ship
->radius
)
195 if(X(cave
, i
, ship
->pos
[0] - ship
->radius
, ship
->pos
[1], i0
, i1
) > 0)
196 ++intersection_count
[0];
198 if(X(cave
, i
, ship
->pos
[0], ship
->pos
[1] + ship
->radius
, i0
, i1
) > 0)
199 ++intersection_count
[1];
201 if(X(cave
, i
, ship
->pos
[0] + ship
->radius
, ship
->pos
[1], i0
, i1
) > 0)
202 ++intersection_count
[2];
204 if(X(cave
, i
, ship
->pos
[0], ship
->pos
[1] - ship
->radius
, i0
, i1
) > 0)
205 ++intersection_count
[3];
208 for(i
= 0; i
< 4; ++i
) {
209 if(intersection_count
[i
] % 2 == 0) {
210 return ship
->dist
= 0; // hit
214 ship
->dist
= min
- 2*ship
->radius
;
218 // vim600:fdm=syntax:fdn=1: