]> git.llucax.com Git - z.facultad/75.07/algowars.git/blob - src/modelo/ov/ObjetoVolador.pas
Import inicial después del "/var incident". :(
[z.facultad/75.07/algowars.git] / src / modelo / ov / ObjetoVolador.pas
1 {** Clase abstracta, implementa todas las funcionalidades básicas de los objetos voladores.\r
2     De esta van a derivar la mayor parte del resto de las clases.<br>\r
3     <i>Cambios:</i>\r
4     <PRE>\r
5     05/10/00: Se agregaron los métodos mGetDistancia y mColisiono. De esta manera se deja\r
6               a los objetos voladores manejar las colisiones mas intuitivamente.\r
7     30/10/00: Se agregó un atributo <b>aCoordenadas</b> para que se pueda orientar al objeto volador.\r
8     02/11/00: Se agregaron métodos para cambiar solamente el modulo de la velocidad, para cambiar solo\r
9               la direccion de la velocidad y para extraer directamente copias de los versores i, j, k y\r
10               para rotar el objeto volador en todas direcciones.\r
11               Los nuevos métodos son: mSetVelModulo, mSetVelDir, mGetVelModulo,\r
12                                       mGetI, mGetJ, mGetK, mRotarEnI,\r
13                                       mRotarEnJ, mRotarEnK\r
14     07/11/00: Se agrega un nuevo método (mSetPosicion) y se hace a público otro (mSetVelocidad) para\r
15               que se pueda cambiar la configuración (es temporal, se planea cambiar el sistema de\r
16               configuración del juego para que esto no sea necesario)\r
17     29/11/00: Se arregla un BUG en mSetVelModulo que no modificaba el modulo si la velocidad pasada\r
18               como argumento era menor que cero. En este caso el modulo de la velocidad se setea en 0.\r
19     02/12/00: Se cambio el dato que devuelve el método mDibujar. Ahora devuelve un tipo de dato enumerado\r
20               tObjetosVoladores. Todas sus subclases fueron actualizadas también.\r
21     08/12/00: Se agregan menúes para manejar la nueva vistas con varias camaras. Se agrega la opcion de\r
22               alta calidad en el menú vista. Se carga un escenario por defecto (si existe) al iniciar el\r
23               juego, el nombre de dicho escenario debe ser 'comun.eaw'.\r
24               Se agrega una nueva tecla para cambiar de cámara ('C'), además de las que se provee con las\r
25               teclas de atajo.\r
26     </PRE>}\r
27 unit ObjetoVolador;\r
28 \r
29 interface\r
30 \r
31 uses\r
32   Tipos,\r
33   ObjetoPersistente,\r
34   Coordenadas,\r
35   Vectores;\r
36 \r
37 type\r
38   {** Clase abstracta, implementa todas las funcionalidades básicas de los objetos voladores.\r
39       De esta van a derivar la mayor parte del resto de las clases.}\r
40   cObjetoVolador = class( cObjetoPersistente )\r
41     private\r
42       aPosicion:    cVector;      // Posicion del objeto volador en el espacio\r
43       aVelocidad:   tLongitud;    // Velocidad del objeto volador (en modulo)\r
44       aPotencia:    tEnergia;     // Potencia del objeto volador (la cantidad de daño que hace por impacto)\r
45       aEnergia:     tEnergia;     // Energía del objeto volador (la cantidad de daño que soporta antes de ser destruido)\r
46       aDimension:   tLongitud;    // La dimesión del objeto volador (es el radio de una esfera)\r
47       // Agregado 30/10/00\r
48       aCoordenadas: cCoordenadas; // Sistema de coordenadas del objeto volador (para tener nocion de la orientación)\r
49                                   //  El versor i es la direccion de la velocidad\r
50     protected\r
51       {** Método para establecer la energía}\r
52       function mSetEnergia( ene: tEnergia ): cObjetoVolador;\r
53       {** Rota el objeto volador sobre el eje i\r
54           (el sentido positivo es de j a k)}\r
55       function mRotarEnI( dAngulo: tAngulo ): cObjetoVolador;\r
56       {** Rota el objeto volador sobre el eje j\r
57           (el sentido positivo es de i a k)}\r
58       function mRotarEnJ( dAngulo: tAngulo ): cObjetoVolador;\r
59       {** Rota el objeto volador sobre el eje k\r
60           (el sentido positivo es de i a j)}\r
61       function mRotarEnK( dAngulo: tAngulo ): cObjetoVolador;\r
62     public\r
63       {** Constructor}\r
64       constructor create( pos: cVector = nil; vel: cVector = nil; dim: tLongitud = 5; pot: tEnergia = 1; ene: tEnergia = 100 ); overload;\r
65       {** Constructor que copia los atributos de un Objeto volador existente}\r
66       constructor create( ov:  cObjetoVolador ); overload;\r
67       {$IFDEF DebugAlgoWars}\r
68       {** Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar\r
69           y la información entregada depende del parámetro tDebugInfo.}\r
70       function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; override;\r
71       {$ENDIF}\r
72       {** Mueve el objeto volador basandose en su posicion, su velocidad y un intervalo de tiempo}\r
73       procedure mMover( dT: tTiempo ); virtual;\r
74       {** Calcula la distancia a otro objeto volador}\r
75       function mGetDistancia( ov: cObjetoVolador ): tLongitud;\r
76       {** Devuelve true si colisionaron los objetos voladores}\r
77       function mColisiono( ov: cObjetoVolador ): boolean;\r
78       {** Obtiene la velocidad del objeto volador}\r
79       function mGetVelocidad: cVector;\r
80       {** Obtiene el modulo de la velocidad del objeto volador}\r
81       function mGetVelModulo: tLongitud;\r
82       {** Obtiene la Posicion del objeto volador}\r
83       function mGetPosicion: cVector;\r
84       {** Obtiene la Potencia del objeto volador}\r
85       function mGetPotencia: tEnergia;\r
86       {** Obtiene la Energia del objeto volador}\r
87       function mGetEnergia: tEnergia;\r
88       {** Obtiene la Dimension del objeto volador}\r
89       function mGetDimension: tLongitud;\r
90       {** Obtiene el sistema de coordenadas de la nave}\r
91       function mGetCoordenadas: cCoordenadas;\r
92       {** Obtiene el versor i del sistema de coordenadas de la nave}\r
93       function mGetI: cVector;\r
94       {** Obtiene el versor j del sistema de coordenadas de la nave}\r
95       function mGetJ: cVector;\r
96       {** Obtiene el versor k del sistema de coordenadas de la nave}\r
97       function mGetK: cVector;\r
98       {** Método para establecer la posición}\r
99       function mSetPosicion( posicion: cVector ): cObjetoVolador;\r
100       {** Método para establecer la velocidad}\r
101       function mSetVelocidad( velocidad: cVector ): cObjetoVolador; virtual;\r
102       {** Método para establecer el modulo de la velocidad}\r
103       function mSetVelModulo( velocidad: tLongitud ): cObjetoVolador; virtual;\r
104       {** Método para establecer la direccion de la velocidad}\r
105       function mSetVelDir( velocidad: cVector ): cObjetoVolador;\r
106       {** Resta energia al objeto volador}\r
107       function mRestarEnergia( ene: tEnergia ): cObjetoVolador;\r
108       {** Método abstracto, se sobreescribira en las subclases porque van a ser\r
109           dibujadas de forma diferente}\r
110       function mDibujar: tObjetosVoladores; virtual; abstract;\r
111       {** Destructor}\r
112       destructor destroy; override;\r
113       // SERIALIZACION\r
114       {** Devuelve una cadena de texto con el objeto serializado.}\r
115       function mSerializar: string; override;\r
116       {** Recrea el objeto a partir de una cadena de texto con el objeto\r
117           serializado.}\r
118       procedure mDesSerializar( str: string ); override;\r
119   end;\r
120 \r
121 implementation\r
122 \r
123 uses\r
124   RegExpr,\r
125   Sysutils;\r
126 \r
127 { cObjetoVolador }\r
128 \r
129 {** Constructor\r
130     @param ov Objeto volador del cual extraer los datos para inicializar en actual}\r
131 constructor cObjetoVolador.create( ov: cObjetoVolador );\r
132 var\r
133   vel: cVector;\r
134 begin\r
135   // Crea el objeto basandose en los atributos del parametro\r
136   inherited create;\r
137   aPosicion := ov.mGetPosicion;\r
138   vel := ov.mGetVelocidad;\r
139   aVelocidad := vel.mGetModulo;\r
140   vel.free;\r
141   aDimension := ov.mGetDimension;\r
142   aPotencia  := ov.mGetPotencia;\r
143   aEnergia   := ov.mGetEnergia;\r
144   aCoordenadas := ov.mGetCoordenadas;\r
145 end;\r
146 \r
147 {** Constructor\r
148     @param pos Posicion inicial\r
149     @param vel Velocidad inicial\r
150     @param dim Dimensión del objeto volador (radio, en metros)\r
151     @param pot Potencia del objeto volador (cantidad de daño que hace por intervalode tiempo)\r
152     @param ene Energía del objeto volador(cantidad de daño que soporta antes de ser destruido)}\r
153 constructor cObjetoVolador.create(pos: cVector = nil; vel: cVector = nil;\r
154   dim: tLongitud = 5; pot: tEnergia = 1; ene: tEnergia = 100);\r
155 begin\r
156   inherited create;\r
157   aDimension := dim;\r
158   aPotencia  := pot;\r
159   aEnergia   := ene;\r
160   aCoordenadas := cCoordenadas.create;\r
161   // Si la posicion es nula crea una nueva\r
162   if pos = nil then\r
163     aPosicion := cVector.create( 0, 0, 0 )\r
164   else\r
165     aPosicion := cVector.create( pos );\r
166   // Si la velocidad es nula crea una nueva\r
167   if vel = nil then\r
168     aVelocidad := 0\r
169   else begin\r
170     aVelocidad := vel.mGetModulo;\r
171     aCoordenadas.mSetI( vel );\r
172   end;\r
173 end;\r
174 \r
175 {** Mueve el objeto volador basandose en su posicion, su velocidad y un intervalo de tiempo\r
176     @param dT Intervalo de tiempo}\r
177 procedure cObjetoVolador.mMover( dT: tTiempo );\r
178 var\r
179   v: cVector;\r
180 begin\r
181   v := cVector.create( mGetVelocidad );\r
182   aPosicion.mModificarCon( v, dT );\r
183   v.free;\r
184 end;\r
185 \r
186 {** Establece la velocidad del objeto volador\r
187     @param velocidad Nuevo vector velocidad}\r
188 function cObjetoVolador.mSetVelocidad( velocidad: cVector ): cObjetoVolador;\r
189 begin\r
190   aVelocidad := velocidad.mGetModulo;\r
191   // Agregado 30/10/00 para que mantenga las coordenadas\r
192   aCoordenadas.mSetI( velocidad );\r
193   result := self;\r
194 end;\r
195 \r
196 {** Obtiene la velocidad del objeto volador\r
197     @return Vector velocidad}\r
198 function cObjetoVolador.mGetVelocidad: cVector;\r
199 begin\r
200   result := aCoordenadas.mGetI.mMultiplicar( aVelocidad );\r
201 end;\r
202 \r
203 {** Obtiene la posición del objeto volador\r
204     @return Vector posición}\r
205 function cObjetoVolador.mGetPosicion: cVector;\r
206 begin\r
207   result := cVector.create( aPosicion );\r
208 end;\r
209 \r
210 {** Obtiene la dimensión del objeto volador\r
211     @return Dimensión (radio, en metros)}\r
212 function cObjetoVolador.mGetDimension: tLongitud;\r
213 begin\r
214   result := aDimension;\r
215 end;\r
216 \r
217 {** Destructor}\r
218 destructor cObjetoVolador.destroy;\r
219 begin\r
220   // Libera los atributo objeto\r
221   aPosicion.free;\r
222   aCoordenadas.free;\r
223   inherited;\r
224 end;\r
225 \r
226 {** Obtiene la potencia del objeto volador\r
227     @return Potencia (cantidad de daño que realiza por intervalo de tiempo)}\r
228 function cObjetoVolador.mGetPotencia: tEnergia;\r
229 begin\r
230  result := aPotencia;\r
231 end;\r
232 \r
233 {** Obtiene la e del objeto volador\r
234     @return Energía (cantidad de daño que soporta antes de ser destruido)}\r
235 function cObjetoVolador.mGetEnergia: tEnergia;\r
236 begin\r
237  result := aEnergia;\r
238 end;\r
239 \r
240 {$IFDEF DebugAlgoWars}\r
241 {** Devuelve el estado del objeto basandose en la cantidad de datos requeridos.\r
242     @return            Cadena de texto con el estado del Objeto.\r
243     @param   debugLevel Cantidad de información requerida}\r
244 function cObjetoVolador.mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string;\r
245 begin\r
246   // Construye la cadena dependiendo de la cantidad de informacion que se quiera obtener\r
247   result := 'Posición: ' + aPosicion.mGetDebugInfo( debugLevel );\r
248   if debugLevel > DI_MINI then\r
249     result := result + #13 + #10 +\r
250               'Energia: ' + FloatToStrF( aEnergia, ffNumber, 5, 5 );\r
251   if debugLevel > DI_NORMAL then\r
252     result := result + ' | Potencia: ' + FloatToStrF( aPotencia, ffNumber, 5, 5 ) +\r
253                        ' | Dimension: ' + FloatToStrF( aDimension, ffNumber, 5, 5 ) + #13 + #10 +\r
254                        'Velocidad: ' + mGetVelocidad.mGetDebugInfo( debugLevel ) + #13 + #10 +\r
255                        'Coordenadas: ' + #13 + #10 + aCoordenadas.mGetDebugInfo;\r
256 end;\r
257 {$ENDIF}\r
258 \r
259 {** Resta energía al objeto volador\r
260     @param ene Energía a restar}\r
261 function cObjetoVolador.mRestarEnergia(ene: tEnergia): cObjetoVolador;\r
262 begin\r
263   aEnergia := aEnergia - ene;\r
264   result := self;\r
265 end;\r
266 \r
267 {** Setea la energía del objeto volador a un valor arbitrario\r
268     @param ene Nueva energía}\r
269 function cObjetoVolador.mSetEnergia(ene: tEnergia): cObjetoVolador;\r
270 begin\r
271   aEnergia := ene;\r
272   result := self;\r
273 end;\r
274 \r
275 {** Calcula la distancia a otro objeto volador\r
276     @return     Distancia al otro objeto volador\r
277     @param   ov Objeto volador al que se calcula la distancia}\r
278 function cObjetoVolador.mGetDistancia(ov: cObjetoVolador): tLongitud;\r
279 var\r
280   v: cVector; // Vector temporal\r
281 begin\r
282   v := ov.mGetPosicion; // obtiene la posicion de ov\r
283   result := v.mGetDistancia( aPosicion ); // obtiene la distancia\r
284   v.free; // Libera al vector temporal\r
285 end;\r
286 \r
287 {** Devuelve true si colisionaron los objetos voladores\r
288     @return     <i>true<i> si colisionaron, <i>false</i> si no lo hicieron\r
289     @param   ov Objeto volador con el que se evalua si colisiono}\r
290 function cObjetoVolador.mColisiono(ov: cObjetoVolador): boolean;\r
291 begin\r
292   // true si la distancia es menor a la suma de las dimensiones\r
293   result := ( mGetDistancia( ov ) <= ( aDimension + ov.mGetDimension ) );\r
294 end;\r
295 \r
296 {** Obtiene el sistema de coordenadas de la nave\r
297     @return Sistema de coordenadas de la nave}\r
298 function cObjetoVolador.mGetCoordenadas: cCoordenadas;\r
299 begin\r
300   result := cCoordenadas.create( aCoordenadas );\r
301 end;\r
302 \r
303 {** Método para establecer el modulo de la velocidad\r
304     @param velocidad Nuevo módulo de la velocidad}\r
305 function cObjetoVolador.mSetVelModulo( velocidad: tLongitud ): cObjetoVolador;\r
306 begin\r
307   if velocidad > 0 then\r
308     aVelocidad := velocidad\r
309   else\r
310     aVelocidad := 0;\r
311   result := self;\r
312 end;\r
313 \r
314 {** Método para establecer la direccion de la velocidad\r
315     @param velocidad Nueva dirección de la velocidad}\r
316 function cObjetoVolador.mSetVelDir( velocidad: cVector ): cObjetoVolador;\r
317 begin\r
318   aCoordenadas.mSetI( velocidad );\r
319   result := self;\r
320 end;\r
321 \r
322 {** Obtiene el modulo de la velocidad del objeto volador\r
323     @return Módulo de la velocidad}\r
324 function cObjetoVolador.mGetVelModulo: tLongitud;\r
325 begin\r
326   result := aVelocidad;\r
327 end;\r
328 \r
329 {** Obtiene el versor i del sistema de coordenadas de la nave\r
330     @return Versor i, que representa la direccion en la que viaja el objeto}\r
331 function cObjetoVolador.mGetI: cVector;\r
332 begin\r
333   result := aCoordenadas.mGetI;\r
334 end;\r
335 \r
336 {** Obtiene el versor j del sistema de coordenadas de la nave\r
337     @return Versor j, que representa la direccion en la que está la izquierda del objeto}\r
338 function cObjetoVolador.mGetJ: cVector;\r
339 begin\r
340   result := aCoordenadas.mGetJ;\r
341 end;\r
342 \r
343 {** Obtiene el versor k del sistema de coordenadas de la nave\r
344     @return Versor k, que representa la direccion en la que está el "techo" del objeto}\r
345 function cObjetoVolador.mGetK: cVector;\r
346 begin\r
347   result := aCoordenadas.mGetK;\r
348 end;\r
349 \r
350 {** Rota el objeto volador sobre el eje i\r
351     (el sentido positivo es de j a k)}\r
352 function cObjetoVolador.mRotarEnI( dAngulo: tAngulo ): cObjetoVolador;\r
353 begin\r
354   aCoordenadas.mRotarEnI( dAngulo );\r
355   result := self;\r
356 end;\r
357 \r
358 {** Rota el objeto volador sobre el eje j\r
359     (el sentido positivo es de i a k)}\r
360 function cObjetoVolador.mRotarEnJ( dAngulo: tAngulo ): cObjetoVolador;\r
361 begin\r
362   aCoordenadas.mRotarEnJ( dAngulo );\r
363   result := self;\r
364 end;\r
365 \r
366 {** Rota el objeto volador sobre el eje k\r
367     (el sentido positivo es de i a j)}\r
368 function cObjetoVolador.mRotarEnK( dAngulo: tAngulo ): cObjetoVolador;\r
369 begin\r
370   aCoordenadas.mRotarEnK( dAngulo );\r
371   result := self;\r
372 end;\r
373 \r
374 {** Método para establecer la posición\r
375     @param velocidad Nuevo vector posición}\r
376 function cObjetoVolador.mSetPosicion(posicion: cVector): cObjetoVolador;\r
377 begin\r
378   aPosicion := cVector.create( posicion );\r
379   result := self;\r
380 end;\r
381 \r
382 {** Recrea el objeto a partir de una cadena de texto con el objeto\r
383     serializado.\r
384     @param str Cadena de texto con el objeto serializado.}\r
385 procedure cObjetoVolador.mDesSerializar(str: string);\r
386 var\r
387   r: TRegExpr;\r
388 begin\r
389   inherited mDesSerializar( str ); // SIEMPRE el ID debe ser el PRIMER atributo\r
390   r := TRegExpr.create;\r
391   // POSICION\r
392   try // se fija si hay errores al extraer los datos\r
393     r.Expression := '<posicion>\s*(.+)\s*</posicion>'; // contruye la expresion regular a buscar\r
394     if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
395       if aPosicion <> nil then // Si no es nulo\r
396         aPosicion.mDesSerializar( r.Match[1] ) // Lo deserializa\r
397       else // si es nulo\r
398         aPosicion := cVector.crearDeSerializado( r.Match[1] ) // lo crea\r
399     else // si no encontro la experesion...\r
400       raise ESerializacion.create( 'No se encontro la posicion' ); // cae en una excepcion\r
401   except // Si hubieron errores ...\r
402     on e: ESerializacion do begin // Si fueron de serializacion...\r
403       r.Free; // libera memoria\r
404       raise ESerializacion.create( ClassName + ': Error al deserializar la posicion: ' + e.Message ); // cae en una excepcion\r
405     end;\r
406     on e: ERegExpr do begin // si fueron de expresiones regulares...\r
407       r.Free; // libera memoria\r
408       raise ESerializacion.create( ClassName + ': Error al extraer la posicion utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
409     end;\r
410   end;\r
411   // VELOCIDAD\r
412   try // se fija si hay errores al extraer los datos\r
413     r.Expression := '<velocidad>\s*([+\-]?\d+(\,\d+)?([eE][+\-]?\d+)?)\s*</velocidad>'; // contruye la expresion regular a buscar\r
414     if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
415       aVelocidad := StrToFloat( r.Match[1] )\r
416     else // si no encontro la experesion...\r
417       raise ESerializacion.create( 'No se encontro la velocidad' ); // cae en una excepcion\r
418   except // Si hubieron errores ...\r
419     on e: ERegExpr do begin // si fueron de expresiones regulares...\r
420       r.Free; // libera memoria\r
421       raise ESerializacion.create( ClassName + ': Error al extraer la velocidad utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
422     end;\r
423   end;\r
424   // POTENCIA\r
425   try // se fija si hay errores al extraer los datos\r
426     r.Expression := '<potencia>\s*([+\-]?\d+)\s*</potencia>'; // contruye la expresion regular a buscar\r
427     if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
428       aPotencia := StrToInt( r.Match[1] )\r
429     else // si no encontro la experesion...\r
430       raise ESerializacion.create( 'No se encontro la potencia' ); // cae en una excepcion\r
431   except // Si hubieron errores ...\r
432     on e: ERegExpr do begin // si fueron de expresiones regulares...\r
433       r.Free; // libera memoria\r
434       raise ESerializacion.create( ClassName + ': Error al extraer la potencia utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
435     end;\r
436   end;\r
437   // ENERGIA\r
438   try // se fija si hay errores al extraer los datos\r
439     r.Expression := '<energia>\s*([+\-]?\d+)\s*</energia>'; // contruye la expresion regular a buscar\r
440     if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
441       aEnergia := StrToInt( r.Match[1] )\r
442     else // si no encontro la experesion...\r
443       raise ESerializacion.create( 'No se encontro la energia' ); // cae en una excepcion\r
444   except // Si hubieron errores ...\r
445     on e: ERegExpr do begin // si fueron de expresiones regulares...\r
446       r.Free; // libera memoria\r
447       raise ESerializacion.create( ClassName + ': Error al extraer la energia utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
448     end;\r
449   end;\r
450   // DIMENSION\r
451   try // se fija si hay errores al extraer los datos\r
452     r.Expression := '<dimension>\s*([+\-]?\d+(\,\d+)?([eE][+\-]?\d+)?)\s*</dimension>'; // contruye la expresion regular a buscar\r
453     if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
454       aDimension := StrToFloat( r.Match[1] )\r
455     else // si no encontro la experesion...\r
456       raise ESerializacion.create( 'No se encontro la dimension' ); // cae en una excepcion\r
457   except // Si hubieron errores ...\r
458     on e: ERegExpr do begin // si fueron de expresiones regulares...\r
459       r.Free; // libera memoria\r
460       raise ESerializacion.create( ClassName + ': Error al extraer la dimension utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
461     end;\r
462   end;\r
463   // COORDENADAS\r
464   try // se fija si hay errores al extraer los datos\r
465     r.Expression := '<coordenadas>\s*(.+)\s*</coordenadas>'; // contruye la expresion regular a buscar\r
466     if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
467       if aCoordenadas <> nil then // Si no es nulo\r
468         aCoordenadas.mDesSerializar( r.Match[1] ) // Lo deserializa\r
469       else // si es nulo\r
470         aCoordenadas := cCoordenadas.crearDeSerializado( r.Match[1] ) // lo crea\r
471     else // si no encontro la experesion...\r
472       raise ESerializacion.create( ClassName + ': No se pudieron extraer las coordenadas' ); // cae en una excepcion\r
473   except // Si hubieron errores ...\r
474     on e: ESerializacion do begin // Si fueron de serializacion...\r
475       r.Free; // libera memoria\r
476       raise ESerializacion.create( ClassName + ': Error al deserializar las coordenadas: ' + e.Message ); // cae en una excepcion\r
477     end;\r
478     on e: ERegExpr do begin // si fueron de expresiones regulares...\r
479       r.Free; // libera memoria\r
480       raise ESerializacion.create( ClassName + ': Error al extraer las coordenadas utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
481     end;\r
482   end;\r
483   r.free;\r
484 end;\r
485 \r
486 {** Devuelve una cadena de texto con el objeto serializado.\r
487     @return Cadena de texto con el objeto serializado.}\r
488 function cObjetoVolador.mSerializar: string;\r
489 begin\r
490   result := inherited mSerializar +\r
491             '<posicion>' + aPosicion.mSerializar + '</posicion>' +\r
492             '<velocidad>' + FloatToStrF( aVelocidad, ffGeneral, 18, 0 ) + '</velocidad>' +\r
493             '<potencia>' + FloatToStrF( aPotencia, ffGeneral, 18, 0 ) + '</potencia>' +\r
494             '<energia>' + FloatToStrF( aEnergia, ffGeneral, 18, 0 ) + '</energia>' +\r
495             '<dimension>' + FloatToStrF( aDimension, ffGeneral, 18, 0 ) + '</dimension>' +\r
496             '<coordenadas>' + aCoordenadas.mSerializar + '</coordenadas>';\r
497 end;\r
498 \r
499 end.\r