Noticias

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

* Sponsor

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: colision con tile o con objeto  (Leído 552 veces)

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

Desconectado somnus

en: Julio 23, 2018, 05:47:08 pm
estoy viendo si es mejor hacer colisiones con el tile map, porque he leido que usar esas funciones son mas lentas que hacerlo coloquialmente como poner muchos objeto_wall hacerlo invisible y colisionar el personaje principal con este?

como ven conviene usar colisiones con tiles para rooms grandes?

Es Mejor No Saber Porque Funciona, Que Saber El Porque No Funciona...
Tienes alguna duda con "Game Design" o de videojuegos en general, contactamente mas facil en twitter @pavulzavala
 


No Tienes Permisos Para Dar Puntos
point 0 Puntos

Este tema no recibió puntos.


Desconectado BssString

Respuesta #1 en: Julio 25, 2018, 04:22:18 am
Hola somnus

Todo depende de cómo esté diseñado tu juego. Pero un sistema de GRID es más fácil de optimizar.
Cuando tienes 5000 o 15000 objetos en tu room, usar alguna función en esos objetos hace al juego extremadamente lento, incluso abusar del uso constante de un instance_deactivate, se te hará lento.
Caso contrario ocurre con las Grid, ya que puedes trabajar sólo en el sector donde está la cámara y ejecutar una menor cantidad de cálculos por step.

Saludos
« Última modificación: Julio 25, 2018, 05:01:59 am por BssString »

 


Desconectado somnus

Respuesta #2 en: Julio 25, 2018, 04:12:07 pm
Hola somnus

Todo depende de cómo esté diseñado tu juego. Pero un sistema de GRID es más fácil de optimizar.
Cuando tienes 5000 o 15000 objetos en tu room, usar alguna función en esos objetos hace al juego extremadamente lento, incluso abusar del uso constante de un instance_deactivate, se te hará lento.
Caso contrario ocurre con las Grid, ya que puedes trabajar sólo en el sector donde está la cámara y ejecutar una menor cantidad de cálculos por step.

Saludos


suena interesante esa soluciones, sera lo mismo que programar los quads de colision?, tienes a la mano alguna documentacion o tutorial al respecto? gracias de antemano.

Es Mejor No Saber Porque Funciona, Que Saber El Porque No Funciona...
Tienes alguna duda con "Game Design" o de videojuegos en general, contactamente mas facil en twitter @pavulzavala
 


Desconectado Goganpis

Respuesta #3 en: Julio 25, 2018, 05:44:12 pm
No es tan dificil usar las grids mas tardas aprendiendo el funcionamiento de las listas  :P

Bueno en el caso los set los usas para ajustarlos con un igual y los add para sumar cuando nesesitas sumar para no hacer la estupidez de tener que volver a buscar el valor, ya lo demas solo ajusta la grid con una variable en donde por ejemplo: la room todos los bloque son de 16x16 pues bueno con ello los divides y buscas ese valor en floor en los datos  XD Creo que me di a explicar... ya del resto solo lee el manual eso no hace daño

 


Desconectado BssString

Respuesta #4 en: Julio 26, 2018, 04:10:27 am
Hola somnus

Como los objetos fuera de la view siguen ejecutando su draw event (afectando considerablemente el rendimiento cuando tienes miles de objetos), lo mejor es usar un sistema de grid que sólo dibuje los bloques dentro de la view.
El problema de la grid es que al no existir un objeto, no puedes usar las funciones típicas de colisión como el place_free, instance_position, place_meeting, etc...

Como alternativa para realizar la colisión, puedes ver este video de Heart Beast donde enseña una buena lógica de colisión con grids https://youtu.be/fYILA_TWIgs?t=656

Su técnica es utilizar un script para simular la función "place_meeting", pero enfocada en Grids en vez de objetos.
Él mueve el player hacia una posición objetivo, luego detecta si alguna de las 4 esquinas de su máscara de colisión entra en una muralla de la grid, luego devuelve al player a su posición original y retorna si tuvo o no tuvo colisión

El problema de esta técnica es que tu player no puede ser más grande que una celda de la grid.
ej: si tu celda mide 32x32 pixeles, entonces la mascara de colisión de tu player no puede superar ese tamaño o los bloques te pueden atravesar por el centro (ya que la colisión ocurre en las esquinas).

Aquí abajo te redacto mi script llamado "colision", que tiene la misma lógica mostrada por Heart Beast en su video, es el que yo uso para realizar mi colisión y funciona perfecto. Yo uso GMS 1.4, pero no debería ser diferente en GMS 2.
Código: [Seleccionar]
///colision(nueva_x,nueva_y)
var x1,y1,x2,y2,c1,c2,c3,c4
x1 = x //recuerda la x original para después devolverse
y1 = y //Lo mismo
x2 = argument0 //Es la x nueva en la que se detecta la colisión
y2 = argument1 //Lo mismo

//Paso 1, mueve el objeto a la posición objetivo
x = x2
y = y2

//Paso 2, convertimos las coordenadas de las 4 esquinas de la bounding box a coordenadas en la grid y trae el valor de la grid.
var cell_size = 32 //Supongamos que tu grid es de 32x32
c1 = grid[# floor(bbox_right/cell_size),floor(bbox_top/cell_size)] //Esquina superior derecha
c2 = grid[# floor(bbox_left/cell_size),floor(bbox_top/cell_size)] //Esquina superior izquierda
c3 = grid[# floor(bbox_left/cell_size),floor(bbox_bottom/cell_size)] //Esquina inferior izquierda
c4 = grid[# floor(bbox_right/cell_size),floor(bbox_bottom/cell_size)] //Esquina inferior derecha

//Paso 3, devuelve al player a su posición original
x = x1
y = y1

//Paso 4, retorna un valor como resultado del script
var muralla = 2 //Supongamos que en tu grid el valor 2 significa que hay una muralla (en mi caso 0 es vacío, 1 es suelo, 2 es muralla, así que sólo detecto colisión con las celdas de valor 2)
return (c1==muralla) || (c2==muralla) || (c3==muralla) || (c4==muralla) //Si cualquiera de las esquinas toma el valor muralla, el script detecta colisión y devuelve "true", si ninguna de las 4 esquinas tiene valor muralla, devolverá "false"

Luego usas el script en tu código de detección de la colisión de la misma forma que usarías el place_meeting.
Código: [Seleccionar]
if !colision(x+xdir,y) { x += xdir }
Saludos