Septiembre 20, 2018, 02:59:29 PM Ultima modificación: Septiembre 21, 2018, 06:14:42 AM por HKaichim
Hola amigos  :D tengo una duda con las View ya que me gustaria crear dos view distintas una que vea al jugador 1 y otra al jugador 2, pero que estas se unan al estar cerca eso es posible?

Saludos, no puedo serte de ayuda, pero puedo darte alguna idea, porque yo no se como hacerlo, pero prueba creando dos views cada una que persiga a un jugador diferente y mete esos jugadores en el juego y separarlos a ver que hace, y quizás ahí se te ocurra la forma de hacer la pantalla dividida.

Saludos y disculpa por no poder aportar más que una vaga bandera para llegar a donde quieres.

Cita de: n0k en Septiembre 20, 2018, 04:17:29 PM
Saludos, no puedo serte de ayuda, pero puedo darte alguna idea, porque yo no se como hacerlo, pero prueba creando dos views cada una que persiga a un jugador diferente y mete esos jugadores en el juego y separarlos a ver que hace, y quizás ahí se te ocurra la forma de hacer la pantalla dividida.

Saludos y disculpa por no poder aportar más que una vaga bandera para llegar a donde quieres.
El problema no es hacer las dos View, osea ya tengo ambas View donde los Playes se ven en distintas por separado y luego se ven en ambas al estar cerca, pero lo que quiero es que se unan al estar cerca...

No lo he probado pero es lo que se me ocurre y como lo haria:
Tendrias que controlar manualmente cada una de las views. Por ejemplo si la distancia en x entre ambos Players es menor que que el ancho de una view, mover ambas views en el eje x, hacercarlas, para que queden superpuestas, y hacer lo mismo en el eje y.
Mientras que la distancia entre ambos sea mayor a cierto valor, el centro de la view es el centro de cada Player, y si es menor el centro de las view es el centro entre ambos Players.

Cita de: 3dgeminis en Septiembre 20, 2018, 07:38:34 PM
No lo he probado pero es lo que se me ocurre y como lo haria:
Tendrias que controlar manualmente cada una de las views. Por ejemplo si la distancia en x entre ambos Players es menor que que el ancho de una view, mover ambas views en el eje x, hacercarlas, para que queden superpuestas, y hacer lo mismo en el eje y.
Mientras que la distancia entre ambos sea mayor a cierto valor, el centro de la view es el centro de cada Player, y si es menor el centro de las view es el centro entre ambos Players.
Y como se lograria eso? xD?

#5 Septiembre 21, 2018, 02:43:07 AM Ultima modificación: Septiembre 21, 2018, 04:18:15 AM por BssString
Hola HKaichim

Encuentro genial el efecto que intentas conseguir. Si hablas de VIEWs es porque NO estás usando GMS2. Así que he creado un código para GMS1.4.

Intenta lo siguiente:
1-Crea un objeto llamado "obj_player1" (o como lo quieras llamar) y uno llamado "obj_player2", esos serán los objetos que la cámara va a seguir (si le cambias el nombre a los objetos, tienes que ajustar los valores del código de abajo).

2-Crea un objeto control y colócale el siguiente código: (Setea el Width y Height al tamaño que quieras para tu juego)

En el Evento Creación
//Ajusta el tamaño del Juego
width = 960 //MUY IMPORTANTE QUE DECLARES ESTAS DOS VARIABLES
height = 540
window_set_size( width, height )
surface_resize(application_surface, width, height)

//Configura las View
view_enabled = true //Permite usar Views en vez de dibujar la room completa
view_visible[0] = true //Activa la view 0
view_visible[1] = false //Desactiva la view 1
object_left = noone //El ID o object_index del objeto que sigue la cámara de la izquierda
object_right = noone //El ID o object_index del objeto que sigue la cámara de la derecha

//Ajusta el tamaño de la view 0
view_wview[0] = width
view_hview[0] = height
//ahora se asigna el tamaño de la View 1 (se corrige un bug donde la View 1 quedaba escalada)
view_wview[1] = width-1 //Se resta 1 para que aparezca una línea negra dividiendo ambas pantallas.
view_hview[1] = height
view_xport[0] = 0; view_yport[0] = 0;
view_wport[0] = width; view_hport[0] = height
view_xport[1] = width/2+1; view_yport[1] = 0; //La View 1 se crea 1 pixel a la derecha, dejando una franja de vacío entre ambas View
view_wport[1] = width/2-1; view_hport[1] = height //Se resta 1 al ancho para que no haya deformaciones al dibujar la cámara 1 pixel a la derecha

//Target Position, crean el efecto de suavizado (dos array, "target_x" y "target_y").
cam_spd = 10 //Velocidad de la cámara, la idea es que sea mayor a la velocidad de los jugadores
target_x[0] = 0
target_y[0] = 0
target_x[1] = 0
target_y[1] = 0

//Ajusta la posición de la View.
view_xview[0] = ((obj_player1.x+obj_player2.x) - view_wview[0]) /2
view_yview[0] = ((obj_player1.y+obj_player2.y) - view_hview[0]) /2


