initial level selection gui
This commit is contained in:
parent
66c9b10264
commit
ed5084d0fd
11 changed files with 413 additions and 29 deletions
181
src/main.rs
181
src/main.rs
|
@ -1,14 +1,31 @@
|
|||
use std::fs::read_to_string;
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fs::{read_dir, read_to_string},
|
||||
};
|
||||
|
||||
use editor::Editor;
|
||||
use marble_engine::board::Board;
|
||||
use raylib::prelude::*;
|
||||
|
||||
mod editor;
|
||||
mod level;
|
||||
mod marble_engine;
|
||||
mod solution;
|
||||
mod util;
|
||||
|
||||
use editor::Editor;
|
||||
use level::Level;
|
||||
use marble_engine::board::Board;
|
||||
use solution::Solution;
|
||||
use util::*;
|
||||
|
||||
struct Game {
|
||||
levels: Vec<Level>,
|
||||
solutions: HashMap<String, Vec<Solution>>,
|
||||
open_editor: Option<Editor>,
|
||||
textures: Textures,
|
||||
selected_level: usize,
|
||||
selected_solution: usize,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let (mut rl, thread) = raylib::init()
|
||||
.resizable()
|
||||
|
@ -20,18 +37,156 @@ fn main() {
|
|||
rl.set_exit_key(None);
|
||||
rl.set_trace_log(TraceLogLevel::LOG_WARNING);
|
||||
|
||||
let mut textures = Textures::default();
|
||||
textures.load_dir("assets", &mut rl, &thread);
|
||||
textures.load_dir("assets/tiles", &mut rl, &thread);
|
||||
let mut game = Game::new(&mut rl, &thread);
|
||||
game.run(&mut rl, &thread);
|
||||
// let board = Board::parse(&read_to_string("boards/adder.mbl").unwrap());
|
||||
// game.load_board(board);
|
||||
}
|
||||
|
||||
let mut game = Editor::new_sandbox();
|
||||
let board = Board::parse(&read_to_string("boards/adder.mbl").unwrap());
|
||||
game.load_board(board);
|
||||
impl Game {
|
||||
fn new(rl: &mut RaylibHandle, thread: &RaylibThread) -> Self {
|
||||
let mut textures = Textures::default();
|
||||
textures.load_dir("assets", rl, &thread);
|
||||
textures.load_dir("assets/tiles", rl, &thread);
|
||||
|
||||
while !rl.window_should_close() {
|
||||
game.input(&rl);
|
||||
let mut d = rl.begin_drawing(&thread);
|
||||
Self {
|
||||
levels: get_levels(),
|
||||
solutions: HashMap::new(),
|
||||
open_editor: None,
|
||||
textures,
|
||||
selected_level: 0,
|
||||
selected_solution: 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn run(&mut self, rl: &mut RaylibHandle, thread: &RaylibThread) {
|
||||
while !rl.window_should_close() {
|
||||
let mut d = rl.begin_drawing(&thread);
|
||||
if let Some(editor) = &mut self.open_editor {
|
||||
editor.input(&d);
|
||||
editor.draw(&mut d, &self.textures);
|
||||
} else {
|
||||
self.draw(&mut d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn draw(&mut self, d: &mut RaylibDrawHandle) {
|
||||
d.clear_background(Color::new(64, 64, 64, 255));
|
||||
game.draw(&mut d, &textures);
|
||||
let level_list_width = 320;
|
||||
let screen_height = d.get_screen_height();
|
||||
d.draw_rectangle(0, 0, level_list_width, screen_height, Color::GRAY);
|
||||
// let (a, b, c) = d.gui_scroll_panel(
|
||||
// Rectangle {
|
||||
// x: 10.,
|
||||
// y: 10.,
|
||||
// width: level_list_width as f32 - 20.,
|
||||
// height: screen_height as f32 - 40.,
|
||||
// },
|
||||
// Some(rstr!("text")),
|
||||
// Rectangle{},
|
||||
// scroll,
|
||||
// view,
|
||||
// );
|
||||
|
||||
let clicked = d.is_mouse_button_pressed(MouseButton::MOUSE_BUTTON_LEFT);
|
||||
let mouse_pos = d.get_mouse_position();
|
||||
|
||||
for (i, level) in self.levels.iter().enumerate() {
|
||||
let level_entry_height = 48;
|
||||
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: level_entry_height as f32 - 5.,
|
||||
};
|
||||
if clicked && bounds.check_collision_point_rec(mouse_pos) && self.selected_level != i {
|
||||
self.selected_solution = 0;
|
||||
self.selected_level = i;
|
||||
}
|
||||
if self.selected_level == i {
|
||||
d.draw_rectangle_rec(bounds, Color::DARKCYAN);
|
||||
}
|
||||
d.draw_text(level.name(), 10, y, 20, Color::WHITE);
|
||||
let solution_count = self
|
||||
.solutions
|
||||
.get(level.id())
|
||||
.map(Vec::len)
|
||||
.unwrap_or_default();
|
||||
let subtext = format!("solutions: {solution_count}");
|
||||
let subtext_color = if solution_count > 0 {
|
||||
Color::GOLD
|
||||
} else {
|
||||
Color::LIGHTGRAY
|
||||
};
|
||||
d.draw_text(&subtext, 10, y + 20, 10, subtext_color);
|
||||
}
|
||||
|
||||
if let Some(level) = self.levels.get(self.selected_level) {
|
||||
d.draw_text(level.name(), level_list_width + 10, 10, 30, Color::CYAN);
|
||||
d.draw_text(level.id(), level_list_width + 10, 40, 10, Color::GRAY);
|
||||
|
||||
let mut y = 60;
|
||||
if let Some(solutions) = self.solutions.get_mut(level.id()) {
|
||||
let solution_entry_height = 40;
|
||||
for (solution_index, solution) in solutions.iter().enumerate() {
|
||||
simple_option_button(
|
||||
d,
|
||||
level_list_width + 10,
|
||||
y,
|
||||
200,
|
||||
solution_entry_height,
|
||||
solution_index,
|
||||
&mut self.selected_solution,
|
||||
);
|
||||
let name_color = if solution.score.is_some() {
|
||||
Color::LIME
|
||||
} else {
|
||||
Color::ORANGE
|
||||
};
|
||||
d.draw_text(&solution.name, level_list_width + 15, y + 5, 20, name_color);
|
||||
d.draw_text(
|
||||
&solution.score_text(),
|
||||
level_list_width + 15,
|
||||
y + 25,
|
||||
10,
|
||||
Color::WHITE,
|
||||
);
|
||||
y += solution_entry_height + 10;
|
||||
}
|
||||
|
||||
// d.gui_button(bounds, text)
|
||||
if simple_button(d, level_list_width + 10, y, 200, 30) {
|
||||
let n = solutions.len();
|
||||
solutions.push(Solution::new(level.id().to_owned(), n));
|
||||
}
|
||||
d.draw_text(
|
||||
"new solution",
|
||||
level_list_width + 15,
|
||||
y + 5,
|
||||
20,
|
||||
Color::WHITE,
|
||||
);
|
||||
} else {
|
||||
self.solutions.insert(level.id().to_owned(), Vec::new());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_levels() -> Vec<Level> {
|
||||
let mut levels = Vec::<Level>::new();
|
||||
for d in read_dir("levels").unwrap().flatten() {
|
||||
let l = read_to_string(d.path())
|
||||
.ok()
|
||||
.as_deref()
|
||||
.map(|s| serde_json::from_str(s).ok())
|
||||
.flatten();
|
||||
if let Some(level) = l {
|
||||
levels.push(level);
|
||||
}
|
||||
}
|
||||
levels.sort_by(|a, b| a.id().cmp(b.id()));
|
||||
levels
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue