📄 bowl.c
字号:
bowl->unknown_preview->w, bowl->unknown_preview->h ); SOURCE( bowl->unknown_preview, 0, 0 ); alpha_blit_surf( bowl->preview_alpha ); add_refresh_rect( bowl->preview_center_sx - bowl->unknown_preview->w / 2, bowl->preview_center_sy - bowl->unknown_preview->h / 2, bowl->unknown_preview->w, bowl->unknown_preview->h ); } /* score, lines, level */ bowl->font->align = ALIGN_X_RIGHT | ALIGN_Y_TOP; sprintf( aux, "%.0f", counter_get_approach( bowl->score ) ); write_text( bowl->font, sdl.screen, bowl->score_sx + bowl->score_sw - 4, bowl->score_sy + 1, aux, OPAQUE ); bowl->font->align = ALIGN_X_RIGHT | ALIGN_Y_BOTTOM; sprintf( aux, "%i Lvl: %i", bowl->lines, bowl->level ); write_text( bowl->font, sdl.screen, bowl->score_sx + bowl->score_sw - 4, bowl->score_sy + bowl->score_sh, aux, OPAQUE );}void bowl_update( Bowl *bowl, int ms, int game_over ){ int old_bottom_y = ( (int)bowl->block.cur_y + bowl->block_size - 1 ) / bowl->block_size; int target_x; /* target screen position within bowl */ int hori_movement = 0; int new_rot; /* SCORE */ counter_update( &bowl->score, ms ); if ( game_over ) return; /* BLOCK */ if ( !bowl->hide_block ) { /* fake a key event to rotate with cpu */ if ( !bowl->controls && bowl->cpu_dest_rot != bowl->block.rot_id ) if ( delay_timed_out( &bowl->cpu_rot_delay, ms ) ) bowl->stored_key = KEY_ROT_LEFT; /* if CPU may drop in one p-cycle set key */ if ( bowl_cpu_may_drop( bowl ) ) bowl->stored_key = KEY_DROP; /* handle stored key */ switch ( bowl->stored_key ) { case KEY_LEFT: case KEY_RIGHT: /* * horizontal movement has a delay which is nullified by pressing * left or right key. bowl::block::x is set directly and bowl::block::cur_x * do only approach this position if smooth movement is set. */ delay_force_time_out( &bowl->block_hori_delay ); break; case KEY_ROT_LEFT: new_rot = bowl->block.rot_id - 1; if ( new_rot < 0 ) new_rot = 3; if ( bowl_validate_block_pos( bowl, bowl->block.x, bowl->block.check_y, new_rot, 0 ) ) bowl->block.rot_id = new_rot; bowl_compute_help_pos( bowl ); break; case KEY_ROT_RIGHT: new_rot = bowl->block.rot_id + 1; if ( new_rot == 4 ) new_rot = 0; if ( bowl_validate_block_pos( bowl, bowl->block.x, bowl->block.check_y, new_rot, 0 ) ) bowl->block.rot_id = new_rot; bowl_compute_help_pos( bowl ); break; case KEY_DROP: bowl_drop_block( bowl ); break; } /* update horizontal bowl position */ if ( delay_timed_out( &bowl->block_hori_delay, ms ) ) { if ( ( bowl->controls && keystate[bowl->controls->left] ) || ( !bowl->controls && bowl->cpu_dest_x < bowl->block.x ) ) if ( bowl_validate_block_pos( bowl, bowl->block.x - 1, bowl->block.check_y, bowl->block.rot_id, 2 ) ) { bowl->block.x--; hori_movement = 1; } if ( ( bowl->controls && keystate[bowl->controls->right] ) || ( !bowl->controls && bowl->cpu_dest_x > bowl->block.x ) ) if ( bowl_validate_block_pos( bowl, bowl->block.x + 1, bowl->block.check_y, bowl->block.rot_id , 2) ) { bowl->block.x++; hori_movement = 1; } if ( hori_movement ) { bowl_compute_help_pos( bowl );#ifdef SOUND //if ( !bowl->mute ) sound_play( bowl->wav_leftright );#endif } } /* update horizontal float&screen position */ if ( config.smooth_hori ) { target_x = bowl->block.x * bowl->block_size; if ( target_x != (int)bowl->block.cur_x ) { if ( (int)bowl->block.cur_x > target_x ) { bowl->block.cur_x -= bowl->block_hori_vel * ms; if ( (int)bowl->block.cur_x < target_x ) bowl->block.cur_x = target_x; } else { bowl->block.cur_x += bowl->block_hori_vel * ms; if ( (int)bowl->block.cur_x > target_x ) bowl->block.cur_x = target_x; } bowl->block.sx = (int)bowl->block.cur_x + bowl->sx; } } else if ( hori_movement ) bowl->block.sx = bowl->block.x * bowl->block_size + bowl->sx; /* update vertical float position */ if ( !bowl->controls && !bowl->cpu_down ) if ( delay_timed_out( &bowl->cpu_delay, ms ) ) bowl->cpu_down = 1; if ( ( bowl->controls && keystate[bowl->controls->down] ) || bowl_cpu_may_move_down( bowl ) ) bowl->block.cur_y += bowl->block_drop_vel * ms; else bowl->block.cur_y += bowl->block_vert_vel * ms; /* update vertical bowl position */ bowl->block.y = (int)bowl->block.cur_y / bowl->block_size; /* update check y */ if ( config.block_by_block || config.async_col_check ) bowl->block.check_y = bowl->block.y * bowl->block_size; else bowl->block.check_y = (int)bowl->block.cur_y; /* if we entered a new tile check if block stops */ if ( old_bottom_y != ( bowl->block.cur_y + bowl->block_size - 1 ) / bowl->block_size ) bowl_check_block_insertion( bowl ); /* update vertical screen position */ if ( config.block_by_block ) bowl->block.sy = bowl->block.y * bowl->block_size + bowl->sy; else { /* to allow horizontal movement after the block touched the ground we allow moving into the next block. this shouldn't be seen, of course */ if ( !config.async_col_check || bowl_validate_block_pos( bowl, bowl->block.x, (int)bowl->block.cur_y, bowl->block.rot_id, 0) ) bowl->block.sy = (int)bowl->block.cur_y + bowl->sy; else bowl->block.sy = bowl->block.y * bowl->block_size + bowl->sy; } /* clear stored key */ bowl->stored_key = -1; } /* CHECK SPECIAL EVENTS */ if ( !bowl->paused ) { if ( delay_timed_out( &bowl->add_delay, ms ) ) { if ( bowl->add_lines ) { bowl_add_line( bowl, bowl->add_line_holes ); bowl->draw_contents = 1; } if ( bowl->add_tiles ) bowl_add_tile( bowl ); } } /* HELP ALPHA */ bowl->help_alpha += bowl->help_alpha_change * ms; if ( bowl->help_alpha_change > 0 ) { if ( bowl->help_alpha > 255 ) { bowl->help_alpha_change = -bowl->help_alpha_change; bowl->help_alpha = 255; } } else { if ( bowl->help_alpha < 0 ) { bowl->help_alpha_change = -bowl->help_alpha_change; bowl->help_alpha = 0; } } /* PREVIEW ALPHA */ bowl->preview_alpha += bowl->preview_alpha_change * ms; if ( bowl->preview_alpha_change > 0 ) { if ( bowl->preview_alpha > 255 ) { bowl->preview_alpha_change = -bowl->preview_alpha_change; bowl->preview_alpha = 255; } } else { if ( bowl->preview_alpha < 0 ) { bowl->preview_alpha_change = -bowl->preview_alpha_change; bowl->preview_alpha = 0; } }}/*====================================================================Draw a single bowl tile.====================================================================*/void bowl_draw_tile( Bowl *bowl, int i, int j ){ int x = bowl->sx + i * bowl->block_size; int y = bowl->sy + j * bowl->block_size; int offset; if ( bowl->blind ) return; if ( bowl->contents[i][j] != -1 ) { offset = bowl->contents[i][j] * bowl->block_size; DEST( offscreen, x, y, bowl->block_size, bowl->block_size ); SOURCE( bowl->blocks, offset, 0 ); blit_surf(); } else { DEST( offscreen, x, y, bowl->block_size, bowl->block_size ); SOURCE( bkgnd, x, y ); blit_surf(); } DEST( sdl.screen, x, y , bowl->block_size, bowl->block_size ); SOURCE( offscreen, x, y ); blit_surf(); add_refresh_rect( x, y, bowl->block_size, bowl->block_size );}/*====================================================================Draw bowl to offscreen and screen.====================================================================*/void bowl_draw_contents( Bowl *bowl ){ int i, j; int x = bowl->sx, y = bowl->sy, offset; if ( bowl->blind ) return; for ( j = 0; j < bowl->h; j++ ) { for ( i = 0; i < bowl->w; i++ ) { if ( bowl->contents[i][j] != -1 ) { offset = bowl->contents[i][j] * bowl->block_size; DEST( offscreen, x, y, bowl->block_size, bowl->block_size ); SOURCE( bowl->blocks, offset, 0 ); blit_surf(); } else { DEST( offscreen, x, y, bowl->block_size, bowl->block_size ); SOURCE( bkgnd, x, y ); blit_surf(); } DEST( sdl.screen, x, y , bowl->block_size, bowl->block_size ); SOURCE( offscreen, x, y ); blit_surf(); x += bowl->block_size; } x = bowl->sx; y += bowl->block_size; } add_refresh_rect( bowl->sx, bowl->sy, bowl->sw, bowl->sh );}/*====================================================================Draw frames and fix text to bkgnd.====================================================================*/void bowl_draw_frames( Bowl *bowl ){ /* data box */ int dx = bowl->sx + 10, dy = bowl->sy + bowl->sh + 20, dw = bowl->sw - 20, dh = 50; /* bowl itself */ draw_3dframe( bkgnd, bowl->sx, bowl->sy, bowl->sw, bowl->sh, 6 ); /* name&score&level */ draw_3dframe( bkgnd, dx, dy, dw, dh, 4 ); bowl->font->align = ALIGN_X_LEFT | ALIGN_Y_TOP; write_text( bowl->font, bkgnd, dx + 4, dy + 4, "Player:", OPAQUE ); bowl->font->align = ALIGN_X_RIGHT | ALIGN_Y_TOP; write_text( bowl->font, bkgnd, dx + dw - 4, dy + 4, bowl->name, OPAQUE ); bowl->font->align = ALIGN_X_LEFT | ALIGN_Y_CENTER; write_text( bowl->font, bkgnd, dx + 4, dy + dh / 2, "Score:", OPAQUE ); bowl->font->align = ALIGN_X_LEFT | ALIGN_Y_BOTTOM; write_text( bowl->font, bkgnd, dx + 4, dy + dh - 4, "Lines:", OPAQUE ); /* preview */ if ( bowl->preview_center_sx != -1 ) draw_3dframe( bkgnd, bowl->preview_center_sx - 2 * bowl->block_size - 2, bowl->preview_center_sy - 2 * bowl->block_size - 2, 4 * bowl->block_size + 4, 4 * bowl->block_size + 4, 4 ); /* part that is updated when redrawing score/level */ bowl->score_sx = dx + dw / 2 - 36; bowl->score_sy = dy + bowl->font->height + 4; bowl->score_sw = dw / 2 + 36; bowl->score_sh = dh - bowl->font->height - 8;}/*====================================================================Toggle pause of bowl.====================================================================*/void bowl_toggle_pause( Bowl *bowl ){ if ( bowl->paused ) { /* unpause */ bowl->hide_block = 0; bowl_draw_contents( bowl ); bowl->paused = 0; } else { /* pause */ bowl->hide_block = 1; DEST( offscreen, bowl->sx, bowl->sy, bowl->sw, bowl->sh ); SOURCE( bkgnd, bowl->sx, bowl->sy ); blit_surf(); bowl->font->align = ALIGN_X_CENTER | ALIGN_Y_CENTER; write_text( bowl->font, offscreen, bowl->sx + bowl->sw / 2, bowl->sy + bowl->sh / 2, "Paused", OPAQUE ); DEST( sdl.screen, bowl->sx, bowl->sy, bowl->sw, bowl->sh ); SOURCE( offscreen, bowl->sx, bowl->sy ); blit_surf(); add_refresh_rect( bowl->sx, bowl->sy, bowl->sw, bowl->sh ); bowl->paused = 1; }}/*====================================================================Play an optimized mute game. (used for stats)====================================================================*/void bowl_quick_game( Bowl *bowl, int aggr ){ int old_level; int line_score; int line_count; int line_y[4]; int i, j, l; CPU_Data cpu_data; /* constant cpu data */ cpu_data.bowl_w = bowl->w; cpu_data.bowl_h = bowl->h; cpu_data.aggr = aggr; /* reset bowl */ for ( i = 0; i < bowl->w; i++ ) { for ( j = 0; j < bowl->h; j++ ) bowl->contents[i][j] = -1; } bowl->score.value = 0; bowl->lines = bowl->level = bowl->use_figures = 0; bowl->game_over = 0; bowl->add_lines = bowl->add_tiles = 0; bowl->next_block_id = rand() % BLOCK_COUNT; while ( !bowl->game_over ) { /* get next block */ bowl->block.id = bowl->next_block_id; do { bowl->next_block_id = rand() % BLOCK_COUNT; } while ( bowl->next_block_id == bowl->block.id ); /* compute cpu dest */ cpu_data.original_block = &block_masks[bowl->block.id]; cpu_data.original_preview = &block_masks[bowl->next_block_id]; for ( i = 0; i < bowl->w; i++ ) for ( j = 0; j < bowl->h; j++ ) cpu_data.original_bowl[i][j] = ( bowl->contents[i][j] != -1 ); cpu_analyze_data( &cpu_data ); /* insert -- no additional checks as there is no chance for an illegal block else the fucking CPU sucks!!!! */ for ( i = 0; i < 4; i++ ) { for ( j = 0; j < 4; j++ ) if ( block_masks[bowl->block.id].mask[cpu_data.dest_rot][i][j] ) { if ( j + cpu_data.dest_y < 0 ) { bowl->game_over = 1; break; } bowl->contents[i + cpu_data.dest_x][j + cpu_data.dest_y] = 1; } if ( bowl->game_over ) break; } if ( bowl->game_over ) break; /* check for completed lines */ line_count = 0; for ( j = 0; j < bowl->h; j++ ) { for ( i = 0; i < bowl->w; i++ ) { if ( bowl->contents[i][j] == -1 ) break; } if ( i == bowl->w ) line_y[line_count++] = j; } for ( j = 0; j < line_count; j++ ) for ( i = 0; i < bowl->w; i++ ) { for ( l = line_y[j]; l > 0; l-- ) bowl->contents[i][l] = bowl->contents[i][l - 1]; bowl->contents[i][0] = -1; } /* score */ line_score = 100 * ( bowl->level + 1 ); for ( i = 0; i < line_count; i++ ) { bowl->score.value += line_score; line_score *= 2; } /* line and level update */ old_level = bowl->lines / 10; bowl->lines += line_count; if ( old_level != bowl->lines / 10 ) { /* new level */ bowl->level++; bowl_set_vert_block_vel( bowl ); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -