Enero 06, 2018, 01:37:17 AM Ultima modificación: Enero 08, 2018, 11:39:26 PM por Naitsabes0
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

///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

///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

/// destruir la superficie
if (surface_exists(superficie)) {
    surface_free(superficie);
}


DRAW

///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?

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.

Emm...
Esteh, estoy desde el celular pero si no recuerdo mal es código es algo como:

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.

Cita de: TheJaj 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:

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.

Podes programar un objeto padre y después le definís a los demás objetos el padre y te ahorrás usar Surfaces.

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:


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.

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

globalvar Oscuridad;
Oscuridad = surface_create(view_wview,view_hview)


Step end

surface_set_target(Oscuridad)
draw_set_color(c_white)
draw_rectangle(0,0,view_wview,view_hview,false)
surface_reset_target()


Draw

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

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);

Cita de: TheJaj 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

globalvar Oscuridad;
Oscuridad = surface_create(view_wview,view_hview)


Step end

surface_set_target(Oscuridad)
draw_set_color(c_white)
draw_rectangle(0,0,view_wview,view_hview,false)
surface_reset_target()


Draw

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

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

///Variable
globalvar Oscuridad;
Oscuridad = surface_create(view_wview,view_hview)


END STEP

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

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.

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

Cita de: TheJaj 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

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.  ;)

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".

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

Cita de: DavidTheAnswerer 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
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.

Cita de: TheJaj 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".
Bueno lo he dejado como esto.

obj_Linterna_Invisible

CREATE

///Variable
globalvar Oscuridad;
Oscuridad = surface_create(view_wview,view_hview)


STEP

surface_set_target(Oscuridad)
draw_set_color(c_white)
draw_rectangle(0,0,view_wview,view_hview,false)
surface_reset_target()


DRAW

draw_set_blend_mode(bm_subtract);
draw_surface(Oscuridad,view_xview,view_yview)
draw_set_blend_mode(bm_normal);


obj_Linterna_Visible
END STEP

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?

Sep, esa sería la estructura.

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