Compare commits
3 commits
59aeeff5b6
...
6dcb6c9dd7
Author | SHA1 | Date | |
---|---|---|---|
6dcb6c9dd7 | |||
9d54c17dcd | |||
092a7b70ff |
6 changed files with 75 additions and 80 deletions
Binary file not shown.
Before Width: | Height: | Size: 105 B |
Binary file not shown.
Before Width: | Height: | Size: 122 B After Width: | Height: | Size: 99 B |
140
src/editor.rs
140
src/editor.rs
|
@ -21,13 +21,17 @@ use crate::{
|
||||||
solution::{Score, Solution},
|
solution::{Score, Solution},
|
||||||
text_input, texture_option_button,
|
text_input, texture_option_button,
|
||||||
theme::*,
|
theme::*,
|
||||||
userdata_dir, Scroll, Textures,
|
userdata_dir, Scroll, Textures, TILE_TEXTURE_SIZE,
|
||||||
};
|
};
|
||||||
|
|
||||||
const HEADER_HEIGHT: i32 = 40;
|
const HEADER_HEIGHT: i32 = 40;
|
||||||
const FOOTER_HEIGHT: i32 = 95;
|
const FOOTER_HEIGHT: i32 = 95;
|
||||||
const SIDEBAR_WIDTH: i32 = 200 + 32 * 2 + 5 * 4;
|
const SIDEBAR_WIDTH: i32 = 200 + 32 * 2 + 5 * 4;
|
||||||
const MAX_ZOOM_IN: i32 = 3;
|
const POPUP_WIDTH: i32 = 320;
|
||||||
|
const POPUP_HEIGHT: i32 = 165;
|
||||||
|
|
||||||
|
const MAX_ZOOM: f32 = 8.;
|
||||||
|
const MIN_ZOOM: f32 = 0.25;
|
||||||
const BOARD_MARGIN: PosInt = 3;
|
const BOARD_MARGIN: PosInt = 3;
|
||||||
const MAX_SPEED_POWER: u8 = 16;
|
const MAX_SPEED_POWER: u8 = 16;
|
||||||
const SPEED_DIGITS: u8 = 5;
|
const SPEED_DIGITS: u8 = 5;
|
||||||
|
@ -40,7 +44,7 @@ pub struct Editor {
|
||||||
machine: Machine,
|
machine: Machine,
|
||||||
sim_state: SimState,
|
sim_state: SimState,
|
||||||
view_offset: Vector2,
|
view_offset: Vector2,
|
||||||
zoom: i32,
|
zoom: f32,
|
||||||
output_as_text: bool,
|
output_as_text: bool,
|
||||||
input_as_text: bool,
|
input_as_text: bool,
|
||||||
active_tool: Tool,
|
active_tool: Tool,
|
||||||
|
@ -119,7 +123,7 @@ impl Editor {
|
||||||
machine: Machine::new_empty(level.inputs().to_owned(), 1),
|
machine: Machine::new_empty(level.inputs().to_owned(), 1),
|
||||||
sim_state: SimState::Editing,
|
sim_state: SimState::Editing,
|
||||||
view_offset: Vector2::zero(),
|
view_offset: Vector2::zero(),
|
||||||
zoom: 1,
|
zoom: 1.,
|
||||||
active_tool: Tool::None,
|
active_tool: Tool::None,
|
||||||
output_as_text: level.output_is_text(),
|
output_as_text: level.output_is_text(),
|
||||||
input_as_text: level.input_is_text(),
|
input_as_text: level.input_is_text(),
|
||||||
|
@ -166,7 +170,7 @@ impl Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pos_to_screen(&self, pos: Vector2) -> Vector2 {
|
fn pos_to_screen(&self, pos: Vector2) -> Vector2 {
|
||||||
pos * (16 << self.zoom) as f32 + self.view_offset
|
pos * (TILE_TEXTURE_SIZE * self.zoom) as f32 + self.view_offset
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_sim(&mut self) {
|
fn start_sim(&mut self) {
|
||||||
|
@ -234,7 +238,7 @@ impl Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn center_view(&mut self, d: &RaylibHandle) {
|
pub fn center_view(&mut self, d: &RaylibHandle) {
|
||||||
let tile_size = (16 << self.zoom) as f32;
|
let tile_size = (TILE_TEXTURE_SIZE * self.zoom) as f32;
|
||||||
let tile_x = self.source_board.width() as f32 / 2. * tile_size;
|
let tile_x = self.source_board.width() as f32 / 2. * tile_size;
|
||||||
let tile_y = self.source_board.height() as f32 / 2. * tile_size;
|
let tile_y = self.source_board.height() as f32 / 2. * tile_size;
|
||||||
let screen_x = d.get_screen_width() as f32 / 2.;
|
let screen_x = d.get_screen_width() as f32 / 2.;
|
||||||
|
@ -243,26 +247,26 @@ impl Editor {
|
||||||
self.view_offset.y = (screen_y - tile_y).floor();
|
self.view_offset.y = (screen_y - tile_y).floor();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn change_zoom_level(&mut self, d: &RaylibHandle, delta: i32) {
|
fn change_zoom_level(&mut self, d: &RaylibHandle, delta: f32) {
|
||||||
let tile_size = (16 << self.zoom) as f32;
|
let tile_size = (TILE_TEXTURE_SIZE * self.zoom) as f32;
|
||||||
let mouse_pos = d.get_mouse_position();
|
let mouse_pos = d.get_mouse_position();
|
||||||
let tile_pos_of_mouse = (mouse_pos - self.view_offset) / tile_size;
|
let tile_pos_of_mouse = (mouse_pos - self.view_offset) / tile_size;
|
||||||
self.zoom += delta;
|
self.zoom += delta;
|
||||||
let tile_size = (16 << self.zoom) as f32;
|
let tile_size = (TILE_TEXTURE_SIZE * self.zoom) as f32;
|
||||||
self.view_offset = mouse_pos - tile_pos_of_mouse * tile_size;
|
self.view_offset = mouse_pos - tile_pos_of_mouse * tile_size;
|
||||||
self.view_offset.x = self.view_offset.x.floor();
|
self.view_offset.x = self.view_offset.x.floor();
|
||||||
self.view_offset.y = self.view_offset.y.floor();
|
self.view_offset.y = self.view_offset.y.floor();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn zoom_in(&mut self, d: &RaylibHandle) {
|
fn zoom_in(&mut self, d: &RaylibHandle) {
|
||||||
if self.zoom < MAX_ZOOM_IN {
|
if self.zoom < MAX_ZOOM {
|
||||||
self.change_zoom_level(d, 1);
|
self.change_zoom_level(d, self.zoom);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn zoom_out(&mut self, d: &RaylibHandle) {
|
fn zoom_out(&mut self, d: &RaylibHandle) {
|
||||||
if self.zoom > 0 {
|
if self.zoom > MIN_ZOOM {
|
||||||
self.change_zoom_level(d, -1);
|
self.change_zoom_level(d, self.zoom / -2.);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,7 +292,7 @@ impl Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn grow_board_and_update_view(&mut self, pos: &mut Pos) {
|
fn grow_board_and_update_view(&mut self, pos: &mut Pos) {
|
||||||
let tile_size = (16 << self.zoom) as f32;
|
let tile_size = (TILE_TEXTURE_SIZE * self.zoom) as f32;
|
||||||
let (x, y) = self.source_board.grow_to_include(*pos);
|
let (x, y) = self.source_board.grow_to_include(*pos);
|
||||||
if x != 0 || y != 0 {
|
if x != 0 || y != 0 {
|
||||||
self.view_offset.x -= x as f32 * tile_size;
|
self.view_offset.x -= x as f32 * tile_size;
|
||||||
|
@ -315,7 +319,7 @@ impl Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_tile(&mut self, mut pos: Pos, tile: Tile) {
|
fn set_tile(&mut self, mut pos: Pos, tile: Tile) {
|
||||||
let tile_size = (16 << self.zoom) as f32;
|
let tile_size = (TILE_TEXTURE_SIZE * self.zoom) as f32;
|
||||||
pos.x -= BOARD_MARGIN;
|
pos.x -= BOARD_MARGIN;
|
||||||
pos.y -= BOARD_MARGIN;
|
pos.y -= BOARD_MARGIN;
|
||||||
self.grow_board_and_update_view(&mut pos);
|
self.grow_board_and_update_view(&mut pos);
|
||||||
|
@ -442,8 +446,8 @@ impl Editor {
|
||||||
pub fn draw(&mut self, d: &mut RaylibDrawHandle, textures: &Textures) {
|
pub fn draw(&mut self, d: &mut RaylibDrawHandle, textures: &Textures) {
|
||||||
d.clear_background(Color::new(64, 64, 64, 255));
|
d.clear_background(Color::new(64, 64, 64, 255));
|
||||||
|
|
||||||
if self.draw_overlay {
|
if self.draw_overlay && self.zoom >= 1. {
|
||||||
let tile_size = (16 << self.zoom) as f32;
|
let tile_size = (TILE_TEXTURE_SIZE * self.zoom) as f32;
|
||||||
let grid_spill_x = (self.view_offset.x).rem(tile_size) - tile_size;
|
let grid_spill_x = (self.view_offset.x).rem(tile_size) - tile_size;
|
||||||
let grid_spill_y = (self.view_offset.y).rem(tile_size) - tile_size;
|
let grid_spill_y = (self.view_offset.y).rem(tile_size) - tile_size;
|
||||||
d.gui_grid(
|
d.gui_grid(
|
||||||
|
@ -517,48 +521,41 @@ impl Editor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.popup == EndPopup::Success {
|
if matches!(self.popup, EndPopup::Success | EndPopup::Failure) {
|
||||||
let width = 320;
|
let x = d.get_screen_width() / 2 - POPUP_WIDTH / 2;
|
||||||
let height = 165;
|
let y = d.get_screen_height() / 2 - POPUP_HEIGHT / 2;
|
||||||
let x = d.get_screen_width() / 2 - width / 2;
|
d.draw_rectangle(x, y, POPUP_WIDTH, POPUP_HEIGHT, BG_DARK);
|
||||||
let y = d.get_screen_height() / 2 - height / 2;
|
if self.popup == EndPopup::Success {
|
||||||
d.draw_rectangle(x, y, width, height, BG_DARK);
|
d.draw_text("Level Complete!", x + 45, y + 10, 30, Color::LIME);
|
||||||
d.draw_text("Level Complete!", x + 45, y + 10, 30, Color::LIME);
|
if let Some(score) = &self.score {
|
||||||
if let Some(score) = &self.score {
|
d.draw_text("cycles", x + 15, y + 45, 20, Color::WHITE);
|
||||||
d.draw_text("cycles", x + 15, y + 45, 20, Color::WHITE);
|
draw_usize(d, textures, score.cycles, x + 10, y + 70, 9, 2);
|
||||||
draw_usize(d, textures, score.cycles, x + 10, y + 70, 9, 2);
|
d.draw_text("tiles", x + 215, y + 45, 20, Color::WHITE);
|
||||||
d.draw_text("tiles", x + 215, y + 45, 20, Color::WHITE);
|
draw_usize(d, textures, score.tiles, x + 210, y + 70, 5, 2);
|
||||||
draw_usize(d, textures, score.tiles, x + 210, y + 70, 5, 2);
|
}
|
||||||
}
|
if simple_button(d, x + 10, y + 110, 140, 45) {
|
||||||
if simple_button(d, x + 10, y + 110, 140, 45) {
|
self.popup = EndPopup::Dismissed;
|
||||||
self.popup = EndPopup::Dismissed;
|
}
|
||||||
}
|
d.draw_text("continue\nediting", x + 15, y + 115, 20, Color::WHITE);
|
||||||
d.draw_text("continue\nediting", x + 15, y + 115, 20, Color::WHITE);
|
|
||||||
|
|
||||||
if simple_button(d, x + width / 2 + 5, y + 110, 140, 45) {
|
if simple_button(d, x + POPUP_WIDTH / 2 + 5, y + 110, 140, 45) {
|
||||||
self.exit_state = ExitState::ExitAndSave;
|
self.exit_state = ExitState::ExitAndSave;
|
||||||
|
}
|
||||||
|
d.draw_text(
|
||||||
|
"return to\nlevel list",
|
||||||
|
x + POPUP_WIDTH / 2 + 10,
|
||||||
|
y + 115,
|
||||||
|
20,
|
||||||
|
Color::WHITE,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
d.draw_text("Level Failed!", x + 45, y + 10, 30, Color::RED);
|
||||||
|
d.draw_text("incorrect output", x + 45, y + 45, 20, Color::WHITE);
|
||||||
|
if simple_button(d, x + 10, y + 110, 300, 25) {
|
||||||
|
self.popup = EndPopup::Dismissed;
|
||||||
|
}
|
||||||
|
d.draw_text("ok :(", x + 15, y + 115, 20, Color::WHITE);
|
||||||
}
|
}
|
||||||
d.draw_text(
|
|
||||||
"return to\nlevel list",
|
|
||||||
x + width / 2 + 10,
|
|
||||||
y + 115,
|
|
||||||
20,
|
|
||||||
Color::WHITE,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.popup == EndPopup::Failure {
|
|
||||||
let width = 320;
|
|
||||||
let height = 165;
|
|
||||||
let x = d.get_screen_width() / 2 - width / 2;
|
|
||||||
let y = d.get_screen_height() / 2 - height / 2;
|
|
||||||
d.draw_rectangle(x, y, width, height, BG_DARK);
|
|
||||||
d.draw_text("Level Failed!", x + 45, y + 10, 30, Color::RED);
|
|
||||||
d.draw_text("incorrect output", x + 45, y + 45, 20, Color::WHITE);
|
|
||||||
if simple_button(d, x + 10, y + 110, 300, 25) {
|
|
||||||
self.popup = EndPopup::Dismissed;
|
|
||||||
}
|
|
||||||
d.draw_text("ok :(", x + 15, y + 115, 20, Color::WHITE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -903,8 +900,7 @@ impl Editor {
|
||||||
let footer_top = (d.get_screen_height() - FOOTER_HEIGHT) as f32;
|
let footer_top = (d.get_screen_height() - FOOTER_HEIGHT) as f32;
|
||||||
let mouse_pos = d.get_mouse_position();
|
let mouse_pos = d.get_mouse_position();
|
||||||
let scroll_delta = d.get_mouse_wheel_move();
|
let scroll_delta = d.get_mouse_wheel_move();
|
||||||
let tile_scale = (1 << self.zoom) as f32;
|
let tile_size = TILE_TEXTURE_SIZE * self.zoom;
|
||||||
let tile_size = 16 << self.zoom;
|
|
||||||
if self.sim_state == SimState::Editing {
|
if self.sim_state == SimState::Editing {
|
||||||
if let Some(board) = &self.pasting_board {
|
if let Some(board) = &self.pasting_board {
|
||||||
if d.is_key_pressed(KeyboardKey::KEY_ESCAPE) {
|
if d.is_key_pressed(KeyboardKey::KEY_ESCAPE) {
|
||||||
|
@ -942,7 +938,7 @@ impl Editor {
|
||||||
textures.get("selection"),
|
textures.get("selection"),
|
||||||
tile_screen_pos,
|
tile_screen_pos,
|
||||||
0.,
|
0.,
|
||||||
tile_scale,
|
self.zoom,
|
||||||
Color::new(255, 180, 20, 255),
|
Color::new(255, 180, 20, 255),
|
||||||
);
|
);
|
||||||
if d.is_key_pressed(KeyboardKey::KEY_LEFT) {
|
if d.is_key_pressed(KeyboardKey::KEY_LEFT) {
|
||||||
|
@ -995,7 +991,7 @@ impl Editor {
|
||||||
textures.get(&tex),
|
textures.get(&tex),
|
||||||
tile_screen_pos,
|
tile_screen_pos,
|
||||||
0.,
|
0.,
|
||||||
tile_scale,
|
self.zoom,
|
||||||
Color::new(255, 255, 255, 100),
|
Color::new(255, 255, 255, 100),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1088,18 +1084,16 @@ impl Editor {
|
||||||
is_selecting: _,
|
is_selecting: _,
|
||||||
}) = self.active_tool
|
}) = self.active_tool
|
||||||
{
|
{
|
||||||
let min = start.min(end);
|
let p_min = self.pos_to_screen(start.min(end).to_vec());
|
||||||
let max = start.max(end);
|
let p_max = self.pos_to_screen((start.max(end) + (1, 1).into()).to_vec());
|
||||||
let p_min = self.pos_to_screen(min.to_vec());
|
let x = p_min.x as i32;
|
||||||
let p_max = self.pos_to_screen(max.to_vec());
|
let y = p_min.y as i32;
|
||||||
let tex = textures.get("area_corner");
|
let width = p_max.x as i32 - x;
|
||||||
d.draw_texture_ex(tex, p_min, 0., tile_scale, Color::WHITE);
|
let height = p_max.y as i32 - y;
|
||||||
let one_xy = Vector2::new(tile_size as f32, tile_size as f32);
|
d.draw_rectangle(x, y, width, 4, Color::WHITE);
|
||||||
d.draw_texture_ex(tex, p_max + one_xy, 180., tile_scale, Color::WHITE);
|
d.draw_rectangle(x, y + height - 4, width, 4, Color::WHITE);
|
||||||
let top_right = Vector2::new(p_max.x + tile_size as f32, p_min.y);
|
d.draw_rectangle(x, y, 4, height, Color::WHITE);
|
||||||
d.draw_texture_ex(tex, top_right, 90., tile_scale, Color::WHITE);
|
d.draw_rectangle(x + width - 4, y, 4, height, Color::WHITE);
|
||||||
let bot_left = Vector2::new(p_min.x, p_max.y + tile_size as f32);
|
|
||||||
d.draw_texture_ex(tex, bot_left, -90., tile_scale, Color::WHITE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,8 @@ use util::*;
|
||||||
|
|
||||||
const TITLE_TEXT: &str = concat!("Marble Machinations v", env!("CARGO_PKG_VERSION"));
|
const TITLE_TEXT: &str = concat!("Marble Machinations v", env!("CARGO_PKG_VERSION"));
|
||||||
|
|
||||||
|
pub const TILE_TEXTURE_SIZE: f32 = 16.0;
|
||||||
|
|
||||||
struct Game {
|
struct Game {
|
||||||
levels: Vec<Level>,
|
levels: Vec<Level>,
|
||||||
level_scroll: usize,
|
level_scroll: usize,
|
||||||
|
|
|
@ -7,7 +7,7 @@ use board::Board;
|
||||||
use pos::*;
|
use pos::*;
|
||||||
use tile::*;
|
use tile::*;
|
||||||
|
|
||||||
use crate::{draw_usize_small, Textures};
|
use crate::{draw_usize_small, Textures, TILE_TEXTURE_SIZE};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Machine {
|
pub struct Machine {
|
||||||
|
@ -76,10 +76,9 @@ impl Machine {
|
||||||
d: &mut RaylibDrawHandle,
|
d: &mut RaylibDrawHandle,
|
||||||
textures: &Textures,
|
textures: &Textures,
|
||||||
offset: Vector2,
|
offset: Vector2,
|
||||||
zoom: i32,
|
scale: f32,
|
||||||
) {
|
) {
|
||||||
let tile_size = 16 << zoom;
|
let tile_size = (TILE_TEXTURE_SIZE * scale) as i32;
|
||||||
let scale = (1 << zoom) as f32;
|
|
||||||
for marble in &self.marbles {
|
for marble in &self.marbles {
|
||||||
let x = marble.x;
|
let x = marble.x;
|
||||||
let y = marble.y;
|
let y = marble.y;
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::TILE_TEXTURE_SIZE;
|
||||||
use crate::{draw_scaled_texture, Textures};
|
use crate::{draw_scaled_texture, Textures};
|
||||||
|
|
||||||
use super::tile::*;
|
use super::tile::*;
|
||||||
|
@ -245,9 +246,8 @@ impl Board {
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw(&self, d: &mut RaylibDrawHandle, textures: &Textures, offset: Vector2, zoom: i32) {
|
pub fn draw(&self, d: &mut RaylibDrawHandle, textures: &Textures, offset: Vector2, scale: f32) {
|
||||||
let tile_size = 16 << zoom;
|
let tile_size = (TILE_TEXTURE_SIZE * scale) as i32;
|
||||||
let scale = (1 << zoom) as f32;
|
|
||||||
|
|
||||||
let start_x = (-offset.x as i32) / tile_size - 1;
|
let start_x = (-offset.x as i32) / tile_size - 1;
|
||||||
let tile_width = d.get_screen_width() / tile_size + 2;
|
let tile_width = d.get_screen_width() / tile_size + 2;
|
||||||
|
|
Loading…
Add table
Reference in a new issue