Add main Godot project files
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
extends Camera2D
|
||||
|
||||
@export var min_zoom: float = 0.5
|
||||
@export var max_zoom: float = 4.0
|
||||
@export var zoom_speed: float = 0.1
|
||||
@export var target_zoom: float = 2.0
|
||||
|
||||
func _ready() -> void:
|
||||
zoom = Vector2(target_zoom, target_zoom)
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if event is InputEventMouseButton:
|
||||
if event.button_index == MOUSE_BUTTON_WHEEL_UP:
|
||||
target_zoom = clamp(target_zoom - zoom_speed, min_zoom, max_zoom)
|
||||
elif event.button_index == MOUSE_BUTTON_WHEEL_DOWN:
|
||||
target_zoom = clamp(target_zoom + zoom_speed, min_zoom, max_zoom)
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
var current_zoom = zoom.x
|
||||
var new_zoom = lerp(current_zoom, target_zoom, delta * 10)
|
||||
zoom = Vector2(new_zoom, new_zoom)
|
||||
@@ -0,0 +1 @@
|
||||
uid://c77xgwesiblyk
|
||||
@@ -0,0 +1,37 @@
|
||||
extends CanvasLayer
|
||||
|
||||
@onready var health_bar = $PanelStats/VBox/HealthBar
|
||||
@onready var health_label = $PanelStats/VBox/HealthLabel
|
||||
@onready var stamina_bar = $PanelStats/VBox/StaminaBar
|
||||
@onready var stamina_label = $PanelStats/VBox/StaminaLabel
|
||||
@onready var hunger_bar = $PanelStats/VBox/HungerBar
|
||||
@onready var hunger_label = $PanelStats/VBox/HungerLabel
|
||||
@onready var thirst_bar = $PanelStats/VBox/ThirstBar
|
||||
@onready var thirst_label = $PanelStats/VBox/ThirstLabel
|
||||
@onready var mood_bar = $PanelStats/VBox/MoodBar
|
||||
@onready var mood_label = $PanelStats/VBox/MoodLabel
|
||||
@onready var heart_label = $PanelStats/VBox/HeartLabel
|
||||
@onready var lungs_label = $PanelStats/VBox/LungsLabel
|
||||
@onready var brain_label = $PanelStats/VBox/BrainLabel
|
||||
@onready var cyber_label = $PanelStats/VBox/CyberLabel
|
||||
|
||||
func update_stats(stats: Dictionary) -> void:
|
||||
health_bar.value = stats.health
|
||||
health_label.text = "Здоровье: %d" % stats.health
|
||||
|
||||
stamina_bar.value = stats.stamina
|
||||
stamina_label.text = "Выносливость: %d" % stats.stamina
|
||||
|
||||
hunger_bar.value = stats.hunger
|
||||
hunger_label.text = "Голод: %d" % stats.hunger
|
||||
|
||||
thirst_bar.value = stats.thirst
|
||||
thirst_label.text = "Жажда: %d" % stats.thirst
|
||||
|
||||
mood_bar.value = stats.mood
|
||||
mood_label.text = "Настроение: %d" % stats.mood
|
||||
|
||||
heart_label.text = "Сердце: %d%%" % stats.organs.heart
|
||||
lungs_label.text = "Лёгкие: %d%%" % stats.organs.lungs
|
||||
brain_label.text = "Мозг: %d%%" % stats.organs.brain
|
||||
cyber_label.text = "Кибер-имплант: %d%%" % stats.organs.cyber
|
||||
@@ -0,0 +1 @@
|
||||
uid://bpbyi111yqlt1
|
||||
@@ -0,0 +1,224 @@
|
||||
extends Node2D
|
||||
|
||||
@export var map_width: int = 80
|
||||
@export var map_height: int = 80
|
||||
@export var tile_size: int = 64
|
||||
|
||||
var rng = RandomNumberGenerator.new()
|
||||
var zone_map = []
|
||||
var region_map = []
|
||||
var tile_map: TileMap
|
||||
|
||||
const ZONE_ASPHALT = 0
|
||||
const ZONE_CONCRETE = 1
|
||||
const ZONE_GROUND = 2
|
||||
const ZONE_GRASS = 3
|
||||
const ZONE_STEEL = 4
|
||||
const ZONE_WATER = 5
|
||||
|
||||
var zone_textures = {}
|
||||
|
||||
func _ready() -> void:
|
||||
rng.randomize()
|
||||
tile_map = get_node("/root/Main/TileMap")
|
||||
|
||||
if not tile_map:
|
||||
push_error("TileMap not found!")
|
||||
return
|
||||
|
||||
load_textures()
|
||||
generate_map()
|
||||
|
||||
func load_textures() -> void:
|
||||
var base = "res://assets/seamless/"
|
||||
var ts = TileSet.new()
|
||||
ts.tile_size = Vector2i(tile_size, tile_size)
|
||||
|
||||
zone_textures = {
|
||||
ZONE_ASPHALT: ["asfalt1.jpg", "asfalt2.jpg", "asfalt3.jpg", "asfalt4.jpg", "asfalt5.jpg"],
|
||||
ZONE_CONCRETE: ["beton1.jpg", "beton2.jpg", "beton3.jpg", "beton4.jpg", "beton5.jpg"],
|
||||
ZONE_GROUND: ["ground1.jpg", "ground2.jpg", "ground3.jpg", "ground4.jpg", "ground5.jpg",
|
||||
"ground6.jpg", "ground7.jpg", "ground8.jpg", "ground9.jpg", "ground10.jpg"],
|
||||
ZONE_GRASS: ["grass1.jpg", "grass2.jpg", "grass3.jpg", "grass4.jpg", "grass5.jpg"],
|
||||
ZONE_STEEL: ["steel1.jpg", "steel2.jpg", "steel3.jpg", "steel4.jpg", "steel5.jpg"],
|
||||
}
|
||||
|
||||
var source_id = 0
|
||||
for zone in zone_textures:
|
||||
var textures = zone_textures[zone]
|
||||
var zone_sources = []
|
||||
|
||||
for tex_name in textures:
|
||||
var full_path = base + tex_name
|
||||
var tex = load(full_path)
|
||||
if tex:
|
||||
var source = TileSetAtlasSource.new()
|
||||
source.texture = tex
|
||||
source.texture_region_size = Vector2i(tile_size, tile_size)
|
||||
source.create_tile(Vector2i(0, 0))
|
||||
ts.add_source(source, source_id)
|
||||
zone_sources.append(source_id)
|
||||
source_id += 1
|
||||
|
||||
zone_textures[zone] = zone_sources
|
||||
|
||||
tile_map.tile_set = ts
|
||||
|
||||
func generate_map() -> void:
|
||||
zone_map.clear()
|
||||
region_map.clear()
|
||||
|
||||
for x in range(map_width):
|
||||
zone_map.append([])
|
||||
region_map.append([])
|
||||
for y in range(map_height):
|
||||
zone_map[x].append(-1)
|
||||
region_map[x].append(-1)
|
||||
|
||||
generate_zones()
|
||||
add_water_features()
|
||||
smooth_zones()
|
||||
identify_regions()
|
||||
draw_map()
|
||||
|
||||
func generate_zones() -> void:
|
||||
for x in range(map_width):
|
||||
for y in range(map_height):
|
||||
var h = get_noise(x, y)
|
||||
var zone = get_zone(h)
|
||||
zone_map[x][y] = zone
|
||||
|
||||
func get_noise(x: int, y: int) -> float:
|
||||
var s = 0.05
|
||||
var v = sin(x * s * 2) * cos(y * s * 1.5)
|
||||
v += sin(x * s * 4 + y * s * 3) * 0.3
|
||||
v += sin(x * s * 8 + y * s * 7) * 0.15
|
||||
return clamp(v * 0.5 + 0.5, 0.0, 1.0)
|
||||
|
||||
func get_zone(val: float) -> int:
|
||||
if val < 0.15:
|
||||
return ZONE_ASPHALT
|
||||
elif val < 0.3:
|
||||
return ZONE_CONCRETE
|
||||
elif val < 0.45:
|
||||
return ZONE_STEEL
|
||||
elif val < 0.65:
|
||||
return ZONE_GROUND
|
||||
else:
|
||||
return ZONE_GRASS
|
||||
|
||||
func add_water_features() -> void:
|
||||
for _i in range(8):
|
||||
var rx = rng.randi() % map_width
|
||||
var ry = rng.randi() % map_height
|
||||
create_water_body(rx, ry, rng.randi() % 3 + 1)
|
||||
|
||||
func create_water_body(start_x: int, start_y: int, size: int) -> void:
|
||||
var queue = [{"x": start_x, "y": start_y}]
|
||||
var visited = {}
|
||||
visited[str(start_x) + "," + str(start_y)] = true
|
||||
|
||||
var count = 0
|
||||
while not queue.is_empty() and count < size * 15:
|
||||
var current = queue.pop_front()
|
||||
var x = current.x
|
||||
var y = current.y
|
||||
|
||||
if x >= 0 and x < map_width and y >= 0 and y < map_height:
|
||||
if zone_map[x][y] != ZONE_WATER:
|
||||
zone_map[x][y] = ZONE_WATER
|
||||
count += 1
|
||||
|
||||
var dirs = [[0,1], [0,-1], [1,0], [-1,0]]
|
||||
for d in dirs:
|
||||
var nx = x + d[0]
|
||||
var ny = y + d[1]
|
||||
var key = str(nx) + "," + str(ny)
|
||||
if not visited.has(key):
|
||||
visited[key] = true
|
||||
if rng.randf() > 0.3:
|
||||
queue.append({"x": nx, "y": ny})
|
||||
|
||||
func smooth_zones() -> void:
|
||||
for iter in range(2):
|
||||
var new_zone = []
|
||||
for x in range(map_width):
|
||||
new_zone.append([])
|
||||
for y in range(map_height):
|
||||
new_zone[x].append(zone_map[x][y])
|
||||
|
||||
for x in range(1, map_width - 1):
|
||||
for y in range(1, map_height - 1):
|
||||
if zone_map[x][y] == ZONE_WATER:
|
||||
continue
|
||||
|
||||
var counts = {}
|
||||
for dx in [-1, 0, 1]:
|
||||
for dy in [-1, 0, 1]:
|
||||
var n = zone_map[x + dx][y + dy]
|
||||
if n != ZONE_WATER:
|
||||
counts[n] = counts.get(n, 0) + 1
|
||||
|
||||
var max_count = 0
|
||||
var dominant = zone_map[x][y]
|
||||
for z in counts:
|
||||
if counts[z] > max_count:
|
||||
max_count = counts[z]
|
||||
dominant = z
|
||||
|
||||
if max_count >= 6:
|
||||
new_zone[x][y] = dominant
|
||||
|
||||
zone_map = new_zone
|
||||
|
||||
func identify_regions() -> void:
|
||||
var visited = {}
|
||||
var region_id = 0
|
||||
|
||||
for x in range(map_width):
|
||||
for y in range(map_height):
|
||||
var key = str(x) + "," + str(y)
|
||||
if visited.has(key):
|
||||
continue
|
||||
|
||||
var zone = zone_map[x][y]
|
||||
var queue = [{"x": x, "y": y}]
|
||||
visited[key] = true
|
||||
|
||||
while not queue.is_empty():
|
||||
var current = queue.pop_front()
|
||||
var cx = current.x
|
||||
var cy = current.y
|
||||
|
||||
region_map[cx][cy] = region_id
|
||||
|
||||
var dirs = [[0,1], [0,-1], [1,0], [-1,0]]
|
||||
for d in dirs:
|
||||
var nx = cx + d[0]
|
||||
var ny = cy + d[1]
|
||||
var nkey = str(nx) + "," + str(ny)
|
||||
|
||||
if nx >= 0 and nx < map_width and ny >= 0 and ny < map_height:
|
||||
if not visited.has(nkey) and zone_map[nx][ny] == zone:
|
||||
visited[nkey] = true
|
||||
queue.append({"x": nx, "y": ny})
|
||||
|
||||
region_id += 1
|
||||
|
||||
func draw_map() -> void:
|
||||
for x in range(map_width):
|
||||
for y in range(map_height):
|
||||
place_tile(x, y, zone_map[x][y], region_map[x][y])
|
||||
|
||||
func place_tile(x: int, y: int, zone: int, region: int) -> void:
|
||||
if not zone_textures.has(zone):
|
||||
zone = ZONE_GROUND
|
||||
|
||||
var sources = zone_textures[zone]
|
||||
if sources.is_empty():
|
||||
return
|
||||
|
||||
var variant_idx = region % sources.size()
|
||||
var source_id = sources[variant_idx]
|
||||
|
||||
tile_map.set_cell(0, Vector2i(x, y), source_id, Vector2i(0, 0))
|
||||
@@ -0,0 +1 @@
|
||||
uid://bpsfqa4sjj52v
|
||||
Reference in New Issue
Block a user