📄 star.c
字号:
/** * Do a pretty transition from one level to another. */static void star_transition_update(void){ int center_x = LCD_WIDTH / 2; int lcd_demi_width = LCD_WIDTH / 2; int center_y = LCD_HEIGHT / 2; int x; int y = 0; int var_y = 0; for (x = 1 ; x < lcd_demi_width ; x++) { var_y += LCD_HEIGHT; if (var_y > LCD_WIDTH) { var_y -= LCD_WIDTH; y++; } rb->lcd_update_rect(center_x - x, center_y - y, x * 2, y * 2); rb->sleep(STAR_SLEEP); } rb->lcd_update();}/** * Display information board of the current level. */static void star_display_board_info(void){ int label_offset_y = label_offset_y = LCD_HEIGHT - char_height; char str_info[32]; rb->snprintf(str_info, sizeof(str_info), "L:%02d S:%02d C:", current_level, star_count); rb->lcd_putsxy(0, label_offset_y, str_info); if (control == STAR_CONTROL_BALL) rb->lcd_bitmap (ball_bmp, 103, label_offset_y + 1, STAR_TILE_SIZE, STAR_TILE_SIZE, true); else rb->lcd_bitmap (block_bmp, 103, label_offset_y + 1, STAR_TILE_SIZE, STAR_TILE_SIZE, true); rb->lcd_update_rect(0, label_offset_y, LCD_WIDTH, char_height);}/** * Load a level into board array. */static int star_load_level(int current_level){ int x, y; char *ptr_tab; ptr_tab = levels + current_level * STAR_LEVEL_SIZE; control = STAR_CONTROL_BALL; star_count = 0; rb->lcd_clear_display(); for (y = 0 ; y < STAR_HEIGHT ; y++) { for (x = 0 ; x < STAR_WIDTH ; x++) { board[y][x] = *ptr_tab; switch (*ptr_tab) { case STAR_VOID: break; case STAR_WALL: rb->lcd_bitmap (wall_bmp, STAR_OFFSET_X + x * STAR_TILE_SIZE, STAR_OFFSET_Y + y * STAR_TILE_SIZE, STAR_TILE_SIZE, STAR_TILE_SIZE, false); break; case STAR_STAR: rb->lcd_bitmap (star_bmp, STAR_OFFSET_X + x * STAR_TILE_SIZE, STAR_OFFSET_Y + y * STAR_TILE_SIZE, STAR_TILE_SIZE, STAR_TILE_SIZE, false); star_count++; break; case STAR_BALL: ball_x = x; ball_y = y; rb->lcd_bitmap (ball_bmp, STAR_OFFSET_X + x * STAR_TILE_SIZE, STAR_OFFSET_Y + y * STAR_TILE_SIZE, STAR_TILE_SIZE, STAR_TILE_SIZE, false); break; case STAR_BLOCK: block_x = x; block_y = y; rb->lcd_bitmap (block_bmp, STAR_OFFSET_X + x * STAR_TILE_SIZE, STAR_OFFSET_Y + y * STAR_TILE_SIZE, STAR_TILE_SIZE, STAR_TILE_SIZE, false); break; } ptr_tab++; } ptr_tab++; } star_display_board_info(); star_transition_update(); return 1;}/** * Run the game. */static int star_run_game(void){ int move_x = 0; int move_y = 0; int i; int label_offset_y; label_offset_y = LCD_HEIGHT - char_height; if (!star_load_level(current_level)) return 0; while (true) { move_x = 0; move_y = 0; switch (rb->button_get(true)) { case BUTTON_OFF: return PLUGIN_OK; case BUTTON_LEFT: move_x = -1; break; case BUTTON_RIGHT: move_x = 1; break; case BUTTON_UP: move_y = -1; break; case BUTTON_DOWN: move_y = 1; break; case BUTTON_F1: if (current_level > 0) { current_level--; star_load_level(current_level); } continue; case BUTTON_F2: star_load_level(current_level); continue; case BUTTON_F3: if (current_level < STAR_LEVEL_COUNT - 1) { current_level++; star_load_level(current_level); } continue; case BUTTON_PLAY: case BUTTON_ON: if (control == STAR_CONTROL_BALL) control = STAR_CONTROL_BLOCK; else control = STAR_CONTROL_BALL; star_display_board_info(); continue; default: continue; } if (control == STAR_CONTROL_BALL) { board[ball_y][ball_x] = STAR_VOID; while ((board[ball_y + move_y][ball_x + move_x] == STAR_VOID || board[ball_y + move_y][ball_x + move_x] == STAR_STAR)) { for (i = 0 ; i < 7 ; i++) { rb->lcd_bitmap( ball_bmp, STAR_OFFSET_X + ball_x * STAR_TILE_SIZE + move_x * i, STAR_OFFSET_Y + ball_y * STAR_TILE_SIZE + move_y * i, STAR_TILE_SIZE, STAR_TILE_SIZE, true); rb->lcd_update_rect( STAR_OFFSET_X + ball_x * STAR_TILE_SIZE + move_x * i, STAR_OFFSET_Y + ball_y * STAR_TILE_SIZE + move_y * i, STAR_TILE_SIZE, STAR_TILE_SIZE); rb->sleep(STAR_SLEEP); } ball_x += move_x; ball_y += move_y; if (board[ball_y][ball_x] == STAR_STAR) { board[ball_y][ball_x] = STAR_VOID; star_count--; star_display_board_info(); } } board[ball_y][ball_x] = STAR_BALL; } else { board[block_y][block_x] = STAR_VOID; while (board[block_y + move_y][block_x + move_x] == STAR_VOID) { for (i = 0 ; i < 7 ; i++) { rb->lcd_bitmap( block_bmp, STAR_OFFSET_X + block_x * STAR_TILE_SIZE + move_x * i, STAR_OFFSET_Y + block_y * STAR_TILE_SIZE + move_y * i, STAR_TILE_SIZE, STAR_TILE_SIZE, true); rb->lcd_update_rect( STAR_OFFSET_X + block_x * STAR_TILE_SIZE + move_x * i, STAR_OFFSET_Y + block_y * STAR_TILE_SIZE + move_y * i, STAR_TILE_SIZE, STAR_TILE_SIZE); rb->sleep(STAR_SLEEP); } block_x += move_x; block_y += move_y; } board[block_y][block_x] = STAR_BLOCK; } if (star_count == 0) { current_level++; if (current_level == STAR_LEVEL_COUNT) { rb->lcd_clear_display(); star_display_text("Congratulation !", true); rb->lcd_update(); return 1; } star_load_level(current_level); } }}/** * Display the choice menu. */static int star_menu(void){ int move_y; int menu_y = 0; int i = 0; bool refresh = true; char anim_state = 0; unsigned char *menu[4] = {"Start", "Information", "Keys", "Exit"}; int menu_count = sizeof(menu) / sizeof(unsigned char *); int menu_offset_y; menu_offset_y = LCD_HEIGHT - char_height * menu_count; while (true) { if (refresh) { rb->lcd_clear_display(); rb->lcd_putsxy((LCD_WIDTH - char_width * rb->strlen(STAR_TITLE)) / 2, 0, STAR_TITLE); for (i = 0 ; i < menu_count ; i++) { rb->lcd_putsxy(15, menu_offset_y + char_height * i, menu[i]); } rb->lcd_update(); refresh = false; } move_y = 0; rb->lcd_bitmap(arrow_bmp[anim_arrow[(anim_state & 0x38) >> 3]], 2, menu_offset_y + menu_y * char_height, 7, 8, true); rb->lcd_update_rect (2, menu_offset_y + menu_y * 8, 8, 8); rb->sleep(STAR_SLEEP); anim_state++; switch (rb->button_get(false)) { case BUTTON_OFF: return PLUGIN_OK; case BUTTON_UP: if (menu_y > 0) move_y = -1; break; case BUTTON_DOWN: if (menu_y < 3) move_y = 1; break; case BUTTON_ON: case BUTTON_PLAY: case BUTTON_RIGHT: refresh = true; switch (menu_y) { case 0: if (!star_run_game()) return PLUGIN_OK; break; case 1: star_display_text( "INFO\n\n" "Take all \"o\" to go to the next level. " "You can toggle control with the block to " "use it as a mobile wall. The block cannot " "take \"o\".", true); break; case 2: star_display_text("KEYS\n\n" "[ON] Toggle Ctl.\n" "[OFF] Exit\n" "[F1] Prev. level\n" "[F2] Reset level\n" "[F3] Next level", true); break; case 3: return PLUGIN_OK; } break; case SYS_USB_CONNECTED: rb->usb_screen(); return PLUGIN_USB_CONNECTED; default: continue; } for (i = 0 ; i < char_height ; i++) { rb->lcd_clearrect (2, 30, 7, 4 * 8); rb->lcd_bitmap(arrow_bmp[anim_arrow[(anim_state & 0x38) >> 3]], 2, menu_offset_y + menu_y * 8 + move_y * i, 7, 8, false); rb->lcd_update_rect(2, 30, 8, 4 * 8); anim_state++; rb->sleep(STAR_SLEEP); } menu_y += move_y; }}/** * Main entry point */enum plugin_status plugin_start(struct plugin_api* api, void* parameter){ TEST_PLUGIN_API(api); (void)parameter; rb = api; /* get the size of char */ rb->lcd_setfont(FONT_SYSFIXED); if (char_width == -1) rb->lcd_getstringsize("a", &char_width, &char_height); /* display choice menu */ return star_menu();}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -