Título: ¿Como puedo mejorar esta colisión? JS "canvas" Publicado por: SrTrp en 19 Agosto 2017, 04:26 am Que creen que pueda mejorar esta función de colision de enemigos y jugador? quisiera saber como puedo hacer que no trasparece el enemigo si detecta cuando se topan.
Código
Título: Re: ¿Como puedo mejorar esta colisión? JS "canvas" Publicado por: 0xFer en 19 Agosto 2017, 05:29 am quisiera saber como puedo hacer que no trasparece el enemigo si detecta cuando se topan. Código
En caso de que se topen solo baja la vida, en caso contrario sigue con las acciones normales de desplazamiento. Título: Re: ¿Como puedo mejorar esta colisión? JS "canvas" Publicado por: engel lex en 19 Agosto 2017, 05:51 am creo que la intersección está mala... solo intersectará si está completamente adentro...
es preferible que definas unas clases decentemente Código
Título: Re: ¿Como puedo mejorar esta colisión? JS "canvas" Publicado por: Serapis en 19 Agosto 2017, 06:12 am No hay mucho de donde mejorarla. Técnicamente es correcta. Aunque es cierto que algo si se puede.
Te comento. Tu estás considerando siempre dos áreas, pero vamos a hacernos una imagen mental, para que sea más fácil entender donde quiero ir a parar. imagina que tienes una espda y luchas contra otro que también tiene una espada. El área de cada uno, entonces es uno mismo y las dimensiones de la propia espada. es fácil de entender, verdad? Bien, entonces la cuestión es... a quién le importa, tu espalda o 'su' espalda?. quiero decir, que la intercepción se basará en un punto, y no es preciso un área. Supongamos que 'el jugador' es This (tu, yo, el que lo lea que se ponga en primera persona) y que el 'enemigo' es el área (rect).... con esto y lo dicho previamente pasemos al pseudocódigo... Código: Clase cThis entero X, Y, Width, Height entero Right, Bottom // Asignación de todos los datos del área (se reposiciona y redimensiona) Funcion MoverYDimensionar(rect Area) // puedes pasar valores individuales, (x,y,Width,Height) o incluso solo dos puntos de la diagonal principal '\' y calcular como proceda, o bien sobrecargar la función si se usan más que solo una. This.x = Area.X This.y = Area.Y This.Width = Area.Width This.Height = Area.Height This.Right = (This.X + This.Width) This.Bottom = (This.Y + This.Height) Fin Funcion // Cuando se desplaza (pero mantiene el tamaño): // ('Inc'remento indica si los valores son relativos o absolutos) Funcion Mover(entero X, entero Y, buleano Inc) Si (Inc = FALSE) This.X = X This.Y = Y Sino This.X += X This.Y += Y Fin si This.Right = (This.X + This.Width) This.Bottom = (This.Y + This.Height) Fin funcion // Cuando se cambia de tamaño (pero mantiene su posición): // ('Inc'remento indica si los valores son relativos o absolutos) Funcion Dimensionar(entero Witdth, entero Height, buleano Inc) Si (Inc = FALSE) This.Width = Width This.Height = Height Sino This.Width += Width This.Height += Height Fin si This.Right = (This.X + This.Width) This.Bottom = (This.Y + This.Height) Fin Funcion // y por fin la detección de la colisión. // El detector de colisión, ahora exige menos matemáticas. Buleano = Funcion ColisionaCon(cThis cT) // si de entrada se aleja horizontalmente, no perdemos tiempo en comprobaciones verticales Si ( cT.Rigth > This.X) y (cT.X < This.Right) luego Devolver ( cT.Bottom > This.Y) y (cT.Y < This.Bottom) Sino Devolver FALSE Fin si Fin Funcion Fin clase Tanto 'nosotros' (player) como el 'enemigo' seríamos instancias de cThis, y se llamaría así: Código: Si Player.ColisionaCon(Enemigo) luego ... Funciona y es más rápido, porque: A - Se calcula una única vez, el valor 'Right y Botton', y se guardan, en lo sucesivo ya no se calculan. Por tanto cada vez que haya que hacer la detección de colisión, nos ahorramos 4 sumas. B - También contribuye a la velocidad que la comparación la dividimos en dos pasos, primero horizontal y luego vertical, (no importa si fuera al revés, de hecho si fuere más frecuente los movimientos verticales, sería mejor poner delante la comprobación vertical). al dividirlo en dos pasos no forzamos una posterior comprobación si la previa ya falló, pero incluso si es necesario la segunda comprobación también es ligera (no realiza sumas). En Resumen, la detección ahora solo requiere: 2 ó 4 comparaciones y 0 sumas Antes requería: 4 comparaciones y 4 sumas Las sumas se hacen una sola vez cuando se establece/modifica el tamaño o se reposiciona, pero no con cada verificación de colisión. Aunque al final viene a ser lo mismo, sin embargo el momento es diferente, al mover o redimensionar, no suele haber tanta carga de trabajo, luego... deja más tiempo para actualizar valores, en cambio cuando se exige detectar suele haber más trabajo 'pesado' en curso, entonces aligerar de ahí es adecuado. En resumen, desplazamos la carga de trabajao a momentos menos activos, aligerando los momentos más activos. Aunque siempre va a depender de cada caso concreto... ...pero bueno, lo que pedías es posible... --------------------- p.d.: Al publicar ya había más respuestas... te comento: asegúrate tras rehacer tu código que funciona en todos los casos... he aquí una imagen de los casos posibles (considera el cuadro rosado como el jugador y los azules como el enemigo), falta el caso de que el jugador esté completamente dentro del área del enemigo (el cuadro rosa dentro de uno azul), en las imágenes quedaba sobrecargado y se prestaba a confusión así que la he evitado. (http://i.imgur.com/Wj6N19l.png) |