Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 07-06-2012
gabtroc gabtroc is offline
Miembro
NULL
 
Registrado: may 2012
Posts: 10
Poder: 0
gabtroc Va por buen camino
Animacion usando unidad crt

Buenas noches amigos de club delphi tengo un nuevo tema en el que necesito algo de ayuda me mandan a hacer una animacion en una aplicacion tipo consola utilizando la unidad crt en donde aparezca una pelota que se mueve de manera lineal y que cuando choque con los bordes de la pantalla rebote, tal cual como si fuera el protector de pantalla de windows.

Como segundo problema me mandan a hacer que la pelota haga un moviemiento parabolico y que tenga un rebote perfectamente elastico, es decir que cuando llegue al piso rebote y llegue a la misma altura de la cual se solto la pelota.

Para el primer problema si tengo algo hecho para el segundo no tengo ni idea de como hacer que el movimiento sea curvo. La aplicacion esta colocada en un menu por eso el codigo del primer problema lo tengo como un procedure.

La cosa esta asi

Código Delphi [-]
Procedure MovRectilineo;
Const colmax=80;
      linmax=24;

var col,lin,k:integer;

Begin
lin:=1;
col:=1;
k:=0;
ClrScr;
  repeat
   Write('O');
   sleep(90);
   clrscr;
   inc(lin);
   inc(col);
   GotoXY(col,lin);
   if lin=24 then begin
                   repeat
                    dec(lin);
                    inc(col);
                    Write('O');
                    sleep(90);
                    clrscr;
                    if col=80 then begin
                                     repeat
                                     dec(col);
                                     until col=1;
                                     GotoXY(col,lin);
                                   end;

                    GotoXY(col,lin);
                   until lin=1;

                  end;


   inc(k);
   until k=300;

Ahora pasa lo siguiente mis limites en la pantalla son 24 lineas y 80 columnas, la pelota comienza a moverse llega al borde de abajo y rebota perfecto y vuelve a subir y si rebota de arriba baja perfecto tambien el problema esta en que cuando llega al borde de la derecha el moviemiento comienza desde el principio, luego da una segunda vuelta y cuando vuelve a llegar al borde derecho aparece en la izquina superior izquierda y se imprime infinias veces en ese punto. Pueden correrlo para que vean mejor que eslo que esta haciendo pero eso es mas o menos la explicacion.

Como podria arreglar ese problema? y como puedo hacer con el segundo problema para que el movimiento sea curvo?
Responder Con Cita
  #2  
Antiguo 07-06-2012
Avatar de duilioisola
[duilioisola] duilioisola is offline
Miembro Premium
 
Registrado: ago 2007
Ubicación: Barcelona, España
Posts: 1.734
Poder: 20
duilioisola Es un diamante en brutoduilioisola Es un diamante en brutoduilioisola Es un diamante en bruto
Creo que te falta tener un campo que te diga la dirección en que se está moviendo la pelota.
En tal caso, el incrementeo/decremento de tu posición dependerá de la dirección:
Algo así:

Código Delphi [-]
// valor de direcciones
// 1 2 3
// 4 * 8
// 5 6 7

// inicializo al centro de la pantalla, direccion 5 (derecha, abajo)
col := 40;
lin := 12;
direccion := 5
k := 0;
repeat
   case direccion of
      1 :
      begin
         dec(col);
         dec(lin);
      end
      2 :
      begin
         dec(lin);
      end
      3 :
      begin
         inc(col);
         dec(lin);
      end
      4 :
      begin
         dec(col);
      end
      5 :
      begin
         dec(col);
         inc(lin);
      end
      6 :
      begin
         inc(lin);
      end
      7 :
      begin
         inc(col);
         inc(lin);
      end
      8 :
      begin
         dec(col);
      end
   end // case

   // Ahora me toca ver si me pase de los limites y cambiar la direccion segun corresponda
   // Si voy hacia arriba
   if (direccion >= 1) and (direccion <= 3)
      // y me paso del limite
      if (lin = 0) then
      begin
         direccion := direccion + 4; // 1 --> 5, 2 --> 6, 3 --> 7
         line := 1;
      end;

   // Si voy hacia abajo
   if (direccion >= 5) and (direccion <= 7)
      // y me paso del limite
      if (lin > 25) then
      begin
         direccion := direccion - 4; // 5 --> 1, 6 --> 2, 7 --> 3
         lin := 24;
      end;

   // Si voy a izquierda
   if (direccion = 1) or (direccion = 4) or (direccion = 5)
      // y me paso del limite
      if (col = 0) then
      begin
         case direccion of
            1 : direccion := 3;
            4 : direccion := 8;
            5 : direccion := 7;
         end;
         col := 0;
      end;

   // Si voy a derecha
   if (direccion = 3) or (direccion = 8) or (direccion = 7)
      // y me paso del limite
      if (col = 81) then
      begin
         case direccion of
            3 : direccion := 1;
            8 : direccion := 4;
            7 : direccion := 5;
         end;
         col := 80;
      end;

   clrscr;
   GotoXY(col,lin);
   write('O')
