jueves, 30 de octubre de 2025

GDScript para Godot 4.5 provocar un sonido al entrar en un area y cerrar otro que venia por defecto;

 extends Area3D


# --- Referencia al Nodo de Sonido de Premio/Ganancia (EXISTENTE) ---

# El nodo AudioStreamPlayer3D debe ser un hijo de este Area3D.

@onready var audio_player: AudioStreamPlayer3D = $AudioStreamPlayer3D


# --- NUEVA REFERENCIA: Sonido de Daño (A DETENER) ---

# ⚠️ IMPORTANTE: Esta ruta DEBE ser correcta desde la raíz de este script.

#@onready var audio_player_daño = $CollisionShape3D/AudioStreamPlayer3DSONIDODEMEMATANLENTO

@onready var audio_player_daño = $"../CharacterBody3D/Area3D cuando entra en area MATAEROE/CollisionShape3D/AudioStreamPlayer3DSONIDODEMEMATANLENTO"


# --- Control de Cooldown (Enfriamiento) ---

# Evita que el sonido se repita frenéticamente por una sola colisión.

var can_play_sound: bool = true

const COOLDOWN_TIME: float = 0.5 # Tiempo de espera para poder reproducir de nuevo (0.5 segundos)



# --- FUNCIÓN DE COLISIÓN ---

# ⚠️ Conecta la señal 'area_entered' del Area3D a esta función.

func _on_area_entered(area: Area3D) -> void:

# 🔊 LÓGICA AÑADIDA: Detener el sonido de peligro 

if is_instance_valid(audio_player_daño) and audio_player_daño.playing:

audio_player_daño.stop()

print("Sonido de peligro detenido.")

# 1. Comprueba si el sonido de premio puede reproducirse

if can_play_sound and audio_player != null:

# 2. Reproduce el sonido de premio

audio_player.play()

print("Sonido de premio/ganancia generado.")

# 3. Inicia el cooldown

can_play_sound = false

# 4. Usa un Timer de la escena para restablecer la capacidad de reproducción después del cooldown.

get_tree().create_timer(COOLDOWN_TIME).timeout.connect(func(): can_play_sound = true)


# --- Comprobación Inicial ---

func _ready() -> void:

if audio_player == null:

push_error("ERROR: El nodo AudioStreamPlayer3D (premio) no fue encontrado. Revisa la ruta '$AudioStreamPlayer3D'.")

# Opcional: Comprobar el sonido de daño al inicio

if audio_player_daño == null:

push_error("ERROR: El nodo AudioStreamPlayer3DSONIDODEMEMATANLENTO no fue encontrado. Revisa la ruta.")




🔉🔉🔉🔉🔉🔉🔉🔉🔉🔉🔉🔉🔉🔉🔉🔉🔉🔉🔉🔉🔉🔉🔉🔉🔉🔉🔉🔉🔉🔉

Explicacion: La idea es que el player es herido por un enemigo, tiene consigo un sonido de apagamiento muerte, entonces cuando toca el botiquin ese sonido desaparece y aparece el sonido de energia nueva recuperada, esto va acompañado de un corazon que se va encojiendo, y que al tocar el botiquin se agranda asta estar sano...............

💗💗💗💗💗💗💗💗💗💗💗💗💗💗💗💗💗💗💗💗💗💗💗💗💗💗💗💗💗💗💗💗


extends Area3D

# Define la ruta de la escena de destino
@export var destination_scene_path: String = "res://ESCENAS/PROTAMUERTE.tscn"

# Define el tiempo de espera antes de cambiar de escena
const DELAY_TIME: float = 44.0 

# Bandera para asegurar que la acción solo se ejecute una vez
var is_scene_change_scheduled: bool = false 

# --- VARIABLES DEL ENCOGIMIENTO ---
@onready var corazon_mesh = $MeshInstance3D # ⚠️ Asegúrate de que esta ruta sea correcta
var is_shrinking: bool = false
var elapsed_shrink_time: float = 0.0

# --- VARIABLE CRÍTICA PARA CANCELAR EL TEMPORIZADOR ---
var active_timer: SceneTreeTimer = null

# --- VARIABLES DE SONIDO (BOTIQUÍN) ---
@onready var audio_player_botikin = $"Area3DBOTIKIN/AudioStreamPlayer3D" 
var can_play_botikin_sound: bool = true
const BOTIKIN_COOLDOWN_TIME: float = 1.0 

