elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Usando Git para manipular el directorio de trabajo, el índice y commits (segunda parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Desarrollo Web (Moderador: #!drvy)
| | |-+  ¿Como puedo mejorar esta colisión? JS "canvas"
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: ¿Como puedo mejorar esta colisión? JS "canvas"  (Leído 3,817 veces)
SrTrp


Desconectado Desconectado

Mensajes: 323


Script/C#


Ver Perfil
¿Como puedo mejorar esta colisión? JS "canvas"
« 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
  1. //AQUI ESTA CUANDO HAGO LA COLISION ENTRE ENEMIGO Y JUGADOR
  2. if(player.intersects(enemigos[i])&&player.timer<1){
  3.                    player.vida--;
  4.                    player.timer=20;
  5.  
  6.                }
  7.  
  8.  
  9. //AQUI ESTA LA FUNCION DE COLISION
  10. Rectangle.prototype.intersects=function(rect){
  11.        if(rect!=null){
  12.            return(this.x<rect.x+rect.width&&
  13.                this.x+this.width>rect.x&&
  14.                this.y<rect.y+rect.height&&
  15.                this.y+this.height>rect.y);
  16.        }
  17.    }


En línea

0xFer


Desconectado Desconectado

Mensajes: 400



Ver Perfil
Re: ¿Como puedo mejorar esta colisión? JS "canvas"
« Respuesta #1 en: 19 Agosto 2017, 05:29 am »

 quisiera  saber como puedo hacer que no trasparece el enemigo si detecta cuando se topan.

Código
  1. if(player.intersects(enemigos[i])&&player.timer<1){
  2.                    player.vida--;
  3.                    player.timer=20;
  4.  
  5.                }
  6. else{
  7.  
  8. }

En caso de que se topen solo baja la vida, en caso contrario sigue con las acciones normales de desplazamiento.


En línea

Código
  1. int getRandomNumber(){
  2.    return 4; //chosen by fair dice roll
  3.              //guaranteed to be random
  4. }
engel lex
Moderador Global
***
Desconectado Desconectado

Mensajes: 15.514



Ver Perfil
Re: ¿Como puedo mejorar esta colisión? JS "canvas"
« Respuesta #2 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
  1. class Rect{
  2.  constructor(x,y,w,h){
  3.    this.x = x;
  4.    this.y = y;
  5.    this.w = w; //ancho
  6.    this.h = h; //alto
  7.    this.l = x; //left
  8.    this.r = x+w; //right
  9.    this.t = y; //top
  10.    this.b = y+h; //bottom
  11.  }
  12.  
  13.  colision(otro){
  14.    //si this l está entre l y r de otro hay colisión izquierda
  15.    //si this r está entre l y r de otro hay colisión derecha
  16.    //si this l es mayor que otro l y this r es menor que otro r, otro adentro de this
  17.    //si this l es menor que otro l y this r es mayor que otro r, this adentro de otro
  18.    //repetir con vertical
  19.  }
  20. }
  21.  
  22. var cajaDeColision  = new Rect (10, 10, 50, 50);
  23.  
  24. if(cajaDeColision.colision(otraCajaDeColision)){
  25.  console.log("hay colision");
  26. }
  27.  
  28.  


« Última modificación: 19 Agosto 2017, 06:15 am por engel lex » En línea

El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.
Serapis
Colaborador
***
Desconectado Desconectado

Mensajes: 3.348


Ver Perfil
Re: ¿Como puedo mejorar esta colisión? JS "canvas"
« Respuesta #3 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.
« Última modificación: 19 Agosto 2017, 06:44 am por NEBIRE » En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines