Skip to content

Commit

Permalink
drawing functionality for tile map editor
Browse files Browse the repository at this point in the history
- very basic and buggy
  • Loading branch information
mrDIMAS committed Jul 6, 2024
1 parent 8fa53bb commit 864c7a7
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 39 deletions.
2 changes: 1 addition & 1 deletion editor/src/plugins/tilemap/brush.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::fyrox::{

#[derive(Default, PartialEq, Debug, Clone)]
pub struct BrushTile {
pub tile_index: usize,
pub definition_index: usize,
pub local_position: Vector2<i32>,
}

Expand Down
91 changes: 80 additions & 11 deletions editor/src/plugins/tilemap/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ pub mod panel;
pub mod tile_set_import;
pub mod tileset;

use crate::plugins::tilemap::palette::PaletteMessage;
use crate::{
command::SetPropertyCommand,
fyrox::{
core::{
algebra::{Vector2, Vector3},
Expand All @@ -17,17 +17,24 @@ use crate::{
Uuid,
},
engine::Engine,
graph::{BaseSceneGraph, SceneGraphNode},
graph::{BaseSceneGraph, SceneGraph, SceneGraphNode},
gui::{
button::ButtonBuilder, message::UiMessage, utils::make_simple_tooltip,
widget::WidgetBuilder, BuildContext, Thickness, UiNode,
},
scene::{debug::Line, node::Node, tilemap::TileMap},
scene::{
debug::Line,
node::Node,
tilemap::{Tile, TileMap, Tiles},
},
},
interaction::{make_interaction_mode_button, InteractionMode},
message::MessageSender,
plugin::EditorPlugin,
plugins::tilemap::{brush::TileMapBrush, panel::TileMapPanel, tileset::TileSetEditor},
scene::{controller::SceneController, GameScene, Selection},
plugins::tilemap::{
brush::TileMapBrush, palette::PaletteMessage, panel::TileMapPanel, tileset::TileSetEditor,
},
scene::{commands::GameSceneContext, controller::SceneController, GameScene, Selection},
settings::Settings,
Editor, Message,
};
Expand All @@ -51,38 +58,80 @@ fn make_button(
.build(ctx)
}

struct InteractionContext {
previous_tiles: Tiles,
}

#[derive(TypeUuidProvider)]
#[type_uuid(id = "33fa8ef9-a29c-45d4-a493-79571edd870a")]
pub struct TileMapInteractionMode {
#[allow(dead_code)]
tile_map: Handle<Node>,
brush: Arc<Mutex<TileMapBrush>>,
brush_position: Vector2<i32>,
interaction_context: Option<InteractionContext>,
sender: MessageSender,
}

impl InteractionMode for TileMapInteractionMode {
fn on_left_mouse_button_down(
&mut self,
_editor_selection: &Selection,
_controller: &mut dyn SceneController,
_engine: &mut Engine,
controller: &mut dyn SceneController,
engine: &mut Engine,
_mouse_pos: Vector2<f32>,
_frame_size: Vector2<f32>,
_settings: &Settings,
) {
// TODO
let Some(game_scene) = controller.downcast_mut::<GameScene>() else {
return;
};

let scene = &engine.scenes[game_scene.scene];

let Some(tile_map) = scene.graph.try_get_of_type::<TileMap>(self.tile_map) else {
return;
};

self.interaction_context = Some(InteractionContext {
previous_tiles: tile_map.tiles().clone(),
});
}

fn on_left_mouse_button_up(
&mut self,
_editor_selection: &Selection,
_controller: &mut dyn SceneController,
_engine: &mut Engine,
controller: &mut dyn SceneController,
engine: &mut Engine,
_mouse_pos: Vector2<f32>,
_frame_size: Vector2<f32>,
_settings: &Settings,
) {
// TODO
let Some(game_scene) = controller.downcast_mut::<GameScene>() else {
return;
};

let scene = &mut engine.scenes[game_scene.scene];

let tile_map_handle = self.tile_map;
let Some(tile_map) = scene.graph.try_get_mut_of_type::<TileMap>(tile_map_handle) else {
return;
};

if let Some(interaction_context) = self.interaction_context.take() {
let new_tiles = tile_map.tiles().clone();
tile_map.set_tiles(interaction_context.previous_tiles);
self.sender.do_command(SetPropertyCommand::new(
"tiles".to_string(),
Box::new(new_tiles),
move |ctx| {
ctx.get_mut::<GameSceneContext>()
.scene
.graph
.node_mut(tile_map_handle)
},
));
}
}

fn on_mouse_move(
Expand Down Expand Up @@ -111,6 +160,24 @@ impl InteractionMode for TileMapInteractionMode {
if let Some(intersection) = ray.plane_intersection_point(&plane) {
let grid_coord = Vector2::new(intersection.x as i32, intersection.y as i32);
self.brush_position = grid_coord;

let Some(tile_map) = scene.graph.try_get_mut_of_type::<TileMap>(self.tile_map) else {
return;
};

if self.interaction_context.is_some() {
let brush = self.brush.lock();
for tile in brush.tiles.iter() {
let position = grid_coord + tile.local_position;
tile_map.insert_tile(
position,
Tile {
position,
definition_index: tile.definition_index,
},
)
}
}
}
}

Expand Down Expand Up @@ -262,6 +329,8 @@ impl EditorPlugin for TileMapEditorPlugin {
tile_map: *node_handle,
brush: self.brush.clone(),
brush_position: Default::default(),
interaction_context: None,
sender: editor.message_sender.clone(),
});

self.panel = Some(TileMapPanel::new(
Expand Down
50 changes: 33 additions & 17 deletions editor/src/plugins/tilemap/palette.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,17 +98,33 @@ impl PaletteWidget {
}

fn selected_tiles_to_brush(&self, ui: &UserInterface) -> TileMapBrush {
TileMapBrush {
tiles: self
.selection
.iter()
.filter_map(|h| ui.try_get_of_type::<TileView>(*h))
.map(|view| BrushTile {
tile_index: view.tile_index,
local_position: view.local_position,
})
.collect::<Vec<_>>(),
let mut tiles = self
.selection
.iter()
.filter_map(|h| ui.try_get_of_type::<TileView>(*h))
.map(|view| BrushTile {
definition_index: view.definition_index,
local_position: view.local_position,
})
.collect::<Vec<_>>();

let mut min_x = i32::MAX;
let mut min_y = i32::MAX;
for tile in tiles.iter() {
if tile.local_position.x < min_x {
min_x = tile.local_position.x;
}
if tile.local_position.y < min_y {
min_y = tile.local_position.y;
}
}
let origin = Vector2::new(min_x, min_y);

for tile in tiles.iter_mut() {
tile.local_position -= origin;
}

TileMapBrush { tiles }
}

fn set_selection(&mut self, new_selection: &[Handle<UiNode>], ui: &UserInterface) {
Expand Down Expand Up @@ -315,7 +331,7 @@ pub struct TileView {
widget: Widget,
#[component(include)]
selectable: Selectable,
tile_index: usize,
definition_index: usize,
local_position: Vector2<i32>,
tile_set: TileSetResource,
}
Expand All @@ -325,7 +341,7 @@ define_widget_deref!(TileView);
impl Control for TileView {
fn draw(&self, drawing_context: &mut DrawingContext) {
let tile_set = self.tile_set.data_ref();
if let Some(tile_definition) = tile_set.tiles.get(self.tile_index) {
if let Some(tile_definition) = tile_set.tiles.get(self.definition_index) {
if let Some(texture) = tile_definition
.material
.data_ref()
Expand Down Expand Up @@ -380,7 +396,7 @@ impl Control for TileView {

pub struct TileViewBuilder {
widget_builder: WidgetBuilder,
tile_index: usize,
definition_index: usize,
local_position: Vector2<i32>,
tile_set: TileSetResource,
}
Expand All @@ -389,7 +405,7 @@ impl TileViewBuilder {
pub fn new(tile_set: TileSetResource, widget_builder: WidgetBuilder) -> Self {
Self {
widget_builder,
tile_index: 0,
definition_index: 0,
local_position: Default::default(),
tile_set,
}
Expand All @@ -400,16 +416,16 @@ impl TileViewBuilder {
self
}

pub fn with_tile_index(mut self, index: usize) -> Self {
self.tile_index = index;
pub fn with_definition_index(mut self, index: usize) -> Self {
self.definition_index = index;
self
}

pub fn build(self, ctx: &mut BuildContext) -> Handle<UiNode> {
ctx.add_node(UiNode::new(TileView {
widget: self.widget_builder.build(),
selectable: Default::default(),
tile_index: self.tile_index,
definition_index: self.definition_index,
local_position: self.local_position,
tile_set: self.tile_set,
}))
Expand Down
2 changes: 1 addition & 1 deletion editor/src/plugins/tilemap/panel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ impl TileMapPanel {
let side_size = 10;

TileViewBuilder::new(tile_set_resource.clone(), WidgetBuilder::new())
.with_tile_index(index)
.with_definition_index(index)
.with_position(Vector2::new(
index as i32 % side_size,
index as i32 / side_size,
Expand Down
31 changes: 22 additions & 9 deletions fyrox-impl/src/scene/tilemap/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,25 @@ use crate::{
tilemap::tileset::{TileDefinition, TileSet, TileSetResource},
},
};
use fxhash::FxHashMap;
use std::ops::{Deref, DerefMut};

#[derive(Clone, Reflect, Default, Debug, PartialEq, Visit, ComponentProvider, TypeUuidProvider)]
#[type_uuid(id = "e429ca1b-a311-46c3-b580-d5a2f49db7e2")]
pub struct Tile {
position: Vector2<i32>,
definition_index: usize,
pub position: Vector2<i32>,
pub definition_index: usize,
}

pub type Tiles = FxHashMap<Vector2<i32>, Tile>;

#[derive(Clone, Reflect, Debug, Visit, ComponentProvider, TypeUuidProvider)]
#[type_uuid(id = "aa9a3385-a4af-4faf-a69a-8d3af1a3aa67")]
pub struct TileMap {
base: Base,
tile_set: InheritableVariable<Option<TileSetResource>>,
#[reflect(read_only)]
tiles: InheritableVariable<Vec<Tile>>,
tiles: InheritableVariable<Tiles>,
tile_scale: InheritableVariable<Vector2<f32>>,
}

Expand All @@ -54,11 +57,11 @@ impl TileMap {
self.tile_set.set_value_and_mark_modified(tile_set);
}

pub fn tiles(&self) -> &[Tile] {
pub fn tiles(&self) -> &Tiles {
&self.tiles
}

pub fn set_tiles(&mut self, tiles: Vec<Tile>) {
pub fn set_tiles(&mut self, tiles: Tiles) {
self.tiles.set_value_and_mark_modified(tiles);
}

Expand All @@ -69,6 +72,13 @@ impl TileMap {
pub fn set_tile_scale(&mut self, tile_scale: Vector2<f32>) {
self.tile_scale.set_value_and_mark_modified(tile_scale);
}

pub fn insert_tile(&mut self, position: Vector2<i32>, tile: Tile) {
self.tiles
.entry(position)
.and_modify(|entry| *entry = tile.clone())
.or_insert(tile);
}
}

impl Default for TileMap {
Expand Down Expand Up @@ -137,7 +147,7 @@ impl NodeTrait for TileMap {

let tile_set = tile_set_resource.data_ref();

for tile in self.tiles.iter() {
for tile in self.tiles.values() {
let Some(tile_definition) = tile_set.tiles.get(tile.definition_index) else {
continue;
};
Expand Down Expand Up @@ -213,7 +223,7 @@ impl NodeTrait for TileMap {
pub struct TileMapBuilder {
base_builder: BaseBuilder,
tile_set: Option<TileSetResource>,
tiles: Vec<Tile>,
tiles: Tiles,
tile_scale: Vector2<f32>,
}

Expand Down Expand Up @@ -251,7 +261,10 @@ impl TileMapBuilder {
Self {
base_builder,
tile_set,
tiles,
tiles: tiles
.into_iter()
.map(|tile| (tile.position, tile))
.collect(),
tile_scale: Vector2::repeat(1.0),
}
}
Expand All @@ -261,7 +274,7 @@ impl TileMapBuilder {
self
}

pub fn with_tiles(mut self, tiles: Vec<Tile>) -> Self {
pub fn with_tiles(mut self, tiles: Tiles) -> Self {
self.tiles = tiles;
self
}
Expand Down

0 comments on commit 864c7a7

Please sign in to comment.