📄 draw.c
字号:
state->splash->w, state->splash->h, state->splash->p, 0, 0, GR_ALPHA_BLEND);}/* Draw the specified portion of the specified brick onto the canvas, reducing * the opacity of the alpha channel if it is a multiple-hit brick which has * been hit at least once already. */void draw_brick(nbstate *state, grid *g, int x, int y, int w, int h){ GR_ALPHA_ID a; int alpha = 0; /* If there is no brick at this grid location, return to caller. */ if(!g->b) return; /* If it's a 2 hit brick and it's been hit once already, set the level * to about 60%. If it's a 3 hit brick and it's been hit once, set it * to about 75%. If it's a 3 hit brick and it's been hit twice, set it * to just over 50% (not below because then the transparency only * alpha channel drivers would draw it as completely transparent): */ if(g->b->flags & BRICK_FLAG_2_HITS && g->hits == 1) alpha = 155; else if(g->b->flags & BRICK_FLAG_3_HITS) { if(g->hits == 1) alpha = 190; else if(g->hits == 2) alpha = 128; } /* If a reduced opacity level was chosen, draw a lighter version of * the sprites alpha channel and use that. */ if(alpha) { /* Start with black, */ GrSetGCForeground(state->gc, GR_COLOR_BLACK); GrFillRect(state->brickalpha, state->gc, 0, 0, state->brickwidth, state->brickheight); /* and add the specified percentage of the original alpha * channel to it: */ GrCopyArea(state->brickalpha, state->gc, 0, 0, state->brickwidth, state->brickheight, g->b->s->a, 0, 0, GR_CONST_ADD | alpha); a = state->brickalpha; /* Normal opacity, so just use the sprites alpha channel directly. */ } else a = g->b->s->a; /* Copy the specified portion of the brick onto the canvas with the * chosen alpha channel. */ GrCopyAreaAlpha(state->canvas, state->gc, a, g->x + x, g->y + y, w, h, g->b->s->p, x, y, GR_ALPHA_BLEND);}/* Draw the bricks which are in the specified area onto the canvas. * This is a modified version of draw_tiled_background(), so see that for the * comments on how it works. */void draw_bricks(nbstate *state, int x, int y, int w, int h){ int tilex = 0, tiley = 0, fromx, fromy; int destwidth, destheight, srcwidth, srcheight, cwidth, cheight; int offy = state->scores.h + state->ball.s->h + (BALLS_BORDER * 2); int dwidth = state->canvaswidth; int dheight = state->height * state->brickheight; int swidth = state->brickwidth; int sheight = state->brickheight; grid *g = state->grid - 1; y -= offy; if(y < 0) y = 0; if(swidth > dwidth) srcwidth = dwidth; else srcwidth = swidth; if(sheight > dheight) srcheight = dheight; else srcheight = sheight; for(;tiley < dheight; tiley += srcheight, tilex = 0) { if(tiley > (y + h)) return; if(y > (tiley + srcheight)) { g += state->width; continue; } if((tiley + srcheight) > dheight) destheight = dheight - tiley; else destheight = srcheight; for(;tilex < dwidth; tilex += srcwidth) { g++; if(tilex > (x + w)) continue; if(x > (tilex + srcwidth)) continue; if((tilex + srcwidth) > dwidth) destwidth = dwidth - tilex; else destwidth = srcwidth; if((tilex >= x) && ((tilex + destwidth) <= (x + w))) { fromx = 0; cwidth = destwidth; } else { if(x > tilex) { fromx = x - tilex; cwidth = destwidth - fromx; } else { fromx = 0; cwidth = x + w - tilex; } if(cwidth > w) cwidth = w; if(cwidth > destwidth) cwidth = destwidth; } if((tiley >= y)&&((tiley + destheight)<=(y + h))) { fromy = 0; cheight = destheight; } else { if(y > tiley) { fromy = y - tiley; cheight = destheight - fromy; } else { fromy = 0; cheight = y + h - tiley; } if(cheight > h) cheight = h; if(cheight > destheight) cheight = destheight; } if((cwidth > 0) && (cheight > 0)) draw_brick(state, g, fromx, fromy, cwidth, cheight); } }}/* Draw the bat onto the canvas. */void draw_bat(nbstate *state){ GrCopyAreaAlpha(state->canvas, state->gc, state->bats[state->bat]->a, state->batx - (state->batwidths[state->bat] / 2), state->canvasheight - state->batheight, state->batwidths[state->bat], state->batheight, state->bats[state->bat]->p, 0, 0, GR_ALPHA_BLEND);}/* Draw the ball onto the canvas and remember the current position so when the * ball is moved, the old ball position is available to figure out where to * redraw the background in order to erase the old ball. */void draw_ball(nbstate *state){ GrCopyAreaAlpha(state->canvas, state->gc, state->ball.s->a, state->ball.x, state->ball.y, state->ball.s->w, state->ball.s->w, state->ball.s->p, 0, 0, GR_ALPHA_BLEND); state->ball.lx = (int)state->ball.x; state->ball.ly = (int)state->ball.y;}/* Draw the balls bar at the top of the screen below the scores strip. */void draw_balls(nbstate *state){ int i, s, x, y; /* Precalculate some values. */ s = state->ball.s->w; x = BALLS_BORDER; y = state->scores.h + BALLS_BORDER; for(i = 0; i < state->numballs; i++) { /* For each ball. */ /* If this ball will run off the edge of the canvas, don't * draw it and return. */ if(x + s + BALLS_BORDER > state->canvaswidth) return; /* Draw the ball. */ GrCopyAreaAlpha(state->canvas, state->gc, state->ball.s->a, x, y, s, s, state->ball.s->p, 0, 0, GR_ALPHA_BLEND); /* Move onto the next ball position. */ x += s + BALLS_BORDER; }}/* Draw the scores bar across the top of the screen. This is somewhat * complicated because we generate the alpha channel on the fly in order * to make the text itself have 100% opacity while the text background is * blended onto the canvas over the background image with partial * transparency. This makes the background of the text area darker and the * text easier to see, while still allowing you to see the background image * pattern through it. */void draw_scores(nbstate *state){ char buf[128]; /* Generate the text that will be printed into the score area. */ snprintf(buf, 128, "Score: %d HiScore: %d Level: %d", state->scores.s, state->scores.hi, state->level); /* Redraw the background that will be underneath the text. */ draw_background(state, 0, 0, state->canvaswidth, state->scores.h); /* Fill the pixmap with the text background colour. */ GrSetGCForeground(state->gc, SCORE_BGCOLOUR); GrFillRect(state->scores.p, state->gc, 0, 0, state->canvaswidth, state->scores.h); /* Draw the text onto the pixmap. */ GrSetGCForeground(state->gc, SCORE_FGCOLOUR); GrSetGCBackground(state->gc, SCORE_BGCOLOUR); GrText(state->scores.p, state->gc, SCORE_BORDER, SCORE_BORDER, buf, -1, GR_TFTOP); /* Draw the text onto the pixmap using white (100% opacity) for the * text and the alpha shade for the background. */ GrSetGCForeground(state->gc, SCORE_ALPHACOLOUR); GrFillRect(state->scores.a, state->gc, 0, 0, state->canvaswidth, state->scores.h); GrSetGCForeground(state->gc, GR_COLOR_WHITE); GrSetGCBackground(state->gc, SCORE_ALPHACOLOUR); GrText(state->scores.a, state->gc, SCORE_BORDER, SCORE_BORDER, buf, -1, GR_TFTOP); /* Blend the scores pixmap onto the canvas over the clean background * using the newly created alpha channel. */ GrCopyAreaAlpha(state->canvas, state->gc, state->scores.a, 0, 0, state->canvaswidth, state->scores.h, state->scores.p, 0, 0, GR_ALPHA_BLEND);}/* Draw the specified portion of the specified power onto the canvas. */void draw_power(nbstate *state, power *p, int x, int y, int w, int h){ sprite *s = state->powersprites[p->type]; GrCopyAreaAlpha(state->canvas, state->gc, s->a, x, y, w, h, s->p, x - p->x, y - p->y, GR_ALPHA_BLEND);}/* Copy the specified area of the canvas onto the output window. */void draw_canvas(nbstate *state, int x, int y, int w, int h){ GrCopyArea(state->wid, state->gc, x, y, w, h, state->canvas, x, y, 0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -