Setup terrains system

This commit is contained in:
Zacharie Guet 2024-08-31 15:24:44 +02:00
parent 45dfd10d3e
commit 4f67fd3c4f
11 changed files with 291 additions and 0 deletions

9
objects/Map.tscn Normal file
View File

@ -0,0 +1,9 @@
[gd_scene load_steps=3 format=3 uid="uid://d3hul8b7hlmj7"]
[ext_resource type="Script" path="res://scripts/map.gd" id="1_3np0o"]
[ext_resource type="PackedScene" uid="uid://6ferubyu2uy1" path="res://scenes/Scanners.tscn" id="1_6mlj0"]
[node name="Map" type="Node2D"]
script = ExtResource("1_3np0o")
[node name="Scanners" parent="." instance=ExtResource("1_6mlj0")]

7
objects/Map7C51.tmp Normal file
View File

@ -0,0 +1,7 @@
[gd_scene load_steps=2 format=3 uid="uid://d3hul8b7hlmj7"]
[ext_resource type="PackedScene" uid="uid://6ferubyu2uy1" path="res://scenes/Scanners.tscn" id="1_6mlj0"]
[node name="Map" type="Node2D"]
[node name="Scanners" parent="." instance=ExtResource("1_6mlj0")]

7
objects/Map9254.tmp Normal file
View File

@ -0,0 +1,7 @@
[gd_scene load_steps=2 format=3 uid="uid://d3hul8b7hlmj7"]
[ext_resource type="PackedScene" uid="uid://6ferubyu2uy1" path="res://scenes/Scanners.tscn" id="1_6mlj0"]
[node name="Map" type="Node2D"]
[node name="Scanners" parent="." instance=ExtResource("1_6mlj0")]

7
objects/MapEC4B.tmp Normal file
View File

@ -0,0 +1,7 @@
[gd_scene load_steps=2 format=3 uid="uid://d3hul8b7hlmj7"]
[ext_resource type="PackedScene" uid="uid://6ferubyu2uy1" path="res://scenes/Scanners.tscn" id="1_6mlj0"]
[node name="Map" type="Node2D"]
[node name="Scanners" parent="." instance=ExtResource("1_6mlj0")]

View File

@ -15,6 +15,10 @@ run/main_scene="res://Game.tscn"
config/features=PackedStringArray("4.3", "Forward Plus")
config/icon="res://icon.svg"
[autoload]
GameTerrain="*res://scenes/Terrain.tscn"
[editor]
version_control/plugin_name="GitPlugin"

44
scenes/Scanners.tscn Normal file
View File

@ -0,0 +1,44 @@
[gd_scene load_steps=8 format=3 uid="uid://6ferubyu2uy1"]
[ext_resource type="Script" path="res://scripts/scanners.gd" id="1_orxwo"]
[ext_resource type="Shader" path="res://scripts/shaders/Scanner.gdshader" id="2_8t6wf"]
[sub_resource type="Gradient" id="Gradient_pafyk"]
offsets = PackedFloat32Array(0, 0.22549, 0.51634, 0.813725, 1)
colors = PackedColorArray(0.66677, 0.166288, 0, 1, 0.41, 0.328, 0, 1, 0, 0, 0, 1, 0, 0.592306, 0, 1, 0, 0.964706, 0.580392, 1)
[sub_resource type="GradientTexture1D" id="GradientTexture1D_mpkd3"]
gradient = SubResource("Gradient_pafyk")
[sub_resource type="ShaderMaterial" id="ShaderMaterial_yl6st"]
shader = ExtResource("2_8t6wf")
shader_parameter/dimension = 1
shader_parameter/gradient = SubResource("GradientTexture1D_mpkd3")
[sub_resource type="Gradient" id="Gradient_sc8ss"]
interpolation_mode = 1
offsets = PackedFloat32Array(0, 0.316568, 0.695266)
colors = PackedColorArray(1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1)
[sub_resource type="GradientTexture2D" id="GradientTexture2D_a7oi7"]
gradient = SubResource("Gradient_sc8ss")
fill_from = Vector2(0, 1)
fill_to = Vector2(1, 1)
[node name="Scanners" type="Node2D"]
script = ExtResource("1_orxwo")
[node name="Data" type="Sprite2D" parent="."]
visible = false
centered = false
[node name="Fertility" type="Sprite2D" parent="."]
visible = false
material = SubResource("ShaderMaterial_yl6st")
centered = false
[node name="Water" type="Sprite2D" parent="."]
visible = false
material = SubResource("ShaderMaterial_yl6st")
texture = SubResource("GradientTexture2D_a7oi7")
centered = false

7
scenes/Terrain.tscn Normal file
View File

@ -0,0 +1,7 @@
[gd_scene load_steps=2 format=3 uid="uid://bifyi58itph4i"]
[ext_resource type="Script" path="res://scripts/terrain.gd" id="1_5hbti"]
[node name="Terrain" type="Node2D"]
position = Vector2(391, 198)
script = ExtResource("1_5hbti")

2
scripts/map.gd Normal file
View File

@ -0,0 +1,2 @@
class_name Map
extends Node2D

11
scripts/scanners.gd Normal file
View File

@ -0,0 +1,11 @@
class_name Scanners
extends Node2D
func _ready():
for sprite in [$Water, $Fertility, $Data]:
sprite.texture = GameTerrain.get_texture()
sprite.scale = Vector2(GameTerrain.MAP_RATIO,GameTerrain.MAP_RATIO,)
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
pass

