How to create a interactive life bar?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By JinnRo
:warning: Old Version Published before Godot 3 was released.

Hi everybody recently I´m working with this engine and I have some questions about this problem.
I have a bar (a kinematidBody2D) with this script code

extends KinematicBody2D

const ball_scene = preload("res://Mini Escenas/Cohete.xml")

func _ready():
	set_fixed_process(true)
	set_process_input(true)
	
func _fixed_process(delta):
	var y = get_pos().y
	var mouse_x = get_viewport().get_mouse_pos().x
	set_pos(Vector2(mouse_x, y)) 
	
func _input(event):
	if event.type == InputEvent.MOUSE_BUTTON && event.is_pressed():
		var ball = ball_scene.instance()
		ball.set_pos(get_pos()-Vector2(0, 16))
		get_tree().get_root().add_child(ball)

The properties are visible, I created a bar with only horizontal movement handled by the mouse that when clicking “expulse” a ball, with a node of collision on it (I do not know how it will be called to this last exactly, the process is to draw A border of collision on the “object”).

My problem is that I do not give to get to the point of creating a smaller bar that is contained within the first bar and that having contact with the ball “expelled” disappears.

I hope it has been quite clear, I look forward to your help and thank you in advance.
Any other questions about my problem will gladly explain. Thank you

I didn’t understand very well, but I see you speak spanish. Edit your question and add the spanish version, so I can help you better. :wink:

rredesigns | 2017-06-06 18:06

En español seria lo mismo, creé una barra y con ese código la barra lo que hace es moverse horizontalmente de izquierda a derecha por orden del puntero del ratón y que cuando hago clic esta “expele” una bola, cuando la bola rebota al estilo pong pero no exactamente, necesito poner una barra pequeña dentro de la primera barra y que cuando la bola rebote sobre el escenario y choque contra la barra, la barra mas pequeña desaparezca.
Para ser mas gráfico seria como poner un sticker(barra pequeña) pegado a una caja(barra grande) y lanzarle una pelota, cuando la pelota le pegue a la caja, el sticker desaparezca. seria algo así.

JinnRo | 2017-06-06 18:38

Hola.

Lamento la tardanza. Por alguna razón las notificaciones se fueron a la carpeta de spam.

Si entiendo bien, la barra grande suelta una bola, o la dispara, y en ese mismo momento se agrega la barra más pequeña sobre la barra grande. Es así?

Cuando la bola colisiona con la barra pequeña quieres que la barra desaparezca? Eso es fácil de hacer, nada más usas .hide() en la barra pequeña cuando detecte la colisión con la bola.

Si lo que quieres es tener como una barra de vida dividida en muchas barritas y hacer desaparecer de a una cuando la golpee la bola, el proceso es el mismo, sólo que en vez de usar un objeto usas un array donde guardas las referencias de los nodos más pequeños y también usas .hide() para cada golpe de la bola.

No sé si llegué a entender bien, pero si no podrías hacer un dibujo, así sea con Paint, para explicar mejor qué es lo que necesitas.

Tal vez mostrar el código que tienes hasta ahora también ayude a entender qué quieres lograr.

Saludos.

rredesigns | 2017-06-09 02:31

Hola, gracias por responder, Si, es mas como tu segundo ejemplo, como una barra de vida dividida y que disminuya por cada golpe… Tal cual, pasa que soy bastante nuevo en esto y no se por donde arrancar, he hecho lo primero a tirones, el código de la barra grande es el que puse arriba y estaba siguiendo el mismo proceso para hacer la barra dividida en barritas, pero no encuentro como hacer la interacción, he usado esto para comenzar con las barritas (mi idea era hacer una barrita con las propiedades y luego un furioso copy/paste)

func _ready():
	set_fixed_process(true)
	set_process_input(true)
	
	
func _fixed_process(delta):
	var y = get_pos().y
	var mouse_x = get_viewport().get_mouse_pos().x
	set_pos(Vector2(mouse_x, y)) 

Un nodo RigidBody2D (hace poco leyendo los tutos de godot me di cuenta que es mejor un kinematicbody2d) y dentro o anidado (como hijo creo que se dice) un nodo de colisión y uno de Sprite, pero para aumentar la apuesta he cambiado un poco esto pues quiero que cuando la barrita desaparezca se vea un especie de gif, una animación de como se descompone (dejo captura al final)… pero la barrita cae al vació, ahora he intentado cambiar su posición y parece que entre las propiedades de colisión entre la barra grande y la barrita, no se gustan pues la barrita no se deja poner sobre la barra grande.
https://k61.kn3.net/6/1/D/A/7/E/4CD.png

JinnRo | 2017-06-09 15:23

Es natural que se caiga. Cada cuerpo físico tiene sus propiedades y el cuerpo rígido que estás usando es afectado por todas las fuerzas físicas, en este caso, la gravedad, por eso se cae.

Para evitar eso lo mejor sería uno estático o cinemático. Por otro lado, cabe aclarar que tu estructura debe ser la apropiada, en general es así: cuerpo físico(rigid, kinematic, static) → Collision shape. Un shape que no es hijo de un cuerpo físico no sirve para nada, y un cuerpo físico sin un shape de hijo no detecta colisiones. Esa es la regla siempre.

Ahora lo complicado es que al poner uno sobre otro, estarían en colisión eterna el padre y el hijo. Para eso existen las excepciones. Se le puede indicar de forma explícita a un cuerpo que no colisione con otro en particular. También podrías usar las capas para separarlos y evitar conflictos.

Pues eso que quieres también es relativamente sencillo de hacer, aunque llevará algún tiempo si no tienes experiencia. Tienes dos opciones, usar una barra única animada con el AnimatedSprite2D como tienes ahí, o hacer secciones diferentes y ocultarlas de a una.

La opción más sencilla sería la primera. Para eso tendrías que tener cada frame, por ejemplo, si la barra tiene 10 segmentos, tendrías 10 frames, y cada vez que la bola golpea lo cambias. El inconveniente es que si le quieres cambiar la salud total al jugador tendrás que hacer un pequeño cálculo matemático, o volver a crear tus sprites.

La segunda opción es más compleja, pero la más personalizable. Como eres nuevo con Godot mejor no te la explico para no confundirte mucho (además es algo largo de explicar), pero con gusto te lo comento en el futuro si te interesa.

Voy a elaborar un muy breve proyecto de ejemplo y te lo paso por aquí ni bien lo tenga. Por cierto, el problema tuyo es la detección de colisión o el cambio de sprites?

rredesigns | 2017-06-10 03:23

Mil gracias por la ayuda, bueno exactamente como se ve en la imagen ambos tienen un nodo de colisión, la barra grande y la pequeña roja y cuando lo testeaba no aparecían así, al momento de probar la barra pequeña aparecía o sobre la grande o debajo pero no dentro, con ridgibodyd se caía al infinito y ahora probando con kinematicbody se queda estático, bien, use el código de arriba y he organizado los nodos como indicas, ahora, la barrita roja no cae, se queda dentro de la barra grande y ademas se mueve junto con la barra grande, lo que es un adelanto, te agradezco un montón… Esperare con ansias tu ejemplo, mientras tanto estoy probando el nodo de animación que mencionas, usaba animatedPlayer pero no tengo una idea clara de como funciona, con el nodo que mencionas de animación pude “cargar” una secuencia de imágenes para animar pero aun estoy crudo.

PD. Creo que el problema era de ambos, el cambio de sprites y la detección de colisión.
PD 2. En principio con el código de la bola, cada vez que impactaba a la barra grande la esfera aumentaba su velocidad, ahora disminuye al impactar, no he cambiado nada, solo agregue el código que puse anteriormente junto a la imagen a el nodo de kinematic de la barra pequeña, que tipo de conflicto sera?.

JinnRo | 2017-06-10 05:15

:bust_in_silhouette: Reply From: rredesigns

