0 votes

I am making a hex painter. If I scale the size up, it slows down drastically. I believe that the slowdown is either because each hex is an Area2D with collision which doesn't scale well, or because program prints everything via draw_line for the hex outlines and draw_polygon for the filled in spaces, and these functions are inefficient. What would be a more optimized alternative?

Godot version 3.2.3
in Engine by (145 points)
edited by

1 Answer

0 votes

Try using Tilemaps, see the documentation in the editor about TileMap and TileSet to see all their methods. You can change the texture of each cell or keep the same by changing the color by modulating, deleting, collisions, etc. To detect each cell with the mouse you can use its collisions or by position proximity. For the continuity of the selection with the mouse you can use a popular algorithm:

https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm

I created an empty tilemap with very small cells (4x4 pixel, no collision), and the drawing is fast.

func _process(delta):
    var pos=$TileMap.world_to_map(get_local_mouse_position())
    $TileMap.set_cell(pos.x, pos.y,0)

Although to avoid empty spaces you have to use the algorithm that I mentioned above or perhaps use a linear interpolation between each position of the mouse.

https://godotengine.org/asset-library/asset/111

by (2,010 points)

Here is an example:

extends Node2D
var pos=Vector2.ZERO

func _input(event):
    if Input.is_mouse_button_pressed(BUTTON_LEFT) and event is InputEventMouseMotion:
        var pos=$TileMap.world_to_map(event.position)
        var line=interpolated_line(event.position-event.relative, event.position)   
        for i in line:
            var w=$TileMap.world_to_map(Vector2(i[0], i[1]))
            $TileMap.set_cell(w.x,w.y,0)

func interpolated_line(p0, p1):
    var points = []
    var dx = p1[0] - p0[0]
    var dy = p1[1] - p0[1]
    var N = max(abs(dx), abs(dy))
    for i in N+1:
        var t = float(i) / float(N)
        var point = [round(lerp(p0[0], p1[0], t)), round(lerp(p0[1], p1[1], t))]
        points.append(point)
    return points
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.