View File

@ -0,0 +1,48 @@
shader_type canvas_item;
#define pow2(x) (x * x)
#define iResolution 1.0/SCREEN_PIXEL_SIZE
uniform sampler2D gradient : source_color, filter_nearest;
uniform int dimension;
const float alpha = 0.3;
const float strength = 0.5;
const float pi = atan(1.0) * 4.0;
const int samples = 35;
const float sigma = float(samples) * 0.25;
float gaussian(vec2 i) {
return 1.0 / (2.0 * pi * pow(sigma,2)) * exp(-((pow(i.x,2) + pow(i.y,2)) / (2.0 * pow(sigma,2))));
}
vec3 blur(sampler2D sp, vec2 uv, vec2 scale) {
vec3 col = vec3(0.0);
float accum = 0.0;
float weight;
vec2 offset;
for (int x = -samples / 2; x < samples / 2; ++x) {
for (int y = -samples / 2; y < samples / 2; ++y) {
offset = vec2(float(x), float(y));
weight = gaussian(offset);
col += texture(sp, uv + scale * offset).rgb * weight;
accum += weight;
}
}
return col / accum;
}
void fragment() {
vec2 ps = vec2(1.0) / iResolution.xy * .000001 * strength;
vec2 uv = UV ;
vec3 pixel_color = blur(TEXTURE, uv, ps );
float value = pixel_color.x;
if (dimension == 1) value = pixel_color.y;
if (dimension == 2) value = pixel_color.z;
COLOR = texture(gradient, vec2(value, 0));
COLOR.a = alpha;
}

145
scripts/terrain.gd Normal file
View File

@ -0,0 +1,145 @@
extends Node2D
enum Stats {WATER, FERTILITY, TEMPERATURE}
const TERRAIN_SIZE = Vector2i(300, 300)
const LEVELS_NUMBER : int = 10
const MAP_RATIO = 4;
@onready var image := Image.create_empty(
TERRAIN_SIZE.x,
TERRAIN_SIZE.y,
true,
Image.Format.FORMAT_RGBF
)
@onready var texture : ImageTexture = ImageTexture.create_from_image(image)
var sum := 0.0
signal terrain_updated
func _ready():
setup_texture(Vector3i())
func map_to_pixel(
position : Vector2
) -> Vector2i :
return Vector2i(
int(position.x / MAP_RATIO),
int(position.y / MAP_RATIO)
)
func color_value_to_level(
color_value : float
) -> int:
return roundi(color_value*LEVELS_NUMBER) - LEVELS_NUMBER/2
func color_to_levels(
color: Color
) -> Vector3i :
return Vector3i(
color_value_to_level(color.r),
color_value_to_level(color.g),
color_value_to_level(color.b),
)
func level_to_color_value(
level : int
) -> float:
var limited_level = max(
min(
level,
LEVELS_NUMBER/2
),
-LEVELS_NUMBER/2
)
return float(limited_level+LEVELS_NUMBER/2)/LEVELS_NUMBER
func levels_to_color(
levels: Vector3i
) -> Color :
return Color(
level_to_color_value(levels.x),
level_to_color_value(levels.y),
level_to_color_value(levels.z)
)
func modification_to_levels(
stat: Stats,
modification: int
) -> Vector3i :
var levels = Vector3i()
match stat:
Stats.WATER:
levels.x = modification
Stats.FERTILITY:
levels.y = modification
Stats.TEMPERATURE:
levels.z = modification
return levels
func modify_pixel(
pixel_pos: Vector2i,
stat: Stats,
modification: int,
):
var actual_levels = color_to_levels(image.get_pixelv(pixel_pos))
var modification_levels = modification_to_levels(stat, modification)
var calculated_levels = actual_levels + modification_levels
set_pixel(pixel_pos, calculated_levels)
func set_pixel(
pixel_pos: Vector2i,
level: Vector3i,
):
image.set_pixelv(pixel_pos, levels_to_color(level))
func modify_zone(
center: Vector2,
radius: float,
stat : Stats,
modification: int
):
var pixel_center = map_to_pixel(center)
var pixel_radius = int(radius / MAP_RATIO)
for x in range(pixel_center.x - pixel_radius, pixel_center.x + pixel_radius + 1) :
for y in range(pixel_center.y - pixel_radius, pixel_center.y + pixel_radius + 1):
if pow(x - pixel_center.x,2) + pow(y - pixel_center.y,2) <= pow(pixel_radius,2):
modify_pixel(
Vector2i(x, y),
stat,
modification
)
update_texture()
func modify_rect(
pos: Vector2,
size: Vector2,
stat : Stats,
modification: int
):
var pixel_pos = map_to_pixel(pos)
var pixel_size = map_to_pixel(size)
for x in range(pixel_pos.x, pixel_pos.x+pixel_size.x) :
for y in range(pixel_pos.y, pixel_pos.y+pixel_size.y):
modify_pixel(
Vector2i(x, y),
stat,
modification
)
update_texture()
func setup_texture(
levels : Vector3i
):
for x in range(0, TERRAIN_SIZE.x) :
for y in range(0, TERRAIN_SIZE.y):
set_pixel(Vector2i(x,y), levels)
update_texture()
func update_texture():
emit_signal("terrain_updated")
texture.update(image)
func get_texture():
return texture