Image-to-region-Godot
Sử dụng map trắng đen và có ShapeBurst được tạo bằng QGIS, sau code trên Godot Engine để cho phép chọn và highlight các region, province trong map.
Created date: 2023-05-30
1 Image-to-region-Godot¶
Để chuyển từ 1 sprite image 2D sáng multiple sprite thì cần phải tách từng sprite sang dạng opaque 100% cho mỗi sub sprite
Phù hợp trong tách region của bản đồ, như các quốc gia trên thế giới, sau đó dùng opaque_to_polygons
của bitmap
để tách từng polygon ra.
Khi sử dụng QGIS cần chú ý phải dùng ShapeBurst Fill
của Layer Styling
- Dùng 2 màu, màu 1 là transparent
- Màu 2 bất kỳ
- Chọn set distance > 3.0 để phân biệt rõ rệt các region của polygon
- Chọn blur Strength khoảng 5
- Tạo layer và export sang SVG để dùng cho Godot
Dưới đây là code để tách region
extends Node2D
@onready var node_to_save = $"."
var scene = PackedScene.new()
@export var hide_raw_map:bool
@onready var map_sprite: Sprite2D = $MapSprite
func _ready() -> void:
create_polygon_from_sprite(map_sprite)
scene.pack(node_to_save)
ResourceSaver.save(scene, "res://test/MyScene2.tscn")
func create_polygon_from_sprite(sprite):
# Get the sprite's texture.
var texture = sprite.texture
# Get the sprite texture's size.
var texture_size = sprite.texture.get_size()
# Get the image from the sprite's texture.
var image = texture.get_image()
# Create a new bitmap.
var bitmap = BitMap.new()
# Create the bitmap from the image. We set the minimum alpha threshold.
bitmap.create_from_image_alpha(image, 0.1) # 0.1 (default threshold).
# Get the rect of the bitmap.
var bitmap_rect = Rect2(Vector2(0, 0), bitmap.get_size())
# Grow the bitmap if you need (we don't need it in this case).
#bitmap.grow_mask(0, bitmap_rect) # 2
# Convert all the opaque parts of the bitmap into polygons.
var polygons = bitmap.opaque_to_polygons(bitmap_rect, 1) # 2 (default epsilon).
print("There are %s region extracted from the image"%(polygons.size()))
# Check if there are polygons.
if polygons.size() > 1:
# Loop through all the polygons.
#map_sprite.visible = hide_raw_map
for i in range(polygons.size()):
# Create a new 'Polygon2D'.
var polygon = Polygon2D.new()
# Set the polygon and texture
polygon.polygon = polygons[i]
polygon.texture = texture
# Check if the sprite is centered to get the proper position.
if sprite.centered:
polygon.position = sprite.position - (texture_size / 2)
else:
polygon.position = sprite.position
# Take the sprite's scale into account and apply it to the position.
polygon.scale = sprite.scale
polygon.position *= polygon.scale
polygon.name = "country_%s"%i
# Create Area2d and collision shape
var area = Area2D.new()
area.name = "area_country_%s"%i
var collision = CollisionPolygon2D.new()
collision.name = "coll_country_%s"%i
collision.polygon = polygon.get_polygon() # return the PackedVector2Array
collision.scale = polygon.scale
collision.position = polygon.position
# add to scene
node_to_save.add_child(area)
area.add_child(collision)
#collision.add_child(polygon)
collision.set_owner(node_to_save)
#polygon.set_owner(node_to_save)
area.set_owner(node_to_save)
else:
print("Cannot extract the region from image")
2 Tạo Clickable region¶
func _ready() -> void:
create_polygon_from_sprite(map_sprite)
scene.pack(node_to_save)
ResourceSaver.save(scene, "res://test/MyScene2.tscn")
for area_item in country_area_list:
print(area_item.name)
var polygon = area_item.get_node("Polygon2D")
area_item.mouse_entered.connect(_on_Area2D_mouse_entered.bind(area_item))
area_item.mouse_exited.connect(_on_Area2D_mouse_exited.bind(area_item))
func _on_Area2D_mouse_entered(area):
area.modulate = Color(0, 1, 0)
func _on_Area2D_mouse_exited(area):
area.modulate = Color(1, 1, 1)
Trong Godot 4, cần phải sử dụng bind
để xác định các arguments sẽ được áp dụng trong function. Nếu không sử dụngg bind(area_item)
thì toàn bộ area_item
sẽ bị ảnh hưởng
Vậy là sau khoảng 3-4 ngày thì mình đã tìm được cách tách region từ map.
Trong game có lẽ sẽ tạo 1 fantasy map để hiển thị. Còn các map region này chỉ giúp select cho dễ
Backlinks¶
No other pages link to this page.
Created : May 30, 2023
Recent Posts
- 2024-11-02: BUỔI 10 - Phân tích thị trường
- 2024-11-02: BUỔI 11 - Phân tích thị trường
- 2024-11-02: BUỔI 12 - Phân tích sóng tăng
- 2024-11-02: BUỔI 13 - Phân tích hỏi đáp
- 2024-11-02: BUỔI 14 - Yếu tố kiểm soát
- 2024-11-02: BUỔI 15 - Hỏi đáp
- 2024-11-01: BUỔI 6 - Ôn lại và bổ sung
- 2024-11-01: BUỔI 7 - Chiến thuật Trend
- 2024-11-01: BUỔI 8 - Công thức điểm vào lệnh
- 2024-11-01: K2023 - BUỔI 9 - Quy trình vào lệnh