Noviembre 07, 2017, 04:33:21 PM Ultima modificación: Diciembre 03, 2017, 11:13:44 AM por Yuzo
Saludos !

He estado muy ocupado ultimamente y tenía mi proyecto bastante abandonado, ahora tengo unos dias y quiero meterle muchas horas, el caso es que llevaba tiempo pensando en como hacer una room sin iluminación y usar el tipico efecto linterna con SURFACES.

El jugador se me ilumina sin problemas, pero el problema viene cuando quiero que las balas también tengan su luz propia.

Como cada bala se llamará igual, en este caso "ob_player_bullet", supongo que no puedo dar las coordenadas del objeto en sí, si no su ID, pero nunca he usado ID´s, así que no se como funciona, y menos si el objeto no se ha creado aún.

De momento expongo mi código del objeto que controla la surface:

EVENTO CREATE:

[gml]///PROPIEDADES

// CREA LA OSCURIDAD
oscuridad=surface_create(room_width,room_height)[/gml]

EVENTO STEP

[gml]///PROPIEDADES

// DIBUJA LA OSCURIDAD
surface_set_target(oscuridad)                   // llama a la surface
draw_set_color(c_black)                         // establece el color negro
draw_set_alpha(0.8)                             // nivel de transparencia en la oscuridad
draw_rectangle(0,0,room_width,room_height,0)    // dibuja el rectangulo negro que ocupa toda la room
draw_set_alpha(1)                               // establece el nivel de transparencia al normal

// CREA LA LUZ SOBRE EL JUGADOR
draw_set_blend_mode(bm_subtract)                // modo de dibujar "EXTRAER"
if instance_exists(ob_player_in_room){          // Lo coloca sobre el jugador entrando en la room
draw_sprite(spr_luz_1,0,ob_player_in_room.x,ob_player_in_room.y)
}else{                                          // lo coloca sobre el jugador
draw_sprite(spr_luz_1,0,ob_player.x,ob_player.y)
}
draw_set_blend_mode(bm_normal)                  // deja el modo de dibujo en normal
surface_reset_target()                          // cierra la surface

// CREA LUZ SOBRE LAS BALAS
if instance_exists(ob_player_bullet){
draw_set_blend_mode(bm_subtract)                // modo de dibujar "EXTRAER"
draw_sprite(spr_luz_1,0,ob_player_bullet.x,ob_player_bullet.y)// Lo coloca sobre las balas
}
draw_set_blend_mode(bm_normal)                  // deja el modo de dibujo en normal
surface_reset_target()                          // cierra la surface[/gml]

EVENTO DRAW

[gml]/// PROPIEDADES

// DIBUJARSE A SI MISMA
draw_self()

// DIBUJAR LA OSCURIDAD
draw_surface(oscuridad,0,0)[/gml]

Lo dicho, con el personaje del jugador funciona todo bien, no funciona con las balas, supongo que por que todas se llaman OB_PLAYER_BULLET, aún que si disparo sólo una, tampoco sale la luz.

Alguien que me pueda ayudar con este código ?.

Gracias como siempre.

Un Saludo.

La parte que dibujas la luz de las balas tenes que colocarlo cuando llamas a la surface  surface_set_target(oscuridad), asi como todo lo que quieras que afecte la surface
[gml]
surface_set_target(oscuridad)

///todos lo que quieras que se dibuje en la surface

surface_reset_target()
[/gml]

#2 Noviembre 08, 2017, 05:38:48 PM Ultima modificación: Noviembre 08, 2017, 05:40:39 PM por Yuzo
El caso es que van a ser muchos los objetos que tienen que usar el substract, y no estan en pantalla aun, como por ejemplo la bala, items, magias, etc.

he intentado poner esto al objeto bala en su evento STEP, pero no funciona, no se por que:

[gml]/// LUZ EN SURFACE

// CREA LA LUZ SOBRE EL ATAQUE
if room == lvl_4 {
surface_set_target(global.oscuridad)            // llama a la surface
draw_set_blend_mode(bm_subtract)                // modo de dibujar "EXTRAER"
draw_sprite_ext(spr_luz_1,0,x,y,1,1,0,1,1)      // dibuja el sprite de luz
draw_set_blend_mode(bm_normal)                  // deja el modo de dibujo en normal
surface_reset_target()                          // cierra la surface
}
[/gml]

En realidad es muy curioso por que parece que funcionar funciona, pero es apenas apreciable.

Alguna ayuda ?.

Gracias.

#3 Noviembre 09, 2017, 03:21:45 AM Ultima modificación: Noviembre 09, 2017, 03:32:37 AM por 3dgeminis
Se ve mal el sprite o no se ve ?

Practicamente no hay efecto de substact, es como si no existiera, no se que hacer.

Será que no puede hacer nada sobre la surface otro objeto mas que el que la creó ?.

Con la surface creada podes modificarla desde cualquier objeto.
Intenta quitarle el sprite desde las propiedades del objeto y solo dibujar el sprite en el evento STEP cuando uses la surface.

Lo probaré y te cuento, gracias 3Dgeminis

Cita de: Yuzo en Noviembre 07, 2017, 04:33:21 PM
...
EVENTO STEP

[gml]///PROPIEDADES

// DIBUJA LA OSCURIDAD
surface_set_target(oscuridad)                   // llama a la surface
draw_set_color(c_black)                         // establece el color negro
draw_set_alpha(0.8)                             // nivel de transparencia en la oscuridad
draw_rectangle(0,0,room_width,room_height,0)    // dibuja el rectangulo negro que ocupa toda la room
draw_set_alpha(1)                               // establece el nivel de transparencia al normal

// CREA LA LUZ SOBRE EL JUGADOR
draw_set_blend_mode(bm_subtract)                // modo de dibujar "EXTRAER"
if instance_exists(ob_player_in_room){          // Lo coloca sobre el jugador entrando en la room
draw_sprite(spr_luz_1,0,ob_player_in_room.x,ob_player_in_room.y)
}else{                                          // lo coloca sobre el jugador
draw_sprite(spr_luz_1,0,ob_player.x,ob_player.y)
}
draw_set_blend_mode(bm_normal)                  // deja el modo de dibujo en normal
surface_reset_target()                          // cierra la surface

// CREA LUZ SOBRE LAS BALAS
if instance_exists(ob_player_bullet){
draw_set_blend_mode(bm_subtract)                // modo de dibujar "EXTRAER"
draw_sprite(spr_luz_1,0,ob_player_bullet.x,ob_player_bullet.y)// Lo coloca sobre las balas
}
draw_set_blend_mode(bm_normal)                  // deja el modo de dibujo en normal
surface_reset_target()                          // cierra la surface[/gml]
...

Sólo tienes que reemplazar esto:
[gml]
// CREA LUZ SOBRE LAS BALAS
if instance_exists(ob_player_bullet){
[/gml]

Por esto:
[gml]
// CREA LUZ SOBRE LAS BALAS
with(ob_player_bullet){
[/gml]
Vota nuestro proyecto en Steam Greenlight:

Estudios Naicura Ltda

3DGeminis, sigue sin funcionar.

Markus, así funciona, pero sólo funciona en un objeto por room, es decir, si hay dos balas o más, sólo la primera que se creó tiene el efecto de luz.

No hay algo que se le pueda poner al objeto bala para que el efecto se haga desde el propio objeto ?, creo que sería mejor, y que usaría menos recursos, no ?.

En un fallido intento de hacerlo de dicha manera puse esto en el evento STEP del objeto bala:

[gml]/// LUZ EN SURFACE

// CREA LA LUZ SOBRE EL ATAQUE
if room == lvl_4 {
surface_set_target(global.oscuridad)            // llama a la surface
draw_set_blend_mode(bm_subtract)                // modo de dibujar "EXTRAER"
draw_sprite_ext(spr_luz_1,0,x,y,1,1,0,1,1)      // dibuja el sprite de luz
draw_set_blend_mode(bm_normal)                  // deja el modo de dibujo en normal
surface_reset_target()                          // cierra la surface
}[/gml]

Pero nada, así tampoco funciona, ya no se que hacer .....

Te dejo un ejemplo, con linterna y balas como fuentes de luz. El codigo esta en el objeto o_superficie, ademas fijate en el objeto o_bala.

Cita de: Yuzo en Noviembre 18, 2017, 10:34:26 AM
3DGeminis, sigue sin funcionar.

Markus, así funciona, pero sólo funciona en un objeto por room, es decir, si hay dos balas o más, sólo la primera que se creó tiene el efecto de luz.

No hay algo que se le pueda poner al objeto bala para que el efecto se haga desde el propio objeto ?, creo que sería mejor, y que usaría menos recursos, no ?.

En un fallido intento de hacerlo de dicha manera puse esto en el evento STEP del objeto bala:

[gml]/// LUZ EN SURFACE

// CREA LA LUZ SOBRE EL ATAQUE
if room == lvl_4 {
surface_set_target(global.oscuridad)            // llama a la surface
draw_set_blend_mode(bm_subtract)                // modo de dibujar "EXTRAER"
draw_sprite_ext(spr_luz_1,0,x,y,1,1,0,1,1)      // dibuja el sprite de luz
draw_set_blend_mode(bm_normal)                  // deja el modo de dibujo en normal
surface_reset_target()                          // cierra la surface
}[/gml]

Pero nada, así tampoco funciona, ya no se que hacer .....

¿Pero hiciste el cambio que te indiqué? Porque con WITH haces que todas las balas ejecuten su código, justamente lo que están diciendo que necesitas hacer.
Vota nuestro proyecto en Steam Greenlight:

Estudios Naicura Ltda

Prueba poniendo el objecto que controla el draw de las luces en el ultimo orden de carga de la room.

Suerte!!!  ;)
PCNONOGames  www.pcnono.es

#12 Noviembre 24, 2017, 11:37:06 AM Ultima modificación: Noviembre 24, 2017, 11:39:10 AM por Yuzo
Gracias 3DGeminis, mirando tu codigo no entiendo que es lo que me funciona mal.

Sí, Markus, esta tal que así:

[gml]// CREA LUZ SOBRE LAS BALAS
with(ob_player_bullet){
draw_set_blend_mode(bm_subtract)                // modo de dibujar "EXTRAER"
draw_sprite(spr_luz_1,0,ob_player_bullet.x,ob_player_bullet.y)// Lo coloca sobre las balas
}[/gml]

NONOROMAN, como se hace eso ?, suena interesante, aun que no se si lo resolverá.

Estoy dandole vueltas y vueltas y he pensado que tal vez se trate de que tengo un objeto en la room que tambien modifica una surface, tal vez sea que entra en conflico con este.

Tiene lo siguiente:

OBJETO LUCIERNAGA:

CREATE:
[gml]/// PROPIEDADES

escala_x        = 0;                // variable que controla la escala X (tamaño del sprite)
escala_y        = 0;                // variable que controla la escala Y (tamaño del sprite)
tamano_luz_x    = 0;                // variable que controla el tamaño de la luz en X
tamano_luz_y    = 0;                // variable que controla el tamaño de la luz en Y

// PROFUNDIDAD
depth = choose(-2,-1,0,1,2,3);

// DIRECCION
direction = irandom_range(0,360);[/gml]

STEP
[gml]
/// LUZ EN SURFACE

// CREA LA LUZ SOBRE LA LUCIERNAGA
surface_set_target(global.oscuridad)            // llama a la surface
draw_set_blend_mode(bm_subtract)                // modo de dibujar "EXTRAER"
draw_sprite_ext(spr_luz_1,0,x,y,tamano_luz_x,tamano_luz_y,0,1,1)  // dibuja el sprite de luz
draw_set_blend_mode(bm_normal)                  // deja el modo de dibujo en normal
surface_reset_target()                          // cierra la surface
[/gml]

DRAW
[gml]
/// PROPIEDADES

// DIBUJA EL SPRITE ORIGINAL
draw_sprite_ext(spr_luciernaga,0,x,y,escala_x,escala_y,0,c_white,1)

// LO HACE BORROSO
draw_set_blend_mode(bm_add)

// DIBUJA EL SPRITE DIFUMINADO
if global.pause == false and global.magia_on == false{
draw_sprite_ext(spr_luciernaga_des,0,x,y,escala_x,escala_y,0,c_white,alpha_level)}

// ESTABLECE EL MODO DE BLEND EN NORMAL
draw_set_blend_mode(bm_normal);
[/gml]


En las propiedades de la room hay un boton que pone instance orden o algo asi. Te sale la.lista de todos los objectos que hay en la room y puedes cambiar su orden. Ponlo el ultimo.

Cita de: Yuzo en Noviembre 24, 2017, 11:37:06 AM
Gracias 3DGeminis, mirando tu codigo no entiendo que es lo que me funciona mal.

Sí, Markus, esta tal que así:

[gml]// CREA LUZ SOBRE LAS BALAS
with(ob_player_bullet){
draw_set_blend_mode(bm_subtract)                // modo de dibujar "EXTRAER"
draw_sprite(spr_luz_1,0,ob_player_bullet.x,ob_player_bullet.y)// Lo coloca sobre las balas
}[/gml]

NONOROMAN, como se hace eso ?, suena interesante, aun que no se si lo resolverá.

Estoy dandole vueltas y vueltas y he pensado que tal vez se trate de que tengo un objeto en la room que tambien modifica una surface, tal vez sea que entra en conflico con este.

Tiene lo siguiente:

OBJETO LUCIERNAGA:

CREATE:
[gml]/// PROPIEDADES

escala_x        = 0;                // variable que controla la escala X (tamaño del sprite)
escala_y        = 0;                // variable que controla la escala Y (tamaño del sprite)
tamano_luz_x    = 0;                // variable que controla el tamaño de la luz en X
tamano_luz_y    = 0;                // variable que controla el tamaño de la luz en Y

// PROFUNDIDAD
depth = choose(-2,-1,0,1,2,3);

// DIRECCION
direction = irandom_range(0,360);[/gml]

STEP
[gml]
/// LUZ EN SURFACE

// CREA LA LUZ SOBRE LA LUCIERNAGA
surface_set_target(global.oscuridad)            // llama a la surface
draw_set_blend_mode(bm_subtract)                // modo de dibujar "EXTRAER"
draw_sprite_ext(spr_luz_1,0,x,y,tamano_luz_x,tamano_luz_y,0,1,1)  // dibuja el sprite de luz
draw_set_blend_mode(bm_normal)                  // deja el modo de dibujo en normal
surface_reset_target()                          // cierra la surface
[/gml]

DRAW
[gml]
/// PROPIEDADES

// DIBUJA EL SPRITE ORIGINAL
draw_sprite_ext(spr_luciernaga,0,x,y,escala_x,escala_y,0,c_white,1)

// LO HACE BORROSO
draw_set_blend_mode(bm_add)

// DIBUJA EL SPRITE DIFUMINADO
if global.pause == false and global.magia_on == false{
draw_sprite_ext(spr_luciernaga_des,0,x,y,escala_x,escala_y,0,c_white,alpha_level)}

// ESTABLECE EL MODO DE BLEND EN NORMAL
draw_set_blend_mode(bm_normal);
[/gml]
PCNONOGames  www.pcnono.es

Nada, que no sale, lo he probado todo chicos, todas vuestras ideas, y más cosas que se me iban ocurriendo.

No tengo ni idea de por que me pasa esto.

Comparto el proyecto a ver si alguien sabe donde está el error.