]> git.llucax.com Git - z.facultad/75.07/algowars.git/blob - doc/src-html/modelo/Espacio.pas
Import inicial después del "/var incident". :(
[z.facultad/75.07/algowars.git] / doc / src-html / modelo / Espacio.pas
1 <HTML><HEAD>\r
2 <TITLE>File: espacio.pas </TITLE>\r
3 <META NAME="GENERATOR" CONTENT="PasToHTML(Bystricky Vladimir)">\r
4 </HEAD>\r
5 <BODY BGCOLOR="#FFFFFF">\r
6 <A NAME=espacio.pas><CENTER><H3>espacio.pas</H3></A><I> from <A HREF=/proyecto/doc/src-html/AlgoWars.html> Project: AlgoWars.dpr</A></I></CENTER>\r
7 <HR>\r
8 <PRE>\r
9 <I><FONT COLOR="Navy">{** Se encarga de controlar la interacción entre \r
10     las naves y el responsable de manejar el tiempo.<br> \r
11     <i>Cambios:</i> \r
12     <PRE> \r
13     05/10/00: Se corrigió para que utilice los nuevos metodos de cNaveEnemiga y cObjetoVolador \r
14               Se corrigió el método mComunicarPosicion para que solo se comunique la posicion \r
15               a las naves que estan en el campo de radar de la nave espia. \r
16     07/10/00: Se agregaron los métodos mDestruir y mActualizarObjetoVolador. Se modificó el \r
17               método mActualizar (para usar los nuevos) y el método mDetectarColisiones para \r
18               manejar de forma más eficiente y clara la destrucción de objetos sin energía. \r
19     03/11/00: Se sacan los metodos mIniciay y mParar, ya que el control del tiempo y el encargado \r
20               de actualizar el espacio sera el Controlador (Controller). \r
21               Se agregaron métodos para facilitar la manipulación del espacio: \r
22               mQuitarObjeto, mGetObjetos, mSetObjetos y mSetNavePropia \r
23     05/11/00: Se corrigió un BUG que hacia que siempre el espacio se inicialice con una lista vacia \r
24               y una nave propia estandar (en el constructor). \r
25     09/11/00: Se corrigió un BUG que hacía que la nave espia no pueda escapar, ya que se avisaba a si misma. \r
26               Tambien se hace que ignore otras naves espias que esten avisando para evitar problemas similares. \r
27               (en el método mComunicarPosicion). \r
28     10/11/00: Se reemplaza el método mNavePropiaDestruida por una excepción (ENavePropiaDestruida). \r
29               Es lanzada por el método mActualizar y otros metodos privados que utilizan la nave propia. \r
30     27/11/00: Se agrega el control de disparos de las naves enemigas en el método mActualizar \r
31     29/11/00: Se elimina el método temporal mActualizarNavePropia. \r
32     01/12/00: Se modifica el método mActualizar para manejar los disparos de la nave propia. \r
33     </PRE>}</FONT></I> \r
34 <B>unit</B> Espacio; \r
35  \r
36 <B>interface</B> \r
37  \r
38 <B>uses</B> \r
39   Tipos, \r
40   ObjetoPersistente, \r
41   ObjetoVolador, \r
42   Nave, \r
43   Vectores, \r
44   Armas, \r
45   NaveEnemiga, \r
46   NavesEnemigas, \r
47   NavePropia, \r
48   Classes, \r
49   Sysutils, \r
50   Meteorito; \r
51  \r
52 <B>type</B> \r
53   <I><FONT COLOR="Navy">{** Excepcion producida por el espacio si la nave propia fue destruido}</FONT></I> \r
54   ENavePropiaDestruida = <B>class</B>( Exception ) \r
55     <B>public</B> \r
56       <I><FONT COLOR="Navy">{** Constructor}</FONT></I> \r
57       <B>constructor</B> create; \r
58   <B>end</B>; \r
59  \r
60   <I><FONT COLOR="Navy">{** Se encarga de controlar la interacción entre \r
61       las naves y el responsable de manejar el tiempo.}</FONT></I> \r
62   cEspacio = <B>class</B>( cObjetoPersistente ) \r
63     <B>private</B> \r
64       aDeltaT:  tTiempo;        <I><FONT COLOR="Navy">// Intervalo de tiempo (en milisegundos) que pasa entre ciclo y ciclo </FONT></I>\r
65       aNavePropia: cNavePropia; <I><FONT COLOR="Navy">// Nave del jugador, tambien esta en la lista, pero se lo </FONT></I>\r
66                                 <I><FONT COLOR="Navy">//  pone a parte para poder ser referenciado más fácilmente </FONT></I>\r
67       aObjetos: TList;          <I><FONT COLOR="Navy">// Lista con los objetos presentes en el espacio </FONT></I>\r
68     <B>protected</B> \r
69       <I><FONT COLOR="Navy">{** Procedimiento que evalua las posiciones de los Objetos Voladores que se encuentran en el espacio, \r
70           verificando 2 a 2 si hay una colisión.}</FONT></I> \r
71       <B>procedure</B> <A HREF="#cEspacio.mDetectarColision">mDetectarColision</A>; \r
72       <I><FONT COLOR="Navy">{** Método que se encarga de avisar al resto de las naves enemigas que estan cerca de una \r
73           espia sobre la ultima posicion de la nave propia.}</FONT></I> \r
74       <B>procedure</B> <A HREF="#cEspacio.mComunicarPosicion">mComunicarPosicion</A>( nEsp: cNaveEspia ); \r
75       <I><FONT COLOR="Navy">{** Destruye un Objeto Volador}</FONT></I> \r
76       <B>procedure</B> <A HREF="#cEspacio.mDestruir">mDestruir</A>( ov: cObjetoVolador ); \r
77       <I><FONT COLOR="Navy">{** Actualiza el estado de un objeto según sea tu tipo}</FONT></I> \r
78       <B>procedure</B> <A HREF="#cEspacio.mActualizarObjetoVolador">mActualizarObjetoVolador</A>( ov: cObjetoVolador ); \r
79       <I><FONT COLOR="Navy">{** Elimina los objetos duplicados después de recuperarlos de una serialización}</FONT></I> \r
80       <B>procedure</B> <A HREF="#cEspacio.mEliminarDuplicados">mEliminarDuplicados</A>; \r
81       <I><FONT COLOR="Navy">{** Busca el duplicado de un objeto volador}</FONT></I> \r
82       <B>function</B> <A HREF="#cEspacio.mBuscarDuplicado">mBuscarDuplicado</A>( ov: cObjetoVolador ): cObjetoVolador; \r
83     <B>public</B> \r
84       <I><FONT COLOR="Navy">{** Constructor. La lista que se pasa NO debe incluir la nave propia}</FONT></I> \r
85       <B>constructor</B> create( np: cNavePropia = <B>nil</B>; objetos: TList = <B>nil</B>; dt: tTiempo = 25 ); \r
86       <I><FONT COLOR="Navy">{** Actualiza el Espacio. En esto se incluye mover las naves, detectar colisiones y tomar las \r
87           desiciones necesarias según sea el caso.}</FONT></I> \r
88       <B>procedure</B> <A HREF="#cEspacio.mActualizar">mActualizar</A>; \r
89       <I><FONT COLOR="Navy">{** Agrega un Objeto Volador al Espacio}</FONT></I> \r
90       <B>procedure</B> <A HREF="#cEspacio.mAgregarObjeto">mAgregarObjeto</A>( ov: cObjetoVolador ); \r
91       <I><FONT COLOR="Navy">{** Quita un Objeto Volador del Espacio. Devuelve true si lo saco y false si no existia}</FONT></I> \r
92       <B>function</B> <A HREF="#cEspacio.mQuitarObjeto">mQuitarObjeto</A>( ov: cObjetoVolador ): boolean; \r
93       <I><FONT COLOR="Navy">{** Obtiene la lista de Objetos Voladores del Espacio}</FONT></I> \r
94       <B>function</B> <A HREF="#cEspacio.mGetObjetos">mGetObjetos</A>: TList; \r
95       <I><FONT COLOR="Navy">{** Cambia la lista de Objetos Voladores del Espacio, devolviendo un puntero a la lista vieja}</FONT></I> \r
96       <B>function</B> <A HREF="#cEspacio.mSetObjetos">mSetObjetos</A>( l: TList ): TList; \r
97       <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
98       <I><FONT COLOR="Navy">{** Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar \r
99           y la información entregada depende del parámetro tDebugInfo.}</FONT></I> \r
100       <B>function</B> <A HREF="#cEspacio.mGetDebugInfo">mGetDebugInfo</A>( debugLevel: tDebugInfo = DI_MINI ): <B>string</B>; <B>override</B>; \r
101       <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
102       <I><FONT COLOR="Navy">{** Método que obtiene la nave propia del espacio (este método es probable que deje de exstir)}</FONT></I> \r
103       <B>function</B> <A HREF="#cEspacio.mGetNavePropia">mGetNavePropia</A>: cNavePropia; \r
104       <I><FONT COLOR="Navy">{** Método para cambiar la nave propia. Devuelve un puntero a la nave propia vieja.}</FONT></I> \r
105       <B>function</B> <A HREF="#cEspacio.mSetNavePropia">mSetNavePropia</A>( np: cNavePropia ): cNavePropia; \r
106       <I><FONT COLOR="Navy">{** Destructor}</FONT></I> \r
107       <B>destructor</B> destroy; <B>override</B>; \r
108       <I><FONT COLOR="Navy">// SERIALIZACION </FONT></I>\r
109       <I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado.}</FONT></I> \r
110       <B>function</B> <A HREF="#cEspacio.mSerializar">mSerializar</A>: <B>string</B>; <B>override</B>; \r
111       <I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto \r
112           serializado.}</FONT></I> \r
113       <B>procedure</B> <A HREF="#cEspacio.mDesSerializar">mDesSerializar</A>( str: <B>string</B> ); <B>override</B>; \r
114     <B>end</B>; \r
115  \r
116 <B>implementation</B> \r
117  \r
118 <B>uses</B> \r
119   RegExpr, \r
120   SerializacionUtils; \r
121  \r
122 <I><FONT COLOR="Navy">{ cEspacio }</FONT></I> \r
123  \r
124 <I><FONT COLOR="Navy">{** Constructor \r
125     @param np      Nave propia a utilizar \r
126     @param objetos Lista de objetos voladores (sin incluir la nave propia!) \r
127     @param dt      Intervalo de tiempo}</FONT></I> \r
128 <B>constructor</B> cEspacio.create(np: cNavePropia; objetos: TList; dt: tTiempo); \r
129 <B>begin</B> \r
130   <B>inherited</B> create; \r
131   <B>if</B> objetos <> <B>nil</B> <B>then</B> \r
132     aObjetos := objetos \r
133   <B>else</B> <I><FONT COLOR="Navy">// Si no se pasó nada como argumento, crea una nueva lista. </FONT></I>\r
134     aObjetos := TList.create; \r
135   <I><FONT COLOR="Navy">// inicializa la nave propia y la inserta en la lista. </FONT></I>\r
136   <B>if</B> np <> <B>nil</B> <B>then</B> \r
137     aNavePropia := np \r
138   <B>else</B> <I><FONT COLOR="Navy">// Si no se pasó nada como argumento, crea una nueva nave propia. </FONT></I>\r
139     aNavePropia := cNavePropia.create; \r
140   aObjetos.Add( aNavePropia ); \r
141   <I><FONT COLOR="Navy">// Define el intervalo de tiempo </FONT></I>\r
142   aDeltaT := dt; \r
143 <B>end</B>; \r
144  \r
145 <I><FONT COLOR="Navy">{** Destructor}</FONT></I> \r
146 <B>destructor</B> cEspacio.destroy; \r
147 <B>var</B> \r
148   oOV: cObjetoVolador; \r
149 <B>begin</B> \r
150   <I><FONT COLOR="Navy">// Recorre la lista, liberando los Objetos Voladores en ella </FONT></I>\r
151   <B>while</B> aObjetos.Count > 0 <B>do</B> <B>begin</B> \r
152     oOV := aObjetos.First; \r
153     aObjetos.Remove( oOV ); \r
154     oOV.free; \r
155   <B>end</B>; \r
156   aObjetos.free; <I><FONT COLOR="Navy">// Libera la memoria de la lista </FONT></I>\r
157   <B>inherited</B>; \r
158 <B>end</B>; \r
159  \r
160 <I><FONT COLOR="Navy">{** Actualiza el Espacio. En esto se incluye mover las naves, detectar colisiones y tomar las \r
161     desiciones necesarias según sea el caso.}</FONT></I> \r
162 <B>procedure</B> <A NAME=cEspacio.mActualizar>cEspacio.mActualizar</A>; \r
163 <B>var</B> \r
164   i:     integer;        <I><FONT COLOR="Navy">// contador para el bucle </FONT></I>\r
165   oOV:   cObjetoVolador; <I><FONT COLOR="Navy">// objeto volador para apuntar al de la lista </FONT></I>\r
166   oArma: cArma;          <I><FONT COLOR="Navy">// Arma disparada </FONT></I>\r
167 <B>begin</B> \r
168   <B>for</B> i:=0 <B>to</B> aObjetos.count -1 <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// recorre la lista de objetos </FONT></I>\r
169     oOV:= aObjetos.items[i]; <I><FONT COLOR="Navy">// obtiene el ObjetoVolador actual </FONT></I>\r
170     mActualizarObjetoVolador( oOV ); <I><FONT COLOR="Navy">// Actualiza el estado del objeto segun su tipo </FONT></I>\r
171     oOV.mMover( aDeltaT );  <I><FONT COLOR="Navy">// Se mueve la objeto volador actual sin importar de que clase sea </FONT></I>\r
172     <B>if</B> oOV <B>is</B> cNave <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Si es una nave, maneja los disparos </FONT></I>\r
173       <B>with</B> oOV <B>as</B> cNave <B>do</B> <B>begin</B>  <I><FONT COLOR="Navy">// Convierte el puntero a cNave </FONT></I>\r
174         <B>if</B> oOV <B>is</B> cNaveEnemiga <B>then</B>                   <I><FONT COLOR="Navy">// Si es una nave enemiga </FONT></I>\r
175           oArma := mDisparar( aDeltaT, aNavePropia )  <I><FONT COLOR="Navy">// Dispara con la NavePropia como objetivo </FONT></I>\r
176         <B>else</B>                                   <I><FONT COLOR="Navy">// Si es otra nave (inclusive la nave propia) </FONT></I>\r
177           oArma := mDisparar( aDeltaT )   <I><FONT COLOR="Navy">// dispara con nil como objetivo (el objetivo es </FONT></I>\r
178       <B>end</B>;                                     <I><FONT COLOR="Navy">// manejado por la propia nave) </FONT></I>\r
179       <B>if</B> oArma <> <B>nil</B> <B>then</B>        <I><FONT COLOR="Navy">// Si efectivamente se disparo un arma </FONT></I>\r
180         mAgregarObjeto( oArma );  <I><FONT COLOR="Navy">// Se la agrega a la lista </FONT></I>\r
181     <B>end</B>; \r
182   <B>end</B>; \r
183   mDetectarColision; <I><FONT COLOR="Navy">// Se detectan las colisiones </FONT></I>\r
184   <B>if</B> aNavePropia = <B>nil</B> <B>then</B> \r
185     <B>raise</B> ENavePropiaDestruida.create; \r
186 <B>end</B>; \r
187  \r
188 <I><FONT COLOR="Navy">{** Actualiza el estado de un objeto volador, dependiendo de que tipo de objeto sea. \r
189     @param ov Objeto Volador a actualizar}</FONT></I> \r
190 <B>procedure</B> <A NAME=cEspacio.mActualizarObjetoVolador>cEspacio.mActualizarObjetoVolador</A>(ov: cObjetoVolador); \r
191 <B>begin</B> \r
192   <B>if</B> ov <B>is</B> cNaveEnemiga <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// si es una nave enemiga... </FONT></I>\r
193     <B>with</B> ov <B>as</B> cNaveEnemiga <B>do</B> <I><FONT COLOR="Navy">// "Transforma el puntero" a uno de clase NaveEnemiga </FONT></I>\r
194     <B>if</B> aNavePropia = <B>nil</B> <B>then</B> \r
195       <B>raise</B> ENavePropiaDestruida.create \r
196     <B>else</B> \r
197       <B>if</B> mDetectado( aNavePropia ) <B>then</B> <I><FONT COLOR="Navy">// si la nave propia esta en el campo de radar de la nave enemiga... </FONT></I>\r
198         mReaccionar( aNavePropia );  <I><FONT COLOR="Navy">// se manda un mensaje a la nave enemiga de atacar a la propia </FONT></I>\r
199       <I><FONT COLOR="Navy">// Si es una nave espia, nos fijamos si esta avisando </FONT></I>\r
200       <B>if</B> ov <B>is</B> cNaveEspia <B>then</B> <B>begin</B> \r
201         <B>with</B> ov <B>as</B> cNaveEspia <B>do</B> <I><FONT COLOR="Navy">// "Transforma el puntero" a uno de clase NaveEspia </FONT></I>\r
202         <B>if</B> mAvisando <B>then</B> \r
203           mComunicarPosicion( ov <B>as</B> cNaveEspia ); \r
204       <B>end</B>; \r
205   <B>end</B>; \r
206 <B>end</B>; \r
207  \r
208 <I><FONT COLOR="Navy">{** Agrega un Objeto Volador al Espacio \r
209     @param ov Objeto volador a agregar}</FONT></I> \r
210 <B>procedure</B> <A NAME=cEspacio.mAgregarObjeto>cEspacio.mAgregarObjeto</A>(ov: cObjetoVolador); \r
211 <B>begin</B> \r
212   aObjetos.Add( ov ); \r
213 <B>end</B>; \r
214  \r
215 <I><FONT COLOR="Navy">{** Método que se encarga de avisar al resto de las naves enemigas que estan cerca de una \r
216     espia sobre la ultima posicion de la nave propia. \r
217     @param nEsp Nave espía que está avisando}</FONT></I> \r
218 <B>procedure</B> <A NAME=cEspacio.mComunicarPosicion>cEspacio.mComunicarPosicion</A>(nEsp: cNaveEspia); \r
219 <B>var</B> \r
220   i:   integer;        <I><FONT COLOR="Navy">// contador para el bucle </FONT></I>\r
221   oOV: cObjetoVolador; <I><FONT COLOR="Navy">// objeto volador para apuntar al de la lista </FONT></I>\r
222 <B>begin</B> \r
223   <B>for</B> i := 0 <B>to</B> aObjetos.Count - 1 <B>do</B> <B>begin</B>  <I><FONT COLOR="Navy">// recorre la lista </FONT></I>\r
224     oOV := aObjetos.Items[i]; <I><FONT COLOR="Navy">// obteniendo el primer objeto volador </FONT></I>\r
225     <B>if</B> oOV = nEsp <B>then</B> <I><FONT COLOR="Navy">// Si es la misma nave propia... </FONT></I>\r
226       continue;        <I><FONT COLOR="Navy">//  la pasa por alto </FONT></I>\r
227     <B>if</B> oOV <B>is</B> cNaveEnemiga <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// si es una nave enemiga... </FONT></I>\r
228       <B>if</B> oOV <B>is</B> cNaveEspia <B>then</B>    <I><FONT COLOR="Navy">// Si es una nave espia, se fija si esta avisando </FONT></I>\r
229         <B>with</B> oOV <B>as</B> cNaveEspia <B>do</B> \r
230           <B>if</B> mAvisando <B>then</B>        <I><FONT COLOR="Navy">// Si esta avisando: </FONT></I>\r
231             continue;              <I><FONT COLOR="Navy">// la pasa por alto </FONT></I>\r
232       <B>if</B> nEsp.mDetectado( oOV ) <B>then</B> <I><FONT COLOR="Navy">// Si esta dentro del radar de la nave espia... </FONT></I>\r
233         <B>with</B> oOV <B>as</B> cNaveEnemiga <B>do</B> \r
234           mIrA( nEsp.mGetPosicionEnemiga );   <I><FONT COLOR="Navy">// Le indica que vaya a la ultima posicion </FONT></I>\r
235                                               <I><FONT COLOR="Navy">//  en donde vio a la nave propia </FONT></I>\r
236     <B>end</B>; \r
237   <B>end</B>; \r
238 <B>end</B>; \r
239  \r
240 <I><FONT COLOR="Navy">{** Destruye un objeto volador, liberando memoria y eliminandolo de la lista \r
241     @param ov Objeto Volador a destruir}</FONT></I> \r
242 <B>procedure</B> <A NAME=cEspacio.mDestruir>cEspacio.mDestruir</A>(ov: cObjetoVolador); \r
243 <B>begin</B> \r
244   aObjetos.Remove( ov ); \r
245   <B>if</B> ov <B>is</B> cNavePropia <B>then</B> \r
246     aNavePropia := <B>nil</B>; \r
247   ov.Free; \r
248 <B>end</B>; \r
249  \r
250 <I><FONT COLOR="Navy">{** Procedimiento que evalua las posiciones de los Objetos Voladores que se encuentran en el espacio, \r
251     verificando si hay una colisión.}</FONT></I> \r
252 <B>procedure</B> <A NAME=cEspacio.mDetectarColision>cEspacio.mDetectarColision</A>; \r
253 <B>var</B> \r
254   i,                    <I><FONT COLOR="Navy">// contador </FONT></I>\r
255   j: integer;           <I><FONT COLOR="Navy">// contador </FONT></I>\r
256   oOV1,                 <I><FONT COLOR="Navy">// variables para apuntar a los dos objetos voladores </FONT></I>\r
257   oOV2: cObjetoVolador; <I><FONT COLOR="Navy">//  que queremos evaluar si colisionaron </FONT></I>\r
258   oRotos: TList;        <I><FONT COLOR="Navy">// lista que contiene todos los objetos voladores destruidos </FONT></I>\r
259  \r
260 <B>begin</B> \r
261   oRotos := TList.create; \r
262   <B>for</B> i := 0 <B>to</B> aObjetos.Count - 1 <B>do</B> <B>begin</B>  <I><FONT COLOR="Navy">// recorre la lista </FONT></I>\r
263     oOV1 := aObjetos.Items[i]; <I><FONT COLOR="Navy">// obteniendo el primer objeto volador </FONT></I>\r
264     <B>for</B> j := i + 1 <B>to</B> aObjetos.Count - 1 <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// recorre la lista a partir del objeto volador anterior (excluyentemente) </FONT></I>\r
265       oOV2 := aObjetos.Items[j]; <I><FONT COLOR="Navy">// obteniendo el segundo objeto volador </FONT></I>\r
266       <B>if</B> oOV1.mColisiono( oOV2 ) <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Si colisionaron los Objetos Voladores... </FONT></I>\r
267         oOV1.mRestarEnergia( oOV2.mGetPotencia ); <I><FONT COLOR="Navy">// Le resta la energia al primer objeto volador </FONT></I>\r
268         oOV2.mRestarEnergia( oOV1.mGetPotencia ); <I><FONT COLOR="Navy">// Le resta la energia al segundo objeto volador </FONT></I>\r
269       <B>end</B>; \r
270     <B>end</B>; \r
271     <I><FONT COLOR="Navy">// Una vez que termina de restarle toda la energia por choques, verifica si esta destruido </FONT></I>\r
272     <B>if</B> oOV1.mGetEnergia <= 0 <B>then</B> <I><FONT COLOR="Navy">// Si quedo con energia negativa, </FONT></I>\r
273       oRotos.Add( oOV1 );         <I><FONT COLOR="Navy">//  lo agrega a la lista de objetos rotos </FONT></I>\r
274   <B>end</B>; \r
275   <I><FONT COLOR="Navy">// Destruye todos los objetos voladores rotos </FONT></I>\r
276   <B>while</B> oRotos.Count > 0 <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// Extra un objeto volador destruido de la lista (mientras que haya alguno) </FONT></I>\r
277     oOV1 := oRotos.First; \r
278     oRotos.Remove( oOV1 ); <I><FONT COLOR="Navy">// Elimina el objeto de la lista de objetos rotos </FONT></I>\r
279     mDestruir( oOV1 ); <I><FONT COLOR="Navy">// Destruye el objeto volador </FONT></I>\r
280   <B>end</B>; \r
281   oRotos.free; <I><FONT COLOR="Navy">// Libera la memoria de la lista </FONT></I>\r
282 <B>end</B>; \r
283  \r
284 <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
285 <I><FONT COLOR="Navy">{** Devuelve el estado del objeto basandose en la cantidad de datos requeridos. \r
286     @return            Cadena de texto con el estado del Objeto. \r
287     @param   debugLevel Cantidad de información requerida}</FONT></I> \r
288 <B>function</B> <A NAME=cEspacio.mGetDebugInfo>cEspacio.mGetDebugInfo</A>( debugLevel: tDebugInfo ): <B>string</B>; \r
289 <B>var</B> \r
290   i:  integer;         <I><FONT COLOR="Navy">// contador </FONT></I>\r
291   oOV: cObjetoVolador; <I><FONT COLOR="Navy">// variable temporal para obtener info del OV </FONT></I>\r
292 <B>begin</B> \r
293   result := ''; \r
294   <I><FONT COLOR="Navy">// Genera el string con el estado del Espacio </FONT></I>\r
295   <B>if</B> debugLevel > DI_NORMAL <B>then</B> \r
296     result := result + 'Delta de T = ' + FloatToStrF( aDeltaT, ffNumber, 10, 0 ) + #13 + #10; \r
297   <I><FONT COLOR="Navy">// Genera el string con el estado de los objetos dentro del Espacio </FONT></I>\r
298   <B>for</B> i := 0 <B>to</B> aObjetos.Count - 1 <B>do</B> <B>begin</B> \r
299     oOV := aObjetos.Items[i]; \r
300     result := result + #13 + #10 + \r
301               'ObjetoVolador' + IntToStr( i ) + ' (' + oOV.ClassName + '): ' + #13 + #10 + \r
302               oOV.mGetDebugInfo( debugLevel ) + #13 + #10 \r
303               + '----'; \r
304   <B>end</B>; \r
305 <B>end</B>; \r
306 <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
307  \r
308 <I><FONT COLOR="Navy">{** Método que obtiene la nave propia del espacio (este método es probable que deje de exstir) \r
309     @return Instancia de la nave propia que se encuentra en el espacio (como puntero)}</FONT></I> \r
310 <B>function</B> <A NAME=cEspacio.mGetNavePropia>cEspacio.mGetNavePropia</A>: cNavePropia; \r
311 <B>begin</B> \r
312   result := aNavePropia; \r
313 <B>end</B>; \r
314  \r
315 <I><FONT COLOR="Navy">{** Quita un Objeto Volador del Espacio. Devuelve true si lo saco y false si no existia \r
316     (esto lo quita del espacio, no lo destruye) \r
317     @param  ov Objeto a quitar del espacio \r
318     @return    <i>true</i> si se quitó, <i>false</i> si no estaba en el espacio}</FONT></I> \r
319 <B>function</B> <A NAME=cEspacio.mQuitarObjeto>cEspacio.mQuitarObjeto</A>( ov: cObjetoVolador ): boolean; \r
320 <B>var</B> \r
321   <B>index</B>: integer; \r
322 <B>begin</B> \r
323   result := false; \r
324   <B>index</B> := aObjetos.IndexOf( ov ); \r
325   <B>if</B> <B>index</B> >= 0 <B>then</B> <B>begin</B> \r
326     aObjetos.Delete( <B>index</B> ); \r
327     result := true; \r
328   <B>end</B>; \r
329 <B>end</B>; \r
330  \r
331 <I><FONT COLOR="Navy">{** Obtiene la lista de Objetos Voladores del Espacio \r
332     @return Lista de objetos del espacio (como puntero)}</FONT></I> \r
333 <B>function</B> <A NAME=cEspacio.mGetObjetos>cEspacio.mGetObjetos</A>: TList; \r
334 <B>begin</B> \r
335   result := aObjetos; \r
336 <B>end</B>; \r
337  \r
338 <I><FONT COLOR="Navy">{** Cambia la lista de Objetos Voladores del Espacio, devolviendo un puntero a la lista vieja \r
339     @param  l Nueva lista de objetos a asignarle al espacio \r
340     @return   Vieja lista de objetos del espacio}</FONT></I> \r
341 <B>function</B> <A NAME=cEspacio.mSetObjetos>cEspacio.mSetObjetos</A>( l: TList ): TList; \r
342 <B>begin</B> \r
343   result := aObjetos; \r
344   aObjetos := l; \r
345 <B>end</B>; \r
346  \r
347 <I><FONT COLOR="Navy">{** Método para cambiar la nave propia. Devuelve un puntero a la nave propia vieja. \r
348     @return Lista de objetos del espacio (como puntero)}</FONT></I> \r
349 <B>function</B> <A NAME=cEspacio.mSetNavePropia>cEspacio.mSetNavePropia</A>( np: cNavePropia ): cNavePropia; \r
350 <B>begin</B> \r
351   result := aNavePropia; \r
352   aNavePropia := np; \r
353 <B>end</B>; \r
354  \r
355 <I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto \r
356     serializado. \r
357     @param str Cadena de texto con el objeto serializado.}</FONT></I> \r
358 <B>procedure</B> <A NAME=cEspacio.mDesSerializar>cEspacio.mDesSerializar</A>(str: <B>string</B>); \r
359 <B>var</B> \r
360   total, \r
361   i:       integer; \r
362   objetos: <B>string</B>; \r
363   r:       TRegExpr; \r
364   ov:      cObjetoVolador; \r
365 <B>begin</B> \r
366   <I><FONT COLOR="Navy">// Crea la lista de ser necesario </FONT></I>\r
367   <B>if</B> aObjetos = <B>nil</B> <B>then</B> \r
368     aObjetos := TList.create; \r
369   <I><FONT COLOR="Navy">// Libera la lista los objetos existentes... </FONT></I>\r
370   <B>while</B> aObjetos.Count > 0 <B>do</B> <B>begin</B> \r
371     ov := aObjetos.First; \r
372     aObjetos.Remove( ov ); \r
373     ov.free; \r
374   <B>end</B>; \r
375   aNavePropia := <B>nil</B>; \r
376   <B>inherited</B> mDesSerializar( str ); <I><FONT COLOR="Navy">// SIEMPRE el ID debe ser el PRIMER atributo </FONT></I>\r
377   r := TRegExpr.create; \r
378   <I><FONT COLOR="Navy">// DELTAT </FONT></I>\r
379   <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
380     r.Expression := '<deltat>/s*([+/-]?/d+(/,/d+)?([eE][+/-]?/d+)?)/s*</deltat>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
381     <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
382       aDeltaT := StrToFloat( r.Match[1] ) \r
383     <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
384       <B>raise</B> ESerializacion.create( 'No se encontro el intervalo de actualizacion' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
385   <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
386     on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
387       r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
388       <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer el intervalo de actualizacion utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
389     <B>end</B>; \r
390   <B>end</B>; \r
391   <I><FONT COLOR="Navy">// OBJETOS </FONT></I>\r
392   <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
393     r.Expression := '<objetos/s+total=(/d+)/s*>/s*(.+)/s*</objetos>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
394     <B>if</B> r.Exec ( str ) <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
395       total := StrToInt( r.Match[1] ); \r
396       objetos := r.Match[2]; \r
397       <B>for</B> i := 0 <B>to</B> total - 1 <B>do</B> <B>begin</B> \r
398         <I><FONT COLOR="Navy">// OBJETO N </FONT></I>\r
399         <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
400           r.Expression := '<objeto' + IntToStr( i ) + '/s+class=([/w/d]+)/s*>/s*(.+)/s*</objeto' + IntToStr( i ) + '>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
401           <B>if</B> r.Exec ( objetos ) <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
402             <I><FONT COLOR="Navy">// lo crea segun su clase y lo agrega a la lista </FONT></I>\r
403             ov := restaurarObjeto( r.Match[1], r.Match[2] ); \r
404             aObjetos.Add( ov ); \r
405             <B>if</B> ov <B>is</B> cNavePropia <B>then</B> <I><FONT COLOR="Navy">// Si es la nave propia </FONT></I>\r
406               aNavePropia := ov <B>as</B> cNavePropia; <I><FONT COLOR="Navy">// Asigna el atributo NavePropia </FONT></I>\r
407           <B>end</B> <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
408             <B>raise</B> ESerializacion.create( 'No se encontro el objeto ' + IntToStr( i ) ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
409         <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
410           on e: ESerializacion <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// Si fueron de serializacion... </FONT></I>\r
411             r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
412             <B>raise</B> ESerializacion.create( ClassName + ': Error al deserializar el objeto ' \r
413                                          + IntToStr( i ) + ': ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
414           <B>end</B>; \r
415           on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
416             r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
417             <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer el objeto ' + IntToStr( i ) + ' utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
418           <B>end</B>; \r
419         <B>end</B>; \r
420       <B>end</B>; \r
421     <B>end</B> <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
422       <B>raise</B> ESerializacion.create( 'No se encontro la potencia' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
423   <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
424     on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
425       r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
426       <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer la potencia utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
427     <B>end</B>; \r
428   <B>end</B>; \r
429   mEliminarDuplicados; \r
430   <B>if</B> aNavePropia = <B>nil</B> <B>then</B> <I><FONT COLOR="Navy">// Si no se deserializo una nave propia ... </FONT></I>\r
431     <B>raise</B> ESerializacion.create( ClassName + ': No se encontro la nave propia' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
432   r.free; \r
433 <B>end</B>; \r
434  \r
435 <I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado. \r
436     @return Cadena de texto con el objeto serializado.}</FONT></I> \r
437 <B>function</B> <A NAME=cEspacio.mSerializar>cEspacio.mSerializar</A>: <B>string</B>; \r
438 <B>var</B> \r
439   i:  integer; \r
440   ov: cObjetoVOlador; \r
441 <B>begin</B> \r
442   result := <B>inherited</B> mSerializar + \r
443             '<deltat>' + FloatToStrF( aDeltaT, ffGeneral, 18, 0 ) + '</deltat>' + \r
444             '<objetos total=' + IntToStr( aObjetos.Count ) + '>'; \r
445   <B>for</B> i := 0 <B>to</B> aObjetos.Count - 1 <B>do</B> <B>begin</B>  <I><FONT COLOR="Navy">// recorre la lista </FONT></I>\r
446     ov := aObjetos.Items[i]; <I><FONT COLOR="Navy">// obteniendo el primer objeto volador </FONT></I>\r
447       <I><FONT COLOR="Navy">// Serializa el objeto actual </FONT></I>\r
448       result := result + '<objeto' + IntToStr( i ) + ' class=' + ov.ClassName + '>' + ov.mSerializar + '</objeto' + IntToStr( i ) + '>'; \r
449   <B>end</B>; \r
450   result := result + '</objetos>'; \r
451 <B>end</B>; \r
452  \r
453 <I><FONT COLOR="Navy">{** Elimina los objetos duplicados después de recuperarlos de una serialización}</FONT></I> \r
454 <B>procedure</B> <A NAME=cEspacio.mEliminarDuplicados>cEspacio.mEliminarDuplicados</A>; \r
455 <B>var</B> \r
456   i:    integer; \r
457   oOV, \r
458   oAux: cObjetoVolador; \r
459 <B>begin</B> \r
460   <B>for</B> i := 0 <B>to</B> aObjetos.Count - 1 <B>do</B> <B>begin</B> \r
461     oOV  := aObjetos.Items[i]; \r
462     <B>if</B> oOV <B>is</B> cNavePropia <B>then</B> <B>begin</B> \r
463       <I><FONT COLOR="Navy">// Busca el duplicado del objetivo </FONT></I>\r
464       oAux := mBuscarDuplicado( (oOV <B>as</B> cNavePropia).mGetLockeado ); \r
465       (oOV <B>as</B> cNavePropia).mGetLockeado.free; <I><FONT COLOR="Navy">// Libera la copia que tiene como objetivo </FONT></I>\r
466       (oOV <B>as</B> cNavePropia).mSetLockeado( oAux ); <I><FONT COLOR="Navy">// Setea como nuevo objetivo al objeto de la lista </FONT></I>\r
467     <B>end</B>; \r
468     <B>if</B> oOV <B>is</B> cMisilDirigido <B>then</B> <B>begin</B> \r
469       <I><FONT COLOR="Navy">// Busca el duplicado del objetivo </FONT></I>\r
470       oAux := mBuscarDuplicado( (oOV <B>as</B> cMisilDirigido).mGetObjetivo ); \r
471       (oOV <B>as</B> cMisilDirigido).mGetObjetivo.free; <I><FONT COLOR="Navy">// Libera la copia que tiene como objetivo </FONT></I>\r
472       (oOV <B>as</B> cMisilDirigido).mSetObjetivo( oAux ); <I><FONT COLOR="Navy">// Setea como nuevo objetivo al objeto de la lista </FONT></I>\r
473     <B>end</B>; \r
474   <B>end</B>; \r
475 <B>end</B>; \r
476  \r
477 <I><FONT COLOR="Navy">{** Busca el duplicado de un objeto volador \r
478     @param  ov Objeto volador al cual se le quiere encontrar un duplicado \r
479     @return Objeto Volador duplicado de ov}</FONT></I> \r
480 <B>function</B> <A NAME=cEspacio.mBuscarDuplicado>cEspacio.mBuscarDuplicado</A>(ov: cObjetoVolador): cObjetoVolador; \r
481 <B>var</B> \r
482   i:   integer; \r
483   oOV: cObjetoVolador; \r
484 <B>begin</B> \r
485   result := <B>nil</B>; \r
486   <B>if</B> ov <> <B>nil</B> <B>then</B> \r
487     <B>for</B> i := 0 <B>to</B> aObjetos.Count - 1 <B>do</B> <B>begin</B> \r
488       oOV  := aObjetos.Items[i]; \r
489       <B>if</B> oOV.mGetID = ov.mGetID <B>then</B> <I><FONT COLOR="Navy">// Si tienen el mismo ID... </FONT></I>\r
490         result := oOV; <I><FONT COLOR="Navy">// Devulve el duplicado </FONT></I>\r
491     <B>end</B>; \r
492 <B>end</B>; \r
493  \r
494 <I><FONT COLOR="Navy">{ ENavePropiaDestruida }</FONT></I> \r
495  \r
496 <B>constructor</B> ENavePropiaDestruida.create; \r
497 <B>begin</B> \r
498   <B>inherited</B> create( 'La Nave Propia fue destruida.' ); \r
499 <B>end</B>; \r
500  \r
501 <B>end</B>. \r
502 </PRE>\r
503 </BODY>\r
504 </HTML>\r