2 <TITLE>File: armas.pas </TITLE>
\r
3 <META NAME="GENERATOR" CONTENT="PasToHTML(Bystricky Vladimir)">
\r
5 <BODY BGCOLOR="#FFFFFF">
\r
6 <A NAME=armas.pas><CENTER><H3>armas.pas</H3></A><I> from <A HREF=/proyecto/doc/src-html/AlgoWars.html> Project: AlgoWars.dpr</A></I></CENTER>
\r
9 <I><FONT COLOR="Navy">{** Contiene las armas que pueden ser usadas por las diferentes naves.<br>
\r
12 10/11/00: Se agrega el manejo de excepciones para evitar un BUG en cMisilDirigido. Si el objetivo del misil
\r
13 dirigido es destruido, la velocidad permanece constante y en mGetDebugInfo se informa que esta destruido.
\r
14 27/11/00: Se le agrega el manejo de la velocidad maxima a la clase cArma y se agrega el Alcance del arma, cambiando
\r
15 el anterior por la Duracion.
\r
16 01/12/00: Se cambiaron las dimensiones de las armas para que los disparos sean mas "jugables".
\r
28 <I><FONT COLOR="Navy">{** La clase cArma esta pensada como una clase abtracta. En ella se encuentran
\r
29 características comunes a todas las armas.}</FONT></I>
\r
30 cArma = <B>class</B>( cObjetoVolador )
\r
32 aDuracion: tTiempo; <I><FONT COLOR="Navy">// Este alcance determina cuanto tiempo tiene que pasar </FONT></I>
\r
33 <I><FONT COLOR="Navy">// para que el arma se autodestruya. </FONT></I>
\r
34 aAlcance: tLongitud; <I><FONT COLOR="Navy">// Alcance en metros del arma </FONT></I>
\r
35 aVelMaxima: tLongitud; <I><FONT COLOR="Navy">// Velocidad máxima del arma </FONT></I>
\r
37 <I><FONT COLOR="Navy">{** Actualiza el alcance del arma, que va disminuyendo a medida que pasa el tiempo}</FONT></I>
\r
38 <B>procedure</B> <A HREF="#cArma.mActualizarDuracion">mActualizarDuracion</A>( dt: tTiempo );
\r
39 <I><FONT COLOR="Navy">{** Devuelve true si el arma todavia tiene alcance}</FONT></I>
\r
40 <B>function</B> <A HREF="#cArma.mActivo">mActivo</A>: boolean;
\r
41 <I><FONT COLOR="Navy">{** Método para obtener el alcance del arma}</FONT></I>
\r
42 <B>procedure</B> <A HREF="#cArma.mSetAlcance">mSetAlcance</A>( alc: tLongitud );
\r
44 <I><FONT COLOR="Navy">{** Constructor}</FONT></I>
\r
45 <B>constructor</B> create( pos: cVector = <B>nil</B>; vel: cVector = <B>nil</B>; dim: tLongitud = 1;
\r
46 pot: tEnergia = 1; ene: tEnergia = 1; duracion: tTiempo = 2500;
\r
47 velMax: tLongitud = 0.25 ); overload;
\r
48 <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I>
\r
49 <I><FONT COLOR="Navy">{** Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar
\r
50 y la información entregada depende del parámetro tDebugInfo.}</FONT></I>
\r
51 <B>function</B> <A HREF="#cArma.mGetDebugInfo">mGetDebugInfo</A>( debugLevel: tDebugInfo = DI_MINI ): <B>string</B>; <B>override</B>;
\r
52 <I><FONT COLOR="Navy">{$ENDIF}</FONT></I>
\r
53 <I><FONT COLOR="Navy">{** Método para obtener el alcance del arma}</FONT></I>
\r
54 <B>function</B> <A HREF="#cArma.mGetAlcance">mGetAlcance</A>: tLongitud;
\r
55 <I><FONT COLOR="Navy">{** Método para obtener el alcance del arma}</FONT></I>
\r
56 <B>function</B> <A HREF="#cArma.mGetVelMax">mGetVelMax</A>: tLongitud;
\r
57 <I><FONT COLOR="Navy">{** Método heredado, se sobreescribe porque se le agrega alguna funcionalidad}</FONT></I>
\r
58 <B>procedure</B> <A HREF="#cArma.mMover">mMover</A>( dt: tTiempo ); <B>override</B>;
\r
59 <I><FONT COLOR="Navy">// SERIALIZACION </FONT></I>
\r
60 <I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado.}</FONT></I>
\r
61 <B>function</B> <A HREF="#cArma.mSerializar">mSerializar</A>: <B>string</B>; <B>override</B>;
\r
62 <I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto
\r
63 serializado.}</FONT></I>
\r
64 <B>procedure</B> <A HREF="#cArma.mDesSerializar">mDesSerializar</A>( str: <B>string</B> ); <B>override</B>;
\r
67 <I><FONT COLOR="Navy">{** El laser es un tipo de arma básica. Es la que menos daño hace pero la que más rápido viaja<br>
\r
68 <u>Características:</u>
\r
70 Dimensión 0,1 metros (10 cm)
\r
71 Potencia: 1 Cantidad de daño que hace por intervalo de tiempo
\r
72 Energía: 1 Cantidad de daño que soporta antes de ser destruída
\r
73 Velocidad: 0,4 metros/milisegundos (1440 km/h)
\r
74 Alcance: 3000 milisegundos (3 segundos, 1,2 km)
\r
76 cLaser = <B>class</B>( cArma )
\r
78 <I><FONT COLOR="Navy">{** Constructor}</FONT></I>
\r
79 <B>constructor</B> create( pos: cVector = <B>nil</B>; vel: cVector = <B>nil</B> ); overload;
\r
80 <I><FONT COLOR="Navy">{** Método heredado, se sobreescribe porque se dibuja de forma distinta}</FONT></I>
\r
81 <B>function</B> <A HREF="#cLaser.mDibujar">mDibujar</A>: tObjetosVoladores; <B>override</B>;
\r
84 <I><FONT COLOR="Navy">{** El misil es un tipo de arma básica. Hace un daño considerable y su velocidad también es alta<br>
\r
85 <u>Características:</u>
\r
87 Dimensión 0,5 metros (50 cm)
\r
88 Potencia: 20 Cantidad de daño que hace por intervalo de tiempo
\r
89 Energía: 1 Cantidad de daño que soporta antes de ser destruída
\r
90 Velocidad: 0,3 metros/milisegundos (1080 km/h)
\r
91 Alcance: 5000 milisegundos (5 segundos, 1,5 km)
\r
93 cMisil = <B>class</B>( cArma )
\r
95 <I><FONT COLOR="Navy">// Constructor </FONT></I>
\r
96 <B>constructor</B> create( pos: cVector = <B>nil</B>; vel: cVector = <B>nil</B> ); overload;
\r
97 <I><FONT COLOR="Navy">// Método heredado, se sobreescribe porque se dibuja de forma distinta </FONT></I>
\r
98 <B>function</B> <A HREF="#cMisil.mDibujar">mDibujar</A>: tObjetosVoladores; <B>override</B>;
\r
101 <I><FONT COLOR="Navy">{** El misil dirigido es un tipo de arma avanzada. Persigue a su objetivo hasta que lo alcanza o
\r
102 hasta que se le acaba el alcance. Hace un daño alto, su velocidad es mediana y tiene un gran alcance.<br>
\r
103 <u>Características:</u>
\r
105 Dimensión 0,7 metros (70 cm)
\r
106 Potencia: 30 Cantidad de daño que hace por intervalo de tiempo
\r
107 Energía: 1 Cantidad de daño que soporta antes de ser destruída
\r
108 Velocidad: 0,25 metros/milisegundos (900 km/h)
\r
109 Alcance: 20000 milisegundos (20 segundos, 5 km)
\r
110 Area de Lock: 2000 metros (2 km)
\r
111 </PRE>}</FONT></I>
\r
112 cMisilDirigido = <B>class</B>( cMisil )
\r
114 aObjetivo: cObjetoVolador; <I><FONT COLOR="Navy">// Objetivo del misil </FONT></I>
\r
115 aLockArea: tLongitud; <I><FONT COLOR="Navy">// Maxima distancia a la que se debe encontrar </FONT></I>
\r
116 <I><FONT COLOR="Navy">// el objetivo para poder ser disparado </FONT></I>
\r
118 <I><FONT COLOR="Navy">{** Método que calcula la nueva velocidad basandose en al posicion del objetivo}</FONT></I>
\r
119 <B>procedure</B> <A HREF="#cMisilDirigido.mModificarVelocidad">mModificarVelocidad</A>;
\r
121 <I><FONT COLOR="Navy">{** Constructor}</FONT></I>
\r
122 <B>constructor</B> create( obj: cObjetoVolador; pos: cVector = <B>nil</B> ); overload;
\r
123 <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I>
\r
124 <I><FONT COLOR="Navy">{** Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar
\r
125 y la información entregada depende del parámetro tDebugInfo.}</FONT></I>
\r
126 <B>function</B> <A HREF="#cMisilDirigido.mGetDebugInfo">mGetDebugInfo</A>( debugLevel: tDebugInfo = DI_MINI ): <B>string</B>; <B>override</B>;
\r
127 <I><FONT COLOR="Navy">{$ENDIF}</FONT></I>
\r
128 <I><FONT COLOR="Navy">{** Método heredado, se sobreescribe porque se le agrega alguna funcionalidad}</FONT></I>
\r
129 <B>procedure</B> <A HREF="#cMisilDirigido.mMover">mMover</A>( dt: tTiempo ); <B>override</B>;
\r
130 <I><FONT COLOR="Navy">{** Obtiene el objetivo del misil dirigido}</FONT></I>
\r
131 <B>function</B> <A HREF="#cMisilDirigido.mGetObjetivo">mGetObjetivo</A>: cObjetoVolador;
\r
132 <I><FONT COLOR="Navy">{** Establece el objetivo del misil dirigido}</FONT></I>
\r
133 <B>procedure</B> <A HREF="#cMisilDirigido.mSetObjetivo">mSetObjetivo</A>( ov: cObjetoVolador );
\r
134 <I><FONT COLOR="Navy">{** Método heredado, se sobreescribe porque se dibuja de forma distinta}</FONT></I>
\r
135 <B>function</B> <A HREF="#cMisilDirigido.mDibujar">mDibujar</A>: tObjetosVoladores; <B>override</B>;
\r
136 <I><FONT COLOR="Navy">// SERIALIZACION </FONT></I>
\r
137 <I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado.}</FONT></I>
\r
138 <B>function</B> <A HREF="#cMisilDirigido.mSerializar">mSerializar</A>: <B>string</B>; <B>override</B>;
\r
139 <I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto
\r
140 serializado.}</FONT></I>
\r
141 <B>procedure</B> <A HREF="#cMisilDirigido.mDesSerializar">mDesSerializar</A>( str: <B>string</B> ); <B>override</B>;
\r
144 <B>implementation</B>
\r
148 ObjetoPersistente,
\r
149 SerializacionUtils,
\r
152 <I><FONT COLOR="Navy">{ cArma }</FONT></I>
\r
154 <I><FONT COLOR="Navy">{** Este constructor es protegido porque solo va a ser utilizado por subclases
\r
155 @param pos Posicion inicial
\r
156 @param vel Velocidad inicial
\r
157 @param dim Dimensión del objeto volador (radio, en metros)
\r
158 @param pot Potencia del objeto volador (cantidad de daño que hace por intervalode tiempo)
\r
159 @param ene Energía del objeto volador(cantidad de daño que soporta antes de ser destruido)
\r
160 @param alcance Tiempo que debe pasar para que el arma se destruya si no impactó con ningún objeto volador}</FONT></I>
\r
161 <B>constructor</B> cArma.create(pos: cVector; vel: cVector; dim: tLongitud;
\r
162 pot, ene: tEnergia; duracion: tTiempo; velMax: tLongitud);
\r
166 <B>inherited</B> create( pos, vel, dim, pot, ene );
\r
167 aDuracion := duracion;
\r
168 aVelMaxima := velMax;
\r
169 aAlcance := aDuracion * aVelMaxima;
\r
170 <I><FONT COLOR="Navy">// Setea el modulo de la velocidad a la maxima </FONT></I>
\r
171 v := mGetVelocidad.mSetModulo( aVelMaxima );
\r
172 mSetVelocidad( v );
\r
176 <I><FONT COLOR="Navy">{** Chequea si el arma todavia tiene alcance
\r
177 @return <i>true</i> si todavía tiene alcance, <i>false</i> si no}</FONT></I>
\r
178 <B>function</B> <A NAME=cArma.mActivo>cArma.mActivo</A>: boolean;
\r
180 result := ( aDuracion > 0 );
\r
183 <I><FONT COLOR="Navy">{** Método para obtener el alcance del arma
\r
184 @return Alcance del arma}</FONT></I>
\r
185 <B>function</B> <A NAME=cArma.mGetAlcance>cArma.mGetAlcance</A>: tLongitud;
\r
187 result := aAlcance;
\r
190 <I><FONT COLOR="Navy">{** Método para establecer el alcance del arma
\r
191 @param alc Alcance del arma}</FONT></I>
\r
192 <B>procedure</B> <A NAME=cArma.mSetAlcance>cArma.mSetAlcance</A>(alc: tLongitud);
\r
197 <I><FONT COLOR="Navy">{** Método para obtener la velocidad maxima del arma
\r
198 @return Velocidad maxima del arma}</FONT></I>
\r
199 <B>function</B> <A NAME=cArma.mGetVelMax>cArma.mGetVelMax</A>: tLongitud;
\r
201 result := aVelMaxima;
\r
204 <I><FONT COLOR="Navy">{** Actualiza el alcance del arma, que va disminuyendo a medida que pasa el tiempo
\r
205 @param dt Intervalo de tiempo}</FONT></I>
\r
206 <B>procedure</B> <A NAME=cArma.mActualizarDuracion>cArma.mActualizarDuracion</A>(dt: tTiempo);
\r
208 aDuracion := aDuracion - dt;
\r
211 <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I>
\r
212 <I><FONT COLOR="Navy">{** Devuelve el estado del objeto basandose en la cantidad de datos requeridos.
\r
213 @return Cadena de texto con el estado del Objeto.
\r
214 @param debugLevel Cantidad de información requerida}</FONT></I>
\r
215 <B>function</B> <A NAME=cArma.mGetDebugInfo>cArma.mGetDebugInfo</A>(debugLevel: tDebugInfo): <B>string</B>;
\r
217 <I><FONT COLOR="Navy">// Genera el string con el estado del Arma </FONT></I>
\r
218 result := <B>inherited</B> mGetDebugInfo( debugLevel );
\r
219 <B>if</B> debugLevel > DI_MINI <B>then</B>
\r
220 result := result + ' | Alcance: ' + FloatToStr( aDuracion );
\r
222 <I><FONT COLOR="Navy">{$ENDIF}</FONT></I>
\r
224 <I><FONT COLOR="Navy">{** Mueve el arma basado en su posición y velocidad actual y un intervalo de tiempo
\r
225 @param dt Intervalo de tiempo}</FONT></I>
\r
226 <B>procedure</B> <A NAME=cArma.mMover>cArma.mMover</A>(dt: tTiempo);
\r
228 <B>inherited</B> mMover( dt ); <I><FONT COLOR="Navy">// Mueve el arma de la forma convencional </FONT></I>
\r
229 mActualizarDuracion( dt ); <I><FONT COLOR="Navy">// Actualiza el alcance </FONT></I>
\r
230 <B>if</B> <B>not</B> mActivo <B>then</B> <I><FONT COLOR="Navy">// Si se quedó sin alcance... </FONT></I>
\r
231 mSetEnergia( -1 ); <I><FONT COLOR="Navy">// pone energia en negativo, lo que significa que se destruyó... </FONT></I>
\r
234 <I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto
\r
236 @param str Cadena de texto con el objeto serializado.}</FONT></I>
\r
237 <B>procedure</B> <A NAME=cArma.mDesSerializar>cArma.mDesSerializar</A>(str: <B>string</B>);
\r
241 <B>inherited</B> mDesSerializar( str ); <I><FONT COLOR="Navy">// SIEMPRE el ID debe ser el PRIMER atributo </FONT></I>
\r
242 r := TRegExpr.create;
\r
243 <I><FONT COLOR="Navy">// DURACION </FONT></I>
\r
244 <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>
\r
245 r.Expression := '<duracion>/s*([+-]?/d+)/s*</duracion>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>
\r
246 <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>
\r
247 aDuracion := StrToFloat( r.Match[1] )
\r
248 <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>
\r
249 <B>raise</B> ESerializacion.create( 'No se encontro la duracion' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>
\r
250 <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>
\r
251 on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>
\r
252 r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>
\r
253 <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer la duracion utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>
\r
256 <I><FONT COLOR="Navy">// ALCANCE </FONT></I>
\r
257 <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>
\r
258 r.Expression := '<alcance>/s*([+/-]?/d+(/,/d+)?([eE][+/-]?/d+)?)/s*</alcance>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>
\r
259 <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>
\r
260 aAlcance := StrToFloat( r.Match[1] )
\r
261 <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>
\r
262 <B>raise</B> ESerializacion.create( 'No se encontro el alcance' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>
\r
263 <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>
\r
264 on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>
\r
265 r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>
\r
266 <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer el alcance utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>
\r
269 <I><FONT COLOR="Navy">// VELMAXIMA </FONT></I>
\r
270 <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>
\r
271 r.Expression := '<velmaxima>/s*([+/-]?/d+(/,/d+)?([eE][+/-]?/d+)?)/s*</velmaxima>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>
\r
272 <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>
\r
273 aVelMaxima := StrToFloat( r.Match[1] )
\r
274 <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>
\r
275 <B>raise</B> ESerializacion.create( 'No se encontro la velocidad maxima' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>
\r
276 <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>
\r
277 on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>
\r
278 r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>
\r
279 <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer la velocidad maxima utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>
\r
285 <I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado.
\r
286 @return Cadena de texto con el objeto serializado.}</FONT></I>
\r
287 <B>function</B> <A NAME=cArma.mSerializar>cArma.mSerializar</A>: <B>string</B>;
\r
289 result := <B>inherited</B> mSerializar +
\r
290 '<duracion>' + FloatToStrF( aDuracion, ffGeneral, 18, 0 ) + '</duracion>' +
\r
291 '<alcance>' + FloatToStrF( aAlcance, ffGeneral, 18, 0 ) + '</alcance>' +
\r
292 '<velmaxima>' + FloatToStrF( aVelMaxima, ffGeneral, 18, 0 ) + '</velmaxima>';
\r
295 <I><FONT COLOR="Navy">{ cLaser }</FONT></I>
\r
297 <I><FONT COLOR="Navy">{** Crea una nueva instancia.
\r
298 @param pos Vector posición
\r
299 @param vel Dirección del vector velocidad}</FONT></I>
\r
300 <B>constructor</B> cLaser.create(pos: cVector = <B>nil</B>; vel: cVector = <B>nil</B>);
\r
302 <I><FONT COLOR="Navy">// El laser tiene 10 cm de radio, 1 punto de potencia, 1 punto de energia y 3 seg de alcance (1,2 km) </FONT></I>
\r
303 <I><FONT COLOR="Navy">// Setea el modulo de la velocidad a 0,4 m/mseg (1440 km/h) </FONT></I>
\r
304 <B>inherited</B> create( pos, vel, 0.1 <I><FONT COLOR="Navy">{dim}</FONT></I>, 1 <I><FONT COLOR="Navy">{pot}</FONT></I>, 1 <I><FONT COLOR="Navy">{ene}</FONT></I>, 3000 <I><FONT COLOR="Navy">{dur}</FONT></I>, 0.4 <I><FONT COLOR="Navy">{velmax}</FONT></I> );
\r
307 <I><FONT COLOR="Navy">{** Método heredado, se sobreescribe porque se dibuja de forma distinta}</FONT></I>
\r
308 <B>function</B> <A NAME=cLaser.mDibujar>cLaser.mDibujar</A>: tObjetosVoladores;
\r
310 result := OV_LASER;
\r
313 <I><FONT COLOR="Navy">{ cMisil }</FONT></I>
\r
315 <I><FONT COLOR="Navy">{** Crea una nueva instancia.
\r
316 @param pos Vector posición
\r
317 @param vel Dirección del vector velocidad}</FONT></I>
\r
318 <B>constructor</B> cMisil.create(pos: cVector = <B>nil</B>; vel: cVector = <B>nil</B>);
\r
320 <I><FONT COLOR="Navy">// El misil tiene 50 cm de radio, 20 puntos de potencia, 1 punto de energia y 5 seg de alcance (1,5 km) </FONT></I>
\r
321 <I><FONT COLOR="Navy">// Setea el modulo de la velocidad a 0,3 m/mseg (1080 km/h) </FONT></I>
\r
322 <B>inherited</B> create( pos, vel, 0.5 <I><FONT COLOR="Navy">{dim}</FONT></I>, 20 <I><FONT COLOR="Navy">{pot}</FONT></I>, 1 <I><FONT COLOR="Navy">{ene}</FONT></I>, 5000 <I><FONT COLOR="Navy">{dur}</FONT></I>, 0.3 <I><FONT COLOR="Navy">{velmax}</FONT></I> );
\r
325 <I><FONT COLOR="Navy">{** Método heredado, se sobreescribe porque se dibuja de forma distinta}</FONT></I>
\r
326 <B>function</B> <A NAME=cMisil.mDibujar>cMisil.mDibujar</A>: tObjetosVoladores;
\r
328 result := OV_MISIL;
\r
331 <I><FONT COLOR="Navy">{ cMisilDirigido }</FONT></I>
\r
333 <I><FONT COLOR="Navy">{** Crea una nueva instancia.
\r
334 @param obj Objeto volador al que perseguirá (objetivo)
\r
335 @param pos Vector posición}</FONT></I>
\r
336 <B>constructor</B> cMisilDirigido.create( obj: cObjetoVolador; pos: cVector = <B>nil</B> );
\r
338 <I><FONT COLOR="Navy">// El misil dirigido tiene 70 m de radio, 30 puntos de potencia, 1 punto de energia y 20 seg de alcance (5 km) </FONT></I>
\r
339 <B>inherited</B> create( pos, cVector.create, 0.7 <I><FONT COLOR="Navy">{dim}</FONT></I>, 30 <I><FONT COLOR="Navy">{pot}</FONT></I>, 1 <I><FONT COLOR="Navy">{ene}</FONT></I>, 20000 <I><FONT COLOR="Navy">{dur}</FONT></I>, 0.25 <I><FONT COLOR="Navy">{velmax}</FONT></I> );
\r
341 aLockArea := 2000; <I><FONT COLOR="Navy">// 2 km </FONT></I>
\r
342 mSetAlcance( aLockArea ); <I><FONT COLOR="Navy">// Setea como alcance al area de lockeo. </FONT></I>
\r
343 mModificarVelocidad; <I><FONT COLOR="Navy">// Modifica la velocidad de forma tal que apunte al objetivo </FONT></I>
\r
344 <I><FONT COLOR="Navy">// y tenga un modulo constante </FONT></I>
\r
347 <I><FONT COLOR="Navy">{** Método que calcula la nueva velocidad basandose en al posicion del objetivo}</FONT></I>
\r
348 <B>procedure</B> <A NAME=cMisilDirigido.mModificarVelocidad>cMisilDirigido.mModificarVelocidad</A>;
\r
350 pos, <I><FONT COLOR="Navy">// Vector temporal para hacer calculos </FONT></I>
\r
351 vel: cVector; <I><FONT COLOR="Navy">// Vector temporal para hacer calculos </FONT></I>
\r
353 vel := <B>nil</B>;
\r
354 pos := <B>nil</B>;
\r
355 <B>if</B> aObjetivo <> <B>nil</B> <B>then</B> <I><FONT COLOR="Navy">// Si no es nulo ... </FONT></I>
\r
356 <B>try</B> <I><FONT COLOR="Navy">// Probamos que el objetivo no este destruido </FONT></I>
\r
357 <I><FONT COLOR="Navy">// Le resta la posicion propia a la del objetivo, obteniendo la nueva direccion de la velocidad </FONT></I>
\r
358 pos := mGetPosicion;
\r
359 vel := aObjetivo.mGetPosicion.mRestar( pos );
\r
360 vel.mSetModulo( mGetVelMax ); <I><FONT COLOR="Navy">// Setea el modulo al de la velocidad maxima: 0,25 m/mseg (900 km/h) </FONT></I>
\r
361 mSetVelocidad( vel ); <I><FONT COLOR="Navy">// Modifica la velocidad basado en el vector v </FONT></I>
\r
362 <B>except</B> <I><FONT COLOR="Navy">// Si esta destruido queda la velocidad constante y libera los vectores </FONT></I>
\r
363 on e: EAccessViolation <B>do</B> <B>begin</B>
\r
364 mSetVelModulo( mGetVelMax ); <I><FONT COLOR="Navy">// Setea el modulo de la velocidad como la maxima </FONT></I>
\r
365 <I><FONT COLOR="Navy">// (no cambia su direccion ni sentido) </FONT></I>
\r
366 aObjetivo := <B>nil</B>; <I><FONT COLOR="Navy">// Lo seteamos a nil </FONT></I>
\r
367 vel.free; <I><FONT COLOR="Navy">// libera la memoria del vector temporal </FONT></I>
\r
368 pos.free; <I><FONT COLOR="Navy">// libera la memoria del vector temporal </FONT></I>
\r
371 <I><FONT COLOR="Navy">// Si es nulo no modifica la velocidad ... </FONT></I>
\r
374 <I><FONT COLOR="Navy">{** Mueve el arma basado en su posición y velocidad actual, su objetivo y un intervalo de tiempo
\r
375 @param dt Intervalo de tiempo}</FONT></I>
\r
376 <B>procedure</B> <A NAME=cMisilDirigido.mMover>cMisilDirigido.mMover</A>(dt: tTiempo);
\r
378 mModificarVelocidad; <I><FONT COLOR="Navy">// Modifica la velocidad segun su objetivo </FONT></I>
\r
379 <B>inherited</B> mMover( dt ); <I><FONT COLOR="Navy">// Se mueve al igual que el resto de las armas </FONT></I>
\r
382 <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I>
\r
383 <I><FONT COLOR="Navy">{** Devuelve el estado del objeto basandose en la cantidad de datos requeridos.
\r
384 @return Cadena de texto con el estado del Objeto.
\r
385 @param debugLevel Cantidad de información requerida}</FONT></I>
\r
386 <B>function</B> <A NAME=cMisilDirigido.mGetDebugInfo>cMisilDirigido.mGetDebugInfo</A>(debugLevel: tDebugInfo): <B>string</B>;
\r
388 objInfo: <B>string</B>;
\r
390 <I><FONT COLOR="Navy">// Genera el string con el estado del Misil Dirigido </FONT></I>
\r
391 result := <B>inherited</B> mGetDebugInfo( debugLevel );
\r
392 <B>if</B> debugLevel > DI_MINI <B>then</B>
\r
393 result := result + ' | LockArea: ' + FloatToStr( aLockArea );
\r
394 <B>if</B> aObjetivo <> <B>nil</B> <B>then</B> <I><FONT COLOR="Navy">// Si no es nulo ... </FONT></I>
\r
395 <B>try</B> <I><FONT COLOR="Navy">// Probamos que el objetivo no este destruido </FONT></I>
\r
396 objInfo := aObjetivo.mGetDebugInfo( DI_MINI );
\r
397 <B>except</B> <I><FONT COLOR="Navy">// Si esta destruido cambia la cadena de texto </FONT></I>
\r
398 on e: EAccessViolation <B>do</B> <B>begin</B>
\r
399 objInfo := 'DESTRUIDO';
\r
400 aObjetivo := <B>nil</B>;
\r
403 <B>else</B> <I><FONT COLOR="Navy">// Si es nulo ... </FONT></I>
\r
404 objInfo := 'DESTRUIDO';
\r
405 <B>if</B> debugLevel > DI_NORMAL <B>then</B>
\r
406 result := result + #13 + #10 + 'Objetivo: ' + objInfo;
\r
408 <I><FONT COLOR="Navy">{$ENDIF}</FONT></I>
\r
410 <I><FONT COLOR="Navy">{** Obtiene el objetivo del misil dirigido.
\r
411 @return Objetivo del misil dirigido.}</FONT></I>
\r
412 <B>function</B> <A NAME=cMisilDirigido.mGetObjetivo>cMisilDirigido.mGetObjetivo</A>: cObjetoVolador;
\r
414 result := aObjetivo;
\r
415 <B>if</B> aObjetivo <> <B>nil</B> <B>then</B> <I><FONT COLOR="Navy">// Si no es nil... </FONT></I>
\r
416 <B>try</B> <I><FONT COLOR="Navy">// Primero se fija que no esté destruido </FONT></I>
\r
419 on e: EAccessViolation <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// Si lo está... </FONT></I>
\r
420 aObjetivo := <B>nil</B>; <I><FONT COLOR="Navy">// Lo setea a nil </FONT></I>
\r
421 result := aObjetivo;
\r
426 <I><FONT COLOR="Navy">{** Establece el objetivo del misil dirigido
\r
427 @param ov Nuevo objetivo}</FONT></I>
\r
428 <B>procedure</B> <A NAME=cMisilDirigido.mSetObjetivo>cMisilDirigido.mSetObjetivo</A>( ov: cObjetoVolador );
\r
433 <I><FONT COLOR="Navy">{** Método heredado, se sobreescribe porque se dibuja de forma distinta}</FONT></I>
\r
434 <B>function</B> <A NAME=cMisilDirigido.mDibujar>cMisilDirigido.mDibujar</A>: tObjetosVoladores;
\r
436 result := OV_MISDIR;
\r
439 <I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto
\r
441 @param str Cadena de texto con el objeto serializado.}</FONT></I>
\r
442 <B>procedure</B> <A NAME=cMisilDirigido.mDesSerializar>cMisilDirigido.mDesSerializar</A>(str: <B>string</B>);
\r
446 <B>inherited</B> mDesSerializar( str ); <I><FONT COLOR="Navy">// SIEMPRE el ID debe ser el PRIMER atributo </FONT></I>
\r
447 r := TRegExpr.create;
\r
448 <I><FONT COLOR="Navy">// OBJETIVO </FONT></I>
\r
449 <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>
\r
450 r.Expression := '<objetivo/s+class=([/w/d]+)/s*>/s*(.+)/s*</objetivo>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>
\r
451 <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>
\r
452 <B>if</B> r.Match[1] <> '0' <B>then</B> <I><FONT COLOR="Navy">// Si tiene una clase determinada... </FONT></I>
\r
453 <B>if</B> aObjetivo <> <B>nil</B> <B>then</B> <I><FONT COLOR="Navy">// Si no es nulo </FONT></I>
\r
454 <I><FONT COLOR="Navy">// Puede caer en una EAccessViolation si esta destruido </FONT></I>
\r
455 aObjetivo.mDesSerializar( r.Match[2] ) <I><FONT COLOR="Navy">// Lo deserializa </FONT></I>
\r
456 <B>else</B> <I><FONT COLOR="Navy">// si es nulo </FONT></I>
\r
457 aObjetivo := restaurarObjeto( r.Match[1], r.Match[2] ) <I><FONT COLOR="Navy">// lo crea segun su clase </FONT></I>
\r
458 <B>else</B> <I><FONT COLOR="Navy">// Si no tiene una clase determinada, entonces se lo pone en nil </FONT></I>
\r
459 aObjetivo := <B>nil</B>
\r
460 <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>
\r
461 <B>raise</B> ESerializacion.create( 'No se encontro el objetivo' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>
\r
462 <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>
\r
463 on e: ESerializacion <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// Si fueron de serializacion... </FONT></I>
\r
464 r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>
\r
465 <B>raise</B> ESerializacion.create( ClassName + ': Error al deserializar el objetivo: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>
\r
467 on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>
\r
468 r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>
\r
469 <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer el objetivo utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>
\r
471 on e: EAccessViolation <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si el Objetivo fue destruido... </FONT></I>
\r
472 aObjetivo := restaurarObjeto( r.Match[1], r.Match[2] ) <I><FONT COLOR="Navy">// lo crea segun su clase </FONT></I>
\r
475 <I><FONT COLOR="Navy">// LOCKAREA </FONT></I>
\r
476 <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>
\r
477 r.Expression := '<lockarea>/s*([+/-]?/d+(/,/d+)?([eE][+/-]?/d+)?)/s*</lockarea>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>
\r
478 <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>
\r
479 aLockArea := StrToFloat( r.Match[1] )
\r
480 <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>
\r
481 <B>raise</B> ESerializacion.create( 'No se encontro el area de lockeo' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>
\r
482 <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>
\r
483 on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>
\r
484 r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>
\r
485 <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer el area de lockeo utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>
\r
491 <I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado.
\r
492 @return Cadena de texto con el objeto serializado.}</FONT></I>
\r
493 <B>function</B> <A NAME=cMisilDirigido.mSerializar>cMisilDirigido.mSerializar</A>: <B>string</B>;
\r
496 objetivo: <B>string</B>;
\r
498 <I><FONT COLOR="Navy">// Si el objetivo es nil o está destruido, se setea el atributo class del </FONT></I>
\r
499 <I><FONT COLOR="Navy">// TAG objetivo como '0' y entre el TAG se indica que es nil. Si no se </FONT></I>
\r
500 <I><FONT COLOR="Navy">// setea como el nombre de la clase y su expresion serializada respectivamente </FONT></I>
\r
501 objetivo := 'nil';
\r
503 <B>if</B> aObjetivo <> <B>nil</B> <B>then</B>
\r
505 objetivo := aObjetivo.mSerializar;
\r
506 clase := aObjetivo.ClassName;
\r
507 <B>except</B> <I><FONT COLOR="Navy">// Si esta destruido cambia la cadena de texto </FONT></I>
\r
508 on e: EAccessViolation <B>do</B> <B>begin</B>
\r
509 objetivo := 'nil';
\r
511 aObjetivo := <B>nil</B>;
\r
514 result := <B>inherited</B> mSerializar +
\r
515 '<objetivo class=' + clase + '>' + objetivo + '</objetivo>' +
\r
516 '<lockarea>' + FloatToStrF( aLockArea, ffGeneral, 18, 0 ) + '</lockarea>';
\r