until k = 300;
Responder Con Cita
  #3  
Antiguo 07-06-2012
Avatar de duilioisola
[duilioisola] duilioisola is offline
Miembro Premium
 
Registrado: ago 2007
Ubicación: Barcelona, España
Posts: 1.734
Poder: 20
duilioisola Es un diamante en brutoduilioisola Es un diamante en brutoduilioisola Es un diamante en bruto
Para el tema de hacer una parábola, tendrás que jugar con senos cosenos, algo que simule gravedad y el campo dirección será directamente el ángulo en el que está cayendo/subiendo la pelota.
Todo esto suponiendo una velocidad constante... si quieres aceleración según va cayendo y deceleración según va subiendo, deberás agregar esta variable también.

Por ejemplo:
Col y lin será numeros reales (con coma)

Si estás en
  • col = 10.0
  • lin = 10.0
  • y el paso es 1 (te mueves de a 1 caracter)
  • y la direccion es 45º
la siguiente posición será:
col := col * sin(direccion);
lin := lin * cos(direccion);

Luego deberás posicionarte donde debes escribir la pelota.
Esto requiere valores enteros (sin coma)
GotoXY(Trunc(col), Trunc(lin)); // Trunc devuelve la parte entera de un valor.

Ten en cuenta que los valores para los grados deberá estar expresados en radianes (0-2*pi) (0-6.28).
Ten en cuenta que el seno y coseno te darán valores iguales y tendrás que controlarlos (sin(3/4*pi) = sin(1/4*pi)) porque será direcciones diferentes.
Responder Con Cita
  #4  
Antiguo 08-06-2012
gabtroc gabtroc is offline
Miembro
NULL
 
Registrado: may 2012
Posts: 10
Poder: 0
gabtroc Va por buen camino
Buenas amigo el codigo que pusiste tienes unos if sin then que no se bien que es lo que quieres hacer con eso, la verdad no entendi mucho el codigo me lo ppodrias explicar?

Y gracias por la idea de usar sen o cos para hacer el movimiento parabolico cuando termine de hacer el rectilineo veo que logro hacer con eso.
Responder Con Cita
  #5  
Antiguo 14-06-2012
Avatar de Ñuño Martínez
Ñuño Martínez Ñuño Martínez is offline
Moderador
 
Registrado: jul 2006
Ubicación: Ciudad Catedral, Españistán
Posts: 6.000
Poder: 25
Ñuño Martínez Tiene un aura espectacularÑuño Martínez Tiene un aura espectacular
A ver, a ver, "que sus estáis liando".

Cuando se está intentando reproducir un efecto físico, lo mejor es acudir a la física.

La pelota tiene una posición, que en física suele designarse mediante un vector P = { x, y }. Al mismo tiempo tiene una velocidad, que en física también se designa mediante un vector V = { Vx, Vy }, el cual representa la diferencia de posición de la pelota (Δ o "delta") en un espacio de tiempo t (es decir, el tiempo de un fotograma).

Por tanto la nueva posición de la pelota sería la suma de vectores P1 = P + V = { x + Vx, y + Vy }.

Según Newton (que a pesar de Einstein sigue siendo vigente) la velocidad es constante y sólo cambia si se le aplica una fuerza externa (por ejemplo, se golpea la pelota con una pala o raqueta, o la pelota golpea una pared). En física* las fuerzas también son vectores y normalmente se aplican sumándolos al vector V, aunque a la hora de programar pueden usarse algunos trucos. Por ejemplo, si se quiere que rebote contra los bordes de la pantalla entonces lo que hay que hacer es "invertir" el eje afectado. Si golpea los laterales, se invierte el eje horizontal (P2 = { x * (-1), y}), y si es la parte superior o la inferior se invierte el vertical (P2 = { x, y * (-1)}).

