mirror of
https://github.com/Orama-Interactive/Pixelorama.git
synced 2025-02-12 16:53:07 +00:00
Add tile properties window, allowing you to change each tile's probability
More options can be added there in the future. Perhaps we could even add Godot tileset data, once we add Godot tileset exporting.
This commit is contained in:
parent
f2f465a111
commit
34ef0d4d15
|
@ -3551,3 +3551,11 @@ msgstr ""
|
|||
#: src/UI/TilesPanel.tscn
|
||||
msgid "Show empty tile:"
|
||||
msgstr ""
|
||||
|
||||
#: src/UI/TilesPanel.tscn
|
||||
msgid "Tile properties"
|
||||
msgstr ""
|
||||
|
||||
#: src/UI/TilesPanel.tscn
|
||||
msgid "Probability:"
|
||||
msgstr ""
|
||||
|
|
|
@ -287,7 +287,10 @@ func open_pxo_file(path: String, is_backup := false, replace_empty := true) -> v
|
|||
var image := Image.create_from_data(
|
||||
tile_size.x, tile_size.y, false, new_project.get_image_format(), image_data
|
||||
)
|
||||
tileset.add_tile(image, null, 0)
|
||||
if j > tileset.tiles.size() - 1:
|
||||
tileset.add_tile(image, null, 0)
|
||||
else:
|
||||
tileset.tiles[j].image = image
|
||||
for cel in new_project.get_all_pixel_cels():
|
||||
if cel is CelTileMap:
|
||||
cel.find_times_used_of_tiles()
|
||||
|
|
|
@ -29,6 +29,8 @@ class Tile:
|
|||
var image: Image
|
||||
## The amount of tiles this tile is being used in tilemaps.
|
||||
var times_used := 1
|
||||
## The relative probability of this tile appearing when drawing random tiles.
|
||||
var probability := 1.0
|
||||
|
||||
func _init(_image: Image) -> void:
|
||||
image = _image
|
||||
|
@ -38,6 +40,14 @@ class Tile:
|
|||
func can_be_removed() -> bool:
|
||||
return times_used <= 0
|
||||
|
||||
func serialize() -> Dictionary:
|
||||
return {"times_used": times_used, "probability": probability}
|
||||
|
||||
func deserialize(dict: Dictionary, skip_times_used := false) -> void:
|
||||
if not skip_times_used:
|
||||
times_used = dict.get("times_used", times_used)
|
||||
probability = dict.get("probability", probability)
|
||||
|
||||
|
||||
func _init(_tile_size: Vector2i, _name := "", add_empty_tile := true) -> void:
|
||||
tile_size = _tile_size
|
||||
|
@ -150,10 +160,31 @@ func find_using_layers(project: Project) -> Array[LayerTileMap]:
|
|||
return tilemaps
|
||||
|
||||
|
||||
func pick_random_tile(selected_tile_indices: Array[int]) -> int:
|
||||
if selected_tile_indices.is_empty():
|
||||
for i in tiles.size():
|
||||
selected_tile_indices.append(i)
|
||||
var sum := 0.0
|
||||
for i in selected_tile_indices:
|
||||
sum += tiles[i].probability
|
||||
var rand := randf_range(0.0, sum)
|
||||
var current := 0.0
|
||||
for i in selected_tile_indices:
|
||||
current += tiles[i].probability
|
||||
if current >= rand:
|
||||
return i
|
||||
return selected_tile_indices[0]
|
||||
|
||||
|
||||
## Serializes the data of this class into the form of a [Dictionary],
|
||||
## which is used so the data can be stored in pxo files.
|
||||
func serialize() -> Dictionary:
|
||||
return {"name": name, "tile_size": tile_size, "tile_amount": tiles.size()}
|
||||
var dict := {"name": name, "tile_size": tile_size, "tile_amount": tiles.size()}
|
||||
var tile_data := {}
|
||||
for i in tiles.size():
|
||||
tile_data[i] = tiles[i].serialize()
|
||||
dict["tile_data"] = tile_data
|
||||
return dict
|
||||
|
||||
|
||||
## Deserializes the data of a given [member dict] [Dictionary] into class data,
|
||||
|
@ -161,6 +192,16 @@ func serialize() -> Dictionary:
|
|||
func deserialize(dict: Dictionary) -> void:
|
||||
name = dict.get("name", name)
|
||||
tile_size = str_to_var("Vector2i" + dict.get("tile_size"))
|
||||
var tile_data := dict.get("tile_data", {}) as Dictionary
|
||||
for i_str in tile_data:
|
||||
var i := int(i_str)
|
||||
var tile: Tile
|
||||
if i > tiles.size() - 1:
|
||||
tile = Tile.new(null)
|
||||
tiles.append(tile)
|
||||
else:
|
||||
tile = tiles[i]
|
||||
tile.deserialize(tile_data[i_str], true)
|
||||
|
||||
|
||||
## Serializes the data of each tile in [member tiles] into the form of a [Dictionary],
|
||||
|
@ -169,7 +210,7 @@ func serialize_undo_data() -> Dictionary:
|
|||
var dict := {}
|
||||
for tile in tiles:
|
||||
var image_data := tile.image.get_data()
|
||||
dict[tile.image] = [image_data.compress(), image_data.size(), tile.times_used]
|
||||
dict[tile.image] = [image_data.compress(), image_data.size(), tile.serialize()]
|
||||
return dict
|
||||
|
||||
|
||||
|
@ -180,9 +221,10 @@ func deserialize_undo_data(dict: Dictionary, cel: CelTileMap) -> void:
|
|||
for image: Image in dict:
|
||||
var tile_data = dict[image]
|
||||
var buffer_size := tile_data[1] as int
|
||||
var tile_dictionary := tile_data[2] as Dictionary
|
||||
var image_data := (tile_data[0] as PackedByteArray).decompress(buffer_size)
|
||||
image.set_data(tile_size.x, tile_size.y, false, image.get_format(), image_data)
|
||||
tiles[i] = Tile.new(image)
|
||||
tiles[i].times_used = tile_data[2]
|
||||
tiles[i].deserialize(tile_dictionary)
|
||||
i += 1
|
||||
updated.emit(cel, -1)
|
||||
|
|
|
@ -24,7 +24,9 @@ static var selected_tile_index := 0:
|
|||
selected_tiles = [value]
|
||||
_call_update_brushes()
|
||||
get:
|
||||
return selected_tiles.pick_random()
|
||||
if is_instance_valid(current_tileset):
|
||||
return current_tileset.pick_random_tile(selected_tiles)
|
||||
return selected_tiles[0]
|
||||
static var selected_tiles: Array[int] = [0]
|
||||
static var is_flipped_h := false:
|
||||
set(value):
|
||||
|
@ -38,7 +40,7 @@ static var is_transposed := false:
|
|||
set(value):
|
||||
is_transposed = value
|
||||
_call_update_brushes()
|
||||
var current_tileset: TileSetCustom
|
||||
static var current_tileset: TileSetCustom
|
||||
var button_size := 36:
|
||||
set(value):
|
||||
if button_size == value:
|
||||
|
@ -61,6 +63,8 @@ var tile_index_menu_popped := 0
|
|||
@onready var options: Popup = $Options
|
||||
@onready var tile_size_slider: ValueSlider = %TileSizeSlider
|
||||
@onready var tile_button_popup_menu: PopupMenu = $TileButtonPopupMenu
|
||||
@onready var tile_properties: AcceptDialog = $TileProperties
|
||||
@onready var tile_probability_slider: ValueSlider = %TileProbabilitySlider
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
|
@ -197,7 +201,7 @@ func _on_tile_button_gui_input(event: InputEvent, index: int) -> void:
|
|||
tile_button_popup_menu.popup_on_parent(Rect2(get_global_mouse_position(), Vector2.ONE))
|
||||
tile_index_menu_popped = index
|
||||
tile_button_popup_menu.set_item_disabled(
|
||||
0, not current_tileset.tiles[index].can_be_removed()
|
||||
1, not current_tileset.tiles[index].can_be_removed()
|
||||
)
|
||||
|
||||
|
||||
|
@ -277,9 +281,12 @@ func _on_show_empty_tile_toggled(toggled_on: bool) -> void:
|
|||
|
||||
|
||||
func _on_tile_button_popup_menu_index_pressed(index: int) -> void:
|
||||
if tile_index_menu_popped == 0:
|
||||
return
|
||||
if index == 0: # Delete
|
||||
if index == 0: # Properties
|
||||
tile_probability_slider.value = current_tileset.tiles[tile_index_menu_popped].probability
|
||||
tile_properties.popup_centered()
|
||||
elif index == 1: # Delete
|
||||
if tile_index_menu_popped == 0:
|
||||
return
|
||||
if current_tileset.tiles[tile_index_menu_popped].can_be_removed():
|
||||
var undo_data := current_tileset.serialize_undo_data()
|
||||
current_tileset.tiles.remove_at(tile_index_menu_popped)
|
||||
|
@ -295,3 +302,7 @@ func _on_tile_button_popup_menu_index_pressed(index: int) -> void:
|
|||
project.undo_redo.add_undo_method(Global.undo_or_redo.bind(true))
|
||||
project.undo_redo.add_do_method(Global.undo_or_redo.bind(false))
|
||||
project.undo_redo.commit_action()
|
||||
|
||||
|
||||
func _on_tile_probability_slider_value_changed(value: float) -> void:
|
||||
current_tileset.tiles[tile_index_menu_popped].probability = value
|
||||
|
|
|
@ -343,8 +343,49 @@ button_pressed = true
|
|||
text = "On"
|
||||
|
||||
[node name="TileButtonPopupMenu" type="PopupMenu" parent="."]
|
||||
item_count = 1
|
||||
item_0/text = "Delete"
|
||||
item_count = 2
|
||||
item_0/text = "Properties"
|
||||
item_1/text = "Delete"
|
||||
item_1/id = 1
|
||||
|
||||
[node name="TileProperties" type="AcceptDialog" parent="."]
|
||||
title = "Tile properties"
|
||||
size = Vector2i(300, 200)
|
||||
|
||||
[node name="GridContainer" type="GridContainer" parent="TileProperties"]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = 8.0
|
||||
offset_top = 8.0
|
||||
offset_right = -8.0
|
||||
offset_bottom = -49.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
columns = 2
|
||||
|
||||
[node name="TileProbabilityLabel" type="Label" parent="TileProperties/GridContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "Probability:"
|
||||
|
||||
[node name="TileProbabilitySlider" type="TextureProgressBar" parent="TileProperties/GridContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
focus_mode = 2
|
||||
mouse_default_cursor_shape = 2
|
||||
theme_type_variation = &"ValueSlider"
|
||||
max_value = 10.0
|
||||
step = 0.001
|
||||
value = 1.0
|
||||
allow_greater = true
|
||||
nine_patch_stretch = true
|
||||
stretch_margin_left = 3
|
||||
stretch_margin_top = 3
|
||||
stretch_margin_right = 3
|
||||
stretch_margin_bottom = 3
|
||||
script = ExtResource("10_wfr6s")
|
||||
|
||||
[connection signal="toggled" from="VBoxContainer/MarginContainer/VBoxContainer/Buttons/PlaceTiles" to="." method="_on_place_tiles_toggled"]
|
||||
[connection signal="pressed" from="VBoxContainer/MarginContainer/VBoxContainer/Buttons/TransformButtonsContainer/RotateLeftButton" to="." method="_on_rotate_pressed" binds= [false]]
|
||||
|
@ -358,3 +399,4 @@ item_0/text = "Delete"
|
|||
[connection signal="value_changed" from="Options/MarginContainer/ScrollContainer/GridContainer/TileSizeSlider" to="." method="_on_tile_size_slider_value_changed"]
|
||||
[connection signal="toggled" from="Options/MarginContainer/ScrollContainer/GridContainer/ShowEmptyTile" to="." method="_on_show_empty_tile_toggled"]
|
||||
[connection signal="index_pressed" from="TileButtonPopupMenu" to="." method="_on_tile_button_popup_menu_index_pressed"]
|
||||
[connection signal="value_changed" from="TileProperties/GridContainer/TileProbabilitySlider" to="." method="_on_tile_probability_slider_value_changed"]
|
||||
|
|
Loading…
Reference in a new issue