Пример #1
0
/* Called whenever a ball is lost, either by it falling off the bottom of the
 * screen, or the player pressing the "suicide key". */
void lost_ball(nbstate *state)
{
	/* Decrement the balls count and if there are none left: */
	if(!state->numballs--) {
		/* Go to the "game lost" state and update the high score if
		 * appropriate: */
		state->state = STATE_GAMELOST;
		/* Update the high score and save it if necessary: */
		save_hiscore(state);
		/* This could probably be done better by just drawing the
		 * splash- set_level_active() redraws the entire game area: */
		set_level_active(state);
		return;
	}

	/* Erase the balls line at the top of the screen: */
	draw_background(state, 0, state->scores.h, state->canvaswidth,
			state->ball.s->h + (BALLS_BORDER * 2));
	/* Draw the balls again, but with one less than there was before: */
	draw_balls(state);
	/* Copy the balls row to the output window: */
	draw_canvas(state, 0, state->scores.h, state->canvaswidth,
				state->ball.s->h + (BALLS_BORDER * 2));
	/* Park the new ball and erase the old one: */
	park_ball(state);
	move_ball(state);
	/* Redraw the bat. This is a bit of a hack because sometimes when the
	 * ball falls below the top of the bat on its way to the bottom of the
	 * screen it can clip the bat and erase a bit of it. This redraws the
	 * bat to hide that: */
	draw_bat(state);
	/* Copy the redrawn bat to the output window: */
	draw_canvas(state, state->batx - (state->batwidths[state->bat] / 2),
			state->canvasheight - state->batheight,
			state->batwidths[state->bat], state->batheight);
}
Пример #2
0
int main(int argc, char** argv)
{
  SDL_Event event;

  int keypress = 0;
  int t = 0;
  
  // Init everything
  sdl_init();
  init_sin_table();
  
  // Init random number generator
  srand(clock());
  
  // Init balls
  for(int i = 0; i < NUM_BALLS; i++)
    reset_ball(i);
  
  // Create sprites
  ball_surface[0] = sprite_create_ball(1.0, 0.0, 0.0);
  ball_surface[1] = sprite_create_ball(0.0, 1.0, 0.0);
  ball_surface[2] = sprite_create_ball(0.0, 0.0, 1.0);
  
  // Loop until the end
  while(!keypress) 
  {
    // Lock SDL surface if needed
    if(SDL_MUSTLOCK(screen)) 
      if(SDL_LockSurface(screen) < 0)
	exit(EXIT_FAILURE);
  
    // Draw the plasma
    draw_balls(screen, t);

    // Unlock the SDL surface if needed
    if(SDL_MUSTLOCK(screen))
      SDL_UnlockSurface(screen);
  
    // Flip surfaces
    SDL_UpdateRect(screen, 0, 0, 0, 0);
      
    // Handle SDL events
    while(SDL_PollEvent(&event)) 
    {      
      switch (event.type) 
      {
	case SDL_QUIT:
	case SDL_KEYDOWN:
	  keypress = 1;
	  break;
      }
    }
    
    // Sleep until next frame (25 FPS)
    usleep(40000);
    
    // Advance time
    t++;
  }
  
  // Exit gracefully
  SDL_Quit();
  return EXIT_SUCCESS;
}
Пример #3
0
void bBoard::draw()
{
    double vvx = cos(aa), vvy = sin(aa);
    
    if( idle() && camera_type == CT_FPS ) {
        GetCamera.set_eye( bVector3( ball[0]->pos.x - 2*view_r*vvx, 2.0, ball[0]->pos.y - 2*view_r*vvy ) );
        GetCamera.set_dst( bVector3( ball[0]->pos.x + 3*view_r*vvx, 0.2, ball[0]->pos.y + 3*view_r*vvy ) );
    } else {
        GetCamera.set_top_view();   
    }
    
    glDisable( GL_TEXTURE_2D );
    glColor3f( 0.0, 0.0, 0.0 );
    glBegin( GL_TRIANGLE_STRIP );
    for( int i=0; i<BOTTOM_SEGMENTS; ++i ) {
        glVertex3d( bottom_data[i].x, -0.01, bottom_data[i].y );
    }
    glEnd();
    
    if( idle() ) {
        glLineWidth( 2.0 );
        glEnable( GL_LINE_SMOOTH );
        glBegin( GL_LINES );
            glColor4d( 1.0, 0.3, 0.3, 1.0 );
            for(double k=0.0; k<4.0; k+=0.2) {
                glVertex3d( ball[0]->pos.x+vvx*k, ball[0]->radius, ball[0]->pos.y+vvy*k );
            }
        glEnd();
        glDisable( GL_BLEND );
    }
    
    glColor3f( 1.0, 1.0, 1.0 );
    
    board_shader.enable( bShader::B_FRAGMENT );
    board_shader.bind( bShader::B_FRAGMENT );
    
    glActiveTextureARB( GL_TEXTURE0_ARB );
    glEnable(GL_TEXTURE_2D);
    ball_num.bind();
    
    glMultiTexCoord3fARB( GL_TEXTURE1_ARB, 0.0f, 1.0f, 0.0f );
    glMultiTexCoord3fARB( GL_TEXTURE2_ARB, 0.0f, 0.1f, 0.0f );
    
    float lx = 0, ly = 0.3f, lz = 0;
    
    glEnable( GL_TEXTURE_2D );
    desk.bind();
    glBegin( GL_TRIANGLE_STRIP );
        glNormal3f( 0.0f, 1.0f, 0.0f );
        for( int i=0; i<DESK_SEGMENTS; ++i ) {
            glMultiTexCoord2dARB( GL_TEXTURE0_ARB, desk_data[i].tx, desk_data[i].ty ); 
            glMultiTexCoord3dARB( GL_TEXTURE3_ARB, desk_data[i].x-lx, 0.0-ly, desk_data[i].y-lz ); 
            glVertex3d( desk_data[i].x, 0.0, desk_data[i].y );
        }
    glEnd();
    
    Profiler.begin("ball_mgr::draw_bands");
    
    glActiveTextureARB( GL_TEXTURE0_ARB );
    glEnable(GL_TEXTURE_2D);
    band_tex.bind();
    
    glDisable( GL_CULL_FACE );
    for( int i=0; i<band_size; ++i ) {
        band[i]->draw();
    }
    
    glMultiTexCoord3dARB( GL_TEXTURE1_ARB, 0.0, 1.0, 0.0 ); 
        
    glBegin( GL_TRIANGLE_STRIP );
    for( int i=0; i<BOARD_SEGMENTS; ++i ) {
        glNormal3d( 0.0, 1.0, 0.0 );
        //glMultiTexCoord3fARB( GL_TEXTURE3_ARB, band_data[i].x, 0.4-ly, band_data[i].y );
        glMultiTexCoord2dARB( GL_TEXTURE0_ARB, ((i%2)==0)?0.0:1.0, 0.0 ); 
        glVertex3d( band_data[i].x,  0.4, band_data[i].y );
        //glMultiTexCoord3fARB( GL_TEXTURE3_ARB, board_data[i].x, 0.4-ly, board_data[i].y );
        glMultiTexCoord2dARB( GL_TEXTURE0_ARB, ((i%2)==0)?0.0:1.0, 1.0 ); 
        glVertex3d( board_data[i].x, 0.4, board_data[i].y );
    }
    //glMultiTexCoord3fARB( GL_TEXTURE3_ARB, band_data[0].x, 0.4-ly, band_data[0].y );
    glMultiTexCoord2fARB( GL_TEXTURE0_ARB, 1, 0 ); 
    glVertex3d( band_data[0].x,  0.4, band_data[0].y );
    //glMultiTexCoord3fARB( GL_TEXTURE3_ARB, board_data[0].x, 0.4-ly, board_data[0].y );
    glMultiTexCoord2fARB( GL_TEXTURE0_ARB, 1, 1 ); 
    glVertex3d( board_data[0].x, 0.4, board_data[0].y );
    glEnd();
    
    glColor3f(0.0f,0.0f,0.2f);
    glBegin( GL_TRIANGLE_STRIP );
    for( int i=0; i<BOARD_SEGMENTS; ++i ) {
        glVertex3d( band_data[i].x,  0.0, band_data[i].y );
        glVertex3d( band_data[i].x,  0.4, band_data[i].y );
    }
    glVertex3d( band_data[0].x,  0.0, band_data[0].y );
    glVertex3d( band_data[0].x,  0.4, band_data[0].y );
    glEnd();
    
    board_shader.disable( bShader::B_FRAGMENT );
    
    Profiler.begin("ball_mgr::draw_balls");
    draw_balls();
    Profiler.end("ball_mgr::draw_balls");
    
    if( power > 0.0 ) {
        bSystem::video_sys.set_matrix_2d();
        glDisable( GL_TEXTURE_2D );
        glDisable( GL_DEPTH_TEST );
        glColor3f( 0.0f, 0.0f, 0.0f );
        glBegin( GL_TRIANGLE_STRIP );
            glVertex2i( 100, 500 );        
            glVertex2i( 100, 560 );
            glVertex2i( 700, 500 );
            glVertex2i( 700, 560 );
        glEnd();
        
        glBegin( GL_TRIANGLE_STRIP );
            glColor3f( 0.0f, 1.0f, 0.0f );
            glVertex2i( 102, 502 );
            glVertex2i( 102, 558 );
            glColor3d( power/18.2, 1.0-power/18.2, 0.0f );
            glVertex2d( 100.0 + (598.0*power)/18.2, 502 );
            glVertex2d( 100.0 + (598.0*power)/18.2, 558 );
        glEnd();
    }
    
    Profiler.end("ball_mgr::draw_bands");
}
Пример #4
0
/* Make the current level active. This mainly consists of destroying the old
 * background image and loading the new one, destroying the splash image,
 * possibly loading a new splash image depending on the state, copying over the
 * new level data into the current level state, then redrawing the entire game
 * area. */
void set_level_active(nbstate *state)
{
	int i;
	level *lev;
	grid *g, *gg;
	int bgchanged;
	sprite *s = NULL;
	power *p, *pnext;
	GR_PIXMAP_ID ctmp;
	char *backgroundfile;

	/* Destroy the old splash image sprite: */
	destroy_sprite(state, state->splash);

	/* If we're on the title screen: */
	if(state->state == STATE_TITLESCREEN) {
		/* Set the background file to the title background file: */
		backgroundfile = state->titlebackground;
		/* Set the tiled state appropriately: */
		state->backgroundtiled = state->titlebackgroundtiled;
		/* Try to load the title screen splash graphic (if it doesn't
		 * work nothing bad will happen- load_sprite() will print an
		 * error message and draw_splash() will not draw anything.) */
		state->splash = load_sprite(state, state->titlesplash, -1, -1);
	} else { /* Not on the title screen. */
		/* Find the level structure for the current level number: */
		for(lev = state->levels, i = 1; i < state->level;
				lev = lev->next, i++);
		/* Set the current number of bricks and background info: */
		state->numbricks = lev->numbricks;
		backgroundfile = lev->backgroundname;
		state->backgroundtiled = lev->backgroundtiled;
		/* If we're in the "game won" state, try to load the appropriate
		 * splash image: */
		if(state->state == STATE_GAMEWON) {
			state->splash = load_sprite(state, state->gamewonsplash,
									-1, -1);
		/* If we're in the "game lost" state, try to load the
		 * appropriate splash image: */
		} else if(state->state == STATE_GAMELOST) {
			state->splash = load_sprite(state,
						state->gamelostsplash, -1, -1);
		} else { /* We must be in the STATE_RUNNING state. */
			/* No splash image: */
			state->splash = NULL;
			/* Copy this levels game grid into the current game
			 * grid: */
			g = state->grid;
			gg = lev->grid;
			for(i = 0; i < state->width * state->height; i++)
				*g++ = *gg++;
		}
	}

	/* If there was a background filename specified: */
	if(backgroundfile) {
		/* If there is a current background sprite with a filename
		 * and the filename is the same as the new background
		 * filename, the background file has not changed. Otherwise,
		 * assume that it has. */
		if(state->background && state->background->fname &&
				!strcmp(backgroundfile,
					state->background->fname))
			bgchanged = 0;
		else bgchanged = 1;
	/* No background filename was specified, so assume it has changed (to
	 * a blank black frame): */
	} else bgchanged = 1;

	/* If the background image has changed, try to load the new one: */
	if(bgchanged && !(s = load_sprite(state, backgroundfile, -1, -1))) {
		/* If it fails, try to make a new empty sprite and colour it
		 * in black (the 16*16 pixels is purely arbitrary- make it too
		 * large and it uses a lot of memory, make it too small and
		 * we spend ages painting hundreds of tiny tiles onto the
		 * background. */
		if(!(s = make_empty_sprite(state, backgroundfile, 16, 16))) {
			/* If that fails too (shouldn't happen under normal
			 * circumstances), issue a warning and keep the old
			 * background image sprite: */
			s = state->background;
		} else {
			/* Fill in the new dummy background black: */
			GrSetGCForeground(state->gc, GR_COLOR_BLACK);
			GrFillRect(s->p, state->gc, 0, 0, 16, 16);
			/* Make it tiled. FIXME: it would make more sense to
			 * have a "no background image" option which simply
			 * coloured in the background black: */
			state->backgroundtiled = 1;
		}
	}

	/* If we have made a new background image sprite: */
	if(bgchanged && s != state->background) {
		/* Destroy the old one: */
		destroy_sprite(state, state->background);
		/* Set the background to the new sprite: */
		state->background = s;
	}

	/* Empty the list of power boxes: */
	for(p = state->powers; p; p = pnext) {
		pnext = p->next;
		free(p);
	}
	state->powers = NULL;

	/* If fading has been requested, we want to fade the new level in, so
	 * swap the canvasses around so the current screen is the old canvas,
	 * then draw the new screen and make the new canvas, then start the
	 * process of fading it in: */
	if(state->faderate) {
		/* Swap the canvasses around: */
		ctmp = state->oldcanvas;
		state->oldcanvas = state->canvas;
		state->canvas = ctmp;

		/* Remember the state we're fading into: */
		state->nextstate = state->state;

		/* Go into the fading state: */
		state->state= STATE_FADING;

		/* Initialise the fade level as completely opaque: */
		state->fadelevel = 256;
	}

	/* Clear the whole game area to the background image: */
	draw_background(state, 0, 0, state->canvaswidth, state->canvasheight);

	/* If we're not on the title screen or fading to the title screen: */
	if(state->state != STATE_TITLESCREEN && !(state->state == STATE_FADING
				&& state->nextstate == STATE_TITLESCREEN)) {
		/* Draw the bricks: */
		draw_bricks(state, 0, 0, state->canvaswidth,
						state->canvasheight);
		draw_scores(state); /* Draw the scores bar. */
		draw_balls(state); /* Draw the row of balls. */
		draw_bat(state); /* Draw the bat. */
		/* Draw the current ball unless the game is over: */
		if(state->state != STATE_GAMELOST &&
				state->state != STATE_GAMEWON)
			draw_ball(state);
	}

	draw_splash(state); /* Draw the splash graphic (if there is one). */

	/* If we're fading, remember the new canvas and generate the first
	 * frame of the fade: */
	if(state->state == STATE_FADING) {

		/* Swap the canvasses around: */
		ctmp = state->newcanvas;
		state->newcanvas = state->canvas;
		state->canvas = ctmp;

		/* Reduce the opacity: */
		state->fadelevel -= state->faderate;

		/* Generate the first frame: */
		GrCopyArea(state->canvas, state->gc, 0, 0, state->canvaswidth,
				state->canvasheight, state->newcanvas, 0, 0, 0);
		GrCopyArea(state->canvas, state->gc, 0, 0, state->canvaswidth,
				state->canvasheight, state->oldcanvas, 0, 0,
				GR_CONST_BLEND | state->fadelevel);
	}

	/* Copy the entire redrawn canvas to the output window: */
	draw_canvas(state, 0, 0, state->canvaswidth, state->canvasheight);
}