En cuanto a la parábola, sí es cierto que puede simularse mediante el seno y el coseno, pero será complicado. Aplicando la física es mucho más simple. La pelota describe una parábola porque es atraída por la Tierra. La atracción gravitatoria es una fuerza, y hemos dicho que las fuerzas son vectores, así que si tenemos la fuerza G podemos aplicarla a la velocidad de la pelota sumándosela.

¿Y todo esto cómo se codifica? Pues más fácil de lo que parece:
Código Delphi [-]
TYPE
(* Definimos el vector 2D. *)
  TVect2D = RECORD
    x, y: SINGLE;
  END;

(* Definimos una pelota. *)
  TPelota = RECORD
    Posicion, Velocidad: TVect2D
    ...
  END;

VAR
(* La pelota. *)
  Pelota: TPelota;
(* Fuerza gravitatoria. *)
  FuerzaG: TVect2D = (x: 0; y: 0.01); { Seguro que hay que ajustarla...}

(* Suma de vectores. *)
  PROCEDURE SumaVector2D (VAR Resultado: TVect2D; CONST V1, V2: TVect2D); INLINE;
  BEGIN
    Resultado.x := V1.x + V2.x;
    Resultado.y := V1.y + V2.y;
  END;


(* El meollo de la cuestión. *)
  PROCEDURE AnimaPelota;
  BEGIN
  { Movemos la pelota a la nueva posición. }
    SumaVector2D (Pelota.Posicion, Pelota.Posicion, Pelota.Velocidad);
  { Calculamos nueva velocidad. }
  { Primero, colisiones. }
    IF Pelota.Posicion.x <= 0 THEN
    BEGIN
      Pelota.Posicion.x := 0; { Para que no atraviese la pared. }
      Pelota.Velocidad.x := Posicion.Velocidad.x * (-1);
    END;
    IF Pelota.Posicion.x >= AnchoPantalla THEN
    BEGIN
      Pelota.Posicion.x := AnchoPantalla; { Para que no atraviese la pared. }
      Pelota.Velocidad.x := Posicion.Velocidad.x * (-1);
    END;
  { Hacer lo mismo con la parte superior y la inferior, pero no voy a escribirlo
    porque es muy parecido.  }
  { Ahora, la fuerza gravitatoria. }
    SumaVector2D (Pelota.Velocidad, Pelota.Velocidad, FuerzaG);
  END;

Más o menos. Si se quiere hacer absolutamente realista habría que andarse con normales, módulos, producto escalar, producto matricial... Pero para un caso simple como este esto es más que suficiente (estrictamente hablando es una optimización* del cálculo vectorial y matricial implicado).
__________________________

* Si hay algún físico en la sala seguro que me desacreditará dada la extrema simplificación, porque la cosa es algo más complicada a lo que explico, pero para lo que se necesita aquí es suficiente.
__________________
Proyectos actuales --> Allegro 5 Pascal ¡y Delphi!|MinGRo Game Engine
Responder Con Cita
  #6  
Antiguo 14-06-2012
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.038
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular


No es algo complicado, pero la explicación ha quedado muy clara incluso para los más torpes
Responder Con Cita
  #7  
Antiguo 14-06-2012
Avatar de Ñuño Martínez
Ñuño Martínez Ñuño Martínez is offline
Moderador
 
Registrado: jul 2006
Ubicación: Ciudad Catedral, Españistán
Posts: 6.000
Poder: 25
Ñuño Martínez Tiene un aura espectacularÑuño Martínez Tiene un aura espectacular
Bueno, de vez en cuando escribo cosas útiles...
__________________
Proyectos actuales --> Allegro 5 Pascal ¡y Delphi!|MinGRo Game Engine
Responder Con Cita
  #8  
Antiguo 14-06-2012
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
Que la masa por la derivada de la velocidad respecto al tiempo os te acompañe Nuño

Valga aclarar que eso funciona mientras el espacio sea euclidiano

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #9  
Antiguo 14-06-2012
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.038
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Cita:
Empezado por Delphius Ver Mensaje
Valga aclarar que eso funciona mientras el espacio sea euclidiano
Eso es algo que sabe cualquier Klingon
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Problema con animacion dfv Gráficos 4 19-10-2006 15:49:32
animación Delphi anto1178 Varios 1 31-08-2006 23:17:24
Animacion por frames Drake C++ Builder 5 26-06-2006 12:52:04
Animacion por frames Drake C++ Builder 2 28-12-2005 19:30:44
Animacion Troyano Varios 2 16-06-2004 15:29:02


La franja horaria es GMT +2. Ahora son las 06:59:08.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi