diff --git a/README.md b/README.md index 2f7fa49..df716cc 100644 --- a/README.md +++ b/README.md @@ -35,8 +35,11 @@ logic mostly like https://git.crispypin.cc/CrispyPin/marble ``` - assets/ - levels/ - - chapter_01.json - - chapter_02.json + - 01_intro/ + - 01_output.json + - 02_cat.json + - 02_lists/ + - 02_parse.json - sandbox.json - user/ - solutions/ @@ -49,7 +52,46 @@ logic mostly like https://git.crispypin.cc/CrispyPin/marble - blueprints - blueprint_0.json ``` - +## formats +### level +`00_zeroes.json` +```json +{ + "id": "output", + "sortorder": 5, + "name": "Zeroes", + "description": "learn how to output data", + "init_board": "", + "stages": [{ + "input": [], + "output": [0, 0, 0, 0, 0, 0, 0, 0], + }] +} +``` +### solution +`00_zeroes/solution_0.json` +```json +{ + "level_id": "00_zeroes", + "solution_id": 0, + "name": "unnamed 1", + "board": "oo\nP*\n|-", + "score": { + "cycles": 8, + "tiles": 6, + "area": 6, + } +} +``` +### blueprint +`blueprints/blueprint_0.json` +```json +{ + "id": 0, + "name": "zero_printer", + "board": "o -B I\n> * < \n" +} +``` ## levels ### intro, basic mechanics diff --git a/assets/exit.png b/assets/exit.png deleted file mode 100644 index 2dca7a5..0000000 Binary files a/assets/exit.png and /dev/null differ diff --git a/src/editor.rs b/src/editor.rs index 7f116ff..bacdfa3 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -675,27 +675,23 @@ impl Editor { ); if self.exit_menu { - if simple_button(d, 4, 4, 32, 32) { - self.exit_state = ExitState::ExitAndSave; - } - self.tooltip.add(4, 4, 32, 32, "exit"); - draw_scaled_texture(d, textures.get("exit"), 4, 4, 2.); - if simple_button(d, 38, 4, 32, 32) { + if simple_button(d, 5, 5, 75, 30) { self.exit_menu = false; } - draw_scaled_texture(d, textures.get("cancel"), 38, 4, 2.); - self.tooltip.add(38, 4, 32, 32, "cancel"); + d.draw_text("cancel", 10, 10, 20, Color::WHITE); + if simple_button(d, 85, 5, 60, 30) { + self.exit_state = ExitState::ExitAndSave; + } + d.draw_text("exit", 90, 10, 20, Color::WHITE); } else { - if simple_button(d, 4, 4, 32, 32) { + if simple_button(d, 5, 5, 75, 30) { self.exit_menu = true; } - self.tooltip.add(4, 4, 32, 32, "exit"); - draw_scaled_texture(d, textures.get("exit"), 4, 4, 2.); - if simple_button(d, 38, 4, 32, 32) { + d.draw_text("exit", 10, 10, 20, Color::WHITE); + if simple_button(d, 85, 5, 60, 30) { self.exit_state = ExitState::Save; } - draw_scaled_texture(d, textures.get("save"), 38, 4, 2.); - self.tooltip.add(38, 4, 32, 32, "save"); + d.draw_text("save", 90, 10, 20, Color::WHITE); } if self.sim_state == SimState::Editing { diff --git a/src/main.rs b/src/main.rs index 760c56d..a999f71 100644 --- a/src/main.rs +++ b/src/main.rs @@ -40,7 +40,7 @@ struct Game { #[derive(Debug)] enum LevelListEntry { Level(Level), - Chapter(String, usize), + ChapterTitle(String), } fn main() { @@ -128,46 +128,43 @@ impl Game { let mouse_pos = d.get_mouse_position(); let scroll_delta = d.get_mouse_wheel_move(); - const ENTRY_SPACING: i32 = 65; - let fit_on_screen = (d.get_screen_height() / ENTRY_SPACING) as usize; - let max_scroll = self.levels.len().saturating_sub(fit_on_screen); if mouse_pos.x < level_list_width as f32 { - if scroll_delta < 0. && self.level_scroll < max_scroll { + if scroll_delta < 0. && self.level_scroll < self.levels.len().saturating_sub(5) { self.level_scroll += 1; - } - if scroll_delta > 0. && self.level_scroll > 0 { + } else if scroll_delta > 0. && self.level_scroll > 0 { self.level_scroll -= 1; } } - for (row_index, level_index) in (self.level_scroll..self.levels.len()).enumerate() { - let level = &mut self.levels[level_index]; - let y = 10 + row_index as i32 * ENTRY_SPACING; + for (i, level) in self.levels[self.level_scroll..].iter().enumerate() { + let level_entry_height = 65; + let index = i + self.level_scroll; + let y = 10 + i as i32 * level_entry_height; let bounds = Rectangle { x: 5., y: y as f32 - 5., width: level_list_width as f32 - 10., - height: ENTRY_SPACING as f32 - 5., + height: level_entry_height as f32 - 5., }; - let clicked_this = clicked && bounds.check_collision_point_rec(mouse_pos); match level { - LevelListEntry::Chapter(title, level_count) => { + LevelListEntry::ChapterTitle(title) => { d.draw_rectangle_rec(bounds, BG_DARK); d.draw_text(title, 10, y, 30, FG_CHAPTER_TITLE); - let subtitle = format!("{level_count} levels"); - d.draw_text(&subtitle, 10, y + 30, 20, Color::WHITE); } LevelListEntry::Level(level) => { - if clicked_this && self.selected_level != level_index { + if clicked + && bounds.check_collision_point_rec(mouse_pos) + && self.selected_level != index + { self.editing_solution_name = false; - self.selected_level = level_index; + self.selected_level = index; self.selected_solution = 0; // select the last solution of the level, if there is one if let Some(solutions) = self.solutions.get(level.id()) { self.selected_solution = solutions.len().saturating_sub(1); } } - d.draw_rectangle_rec(bounds, widget_bg(self.selected_level == level_index)); + d.draw_rectangle_rec(bounds, widget_bg(self.selected_level == index)); let mut title_color = Color::WHITE; if let Some(solutions) = self.solutions.get(level.id()) { @@ -316,7 +313,7 @@ fn get_levels() -> Vec { let mut levels = Vec::new(); for c in chapters { - levels.push(LevelListEntry::Chapter(c.title, c.levels.len())); + levels.push(LevelListEntry::ChapterTitle(c.title)); levels.extend(c.levels.into_iter().map(LevelListEntry::Level)); } levels