struct rock_struct {
float x,y,dx,dy;
int active;
- int dead; // has been blown out of the way
- // to make room for a new ship appearing.
SDL_Surface *image;
struct shape *shape;
int type_number;
struct rock_struct rock[MAXROCKS], *rockptr = rock;
-float rockrate,rockspeed;
+float rockrate;
SDL_Surface *surf_rock[NROCKS];
struct shape rock_shapes[NROCKS];
-int countdown = 0;
+float rockhtimer = 0;
+int nrocks = 41;
float rnd(void);
-uint32_t area;
+// used for rock generation.
+#define KH (1.0/32.0)
+#define KV (1.0/24.0)
+#define RXMIN 5.0
+#define RXMAX 10.0
+#define RYMIN (-0.5)
+#define RYMAX 0.5
+
int
init_rocks(void)
char a[MAX_PATH_LEN];
SDL_Surface *temp;
- area = 0;
-
for(i = 0; i<NROCKS; i++) {
snprintf(a,MAX_PATH_LEN,add_path("sprites/rock%02d.png"),i);
NULLERROR(temp = IMG_Load(a));
}
void
+reset_rocks(void)
+{
+ int i;
+
+ for(i = 0; i<MAXROCKS; i++ ) rock[i].active = 0;
+
+ rockrate = 54.0;
+}
+
+void
new_rocks(void)
{
- if(--countdown <= 0 && (rnd()*100.0<(rockrate += 0.025))) {
- // Possibly create a rock
- rockptr++;
- if(rockptr-rock >= MAXROCKS) {
- rockptr = rock;
+ int i = 0;
+ float hfactor = KH*nrocks*7.5;
+
+ rockhtimer += hfactor*gamerate/20;
+ if(rockhtimer >= 1) {
+ while(rockptr->active && i<MAXROCKS) {
+ if(++rockptr - rock >= MAXROCKS) rockptr = rock;
+ i++;
}
if(!rockptr->active) {
- rockptr->dx = -(rockspeed)*(1 + rnd());
+ rockhtimer -= 1;
+ rockptr->dx = -5.0*(1.0 + rnd());
rockptr->dy = rnd()-0.5;
rockptr->type_number = random() % NROCKS;
rockptr->image = surf_rock[rockptr->type_number];
rockptr->x = (float)XSIZE;
rockptr->y = rnd()*(YSIZE + rockptr->image->h);
rockptr->active = 1;
- area += rockptr->shape->area;
- }
- if(gamerate>0.1) {
- countdown = (int)(ROCKRATE/gamerate);
- } else {
- countdown = 0;
}
}
}
// Move all the rocks
for(i = 0; i < MAXROCKS; i++) {
if(rock[i].active) {
+ // move
rock[i].x += rock[i].dx*gamerate;
rock[i].y += rock[i].dy*gamerate + yscroll;
- if(rock[i].y > YSIZE || rock[i].y < -rock[i].image->h) {
- if(rock[i].dead) {
- area -= rock[i].shape->area;
- rock[i].dead = 0;
- rock[i].active = 0;
- } else {
- // wrap
- rock[i].y = (YSIZE - rock[i].image->h) - rock[i].y;
- rock[i].y += (rock[i].dy*gamerate + yscroll) * 1.01;
- }
- }
- if(rock[i].x < -rock[i].image->w || rock[i].x > XSIZE) {
- area -= rock[i].shape->area;
- rock[i].active = 0;
- rock[i].dead = 0;
+ // clip
+ if(rock[i].y < -rock[i].image->h || rock[i].y > YSIZE) {
+ // rock[i].active = 0;
+ rock[i].y = (YSIZE - rock[i].image->h) - rock[i].y;
+ rock[i].y += (rock[i].dy*gamerate + yscroll) * 1.01;
}
+ if(rock[i].x < -rock[i].image->w || rock[i].x > XSIZE) rock[i].active = 0;
}
}
}
void
-reset_rocks(void)
-{
- int i;
-
- area = 0;
- for(i = 0; i<MAXROCKS; i++ ) {
- rock[i].active = 0;
- rock[i].dead = 0;
- }
-
- rockrate = 54.0;
- rockspeed = 5.0;
-}
-
-void
draw_rocks(void)
{
int i;
// This makes it so your explosion from dying magically doesn't leave
// any rocks that aren't moving much on the x axis. If onlyslow is set,
// only rocks that are barely moving will be pushed.
- if(onlyslow && (!rock[i].dead || rock[i].dx < -4 || rock[i].dx > 3)) {
- continue;
- }
+ if(onlyslow && (rock[i].dx < -4 || rock[i].dx > 3)) continue;
dx = rock[i].x - x;
dy = rock[i].y - y;
n *= 20;
rock[i].dx += rockrate*(dx+30)/n;
rock[i].dy += rockrate*dy/n;
- rock[i].dead = 1;
}
}
}