Entonces la bola tiene que quedar dentro de la barra o cómo? Ya me perdí. Pero el ejemplo está así que seguro te da buenas ideas.

El código no está comentado porque lo escribí en unos 20 minutos, y los assets son súper básicos por la misma razón, pero sirve perfecto. Aunque en este punto no sé si es lo que estás buscando.

En fín, aquí está el proyecto. Lo importas, revisa el script, y lo ejecutas. Las bolas se disparan con un click común del mouse. Si hay algo que no entiendes nada más me preguntas.

No, me refería a la barra pequeña roja de la imagen, es la que tenia que quedar dentro de la grande, como en la imagen.

JinnRo | 2017-06-10 05:27

Creo que ya entendí cómo querías hacerlo. Yo lo hice de la misma manera pero con sprites. De todos modos se puede hacer fácilmente así como lo quieres. La barra roja más pequeña sería un simple sprite, y todo lo que tienes que hacer es cambiarle la escala en X.

Para que se escale desde un extremo tendrás que cambiarle el punto de anclaje quizá, poniendo el mouse en el extremo izquierdo y presionando V, de esa forma cuando le cambies el tamaño se reduzca desde ahí y no desde el centro.

Pero bueno, tu dirás. Si quieres hacerlo así me avisas y mañana cambio mi demo para que se comporte en esa forma.

rredesigns | 2017-06-10 05:30

Si, me sirve mucho, sobre todo el codigo, en principio es lo que quería, pero lo que busco no solo es una barra completa que vaya disminuyendo, si no mas bien una mini barra y con animación de descomposición.
Te mostrare dos gifs para que mas o menos te hagas una idea.

  1. Lo que busco que pase cuando la bola toque la barra (con las mini barras dentro)
    enter image description here

  2. Lo que busco que pase cuando la mini barra dentro desaparece (las barritas rojas), que no desaparezca solamente, si no que muestre una animación.
    enter image description here

JinnRo | 2017-06-10 06:01

Esto también puede hacerse con facilidad. Cada vez que la bola golpea hay que indicarle a los segmentos que reproduzcan su animación y se oculten luego.

No creo que Godot reproduzca gifs, así que déjame ver si me hago mi propia animación con Blender o separo las capas de este gif con GIMP. Al rato regreso.

EDIT:

Aquíestá el nuevo proyecto. Fijate si es lo que buscas. Lamento la falta de precisión con los sprites pero también lo hice a las apuradas. xD

rredesigns | 2017-06-10 14:22

Muy bueno, muchas gracias, estoy tratando de reproducirlo desde cero por fines didácticos, pero no llego a saber como haces las animaciones.
De igual forma muchas gracias por todo.

JinnRo | 2017-06-11 04:01

Si me confirmas que eso es lo que necesitas, entonces puedo poner comentarios en el código y te lo vuelvo a subir.

EDIT:
Bien, pues ya está. Fijate que lo más importante sucede en la bola, no en la barra. Te dejé una explicación ahí dentro. El proyecto finalizado está aquí.

No dudes en preguntar si necesitas algo más. Si usas Telegram mi usuario es @RREDesigns. Si la respuesta te sirve entonces podrías marcar el post como solucionado. Hasta pronto.

rredesigns | 2017-06-11 04:13

Bueno, creo que con eso ya mas puedo continuar, te escribire al telegram como mencionas para consultas futuras, gracias, creo que si estaría resuelto el tema

pd. como marco el post como resuelto? lo edito simplemente y pongo “resuelto” o hay algun boton que no veo?

JinnRo | 2017-06-15 00:26

Sería lo más práctico, así recibo una notificación en mi escritorio on en mi teléfono. No le hago mucho al 2D, pero seguro que en algunas cosas te podré ayudar. También sería más fácil enviar capturas y eso.

Creo que tienes que ver el menú en mi respuesta y elegirla como la respuesta correcta, o algo así, para que se marque como una respuesta respondida.

Hasta pronto y que te diviertas con Godot. :smiley:

rredesigns | 2017-06-15 01:45