Compare commits

...

3 Commits

  1. BIN
      map.png
  2. 35
      map.png.import
  3. 4
      menu/MainMenu.tscn
  4. 10
      project.godot
  5. 9
      ui/map/cursor/Cursor.gd
  6. 117
      ui/map/map.gd
  7. 6
      ui/map/map.tscn
  8. 59
      utils/Global.gd
  9. 6
      utils/camera/CameraController.gd
  10. 2
      utils/camera/CameraInput.gd
  11. 51
      utils/map/map.gd
  12. 67
      utils/terrain/Terrain.gd
  13. 11
      utils/world_generation/WorldGeneration.gd
  14. 7
      world/game.tscn

Binary file not shown.

After

Width:  |  Height:  |  Size: 448 KiB

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/map.png-9eea34967fae34f4388f4a32a16da936.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://map.png"
dest_files=[ "res://.import/map.png-9eea34967fae34f4388f4a32a16da936.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

@ -47,10 +47,6 @@ margin_right = 360.0
margin_bottom = 377.0
text = "Quitter"
[node name="Viewport" type="Viewport" parent="."]
size = Vector2( 2048, 2048 )
own_world = true
[connection signal="pressed" from="VBoxContainer/NewButton" to="." method="_on_NewButton_pressed"]
[connection signal="pressed" from="VBoxContainer/LoadButton" to="." method="_on_LoadButton_pressed"]
[connection signal="pressed" from="VBoxContainer/QuitButton" to="." method="_on_QuitButton_pressed"]

@ -30,6 +30,11 @@ _global_script_classes=[ {
"path": "res://utils/loading/LoadingHelper.gd"
}, {
"base": "Reference",
"class": "Map",
"language": "GDScript",
"path": "res://utils/map/map.gd"
}, {
"base": "Reference",
"class": "PoissonDiscSampling",
"language": "GDScript",
"path": "res://addons/PoissonDiscSampling/PoissonDiscSampling.gd"
@ -54,6 +59,7 @@ _global_script_class_icons={
"CameraOutline": "",
"Delaunator": "",
"LoadingHelper": "",
"Map": "",
"PoissonDiscSampling": "",
"Terrain": "",
"TerrainMesh": "",
@ -70,6 +76,10 @@ config/icon="res://icon.png"
Global="*res://utils/Global.gd"
[display]
window/dpi/allow_hidpi=true
[editor_plugins]
enabled=PoolStringArray( )

@ -3,6 +3,9 @@ extends Sprite
func _on_Camera_camera_moved(new_location):
var map_x = new_location.x
var map_y = new_location.z
position.x = map_x
position.y = map_y
pass # Replace with function body.
position.x = map_x / 4.0
position.y = map_y / 4.0
func _ready():
scale.x = 1
scale.y = 1

@ -1,113 +1,18 @@
extends Node2D
extends TextureRect
signal map_clicked
func heightmap():
draw_rect(Rect2(Vector2(0, 0), Vector2(2048, 2048)), Color("#0e88bd"))
var coastline = PoolVector2Array()
for center in Global.terrain.get_centers():
if not center.get_data("ocean"):
var colors = Gradient.new()
colors.add_point(0.999, Color("#9e0142")) # red
colors.add_point(0.5, Color("#dc865d")) # orange
colors.add_point(0.25, Color("#fbf8b0")) # yellow
colors.add_point(0.0, Color("#89cfa5")) # green
colors.add_point(-0.999, Color("#5e4fa2")) # blue
var color = colors.interpolate(min(center.get_elevation() + 0.001, 0.999))
var moisture = center.get_data("moisture")
if moisture:
color = colors.interpolate(max(min(moisture + 0.001, 0.999), 0.001))
# color = Color.green
if center.get_data("ocean"):
# var factor = pow((center.get_elevation()+1.001), 10) / 5.0
color = Color("#5e4fa2")
# if center.get_data("snow"):
# color = Color.white
# if center.get_data("coast"):
# color = Color.black
if center.polygon().size() > 2:
draw_polygon(center.polygon(), PoolColorArray([color]))
if center.get_data("coast"):
for border in center.borders():
if (border.end_center().get_data("ocean")):
coastline.append(border.line()[0])
coastline.append(border.line()[1])
# for edge in Global.terrain.get_edges():
# if edge.get_data("coast"):
# if edge.get_data("river"):
# draw_line(edge.line()[0], edge.line()[1], Color.blue, 5.0)
draw_multiline(coastline, Color.black)
func draw_triangles_edges(color=Color("#000000")):
for line in Global.terrain.get_edges_as_line():
draw_line(line[0], line[1], color)
func draw_voronoi_edges(color=Color("#000000")):
for line in Global.terrain.get_voronoi_edges_as_line():
draw_line(line[0], line[1], color)
func draw_voronoi_cells_old():
var seen = []
for edge_idx in Global.terrain.edges():
var triangles = []
var vertices = []
var p = Global.terrain._triangles[Global.terrain.next_half_edge(edge_idx)]
if not seen.has(p):
seen.append(p)
var edges = Global.terrain.edges_around_point(edge_idx)
for edge_around_idx in edges:
triangles.append(Global.terrain.triangle_of_edge(edge_around_idx))
for triangle in triangles:
vertices.append(Global.terrain.triangle_center(triangle))
if triangles.size() > 2:
var color = Color(randf(), randf(), randf(), 1)
var voronoi_cell = PoolVector2Array()
for vertice in vertices:
voronoi_cell.append(Vector2(vertice.x, vertice.z))
draw_polygon(voronoi_cell, PoolColorArray([color]))
func draw_voronoi_cells():
for polygon in Global.terrain.get_voronoi_cells_as_polygon():
var color = Color(randf(), randf(), randf(), 1)
if polygon.size() > 2:
draw_polygon(polygon, PoolColorArray([color]))
func draw_voronoi_cells_convex_hull():
for point_idx in Global.terrain.points():
var triangles = []
var vertices = []
var incoming = Global.terrain._points_to_half_edges.get(point_idx)
if incoming == null:
triangles.append(0)
else:
var edges = Global.terrain.edges_around_point(incoming)
for edge_idx in edges:
triangles.append(Global.terrain.triangle_of_edge(edge_idx))
for triangle_idx in triangles:
vertices.append(Global.terrain.triangle_center(triangle_idx))
if triangles.size() > 2:
var color = Color(randf(), randf(), randf(), 1)
var voronoi_cell = PoolVector2Array()
for vertice in vertices:
voronoi_cell.append(Vector2(vertice[0], vertice[1]))
draw_polygon(voronoi_cell, PoolColorArray([color]))
func _draw():
heightmap()
# draw_voronoi_cells()
# draw_triangles_edges()
# draw_voronoi_cells_convex_hull()
# draw_voronoi_edges(Color("#ff0000"))
func _ready():
var file_name = 'user://terrain/%s/map.png' % (Global.terrain_name)
var image = Image.new()
var err = image.load(file_name)
if err != OK:
print('Image load failed : %s' % (file_name))
texture = ImageTexture.new()
texture.create_from_image(image, Image.FORMAT_RGBA8)
func _process(_delta):
if Input.is_action_pressed("alt_command"):
var new_position = get_viewport().get_mouse_position() / scale
if new_position.x <= 2000 and new_position.y <= 2000:
var new_position = get_viewport().get_mouse_position()
if new_position.x <= 512 and new_position.y <= 512:
emit_signal("map_clicked", new_position)

@ -4,7 +4,11 @@
[ext_resource path="res://ui/map/cursor/cursor.png" type="Texture" id=2]
[ext_resource path="res://ui/map/cursor/Cursor.gd" type="Script" id=3]
[node name="Map" type="Node2D"]
[node name="Map" type="TextureRect"]
anchor_right = 0.5
anchor_bottom = 0.852
margin_right = 3.0
margin_bottom = 0.799988
script = ExtResource( 1 )
[node name="Cursor" type="Sprite" parent="."]

@ -4,6 +4,7 @@ var debug = true
var terrain_name = ""
var terrain_mesh: Mesh
var terrain = Terrain.new()
var map = Map.new(terrain)
# var loading = LoadingHelper.new()
var loadings = {}
var materials
@ -15,6 +16,64 @@ func _ready():
materials = JSON.parse(file.get_as_text()).result
file.close()
func polygon_area(polygon):
var a = 0.0
var b = 0.0
var next = 0
var size = polygon.size()
if(Geometry.is_polygon_clockwise(polygon)):
for idx in range(size-1, -1, -1):
next = idx - 1
if(next == 0):
next = size - 1
a += polygon[idx].x * polygon[next].y
b += polygon[idx].y * polygon[next].x
else:
for idx in size:
next = idx + 1
if(next == size):
next = 0
a += polygon[idx].x * polygon[next].y
b += polygon[idx].y * polygon[next].x
return((a - b) / 2.0)
func polygon_bounding_box(polygon):
var size = polygon.size()
var min_x = 99999999
var max_x = -99999999
var min_y = 99999999
var max_y = -99999999
var polygon_xmin = 0
var polygon_xmax = 1
var polygon_ymin = 0
var polygon_ymax = 1
for idx in size:
polygon_xmin = int(polygon[idx].x)
polygon_xmax = polygon_xmin + 1
polygon_ymin = int(polygon[idx].y)
polygon_ymax = polygon_ymin + 1
if(polygon_xmin < min_x):
min_x = polygon_xmin
if(polygon_xmax > max_x):
max_x = polygon_xmax
if(polygon_ymin < min_y):
min_y = polygon_ymin
if(polygon_ymax > max_y):
max_y = polygon_ymax
return(Rect2(min_x,min_y,max_x - min_x, max_y - min_y))
func pixel_area(voronoi, pixel):
var polygons = Geometry.intersect_polygons_2d(voronoi, pixel)
var number = polygons.size()
var area = 0.0
if(number == 0):
return(0.0)
if(number > 1):
print_debug("Number of polygons : %d" % (number))
for idx in number:
area += polygon_area(polygons[idx])
return(area)
# Debuging messages
func print_debug(message):
if debug:

@ -50,7 +50,7 @@ func change_action(action):
CAMERA_ACTIONS.ROTATING_VIEW:
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
func _process(delta):
func _process(_delta):
match(current_action):
CAMERA_ACTIONS.MOVING:
@ -121,8 +121,8 @@ func rotate_view(axis : Vector2):
rotation.y = yaw
func teleport(position):
global_transform.origin.x = position.x
global_transform.origin.z = position.y
global_transform.origin.x = position.x * 4.0
global_transform.origin.z = position.y * 4.0
var y_offset = 0
var space_state = get_world().direct_space_state

@ -139,7 +139,7 @@ func _input(event):
mouse_wheel += direction * get_process_delta_time() * 1000
###################PC
func _process(delta):
func _process(_delta):
#PC######
match(current_action):

@ -0,0 +1,51 @@
extends Reference
# Build terrain from delaunay graph
class_name Map
var image
var terrain
# Called when the node enters the scene tree for the first time.
func _init(a_terrain):
self.terrain = a_terrain
a_terrain.set_data("map",self)
func gen_map():
Global.loadings["world_creation"].new_phase("Generation de la carte...", terrain._points.size())
image = Image.new()
image.create(terrain._width,terrain._height,false,Image.FORMAT_RGBA8)
image.lock()
image.fill(Color('#5aa6ca'))
image.unlock()
var file_name = "user://terrain/%s/map.png" % (terrain.get_name())
for center in terrain.get_centers():
if not center.get_data("water"):
var voronoi = center.get_data("voronoi")
var voronoi_bounding_box = center.get_data("voronoi_bounding_box")
# print_debug("Creat voronoi image")
var voronoi_image = Image.new()
voronoi_image.create(int(voronoi_bounding_box.size.x), int(voronoi_bounding_box.size.y),false,Image.FORMAT_RGBA8)
voronoi_image.lock()
for x in int(voronoi_bounding_box.size.x):
for y in int(voronoi_bounding_box.size.y):
var pixel = []
pixel.append(Vector2(voronoi_bounding_box.position.x + x, voronoi_bounding_box.position.y + y))
pixel.append(Vector2(voronoi_bounding_box.position.x + x + 1, voronoi_bounding_box.position.y + y))
pixel.append(Vector2(voronoi_bounding_box.position.x + x + 1, voronoi_bounding_box.position.y + y + 1))
pixel.append(Vector2(voronoi_bounding_box.position.x + x, voronoi_bounding_box.position.y + y + 1))
var alpha = Global.pixel_area(voronoi, pixel)
# print_debug("Alpha : %f" % (alpha))
var color
if center.get_data("coast"):
color = Color(0.708, 0.646, 0.138, alpha)
else:
color = Color(0.253, 0.621, 0.229, alpha)
voronoi_image.set_pixel(x,y,color)
image.lock()
image.blend_rect(voronoi_image,Rect2(0.0,0.0,voronoi_bounding_box.size.x,voronoi_bounding_box.size.y),voronoi_bounding_box.position)
image.unlock()
voronoi_image.unlock()
Global.loadings["world_creation"].increment_step()
image.save_png(file_name)

@ -106,7 +106,8 @@ class VoronoiCenter:
func corners():
var list_corners = []
for triangle in to_point().triangles_around():
var a_point = to_point()
for triangle in a_point.triangles_around():
var corner = VoronoiCorner.new(triangle)
list_corners.append(corner)
return list_corners
@ -291,7 +292,6 @@ class Triangle:
)
set_data("center2d", circumcenter)
return circumcenter
return circumcenter
# return (points[0].point2d() + points[1].point2d() + points[2].point2d()) / 3.0
@ -314,7 +314,6 @@ class Triangle:
)
set_data("center3d", circumcenter)
return circumcenter
return circumcenter
# var center2d = center2d()
# return Vector3(center2d.x, )
@ -430,15 +429,16 @@ class Point:
func edges_around():
var list_edges = []
var incoming = _terrain._points_to_halfedges.get(_idx)
var incoming_edge = Edge.new(incoming, _terrain)
var outgoing_edge
while true:
list_edges.append(incoming_edge);
outgoing_edge = incoming_edge.next_half()
incoming_edge = Edge.new(_terrain._halfedges[outgoing_edge._idx], _terrain);
if not (incoming_edge._idx != -1 and incoming_edge._idx != incoming):
break
if _terrain._points_to_halfedges.has(_idx):
var incoming = _terrain._points_to_halfedges.get(_idx)
var incoming_edge = Edge.new(incoming, _terrain)
var outgoing_edge
while true:
list_edges.append(incoming_edge);
outgoing_edge = incoming_edge.next_half()
incoming_edge = Edge.new(_terrain._halfedges[outgoing_edge._idx], _terrain);
if not (incoming_edge._idx != -1 and incoming_edge._idx != incoming):
break
return list_edges
func points_around():
@ -579,7 +579,7 @@ var _path = ""
var _list = []
# Terrain constructor
func _init(width:int=1600, height:int=800, spacing:int=30, create=false, name:String=""):
func _init():
var directory = Directory.new()
var file = File.new()
var file_name = ""
@ -616,18 +616,6 @@ func _init(width:int=1600, height:int=800, spacing:int=30, create=false, name:St
directory_name = directory.get_next()
directory.list_dir_end()
# Create or Load Terrain
_path = "user://terrain/%s" % (name)
parameter_file_name = "%s/param.save" % (_path)
graph_file_name = "%s/graph.save" % (_path)
data_file_name = "%s/data.save" % (_path)
if directory.open(_path) == OK and file.file_exists(parameter_file_name) and file.file_exists(graph_file_name) and file.file_exists(data_file_name) and not create:
Global.print_debug("loading : %s ..." % (name))
load(name)
else:
if name:
create(width, height, spacing, name)
func create(width:int, height:int, spacing:int, name:String):
Global.print_debug("Creating : %s ..." % (name))
var delaunay: Delaunator
@ -644,15 +632,6 @@ func create(width:int, height:int, spacing:int, name:String):
Global.loadings["world_creation"].new_phase("Initialisation du terrain...", get_points().size() + get_edges().size())
# Initialize find_point
_data["find_point"]=[]
_data["find_point"].resize(1024)
for idx in 1024:
_data["find_point"][idx]=[]
for point in get_points():
_data["find_point"][point.find_index()].append(point.get_index())
Global.loadings["world_creation"].increment_step()
# Initialize _points_to_halfedges
for edge in get_edges():
var endpoint = _triangles[edge.next_half().get_index()]
@ -660,6 +639,7 @@ func create(width:int, height:int, spacing:int, name:String):
_points_to_halfedges[endpoint] = edge.get_index()
Global.loadings["world_creation"].increment_step()
_create_find_point_table()
# Initialise _points_data
for point_idx in self.get_points().size():
_points_data.append({})
@ -678,6 +658,22 @@ func create(width:int, height:int, spacing:int, name:String):
_created = true
save()
# Create a table to find a point from vector2
func _create_find_point_table():
var find_point = []
# var corners = {}
# var edges = {}
find_point.resize(1024)
for idx in 1024:
find_point[idx]=[]
for point in get_points():
var point_index = point.get_index()
find_point[point.find_index()].append(point_index)
var center = point.to_center()
set_data("find_point",find_point)
# Create points on the terrain
func _create_points():
var rect = Rect2(Vector2(0, 0), Vector2(_width, _height))
@ -699,6 +695,9 @@ func get_data(key):
if _data.has(key):
return _data[key]
func get_name():
return _name
func get_temp_data(key):
if _temp_data.has(key):
return _temp_data[key]

@ -26,7 +26,7 @@ func _init():
Global.loadings["world_creation"].start(coeffs, "Chargement...", 100)
Global.terrain.load(Global.terrain_name)
else:
var coeffs = [0, 1, 2, 2, 2, 2, 2, 8]
var coeffs = [0, 1, 2, 2, 2, 2, 2, 8, 8]
Global.loadings["world_creation"].start(coeffs, "Start", 100)
Global.terrain.create(width,height,spacing,Global.terrain_name)
@ -36,6 +36,7 @@ func _init():
Global.terrain.save()
var terrain_mesh = TerrainMesh.new()
Global.terrain.set_temp_data("mesh", terrain_mesh.create_mesh())
Global.map.gen_map()
if Global.terrain.is_loaded():
var terrain_mesh = TerrainMesh.new()
@ -73,6 +74,7 @@ func init_data():
center.set_data("material", "stone")
if center.get_data("coast"):
center.set_data("material", "sand")
if (
not center.get_data("coast")
and not center.get_data("mountain")
@ -80,6 +82,13 @@ func init_data():
and center.get_data("moisture") > 0.3
):
center.set_data("forest", true)
if not center.get_data("water"):
var voronoi = center.polygon()
center.set_data("voronoi",voronoi)
var voronoi_bounding_box = Global.polygon_bounding_box(voronoi)
center.set_data("voronoi_bounding_box",voronoi_bounding_box)
Global.loadings["world_creation"].increment_step()

@ -165,7 +165,12 @@ shader_param/outline_color = Color( 0, 0, 0, 1 )
[node name="UI" parent="." instance=ExtResource( 1 )]
[node name="Map" parent="UI" index="0"]
scale = Vector2( 0.25, 0.25 )
anchor_right = 0.0
anchor_bottom = 0.0
margin_right = 512.0
margin_bottom = 512.0
expand = true
stretch_mode = 1
[node name="Cursor" parent="UI/Map" index="0"]
scale = Vector2( 4, 4 )

Loading…
Cancel
Save