]> git.llucax.com Git - z.facultad/75.07/algowars.git/blob - src/vista/Vista.pas
Se expanden keywords del svn.
[z.facultad/75.07/algowars.git] / src / vista / Vista.pas
1 {** Interpreta y dibuja los datos del modelo en un formulario<br>\r
2     <i>Cambios:</i>\r
3     <PRE>\r
4     10/11/00: Se maneja la excepción para evitar usar la camara cuando el cameraman fue destruido (ECameramanDestruido).\r
5               Esta es propagada (por ahora) para que el controlador (formulario) frene el timer\r
6     02/12/00: Se mejoran los graficos usando transparencias en los bitmaps y se da la opcion de presentar\r
7               los graficos con transparencias (alta calidad) o no (a través del atributo aAltaCalidad y\r
8               los métodos mSetAltaCalidad, mSetBajaCalidad y mCambiarCalidad).\r
9               Se mejora la performance gracias a la nueva implementación de mDibujar, ya que los\r
10               bitmas se cargan una sola vez en memoria (en un array aBitmaps) en vez de cargarse\r
11               y liberarse cada vez que se actualiza la pantalla como sucedía anteriormente.\r
12               Se implementa el soporte de visualización de un objeto volador lockeado (utilizando\r
13               otra lista de bitmaps con los gráficos de los objetos lockeados, aBitmapsLockeados).\r
14     08/12/00: Se agregan múltiples cámaras: Derecha, Izquierda, Arriba, Abajo, Atrás, Del Misil. Para hacerlo\r
15               se agragega un array de camaras y un atributo que indica la camara actual. Tambien se agregan\r
16               métodos para cambiar la cámara actual, etc.\r
17               Se arregla el destructor que no liberaba todos los objetos.\r
18     09/12/00: Se reemplaza la vista del misil por una mas general (vista del arma) que permite ver a traves de\r
19               cualquier arma disparada. Se implementa correctamente esta vista.\r
20               Se agrega una vista tipo mapa.\r
21     18/12/00: Se corrige un bug que hacía que en ciertas circunstancias no se encuentren las imágenes, agragando\r
22               la ruta completa.\r
23     </PRE>}\r
24 unit Vista;\r
25 \r
26 interface\r
27 \r
28 uses\r
29   {$IFDEF DebugAlgoWars}\r
30   Objeto,\r
31   {$ENDIF}\r
32   Windows,\r
33   SysUtils,\r
34   Graphics,\r
35   Forms,\r
36   Camara,\r
37   Tipos,\r
38   ObjetoVolador,\r
39   Espacio,\r
40   Armas,\r
41   Lista;\r
42 \r
43 type\r
44   tArrayBitmaps = array [OV_NAVEPESADA..OV_MISDIR] of TBitmap;\r
45   tArrayCamaras = array [CAMARA_FRONTAL..CAMARA_ARMA] of cCamara;\r
46 \r
47   {** Interpreta y dibuja los datos del modelo en un formulario}\r
48   cVista = class{$IFDEF DebugAlgoWars}( cObjeto ){$ENDIF}\r
49     private\r
50       aFormulario:    TCustomForm;   // Formulario en el cual dibuja\r
51       aRegion:        HRgn;          // Región del formulario en la que dibuja\r
52       aCamara:        tCamaras;      // Cámara seleccionada actualmente\r
53       aCamaras:       tArrayCamaras; // Multiples cámaras\r
54       aBitmaps:       tArrayBitmaps; // Lista con los bitmaps\r
55       aBitmapsLocked: tArrayBitmaps; // Lista con los bitmaps\r
56       aAltaCalidad:   boolean;       // Indica si las imagenes se ven con transparencias.\r
57       {$IFDEF DebugAlgoWars}\r
58       aListaProy:     cLista;   // Lista de objetos proyectados (se guarda para poder\r
59                                 //  implementar el método mGetDebugInfo\r
60       {$ENDIF}\r
61     protected\r
62       {** Obtiene el lado menor del formulario}\r
63       function mGetFormLado: integer;\r
64       {** Convierte el tamaño obtenido de la cámara a uno proporcional en píxeles}\r
65       function mGetTam( proy: tPProy ): integer;\r
66       {** Convierte la componente en x obtenida de la cámara a una proporcional en píxeles}\r
67       function mGetX( proy: tPProy ): integer;\r
68       {** Convierte la componente en y obtenida de la cámara a una proporcional en píxeles}\r
69       function mGetY( proy: tPProy ): integer;\r
70       {** Dibuja un ObjetoVolador}\r
71       procedure mDibujarOV( proy: tPProy );\r
72       {** Dibuja el ObjetoVolador lockeado por la nave propia}\r
73       procedure mDibujarOVLockeado( proy: tPProy );\r
74       {** Muestra un mensaje de game over}\r
75       procedure mGameOver;\r
76       {** Convierte un tipo tObjetosVoladores al nombre del archivo que guarda su bitmap}\r
77       function mObjetoVoladorToFilename( obj: tObjetosVoladores ): string;\r
78       {** Convierte un tipo tObjetosVoladores al nombre del archivo que guarda su bitmap lockeado}\r
79       function mObjetoVoladorLockedToFilename( obj: tObjetosVoladores ): string;\r
80       {** Crea una cámara según el tipo}\r
81       function mCrearCamara( cam: tCamaras; ov: cObjetoVolador ): cCamara;\r
82     public\r
83       {** Constructor}\r
84       constructor create( formulario: TCustomForm; ov: cObjetoVolador; calidad: boolean = true );\r
85       {** Dibuja todos los Objetos Voladores que ve la cámara}\r
86       procedure mDibujarVista( oEspacio: cEspacio );\r
87       {** Define el formulario en donde dibujar}\r
88       procedure mSetForm( oForm: TCustomForm );\r
89       {** Setea gráficos de alta calidad}\r
90       procedure mSetAltaCalidad;\r
91       {** Setea gráficos de baja calidad}\r
92       procedure mSetBajaCalidad;\r
93       {** Invierte la calidad de los gráficos. Es decir, si estaban en baja los pone\r
94           en alta y vice versa.}\r
95       procedure mCambiarCalidad;\r
96       {$IFDEF DebugAlgoWars}\r
97       {** Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar\r
98           y la información entregada depende del parámetro tDebugInfo.}\r
99       function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; override;\r
100       {$ENDIF}\r
101       {** Permite realizar el cambio de camara}\r
102       procedure mCambiarCamara( cam: tCamaras );\r
103       {** Cambia a la siguiente cámara}\r
104       procedure mCamaraSiguiente;\r
105       {** Devuelve que camara esta activa}\r
106       function mGetCamaraStr: string;\r
107       {** Crea la cámara del arma}\r
108       procedure mCrearCamaraDeArma( a: cArma );\r
109       {** Destructor}\r
110       destructor destroy; override;\r
111   end;\r
112 \r
113 \r
114 implementation\r
115 \r
116 uses\r
117   Camaras;\r
118 \r
119 { cVista }\r
120 \r
121 {** Constructor\r
122     @param formulario Formulario en donde dibujará la vista\r
123     @param ov         Objeto Volador en el cual montar la cámara}\r
124 constructor cVista.create(formulario: TCustomForm; ov: cObjetoVolador; calidad: boolean);\r
125 var\r
126   obj:    tObjetosVoladores;\r
127   cam:    tCamaras;\r
128   bitmap: TBitmap;\r
129 begin\r
130   inherited create;\r
131   for cam := CAMARA_FRONTAL to pred( CAMARA_ARMA ) do\r
132     aCamaras[cam] := mCrearCamara( cam, ov );\r
133   aCamaras[CAMARA_ARMA] := nil;\r
134   aCamara := CAMARA_FRONTAL;\r
135   aAltaCalidad := calidad;\r
136   {$IFDEF DebugAlgoWars}\r
137   aListaProy := nil;\r
138   {$ENDIF}\r
139   mSetForm( formulario );\r
140   // Carga gráficos Comunes\r
141   for obj := OV_NAVEPESADA to OV_MISDIR do begin\r
142     bitmap := TBitmap.create;\r
143     with bitmap do begin\r
144       LoadFromFile( mObjetoVoladorToFilename( obj ) );\r
145       TransparentColor := clBlack;\r
146       TransparentMode  := tmFixed;\r
147       Transparent      := aAltaCalidad;\r
148     end;\r
149     aBitmaps[obj] := bitmap;\r
150   end;\r
151   // Carga gráficos Lockeados\r
152   for obj := OV_NAVEPESADA to OV_NAVEPROPIA do begin\r
153     bitmap := TBitmap.create;\r
154     with bitmap do begin\r
155       LoadFromFile( mObjetoVoladorLockedToFilename( obj ) );\r
156       TransparentColor := clBlack;\r
157       TransparentMode  := tmFixed;\r
158       Transparent      := aAltaCalidad;\r
159     end;\r
160     aBitmapsLocked[obj] := bitmap;\r
161   end;\r
162 end;\r
163 \r
164 {** Destructor}\r
165 destructor cVista.destroy;\r
166 var\r
167   obj: tObjetosVoladores;\r
168   cam: tCamaras;\r
169 begin\r
170   for cam := CAMARA_FRONTAL to CAMARA_ARMA do\r
171     aCamaras[cam].free;\r
172   for obj := OV_NAVEPESADA to OV_MISDIR do begin\r
173     aBitmaps[obj].free;\r
174     aBitmapsLocked[obj].free;\r
175   end;\r
176   {$IFDEF DebugAlgoWars}\r
177   aListaProy.free;\r
178   {$ENDIF}\r
179 end;\r
180 \r
181 {** Dibuja un ObjetoVolador\r
182     @param proy Puntero a un elemento del tipo tProyeccion con los datos de la proyeccion\r
183                 de un determinado objeto volador (proporcionado por la cámara)}\r
184 procedure cVista.mDibujarOV(proy: tPProy);\r
185 var\r
186   rect:   TRect;\r
187   tam:    integer;\r
188 begin\r
189   tam := mGetTam(proy);\r
190   rect.Left   := mGetX(proy);\r
191   rect.top    := mGetY(proy);\r
192   rect.right  := rect.left + tam;\r
193   rect.bottom := rect.top  + tam;\r
194   // crea una region de dibujo //solo bmp\r
195   // asigna la region anterior\r
196   SelectClipRgn( aFormulario.canvas.handle, aRegion );\r
197   // dibuja el bmp entero entre los puntos de rect o rect1\r
198   aFormulario.canvas.StretchDraw( rect, aBitmaps[proy^.oOV.mDibujar] );\r
199 end;\r
200 \r
201 {** Dibuja el ObjetoVolador lockeado por la nave propia\r
202     @param proy Puntero a un elemento del tipo tProyeccion con los datos de la proyeccion\r
203                 de un determinado objeto volador (proporcionado por la cámara)}\r
204 procedure cVista.mDibujarOVLockeado(proy: tPProy);\r
205 var\r
206   rect:    TRect;\r
207   tam:     integer;\r
208 begin\r
209   tam := mGetTam(proy);\r
210   rect.Left   := mGetX(proy);\r
211   rect.top    := mGetY(proy);\r
212   rect.right  := rect.left + tam;\r
213   rect.bottom := rect.top  + tam;\r
214   // crea una region de dibujo //solo bmp\r
215   // asigna la region anterior\r
216   SelectClipRgn( aFormulario.canvas.handle, aRegion );\r
217   // dibuja el bmp entero entre los puntos de rect\r
218   aFormulario.canvas.StretchDraw( rect, aBitmapsLocked[proy^.oOV.mDibujar] );\r
219 end;\r
220 \r
221 {** Dibuja todos los Objetos Voladores que ve la cámara\r
222     @param oEspacio Espacio del cual obtener la lista de objetos a interpretar por la cámara\r
223                     para dibujarlos}\r
224 procedure cVista.mDibujarVista( oEspacio: cEspacio );\r
225 var\r
226   i:  integer;\r
227   pProy: tPProy;\r
228   {$IFNDEF DebugAlgoWars}\r
229   aListaProy: cLista;\r
230   {$ENDIF}\r
231 begin\r
232   {$IFDEF DebugAlgoWars}\r
233   // Libera la lista vieja\r
234   aListaProy.free;\r
235   aListaProy := nil;\r
236   {$ENDIF}\r
237   //mantiene el circulo negro\r
238   aFormulario.canvas.brush.Color := clblack;\r
239   aFormulario.canvas.ellipse( 0, 0, mGetFormLado, mGetFormLado );\r
240   if aCamaras[aCamara] = nil then // Si es la camara es nil\r
241     mCamaraSiguiente; // Selecciona la camara siguiente\r
242   try // Probamos que el cameraman no este destruido\r
243     aListaProy := aCamaras[aCamara].mProcesar( oEspacio.mGetObjetos );\r
244     for i := 0 to aListaProy.Count - 1 do begin\r
245       pProy := aListaProy.items[i];\r
246       // Si el objeto volador lockeado por la nave propia es el actual...\r
247       if oEspacio.mGetNavePropia.mGetLockeado = pProy^.oOV then\r
248         mDibujarOVLockeado( aListaProy.items[i] ) // lo dibuja de una forma distinta\r
249       else                                   // si no...\r
250         mDibujarOV( aListaProy.items[i] );        // lo dibuja de la forma normal\r
251     end;\r
252   except // Si esta destruido cae en una excepcion\r
253     on e: ENavePropiaDestruida do begin\r
254       mGameOver; // Muestra el mensaje de GAME OVER\r
255       raise; // Propaga la excepcion\r
256     end;\r
257     on e: ECameramanDestruido do begin // Si fue destruido el cameraman\r
258       mCamaraSiguiente; // pasa a la siguiente\r
259     end;\r
260   end;\r
261 end;\r
262 \r
263 {** Obtiene el lado menor del formulario\r
264     @return El alto o el ancho del formulario, dependiendo de cual sea menor}\r
265 function cVista.mGetFormLado: integer;\r
266 begin\r
267  if aFormulario.ClientWidth > aFormulario.ClientHeight then\r
268     result := aFormulario.ClientHeight\r
269   else\r
270     result := aFormulario.ClientWidth;\r
271     //result:=409;\r
272 end;\r
273 \r
274 {** Convierte el tamaño obtenido de la cámara a uno proporcional en píxeles\r
275     @param  proy Puntero a un elemento del tipo tProyeccion con los datos de la proyeccion\r
276                  de un determinado objeto volador (proporcionado por la cámara)\r
277     @return      Tamaño del objeto en píxeles (tamaño del lado del cuadrado que se usará para\r
278                  dibujar el bitmap)}\r
279 function cVista.mGetTam(proy: tPProy): integer;\r
280 begin\r
281   // Se calcula tomando un valor de la supuesta cabina de 1/2 metro, a partir de ahi es una\r
282   //  regla de 3 simple.\r
283   // NOTA: como los objetos quedan demasiado grandes, en vez de tomarse 1/2 metro, se toma mas pequeña\r
284   // La dimension se multiplica por 2 porque es el radio de la nave\r
285   //  TAM = tam * (dim * 2) * (lado / 2) / 25 (metros) = tam * dim * lado / 25\r
286   result := round( proy^.tam * proy^.oOV.mGetDimension * mGetFormLado / 25 );\r
287 end;\r
288 \r
289 {** Convierte la componente en x obtenida de la cámara a una proporcional en píxeles\r
290     @param  proy Puntero a un elemento del tipo tProyeccion con los datos de la proyeccion\r
291                  de un determinado objeto volador (proporcionado por la cámara)\r
292     @return      Componente en X del objeto en píxeles (x de la esquina superior izquierdadel\r
293                  cuadrado que se usará para dibujar el bitmap)}\r
294 function cVista.mGetX(proy: tPProy): integer;\r
295 begin\r
296   // Se calcula por medio de una regla de 3 simple teniendo en cuenta los tamaños maximos y se le\r
297   //  resta la mitad del tamaño porque se dibuja a partir de la esquina superior izquierda, no a\r
298   //  partir del centro como es en el modelo.\r
299   result := round( proy^.x * (mGetFormLado / 2) / aCamaras[aCamara].mGetRadioPantalla + mGetFormLado / 2 ) -\r
300             mGetTam( proy ) div 2;\r
301 end;\r
302 \r
303 {** Convierte la componente en y obtenida de la cámara a una proporcional en píxeles\r
304     @param  proy Puntero a un elemento del tipo tProyeccion con los datos de la proyeccion\r
305                  de un determinado objeto volador (proporcionado por la cámara)\r
306     @return      Componente en Y del objeto en píxeles (y de la esquina superior izquierdadel\r
307                  cuadrado que se usará para dibujar el bitmap)}\r
308 function cVista.mGetY(proy: tPProy): integer;\r
309 begin\r
310   // Se calcula por medio de una regla de 3 simple teniendo en cuenta los tamaños maximos y se le\r
311   //  resta la mitad del tamaño porque se dibuja a partir de la esquina superior izquierda, no a\r
312   //  partir del centro como es en el modelo.\r
313   result := round( proy^.y * (mGetFormLado / 2) / aCamaras[aCamara].mGetRadioPantalla + mGetFormLado / 2 ) -\r
314             mGetTam( proy ) div 2;\r
315 end;\r
316 \r
317 {** Define el formulario en donde dibujar\r
318     @param oForm Formulario en el cual dibujará la vista}\r
319 procedure cVista.mSetForm(oForm: TCustomForm);\r
320 begin\r
321   aFormulario := oForm;\r
322   aRegion := CreateEllipticRgn( 0, 0, mGetFormLado, mGetFormLado );\r
323 end;\r
324 \r
325 {$IFDEF DebugAlgoWars}\r
326 {** Devuelve el estado del objeto basandose en la cantidad de datos requeridos.\r
327     @return            Cadena de texto con el estado del Objeto.\r
328     @param   debugLevel Cantidad de información requerida}\r
329 function cVista.mGetDebugInfo( debugLevel: tDebugInfo ): string;\r
330 var\r
331   i:    integer;  // contador\r
332   proy: tPProy;   // variable temporal para obtener info de la proyeccion\r
333   camInfo: string;\r
334 begin\r
335   result := 'Cámara: ' + #13 + #10;\r
336   try // Probamos que el cameraman no este destruido\r
337     camInfo := aCamaras[aCamara].mGetDebugInfo( debugLevel );\r
338   except // Si esta destruido cae en una excepcion\r
339     on e: ECameramanDestruido do\r
340       camInfo := e.Message;\r
341   end;\r
342   result := result + camInfo;\r
343   // Genera el string con el estado del Espacio\r
344   if aListaProy <> nil then begin\r
345     for i := 0 to aListaProy.Count - 1 do begin\r
346       proy := aListaProy.Items[i];\r
347       result := result + #13 + #10 +\r
348                 'ObjetoVolador Proyectado ' + IntToStr( i ) + ': ' + proy^.oOV.ClassName +\r
349                 ' | X: ' + IntToStr( mGetX( proy ) ) +\r
350                 ' | Y: ' + IntToStr( mGetY( proy ) ) +\r
351                 ' | Tam: ' + IntToStr( mGetTam( proy ) );\r
352       if debugLevel > DI_NORMAL then\r
353         result := result + #13 + #10 +\r
354                   'X (cámara): ' + FloatToStrF( proy^.x, ffNumber, 5, 5 ) +\r
355                   ' | Y (cámara): ' + FloatToStrF( proy^.y, ffNumber, 5, 5 ) +\r
356                   ' | Tam (cámara): ' + FloatToStrF( proy^.tam, ffNumber, 5, 5 );\r
357     end;\r
358   end;\r
359 end;\r
360 {$ENDIF}\r
361 \r
362 {** Muestra un mensaje de game over}\r
363 procedure cVista.mGameOver;\r
364 var\r
365   rect: TRect;\r
366   bitm: TBitMap;\r
367 begin\r
368   rect.Left   := 100;\r
369   rect.top    := 150;\r
370   rect.right  := 300;\r
371   rect.bottom := 250;\r
372   // crea una region de dibujo //solo bmp\r
373   // asigna la region anterior\r
374   SelectClipRgn( aFormulario.canvas.handle, aRegion );\r
375   // dibuja el bmp entero entre los puntos de rect o rect1\r
376   bitm := TBitMap.create;\r
377   bitm.LoadFromFile( 'bitmaps\gameover.bmp' );\r
378   aFormulario.canvas.StretchDraw( rect, bitm );\r
379   // canvas.stretchdraw(rect1,bitm);\r
380   bitm.free;\r
381 end;\r
382 \r
383 {** Convierte un tipo tObjetosVoladores al nombre del archivo que guarda su bitmap\r
384     @param obj Tipo de objeto volador\r
385     @return Nombre del archivo que almacena el bitmap que lo representa}\r
386 function cVista.mObjetoVoladorToFilename(obj: tObjetosVoladores): string;\r
387 begin\r
388   result := ExtractFileDir( ParamStr( 0 ) ) + '\bitmaps\';\r
389   case obj of\r
390     OV_METEORITO:   result := result + 'meteorito.bmp';\r
391     OV_LASER:       result := result + 'laser.bmp';\r
392     OV_MISIL:       result := result + 'misil.bmp';\r
393     OV_MISDIR:      result := result + 'misildirigido.bmp';\r
394     OV_NAVEPROPIA:  result := result + 'navepropia.bmp';\r
395     OV_NAVEPESADA:  result := result + 'navepesada.bmp';\r
396     OV_NAVELIVIANA: result := result + 'naveliviana.bmp';\r
397     OV_NAVEESPIA:   result := result + 'naveespia.bmp';\r
398     OV_NAVESUICIDA: result := result + 'navesuicida.bmp';\r
399     else            result := result + 'desconocido.bmp';\r
400   end;\r
401 end;\r
402 \r
403 {** Convierte un tipo tObjetosVoladores al nombre del archivo que guarda su bitmap lockeado\r
404     @param obj Tipo de objeto volador\r
405     @return Nombre del archivo que almacena el bitmap que lo representa}\r
406 function cVista.mObjetoVoladorLockedToFilename(\r
407   obj: tObjetosVoladores): string;\r
408 begin\r
409   result := ExtractFileDir( ParamStr( 0 ) ) + '\bitmaps\';\r
410   case obj of\r
411     OV_METEORITO:   result := result + 'meteorito_l.bmp';\r
412     OV_NAVEPROPIA:  result := result + 'navepropia_l.bmp';\r
413     OV_NAVEPESADA:  result := result + 'navepesada_l.bmp';\r
414     OV_NAVELIVIANA: result := result + 'naveliviana_l.bmp';\r
415     OV_NAVEESPIA:   result := result + 'naveespia_l.bmp';\r
416     OV_NAVESUICIDA: result := result + 'navesuicida_l.bmp';\r
417     else            result := result + 'desconocido_l.bmp';\r
418   end;\r
419 end;\r
420 \r
421 {** Setea gráficos de alta calidad}\r
422 procedure cVista.mSetAltaCalidad;\r
423 begin\r
424   if not aAltaCalidad then // Si no estan seteados como de alta calidad...\r
425   mCambiarCalidad;\r
426 end;\r
427 \r
428 {** Setea gráficos de baja calidad}\r
429 procedure cVista.mSetBajaCalidad;\r
430 begin\r
431   if aAltaCalidad then // Si no estan seteados como de alta calidad...\r
432   mCambiarCalidad;\r
433 end;\r
434 \r
435 {** Invierte la calidad de los gráficos. Es decir, si estaban en baja los pone\r
436     en alta y vice versa.}\r
437 procedure cVista.mCambiarCalidad;\r
438 var\r
439   obj: tObjetosVoladores;\r
440 begin\r
441   aAltaCalidad := not aAltaCalidad;\r
442   for obj := OV_NAVEPESADA to OV_MISDIR do\r
443     aBitmaps[obj].Transparent := aAltaCalidad;\r
444   for obj := OV_NAVEPESADA to OV_NAVEPROPIA do\r
445     aBitmapsLocked[obj].Transparent := aAltaCalidad;\r
446 end;\r
447 \r
448 procedure cVista.mCambiarCamara(cam : tCamaras);\r
449 begin\r
450   if aCamaras[cam] <>  nil then // Si esta creada es camara, la cambia\r
451     aCamara := cam;\r
452 end;\r
453 \r
454 function cVista.mGetCamaraStr: string;\r
455 begin\r
456   case aCamara of\r
457     CAMARA_FRONTAL: result := 'Cámara Frontal';\r
458     CAMARA_LATDER:  result := 'Cámara Lateral Derecha';\r
459     CAMARA_LATIZQ:  result := 'Cámara Lateral Izquierda';\r
460     CAMARA_TRASERA: result := 'Cámara Trasera';\r
461     CAMARA_ARRIBA:  result := 'Cámara Superior';\r
462     CAMARA_ABAJO:   result := 'Cámara Inferior';\r
463     CAMARA_MAPA:    result := 'Mapa del Escenario';\r
464     CAMARA_ARMA:    result := 'Cámara en el Arma';\r
465   end;\r
466 end;\r
467 \r
468 {** Crea una cámara según el tipo\r
469     @param  cam Tipo de Cámara\r
470     @param  ov  Portador de la cámara\r
471     @return Nueva cámara creada}\r
472 function cVista.mCrearCamara(cam: tCamaras; ov: cObjetoVolador): cCamara;\r
473 begin\r
474   case cam of\r
475     CAMARA_FRONTAL: result := cCamaraFrontal.create( ov, 1 ); // Se la crea con un poco mas de angulo que el comun\r
476     CAMARA_LATDER:  result := cCamaraLatDer.create( ov, 1 );  // Se la crea con un poco mas de angulo que el comun\r
477     CAMARA_LATIZQ:  result := cCamaraLatIzq.create( ov, 1 );  // Se la crea con un poco mas de angulo que el comun\r
478     CAMARA_TRASERA: result := cCamaraTrasera.create( ov, 1 ); // Se la crea con un poco mas de angulo que el comun\r
479     CAMARA_ARRIBA:  result := cCamaraArriba.create( ov, 1 );  // Se la crea con un poco mas de angulo que el comun\r
480     CAMARA_ABAJO:   result := cCamaraAbajo.create( ov, 1 );   // Se la crea con un poco mas de angulo que el comun\r
481     CAMARA_MAPA:    result := cCamaraMapa.create( ov, 1 );    // Se la crea con un poco mas de angulo que el comun\r
482     CAMARA_ARMA:    result := cCamaraFrontal.create( ov, 1 ); // Se la crea con un poco mas de angulo que el comun\r
483   end;\r
484 end;\r
485 \r
486 {** Cambia a la siguiente cámara}\r
487 procedure cVista.mCamaraSiguiente;\r
488 var\r
489   cam: tCamaras;\r
490 begin\r
491   cam := succ( aCamara ); // Pasa a la próxima\r
492   if cam > CAMARA_ARMA then // Si se paso del ultimo ...\r
493     aCamara := CAMARA_FRONTAL // Vuelve a la primera\r
494   else\r
495     if cam = CAMARA_ARMA then // Si es la camara del misil...\r
496       if aCamaras[aCamara] = nil then // Si no esta activa...\r
497         aCamara := CAMARA_FRONTAL // Vuelve a la camara frontal\r
498       else // si esta todo normal...\r
499         aCamara := cam\r
500     else // si esta todo normal...\r
501         aCamara := cam\r
502 end;\r
503 \r
504 {** Crea la cámara del arma\r
505     @param ov Objeto Volador portador de la camara}\r
506 procedure cVista.mCrearCamaraDeArma(a: cArma);\r
507 begin\r
508   if a <> nil then begin\r
509     if aCamaras[CAMARA_ARMA] <> nil then\r
510       aCamaras[CAMARA_ARMA].free;\r
511     aCamaras[CAMARA_ARMA] := mCrearCamara( CAMARA_ARMA, a );\r
512   end;\r
513 end;\r
514 \r
515 end.