1
0
Fork 0
mirror of https://github.com/Orama-Interactive/Pixelorama.git synced 2025-01-18 17:19:50 +00:00

Changed how isometric grid is drawn

Instead of drawing individual lines, execute draw_isometric_tile() multiple times. What this method does is basically draws a single isometric tile, which then gets repeated for the entire canvas size. Also moved all the grid logic to a new script, which gets updated less often that Canvas.gd, for optimization purposes.

Works better than the previous method, although it might be a bit slower, and currently does not work well if the canvas size is not divisible by the grid size. For now, it only gets affected by the grid width. Changing grid height has no effect.
This commit is contained in:
OverloadedOrama 2020-08-17 22:54:33 +03:00
parent 39808082b6
commit 35b2c201ae
7 changed files with 69 additions and 68 deletions

View file

@ -310,6 +310,8 @@ func undo(_frame_index := -1, _layer_index := -1, project : Project = current_pr
if action_name == "Scale":
canvas.camera_zoom()
Global.canvas.grid.isometric_polylines.clear()
Global.canvas.grid.update()
elif "Frame" in action_name:
# This actually means that frames.size is one, but it hasn't been updated yet
@ -338,6 +340,8 @@ func redo(_frame_index := -1, _layer_index := -1, project : Project = current_pr
if action_name == "Scale":
canvas.camera_zoom()
Global.canvas.grid.isometric_polylines.clear()
Global.canvas.grid.update()
elif "Frame" in action_name:
if project.frames.size() == 1: # Stop animating

View file

@ -9,6 +9,8 @@ var can_undo := true
var cursor_image_has_changed := false
var sprite_changed_this_frame := false # for optimization purposes
onready var grid = $Grid
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
@ -42,9 +44,6 @@ func _draw() -> void:
draw_texture(current_cels[i].image_texture, Vector2(location.x + size.x, location.y), modulate_color) # Right
draw_texture(current_cels[i].image_texture, location + size, modulate_color) # Down right
if Global.draw_grid:
draw_grid(Global.grid_type)
# Draw rectangle to indicate the pixel currently being hovered on
if Global.has_focus and Global.can_draw:
Tools.draw_indicator()
@ -251,66 +250,3 @@ func onion_skinning() -> void:
color.a = 0.6 / i
draw_texture(layer.image_texture, location, color)
layer_i += 1
func draw_grid(grid_type : int) -> void:
var size : Vector2 = Global.current_project.size
if grid_type == Global.Grid_Types.CARTESIAN || grid_type == Global.Grid_Types.ALL:
for x in range(Global.grid_width, size.x, Global.grid_width):
draw_line(Vector2(x, location.y), Vector2(x, size.y), Global.grid_color, true)
for y in range(Global.grid_height, size.y, Global.grid_height):
draw_line(Vector2(location.x, y), Vector2(size.x, y), Global.grid_color, true)
# Doesn't work properly yet
if grid_type == Global.Grid_Types.ISOMETRIC || grid_type == Global.Grid_Types.ALL:
var approx_30_degrees = 26.565
var approx_60_degrees = 90 - 26.565
var prev_x := 0
var prev_y := 0
# Draw lines starting from the left side, facing down to the right
for y in range(0, size.y + 1, Global.grid_width):
var yy1 = y + size.y * tan(deg2rad(approx_30_degrees))
# End points touch the right side of the canvas, but not the entire of it
if yy1 <= (size.y + 0.01):
draw_line(Vector2(location.x, y), Vector2(size.x, yy1),Global.grid_color)
# End points touch the bottom side of the canvas
else:
var xx1 = (size.x - y) * tan(deg2rad(approx_60_degrees))
draw_line(Vector2(location.x, y), Vector2(xx1, size.y), Global.grid_color)
# Draw lines starting from the left side, facing up to the right
for y in range(0, size.y + 1, Global.grid_height):
var xx2 = y * tan(deg2rad(approx_60_degrees))
# End points touch the upper side of the canvas
if xx2 <= (size.x + 0.01):
draw_line(Vector2(location.x, y), Vector2(xx2, location.y), Global.grid_color)
prev_y = location.y
# End points touch the right side of the canvas, but not the entire of it
else:
var distance = (xx2 - prev_x) / 2
#var yy2 = (size.y - y) * tan(deg2rad(approx_30_degrees))
var yy2 = prev_y + distance
draw_line(Vector2(location.x, y), Vector2(size.x, yy2), Global.grid_color)
prev_y = yy2
prev_x = xx2
# Draw lines from the top side, facing down to the right
# End points touch the right side of the canvas, but not the entire of it
# Problematic when size.y < size.x / 2
for x in range(0, size.x, Global.grid_width * 2):
if x == 0:
continue
var yy1 = (size.x - x) * tan(deg2rad(approx_30_degrees))
draw_line(Vector2(x, location.y), Vector2(size.x, yy1), Global.grid_color)
# Draw lines from the bottom side, facing up to the right.
# End points touch the right side of the canvas, but not the entire of it
# Problematic when size.y < size.x / 2
for x in range(0, size.x, Global.grid_height * 2):
var yy2 = (size.x - x) * tan(deg2rad(approx_30_degrees))
draw_line(Vector2(x, size.y), Vector2(size.x, size.y - yy2), Global.grid_color)

View file

@ -1,6 +1,10 @@
[gd_scene load_steps=2 format=2]
[gd_scene load_steps=3 format=2]
[ext_resource path="res://src/Canvas.gd" type="Script" id=1]
[ext_resource path="res://src/UI/Grid.gd" type="Script" id=2]
[node name="Canvas" type="Node2D"]
script = ExtResource( 1 )
[node name="Grid" type="Node2D" parent="."]
script = ExtResource( 2 )

View file

@ -160,6 +160,8 @@ func change_project() -> void:
i += 1
Global.zoom_level_label.text = str(round(100 / Global.camera.zoom.x)) + " %"
Global.canvas.update()
Global.canvas.grid.isometric_polylines.clear()
Global.canvas.grid.update()
Global.transparent_checker._ready()
Global.horizontal_ruler.update()
Global.vertical_ruler.update()

View file

@ -116,7 +116,8 @@ func preference_update(prop : String) -> void:
autosave_interval.mouse_default_cursor_shape = Control.CURSOR_FORBIDDEN
if prop in ["grid_width", "grid_height", "grid_color"]:
Global.canvas.update()
Global.canvas.grid.isometric_polylines.clear()
Global.canvas.grid.update()
if prop in ["checker_size", "checker_color_1", "checker_color_2", "checker_follow_movement", "checker_follow_scale"]:
Global.transparent_checker._ready()

53
src/UI/Grid.gd Normal file
View file

@ -0,0 +1,53 @@
extends Node2D
var location := Vector2.ZERO
var isometric_polylines := [] # An array of PoolVector2Arrays
func _draw() -> void:
if Global.draw_grid:
draw_grid(Global.grid_type)
func draw_grid(grid_type : int) -> void:
var size : Vector2 = Global.current_project.size
if grid_type == Global.Grid_Types.CARTESIAN || grid_type == Global.Grid_Types.ALL:
for x in range(Global.grid_width, size.x, Global.grid_width):
draw_line(Vector2(x, location.y), Vector2(x, size.y), Global.grid_color, true)
for y in range(Global.grid_height, size.y, Global.grid_height):
draw_line(Vector2(location.x, y), Vector2(size.x, y), Global.grid_color, true)
# Doesn't work properly yet
# Has problems when the canvas isn't a square, and with some grid sizes
if grid_type == Global.Grid_Types.ISOMETRIC || grid_type == Global.Grid_Types.ALL:
var i := 0
for x in range(Global.grid_width, size.x, Global.grid_width * 2):
for y in range(0, size.y, Global.grid_width):
draw_isometric_tile(i, Vector2(x, y))
i += 1
func draw_isometric_tile(i : int, origin := Vector2.RIGHT) -> void:
# A random value I found by trial and error, I have no idea why it "works"
var diff = 1.11754
var approx_30_degrees = deg2rad(26.565)
var pool := PoolVector2Array()
if i < isometric_polylines.size():
pool = isometric_polylines[i]
else:
var a = origin
var b = a + Vector2(cos(approx_30_degrees), sin(approx_30_degrees)) * Global.grid_width * diff
var c = a + Vector2.DOWN * Global.grid_width
var d = c - Vector2(cos(approx_30_degrees), sin(approx_30_degrees)) * Global.grid_width * diff
pool.append(a)
pool.append(b)
pool.append(c)
pool.append(d)
pool.append(a)
isometric_polylines.append(pool)
if pool.size() > 2:
draw_polyline(pool, Global.grid_color)

View file

@ -251,6 +251,7 @@ func toggle_tile_mode() -> void:
func toggle_show_grid() -> void:
Global.draw_grid = !Global.draw_grid
view_menu.set_item_checked(1, Global.draw_grid)
Global.canvas.grid.update()
func toggle_show_rulers() -> void: