Noticias

Importante: ¡Si quieres publicar tu juego no olvides leer este tema!

Comunidad Game Maker

Bienvenid@ a la comunidad hispana de Game Maker. Nuestro objetivo es crear videojuegos y dar soporte en castellano de GM. Para mejorar nuestro servicio hemos implantado, como adicion al reglamento general, algunas normas especificas en los subforos más comunes. ¡No olvides informarte antes de participar!.

Autor Tema: Como logro ese efecto de creación? [Solucionado]  (Leído 1251 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Naitsabes0

en: Enero 06, 2018, 01:37:17 am
Pues esto es parecido a una linterna, al menos desde mi punto de vista.



Pues tengo un objeto que hace oscuridad, o como muchos le llamarían la linterna clásica en 2D de toda la vida.



Para ello empleo un objeto sin sprite al que llamo obj_Luz_Oscuridad.

CREATE
Código: [Seleccionar]
///Crear la superficie

superficie = surface_create(room_width, room_height);

surface_set_target(superficie);
draw_clear_alpha(c_black, 0);

//Reinicia la superficie
surface_reset_target();

STEP
Código: [Seleccionar]
///Control de la oscuridad
if (surface_exists(superficie)){
    surface_set_target(superficie);
   
    //conjunto oscuridad
    draw_set_colour(c_black);
    draw_set_alpha(1); //intencidad de la oscuridad 0 nada 1 absoluta
    draw_rectangle(0, 0, room_width, room_height, false);
   
    //conjunto circulos
    draw_set_blend_mode(bm_subtract);
   
   
    draw_set_colour(c_black);
    draw_set_alpha(0.2);
   
   
    // dibuja circulos
    with (objJugador) {
        draw_circle(x + random_range(-1,1), y + random_range(-1,1), 80 + random_range(-1, 1), false);
       
        }
       
        draw_set_colour(c_white);
        draw_set_alpha(1);
       
        with (objJugador) {
        draw_circle(x + random_range(-1,1), y + random_range(-1,1), 45 + random_range(-1, 1), false);
       
        }
       
       
       
    //Reinicia todo el conjunto dibujo
    draw_set_blend_mode(bm_normal);
    draw_set_alpha(1);
    surface_reset_target();
} else {
    superficie = surface_create(room_width, room_height);
    surface_set_target(superficie);
    draw_clear_alpha(c_black, 0);
    surface_reset_target();
}

ROOM END
Código: [Seleccionar]
/// destruir la superficie
if (surface_exists(superficie)) {
    surface_free(superficie);
}

DRAW
Código: [Seleccionar]
///Dibuja la superficie

if (!surface_exists(superficie)) {
    superficie = surface_create(room_width, room_height);
} else {
    if (view_current == 0) {
        draw_surface(superficie, 0, 0);
    }
}

Bueno si analizamos esto detenidamente, es lo mismo, ya que no se ve mas haya del circulo, pero por alguna razón se siente como nuevo y llamativo a la vista, al menos desde mi punto de vista, no parece que sea algo muy difícil de programar, aunque parece que todo lo que esta fuera del radio los convierte en opacidad 0 o invisible, y los vuelve a su estado normal que es 1 o visible, solo cuando esta dentro del radio de visión, por lo tanto ¿Como logro ese efecto de creación?
« última modificación: Enero 08, 2018, 11:39:26 pm por Naitsabes0 »

 


No Tienes Permisos Para Dar Puntos
point 0 Puntos

Este tema no recibió puntos.


Desconectado Iros

Respuesta #1 en: Enero 06, 2018, 04:52:46 am
Algo sencillo que se me ocurre, aunque no se cuantos recursos pueda llegar a consumir, sería comprobar los objetos cercanos a X radio del personaje y activarlos, si están fuera del rango se desactivan.

 
Los siguientes usuarios dieron las gracias a este tema: Yuzo


Desconectado TheJaj

Respuesta #2 en: Enero 06, 2018, 04:56:47 am
Emm...
Esteh, estoy desde el celular pero si no recuerdo mal es código es algo como:
Código: [Seleccionar]
If distancia_to_point(objeto_jugador) < 50
{image_alpha = 1}
else
{image_alpha = 0}

Este código va en las paredes.
Te recomiendo que verifiques la función, la de distancia, ya que hace literalmente 6-7 meses no la uso.

 
Los siguientes usuarios dieron las gracias a este tema: Yuzo


Desconectado Naitsabes0

Respuesta #3 en: Enero 06, 2018, 10:28:54 pm
Emm...
Esteh, estoy desde el celular pero si no recuerdo mal es código es algo como:
Código: [Seleccionar]
If distancia_to_point(objeto_jugador) < 50
{image_alpha = 1}
else
{image_alpha = 0}

Este código va en las paredes.
Te recomiendo que verifiques la función, la de distancia, ya que hace literalmente 6-7 meses no la uso.

Supongo que tendría que creear muchos objetos con este código para que se comporten de esa forma, es decir tendría que hacer enemigos,  paredes, pinchos, trampas, etc, en vez de hacer una linterna que haga invisible todo lo que esta lejos del jugador, pues eso seria lo que se trata de lograr, un objeto que haga invisible todo lo que esta fuera de su área de visión, no que los objetos se agan invisibles cuando detecten al jugador, pues resultaría engorroso programarle eso objeto por objeto, a largo plazo no tendría la misma eficiencia que la linterna que solo necesita ser un solo objeto.

 
Los siguientes usuarios dieron las gracias a este tema: Yuzo


Desconectado Iros

Respuesta #4 en: Enero 06, 2018, 11:40:20 pm
Podes programar un objeto padre y después le definís a los demás objetos el padre y te ahorrás usar Surfaces.

 
Los siguientes usuarios dieron las gracias a este tema: Yuzo


Desconectado TheJaj

Respuesta #5 en: Enero 07, 2018, 02:49:46 am
Lo que dice Iros funciona perfectamente siempre y cuando el objeto que es hijo no tiene código propio, para este caso te recomiendo que lo crees como un script y en cada objeto que puedes usar como padre pongas:

Código: [Seleccionar]
if  room = "habitacion en la que quieres este efecto"
{image_alpha = scr_invisible}

y en el scritp solo cambias el "image_apha" por "index" con eso tendria que bastar.

 
Los siguientes usuarios dieron las gracias a este tema: Yuzo


Desconectado TheJaj

Respuesta #6 en: Enero 07, 2018, 03:00:58 am
Ahhh espera. xD

He visto tu codigo y no te voy a mentir no entiendo un huevo, pero yo he logrado lo que buscas con tan solo 12-20 lineas de codigo.

En el objeto que crea la luz/oscuridad

Create
Código: [Seleccionar]
globalvar Oscuridad;
Oscuridad = surface_create(view_wview,view_hview)

Step end
Código: [Seleccionar]
surface_set_target(Oscuridad)
draw_set_color(c_white)
draw_rectangle(0,0,view_wview,view_hview,false)
surface_reset_target()

Draw
Código: [Seleccionar]
draw_set_blend_mode(bm_subtract);
draw_surface(Oscuridad,view_xview,view_yview)
draw_set_blend_mode(bm_normal);


Y en el objeto que crea la luz

Step end
Código: [Seleccionar]
size = 128;
draw_set_blend_mode(bm_subtract);
surface_set_target(Oscuridad);
draw_ellipse_color((x-size)-view_xview,(y-size)-view_yview,(x+size)-view_xview,(y+size)-view_yview,c_white,c_black,false)//,c_orange,c_white,false);
surface_reset_target();
draw_set_blend_mode(bm_normal);

 
Los siguientes usuarios dieron las gracias a este tema: Yuzo


Desconectado Naitsabes0

Respuesta #7 en: Enero 07, 2018, 03:52:37 am
Ahhh espera. xD

He visto tu codigo y no te voy a mentir no entiendo un huevo, pero yo he logrado lo que buscas con tan solo 12-20 lineas de codigo.

En el objeto que crea la luz/oscuridad

Create
Código: [Seleccionar]
globalvar Oscuridad;
Oscuridad = surface_create(view_wview,view_hview)

Step end
Código: [Seleccionar]
surface_set_target(Oscuridad)
draw_set_color(c_white)
draw_rectangle(0,0,view_wview,view_hview,false)
surface_reset_target()

Draw
Código: [Seleccionar]
draw_set_blend_mode(bm_subtract);
draw_surface(Oscuridad,view_xview,view_yview)
draw_set_blend_mode(bm_normal);


Y en el objeto que crea la luz

Step end
Código: [Seleccionar]
size = 128;
draw_set_blend_mode(bm_subtract);
surface_set_target(Oscuridad);
draw_ellipse_color((x-size)-view_xview,(y-size)-view_yview,(x+size)-view_xview,(y+size)-view_yview,c_white,c_black,false)//,c_orange,c_white,false);
surface_reset_target();
draw_set_blend_mode(bm_normal);

El obj_Luz_Oscuridad es solo 1 objeto no 2 no me queda muy claro lo ultimo, ya que dices y el que crea la luz coloca esto, por lo que ¿me dices que son 2 objetos distintos? pues el resultado es visualmente esto.



el objeto contiene esto.
CREATE
Código: [Seleccionar]
///Variable
globalvar Oscuridad;
Oscuridad = surface_create(view_wview,view_hview)

END STEP
Código: [Seleccionar]
surface_set_target(Oscuridad)
draw_set_color(c_white)
draw_rectangle(0,0,view_wview,view_hview,false)
surface_reset_target()

size = 128;
draw_set_blend_mode(bm_subtract);
surface_set_target(Oscuridad);
draw_ellipse_color((x-size)-view_xview,(y-size)-view_yview,(x+size)-view_xview,(y+size)-view_yview,c_white,c_black,false)//,c_orange,c_white,false);
surface_reset_target();
draw_set_blend_mode(bm_normal);

DRAW
Código: [Seleccionar]
draw_set_blend_mode(bm_subtract);
draw_surface(Oscuridad,view_xview,view_yview)
draw_set_blend_mode(bm_normal);

Puede que parte del problema se deba a que aquí están los 2 eventos END STEP en 1, ya que en su ejemplo hay 2 de ellos, asumo que me esta diciendo que deben haber 2 objetos, del cual el 2° tiene un único evento al que se llama END STEP, mientras que el 1° tiene los 3 eventos de CREATE, END STEP y DRAW, otro detalle del que me puedo percatar es que los objetos siguen siendo visibles en todo momento, no presentan ninguna opacidad, en cambio el suelo y fondo al ser un background, ha sido engullido por la oscuridad, pero sigue actuando como colisión apesar de no ser visible.

 


Desconectado TheJaj

Respuesta #8 en: Enero 07, 2018, 04:05:39 am
Tienes razón, los 3 primeros trozos de código corresponden a uno, y el ultimo al objeto que crea la luz.

El problema es que el primer "Step end" es un simple "Step" disculpa que soy retrasado. :_ xD

 
Los siguientes usuarios dieron las gracias a este tema: Yuzo


Desconectado Naitsabes0

Respuesta #9 en: Enero 07, 2018, 04:43:41 am
Tienes razón, los 3 primeros trozos de código corresponden a uno, y el ultimo al objeto que crea la luz.

El problema es que el primer "Step end" es un simple "Step" disculpa que soy retrasado. :_ xD

Ya que mi deducción fue acertada ¿como sugiere que debería ordenar y llamar a ambos objetos? pues de llamarle obj_Luz_Oscuridad entraría en conflicto con el objeto del mismo nombre, para ello creo que seria optimo tenerlos como linterna visible y linterna invisible, pues la visible vendría siendo lo que permite ver mientras que la otra nos pondría invisible el entorno, de aplicar esto ya tendría mi pregunta auto respondida, pero base a como nombro los eventos ¿como deberían llamarse y para quien deberían estar destinados?

Pues tenemos 2 objetos y 4 eventos del cual uno debe tener 3 eventos dejando en solitario al 2°, pero como no esta claro el orden de quien es el 1°, quedaría mas simplificado si me dice la estructura con los nombres correctos de los eventos, de lo contrario volveríamos a donde espesamos por una mala coordinación y nombres de los eventos.

Espero que mi respuesta no haya sonado muy criptica.  ;)

 
Los siguientes usuarios dieron las gracias a este tema: Yuzo


Desconectado TheJaj

Respuesta #10 en: Enero 07, 2018, 11:28:21 am
Creo que entiendo lo que dices, y eso ya es cuestión tuya, mas bien de como organices los "sistemas" de juego.

En mi caso, siempre uso un objeto "omniciente" el cual tiene permanencia entre rooms y ahí es donde he puesto la generación del rectángulo negro, los círculos de luz los he puesto en los personajes/torres. Pero como digo es mi caso, ya que estoy haciendo un tower defense.

Pero supongo que si quieres tener cierto grado de orden podrias hacer un objeto llamado "obj_filtro_oscuridad" y otro "obj_linterna_filtro" pero para el segundo tendrías que programar con unas funciones para que no se note. Eso o en el objeto "filtro_oscuridad" pones un step end y usas un "with()" y te ahorras de crear un segundo objeto que hace el efecto de la "linterna".

 
Los siguientes usuarios dieron las gracias a este tema: Yuzo


Desconectado DavidTheAnswerer

Respuesta #11 en: Enero 07, 2018, 04:00:35 pm
Yo digo... No hubiera sido mas facil hacer un sprite que sea todo negro y en el centro un circulo transparente que de impresion de linterna? y lo programas como un objeto para que siga al personaje y ya :v

 


Desconectado Naitsabes0

Respuesta #12 en: Enero 07, 2018, 05:04:06 pm
Yo digo... No hubiera sido mas facil hacer un sprite que sea todo negro y en el centro un circulo transparente que de impresion de linterna? y lo programas como un objeto para que siga al personaje y ya :v
Parece que no ha leído la descripción del problema, aquí nadie esta tratando de hacer una linterna clásica, aquí se esta tratando de hacer un efecto de creación, claramente el titulo se llama "¿Como logro ese efecto de creación?" no de como hacer el efecto linterna, ya que ese problema fue solucionado en el año pasado.

 


Desconectado Naitsabes0

Respuesta #13 en: Enero 07, 2018, 05:10:34 pm
Creo que entiendo lo que dices, y eso ya es cuestión tuya, mas bien de como organices los "sistemas" de juego.

En mi caso, siempre uso un objeto "omniciente" el cual tiene permanencia entre rooms y ahí es donde he puesto la generación del rectángulo negro, los círculos de luz los he puesto en los personajes/torres. Pero como digo es mi caso, ya que estoy haciendo un tower defense.

Pero supongo que si quieres tener cierto grado de orden podrias hacer un objeto llamado "obj_filtro_oscuridad" y otro "obj_linterna_filtro" pero para el segundo tendrías que programar con unas funciones para que no se note. Eso o en el objeto "filtro_oscuridad" pones un step end y usas un "with()" y te ahorras de crear un segundo objeto que hace el efecto de la "linterna".
Bueno lo he dejado como esto.

obj_Linterna_Invisible

CREATE
Código: [Seleccionar]
///Variable
globalvar Oscuridad;
Oscuridad = surface_create(view_wview,view_hview)

STEP
Código: [Seleccionar]
surface_set_target(Oscuridad)
draw_set_color(c_white)
draw_rectangle(0,0,view_wview,view_hview,false)
surface_reset_target()

DRAW
Código: [Seleccionar]
draw_set_blend_mode(bm_subtract);
draw_surface(Oscuridad,view_xview,view_yview)
draw_set_blend_mode(bm_normal);

obj_Linterna_Visible
END STEP
Código: [Seleccionar]
size = 128;
draw_set_blend_mode(bm_subtract);
surface_set_target(Oscuridad);
draw_ellipse_color((x-size)-view_xview,(y-size)-view_yview,(x+size)-view_xview,(y+size)-view_yview,c_white,c_black,false)//,c_orange,c_white,false);
surface_reset_target();
draw_set_blend_mode(bm_normal);

Aunque sigue funcionando como el GIF que le mostré arriba, por lo que no representa ningún cambio visual, sin embargo ¿esta era la estructura que quería hacer con los 2 objetos y 4 eventos?

 


Desconectado TheJaj

Respuesta #14 en: Enero 07, 2018, 06:09:56 pm
Sep, esa sería la estructura.

En el objeto linterna_invisible dale una profunidad de -999 así Está por encima de todo.