# --- NUEVA VARIABLE DE SONIDO (DAÑO) ---
# ⚠️ ¡IMPORTANTE! Asegúrate de que el AudioStreamPlayer3D exista exactamente en esta ruta:
@onready var audio_player_daño = $CollisionShape3D/AudioStreamPlayer3DSONIDODEMEMATANLENTO


# ----------------------------------------------------------------------
## FUNCIÓN DE DAÑO (INICIA / IGNORA ATAQUES)
# ----------------------------------------------------------------------

# Se ejecuta al recibir daño (conecta la señal 'area_entered' del área de daño)
func _on_area_entered(area):
# Si la secuencia ya está activa, ignoramos el nuevo ataque para CONGELAR el tiempo.
if is_scene_change_scheduled:
print("Ataque ignorado (CONGELACIÓN ACTIVA).")
return # Salimos de la función sin reiniciar
# 🔊 Reproducir el sonido de DAÑO al inicio de la secuencia
if is_instance_valid(audio_player_daño):
audio_player_daño.play()
# --- INICIO DE LA SECUENCIA (SOLO SI NO ESTABA ACTIVA) ---
set_monitoring(false) # Deshabilita el monitoreo para no recibir más daño
is_scene_change_scheduled = true
is_shrinking = true
elapsed_shrink_time = 0.0 
print("Colisión de daño detectada. Secuencia de muerte INICIADA.")
# 3. Crear y almacenar el nuevo temporizador
active_timer = get_tree().create_timer(DELAY_TIME)
active_timer.timeout.connect(_start_scene_change)


# ----------------------------------------------------------------------
## FUNCIÓN DE SALVACIÓN (TOCA EL BOTIQUÍN)
# ----------------------------------------------------------------------

func _on_area_3dbotikin_area_entered(area: Area3D) -> void:
# Solo actúa si la secuencia de muerte está activa
if is_scene_change_scheduled:
# --- LÓGICA DE SONIDO DEL BOTIQUÍN ---
if can_play_botikin_sound and is_instance_valid(audio_player_botikin):
audio_player_botikin.play()
can_play_botikin_sound = false
# Reinicia el cooldown
get_tree().create_timer(BOTIKIN_COOLDOWN_TIME).timeout.connect(func(): can_play_botikin_sound = true)
# Detener y cancelar la secuencia
is_shrinking = false 
is_scene_change_scheduled = false
if active_timer != null:
active_timer.timeout.disconnect(_start_scene_change)
active_timer = null
print("¡SALVADO! El botiquín ha detenido y restablecido el sistema.")
# Restaurar la escala y el contador de tiempo a cero (DESESCALADA)
if is_instance_valid(corazon_mesh):
corazon_mesh.scale = Vector3.ONE * 1.0 # Vuelve a tamaño completo
elapsed_shrink_time = 0.0              # Reinicia el tiempo
# Restaurar la capacidad de recibir daño
set_monitoring(true)


# ----------------------------------------------------------------------
## LÓGICA DE ANIMACIÓN (ENCOGIMIENTO)
# ----------------------------------------------------------------------

func _process(delta: float):
# Solo si el encogimiento ha sido iniciado y el mesh es válido
if is_shrinking and is_instance_valid(corazon_mesh):
elapsed_shrink_time += delta
# Calcular el factor de encogimiento
var scale_factor = 1.0 - (elapsed_shrink_time / DELAY_TIME)
scale_factor = max(0.0, scale_factor) 
# Aplicar la nueva escala
corazon_mesh.scale = Vector3.ONE * scale_factor
# Si el tiempo ha expirado, detenemos la animación
if elapsed_shrink_time >= DELAY_TIME:
is_shrinking = false


# ----------------------------------------------------------------------
## FUNCIÓN DE CAMBIO DE ESCENA
# ----------------------------------------------------------------------

func _start_scene_change():
# Forzamos la escala final a cero
if is_instance_valid(corazon_mesh):
corazon_mesh.scale = Vector3.ZERO
var error = get_tree().change_scene_to_file(destination_scene_path)
if error != OK:
push_error("Error al intentar cambiar de escena: ", error)
else:
print("¡GAME OVER! Cambio de escena realizado.")👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆



Explicacion: el GDscript de arriba pertenece al player esta linea es la que produce el sonido de muerte lenta desinflar el corazon    $CollisionShape3D/AudioStreamPlayer3DSONIDODEMEMATANLENTO--------------------------------------------------------------------------------------------------------------------------------------------------------------La verdad es complicado de entender, yo me ayudo de la IA que hace los GDScripts, de todas formas es dificil hay que saber que se quiere hacer, hay que saber donde ponerlo, hay que saber las rutas de los archibos de sonidos, colocarlos correctamente al arrastrarlos al GDScript, tiene miga todo incluso si los GDScript te lo hace una IA, tambien tienes que pensar, pero en fin es fantastica la ayuda que ofrece hoy en dia la IA con estos temas.


miércoles, 29 de octubre de 2025

GDScript para Godot 4.5, 3d, cañon dispara el solo, y al ser impactado es destruido.;

 extends Area3D


# --- Variables Originales del Disparo ---

var Bullet = preload("res://PROTAGONISTA/area_3d_proyectil_en_si_mismoENEMIGO.tscn")

var timer = Timer.new()

var tiempo_disparo = 0.5  # Tiempo entre disparos en segundos


# --- NUEVA VARIABLE: Escena de la Astilla ---

# ⚠️ CAMBIA ESTA RUTA por la ruta real de tu escena "Astilla.tscn"

const ASTILLA_SCENE_PATH = "res://BARCO ELEMENTOS TEXTURAS/CAÑONES/TIBURON REVENTAO-3-.tscn"

var Astilla = preload(ASTILLA_SCENE_PATH) 



func _ready():

# Lógica original del Timer para disparar

add_child(timer)

timer.timeout.connect(_on_timer_timeout)

timer.start(tiempo_disparo)


# ⚠️ MUY IMPORTANTE: Conecta la señal 'area_entered' de este Area3D

# en el editor de Godot a la función '_on_area_entered'.



func _on_timer_timeout():

var bullet = Bullet.instantiate()

add_child(bullet)



# ----------------------------------------------------------------------

## FUNCIÓN DE COLISIÓN (Se ejecuta al tocar)

# ----------------------------------------------------------------------


# Se ejecuta cuando otro Área entra en la nuestra.

func _on_area_entered(area: Area3D):

_destroy_and_instantiate()


# Si quieres que se destruya al tocar un cuerpo físico (como el jugador o un RigidBody3D),

# usa también la señal 'body_entered'.

func _on_body_entered(body: Node3D):

_destroy_and_instantiate()



# ----------------------------------------------------------------------

## LÓGICA DE INSTANCIACIÓN Y DESTRUCCIÓN

# ----------------------------------------------------------------------


func _destroy_and_instantiate():

# 1. Instanciar la Astilla

var astilla = Astilla.instantiate()

# 2. Posicionar la Astilla en la ubicación de este nodo

# Usamos get_parent() para añadir la astilla al mismo nivel que este nodo,

# asegurando que se muestre correctamente en el mundo.

if is_instance_valid(get_parent()):

get_parent().add_child(astilla)

astilla.global_transform = global_transform

print("Colisión detectada. Instanciando Astilla y destruyendo nodo actual.")

# 3. Eliminar este nodo del árbol de la escena

queue_free()

viernes, 17 de octubre de 2025

extends Skeleton3D GDScript lo gira como peonza en su eje -y-;

 extends Skeleton3D

# Archivo: GirarComoPeonza.gd

 # O el nodo al que se adjunte (CharacterBody3D, Skeleton3D, etc.)


# --- PROPIEDADES EXPORTADAS ---


# Velocidad de rotación en grados por segundo.

# Puedes ajustar este valor en el Inspector.

@export var velocidad_giro_grados_por_segundo: float = 360.0 # Una vuelta completa por segundo


# --- FUNCIÓN DE PROCESAMIENTO ---


func _process(delta: float):

# La rotación se aplica en la función _process, que se llama en cada frame.

# 1. Calcular el ángulo de rotación para este frame:

#    (Velocidad en grados/seg) * (Tiempo transcurrido desde el último frame)

var angulo_delta = deg_to_rad(velocidad_giro_grados_por_segundo) * delta

# 2. Aplicar la rotación al nodo actual (self):

#    'rotate_y(ángulo)' aplica una rotación alrededor del eje Y local del nodo.

#    Esto causa el efecto de "peonza" o "trompo".

rotate_y(angulo_delta)