En el evento STEP
//Calcula cuantas View usar
//Si los players están cerca
if point_distance(obj_player1.x,obj_player1.y,obj_player2.x,obj_player2.y) < min(width*.8,height*.8) {
    //Seteo las coordenadas objetivo
    target_x[0] = ((obj_player1.x+obj_player2.x) - width) /2
    target_y[0] = ((obj_player1.y+obj_player2.y) - height) /2
    target_x[1] = target_x[0] + width/2
    target_y[1] = target_y[0]
    //Centra la cámara al punto central. Ambas View tienen al target0 antes de unirse
    view_xview[0] += sign(target_x[0] - view_xview[0])*min(max(cam_spd,abs(target_x[0] - view_xview[0])/4),abs(target_x[0] - view_xview[0]))
    view_yview[0] += sign(target_y[0] - view_yview[0])*min(max(cam_spd,abs(target_y[0] - view_yview[0])/4),abs(target_y[0] - view_yview[0]))
    view_xview[1] += sign(target_x[1] - view_xview[1])*min(max(cam_spd,abs(target_x[1] - view_xview[1])/4),abs(target_x[1] - view_xview[1]))
    view_yview[1] += sign(target_y[1] - view_yview[1])*min(max(cam_spd,abs(target_y[1] - view_yview[1])/4),abs(target_y[1] - view_yview[1]))
    //Si estaba activa la segunda view, la desactiva
    if view_visible[1] = true && view_xview[1] = target_x[1] && view_yview[1] = target_y[1] {
    view_visible[1] = false //Desactiva la segunda VIEW
    view_wview[0] = width //La única view que queda ahora mide todo el espacio
    view_wport[0] = width //La única view que queda ahora mide todo el espacio
    //Resetea el suavizado de la cámara
    view_xview[1] = target_x[0]; view_yview[1] = target_y[0]
    target_x[1] = target_x[0]; target_y[1] = target_y[0]
    }
}
//En caso que los players se alejen, genera una segunda cámara
else {
//Esto activa la segunda view
if view_visible[1] = false {
    view_visible[1] = true //Activa la segunda VIEW
    view_wview[0] = width/2 //La única view que queda ahora mide todo el espacio
    view_wport[0] = width/2 //Ancho que muestra la view 0
    view_wview[1] = width/2 //La única view que queda ahora mide todo el espacio
    view_wport[1] = width/2 //Ancho que muestra la view 1
    //Calcula a cual objeto debe seguir cada cámara
    if obj_player1.x <= obj_player2.x { object_left = obj_player1; object_right = obj_player2 }
    else { object_left = obj_player2; object_right = obj_player1 }
    view_xview[1] = view_xview[0] + width/2 //Ajusta la posición para que la cámara 2 no se teletransporte
    }
    //Centra la primera cámara al objecto de la izquierda (seteando la posición de destino).
    target_x[0] = object_left.x - view_wview[0]/2
    target_y[0] = object_left.y - view_hview[0]/2
    //Centra la segunda cámara al objecto de la derecha (seteando la posición de destino).
    target_x[1] = object_right.x - view_wview[1]/2
    target_y[1] = object_right.y - view_hview[1]/2
   
    //La VIEW 0 se desplaza de forma suave a la posición de destino
    view_xview[0] += sign(target_x[0] - view_xview[0])*min(max(cam_spd,abs(target_x[0] - view_xview[0])/4),abs(target_x[0] - view_xview[0]))
    view_yview[0] += sign(target_y[0] - view_yview[0])*min(max(cam_spd,abs(target_y[0] - view_yview[0])/4),abs(target_y[0] - view_yview[0]))
    //La VIEW 1 se desplaza de forma suave a la posición de destino
    view_xview[1] += sign(target_x[1] - view_xview[1])*min(max(cam_spd,abs(target_x[1] - view_xview[1])/4),abs(target_x[1] - view_xview[1]))
    view_yview[1] += sign(target_y[1] - view_yview[1])*min(max(cam_spd,abs(target_y[1] - view_yview[1])/4),abs(target_y[1] - view_yview[1]))
}


Es un efecto cutre que se me acaba de ocurrir, pero logra su objetivo. Lo que hace es que si los players se separan en una distancia mayor que el 80% del tamaño de la display, entonces reduce el tamaño de la primera VIEW a la mitad de ancho para seguir al player de la izquierda y activa una segunda VIEW, también a la mitad del ancho de la display, para poder seguir al objeto de la derecha.

El cambio de cámara es instantáneo, lo he probado en mi GM y casi me saca los ojos.
Veré si hay una forma de hacerlo más smooth para que no dañe la vista, así como en los juegos de LEGO (que no sé si los hayas jugado xD). Por el momento ese es el código que te puedo ofrecer y al menos a mí me ha funcionado.

EDIT: Mejoré el código original para que ahora si se vea un movimiento de cámara suavizado, tanto al dividirse las cámaras como al volver a unirse.

Saludos