void display() { const int win_width = glutGet(GLUT_WINDOW_WIDTH); const int win_height = glutGet(GLUT_WINDOW_HEIGHT); const float win_aspect = (float)win_width / (float)win_height; glViewport(0, 0, win_width, win_height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if(win_aspect > RATIO) { glOrtho(-win_aspect, win_aspect, -1., 1., -1., 1.); } else { glOrtho(-RATIO, RATIO, -RATIO/win_aspect, RATIO/win_aspect, -1., 1.); } glMatrixMode(GL_MODELVIEW); glClearColor(0., 0., 1., 1.); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBegin(GL_QUADS); glColor3f(1,1,1); glVertex2f(-RATIO, -1); glVertex2f(RATIO, -1); glVertex2f(RATIO, 1); glVertex2f(-RATIO, 1); glEnd(); draw_bricks(); paddle_draw(); ball_draw(); glutSwapBuffers(); // GLUT doesn't offer cross plattform timing // assume 60Hz refresh rate T_last_frame = 1./60.; }
void boucle_principal(t_bal *bal, t_brick *brick, t_env *e) { t_seg s; while (1) { if (map_end(e)) change_map(e); if (glfwWindowShouldClose(e->window)) break ; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); draw_bricks(e, brick); draw_seg(&s, e); if (e->space == 0) bal->x1 = e->x_bar + 0.125; draw_circle(bal, e); draw_barre(e->x_bar, -0.90); if (e->space == 1 && e->pauz == 1) move_bal(bal, e); glfwSwapBuffers(e->window); glfwPollEvents(); } }
/* Called every animation frame to move all of the power boxes down and perform * collision detection, etc. Doesn't draw the results to the canvas unless the * power collides with something and is destroyed. */ void animate_powers(nbstate *state) { sprite *s; power *p, *pnext; /* For each power in the list: */ for(p = state->powers; p; p = pnext) { /* Remember the next item first, because we may destroy this * power, and then it would be wrong to use the pointer to * find the pointer to the next one in the list: */ pnext = p->next; /* Find the sprite for this power type: */ s = state->powersprites[p->type]; /* Clear the old power away: */ draw_background(state, p->x, p->y, s->w, s->h); /* Redraw any bricks we may have accidentally erased: */ draw_bricks(state, p->x, p->y, s->w, s->h); /* Move it down: */ p->y += state->powerv; /* If it has reached the bottom of the screen: */ if(p->y + s->h > state->canvasheight) { /* Copy the erased region to the screen: */ draw_canvas(state, p->x, p->y - state->powerv, s->w, s->h); /* Destroy the power structure: */ destroy_power(state, p); /* Check if it will collide with the bat: */ } else if(p->y + s->h > state->canvasheight - state->batheight && p->x + s->w > state->batx - (state->batwidths[state->bat] / 2) && p->x < state->batx + (state->batwidths[state->bat] / 2)) { /* Copy the erased region to the screen: */ draw_canvas(state, p->x, p->y - state->powerv, s->w, s->h); /* Activate the relevant power: */ power_collision(state, p); /* Destroy the power structure: */ destroy_power(state, p); } else { /* Redraw it in its new location: */ draw_power(state, p, p->x, p->y, s->w, s->h); } } /* Redraw the ball in case we accidentally drew over it: */ redraw_ball(state); /* Copy all the modified areas to the output window: */ for(p = state->powers; p; p = p->next) draw_canvas(state, p->x, p->y - state->powerv, s->w, s->h + state->powerv); }
/* 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); }