home *** CD-ROM | disk | FTP | other *** search
/ MASPC 1 / MASPC_1.iso / Demos / Demo DIV / DATA / PRG / JUEGOS / CHAPAS.PRG < prev    next >
Encoding:
Text File  |  1997-11-27  |  49.9 KB  |  1,384 lines

  1.  
  2. //-----------------------------------------------------------------------------
  3. // TITULO:      WORLD CAPS CHAMPIONSHIP
  4. // AUTOR:       MANUEL CABAñAS VENERA
  5. // FECHA:       1/6/97
  6. //-----------------------------------------------------------------------------
  7. PROGRAM chapas;
  8.  
  9. CONST
  10.  
  11.     // Limites para los lanzamientos
  12.     poder_maximo=38;
  13.     fuerza_minima=2;
  14.     inclinacion_maxima=pi;
  15.     inclinacion_minima=-pi;
  16.  
  17.     mapa_grafico=100;           // Gráfico del mapa del juego
  18.     ancho_mapa=1134;            // Tamaño del mapa
  19.     alto_mapa=790;
  20.     mapa_deteccion_choque=101;  // Mapa de durezas
  21.  
  22.     color_control_1=200;        // Colores especiales para el mapa de durezas
  23.     color_control_2=156;
  24.     color_control_3=115;
  25.     color_meta=246;
  26.     color_fuera=192;
  27.     color_objetos=141;
  28.  
  29.     vueltas=1;              // Numero de vueltas
  30.     velocidad_anterior=16;  // Velocidad de retorno a la posición previa
  31.     avance_maximo=7;        // Máximo 7 puntos en el lanzamiento
  32.     ultimo_punto=48;        // Ultimo punto de control en el circuito
  33.  
  34. GLOBAL
  35.     fichero_grafico;    // Fichero gráfico
  36.  
  37.     fuente1;            // Fuentes de letras
  38.     fuente2;
  39.     fuente3;
  40.     fuente4;
  41.  
  42.     sonido1;            // Sonidos
  43.     sonido2;
  44.     sonido3;
  45.     canal=-1;           // Canal de sonido. -1= no usado
  46.  
  47.     estado_programa=1;  // (1=Menu principal 2=Juego 3=Creditos 4=Fin)
  48.     nuevo_estado=0;     // El siguiente estado del programa
  49.  
  50.     turno=1;            // Siguiente turno
  51.     toques=1;           // Numero de toques
  52.     id_chapa[1]=0,0;    // Identificador del proceso de la chapa
  53.     posicion_inicial_x[1]=325,325;    // Posición inicial en
  54.     posicion_inicial_y[1]=691,659;    // la meta 0->1º, 1->2º
  55.     num_jugadores=0;    // Numero de jugadores
  56.     modo_juego;         // 1=Practica, 2 =Dos jugadores, 3= Jugador vs CPU
  57.  
  58.     id_camara;          // Identificador de la cámara
  59.     camara_x=0;         // Posición de la cámara
  60.     camara_y=0;
  61.     moviendose=FALSE;   // 1=Cuando el movimiento de pantalla esta activo
  62.  
  63.     id_proceso_direccion=0;     // Identificador del proceso dirección
  64.     id_proceso_inclinacion=0;   // Identificador del proceso inclinación
  65.     id_proceso_fuerza=0;        // Identificador del proceso fuerza
  66.     objetivo=0;                 // Identificador de la chapa
  67.     contador0=0;                // Contador de uso general
  68.  
  69. LOCAL
  70.     fuerza_ini;             // Contador de fuerza inicial
  71.     x_resol=0;              // Posición de la chapa x1000
  72.     y_resol=0;
  73.     mi_turno=0;             // Para saber cuando es nuestro turno
  74.     id_pos_ant=0;           // Identificador del proceso de la posición previa
  75.     fuerza=fuerza_minima;   // Fuerza de lanzamiento
  76.     direccion=0;            // Dirección del lanzamiento(Plano XY)
  77.     inclinacion=0;          // Inclinación del lanzamiento(Plano XZ)
  78.     inc_inclinacion=0;      // Incremento de la inclinación cuando se mueve
  79.     movimiento=0;           // Movimientos (0 = pausa, 1 = lanzamiento, 2 = colisión, 3 & 4 = retorno)
  80.     num_lanzamiento=1;      // Numero de lanzamientos
  81.     vuelta_actual=0;        // Vuelta actual
  82.     control[3]=FALSE,FALSE,FALSE;   // Para controlar las vueltas
  83.     fuera=FALSE;            // TRUE= posición incorrecta de la chapa
  84.     colision_chapa=0;       // Se actualiza cuando colisionamos con algo
  85.     animacion=17;           // Animación de la chapa(17..49)
  86.  
  87. BEGIN // Programa principal
  88.  
  89.     priority=1;             // Esto es para que sea lo primero que se ejecute
  90.  
  91.     // Carga las fuentes de las letras
  92.     fuente1=load_fnt("chapas\titulo.fnt");
  93.     fuente2=load_fnt("chapas\opcion.fnt");
  94.     fuente3=load_fnt("chapas\juego.fnt");
  95.     fuente4=load_fnt("chapas\creditos.fnt");
  96.  
  97.     // Carga los sonidos
  98.     sonido1=load_pcm("chapas\tic7.pcm",1);       // Fuerza
  99.     sonido2=load_pcm("chapas\metal4.pcm",0);     // Lanzamiento
  100.     sonido3=load_pcm("chapas\metal10.pcm",0);    // Colisión
  101.  
  102.     LOOP // Bucle del proceso principal
  103.  
  104.         // Dependiendo del estado del programa ejecuta una parte u otra
  105.         SWITCH (estado_programa);
  106.             CASE 1:             // Estado del programa en titulo (Menú)
  107.                 titulo();       // Proceso del tipo titulo que controla el menú
  108.                 timer[0]=0;     // Pone un contador de tiempo 0
  109.             END
  110.             CASE 2:             // Aqui es donde esta el juego en sí
  111.                 juego();
  112.             END
  113.             CASE 3:
  114.                 creditos();     // Opción de ver créditos
  115.             END
  116.             CASE 4:             // Opción de salir del juego
  117.                 exit("Gracias por jugar!",0);
  118.             END
  119.             DEFAULT:
  120.                 // Si no esta en otro estado de programa de -1
  121.                 // y el tiempo pasado es mayor que 10 segundos
  122.                 // pone el estado del juego en créditos
  123.                 IF (estado_programa==-1 AND timer[0]>1000)
  124.                     nuevo_estado=3;    // Créditos
  125.                     timer[0]=0;
  126.                 END
  127.             END
  128.         END
  129.         FRAME;
  130.     END
  131. END
  132.  
  133. //-----------------------------------------------------------------------------
  134. // Proceso Titulo
  135. // Opciones del menú principal
  136. //-----------------------------------------------------------------------------
  137.  
  138. PROCESS titulo();
  139.  
  140. BEGIN
  141.     estado_programa=-1;     // Cambia el estado del programa a -1 para
  142.                             // llamarse solo una vez
  143.     nuevo_estado=0;
  144.     set_mode(m640x480);     // Selecciona modo de vídeo
  145.     // Carga los gráficos necesarios para el juego
  146.     fichero_grafico=load_fpg("chapas\porchapa.fpg");
  147.     put_screen(fichero_grafico,1);      // Pon la pantalla de fondo
  148.     load_pal("chapas\porchapa.fpg");    // Carga la paleta de colores
  149.     fade_on();
  150.  
  151.     // Opciones del menú principal
  152.     write(fuente2,160,220,3,"1 Practicar");
  153.     write(fuente2,150,260,3,"2 Jugador contra Jugador");
  154.     write(fuente2,150,300,3,"3 Jugador contra Ordenador");
  155.     write(fuente2,150,380,3,"ESC Salir al DOS");
  156.     write(fuente2,320,460,4,"(c) 1997 Hammer Technologies");
  157.     write(fuente1,320,60,4,"WORLD CHAPAS");
  158.     write(fuente1,320,120,4,"CHAMPIONSHIP");
  159.  
  160.     WHILE (nuevo_estado==0) // Repite hasta que se cambie de estado
  161.  
  162.         // Elige el modo de juego según la tecla pulsada
  163.         IF (key(_1))            // Tipo de juego eligido de Practica
  164.             num_jugadores=1;
  165.             modo_juego=1;
  166.             nuevo_estado=2;
  167.         END
  168.         IF (key(_2))            // Tipo de juego eligido
  169.             num_jugadores=2;    // Jugador contra Jugador
  170.             modo_juego=2;
  171.             nuevo_estado=2;
  172.         END
  173.         IF (key(_3))            // Tipo de juego eligido
  174.             num_jugadores=2;    // Jugador contra ordenador
  175.             modo_juego=3;
  176.             nuevo_estado=2;
  177.         END
  178.         IF (key(_esc))          // Salir del programa
  179.             nuevo_estado=4;
  180.         END
  181.  
  182.         FRAME;
  183.  
  184.     END
  185.  
  186.     fade_off();                     // Apaga la pantalla
  187.  
  188.     unload_fpg(fichero_grafico);    // Descarga los gráficos
  189.     delete_text(all_text);          // Borra todos los textos de pantalla
  190.     estado_programa=nuevo_estado;   // Cambia el programa al nuevo estado
  191. END
  192.  
  193. //-----------------------------------------------------------------------------
  194. //  Proceso Créditos
  195. //  Muestra los créditos del juego World Caps Championship
  196. //-----------------------------------------------------------------------------
  197.  
  198. PROCESS creditos();
  199.  
  200. PRIVATE
  201.     // Identificadores de textos
  202.     id_texto_titulo;
  203.     id_texto_prog_1;
  204.     id_texto_prog_2;
  205.     id_texto_graf_1;
  206.     id_texto_graf_2;
  207.     id_texto_musi_1;
  208.     id_texto_musi_2;
  209.     id_copia_texto;
  210.  
  211. BEGIN
  212.     estado_programa=-3;
  213.     set_mode(m640x480);                 // Selecciona el modo de vídeo
  214.     fichero_grafico=load_fpg("chapas\creditos.fpg");    // Carga gráficos
  215.     put_screen(fichero_grafico,1);      // Pone pantalla de fondo
  216.     load_pal("chapas\creditos.fpg");    // Carga paleta de colores
  217.     fade_on();                          // Enciende la pantalla
  218.     WHILE (fading)                      // Espera a que se encienda
  219.         FRAME;
  220.     END
  221.  
  222.     x=120;                              // Utiliza las coordenadas destinadas a gráficos
  223.     y=480;                              // para mover los textos
  224.  
  225.     // Pone los textos
  226.     id_texto_titulo=write(fuente4,320,y,1,"WORLD CHAPAS CHAMPIONSHIP");
  227.     id_texto_prog_1=write(fuente4,x,y+80,0,"Programación:");
  228.     id_texto_prog_2=write(fuente4,x,y+120,0,"  Manuel Cabañas Venera");
  229.     id_texto_graf_1=write(fuente4,x,y+200,0,"Gráficos:");
  230.     id_texto_graf_2=write(fuente4,x,y+240,0,"  Pablo de la Sierra");
  231.     id_texto_musi_1=write(fuente4,x,y+320,0,"Idea original:");
  232.     id_texto_musi_2=write(fuente4,x,y+360,0,"  Luis F. Fernandez");
  233.     id_copia_texto=write(fuente4,320,y+440,1,"(c) Daniel Navarro - DIV Games Studio ");
  234.     scan_code=0;
  235.     FRAME;
  236.  
  237.     REPEAT
  238.         // Si se pulsa una tecla o han aparecido todos los textos, termina
  239.         IF (scan_code<>0 OR y<-480) BREAK; END
  240.  
  241.         y-=2;   // Va moviendo el texto hacia arriba
  242.         move_text(id_texto_titulo,320,y);
  243.         move_text(id_texto_prog_1,x,y+80);
  244.         move_text(id_texto_prog_2,x,y+120);
  245.         move_text(id_texto_graf_1,x,y+200);
  246.         move_text(id_texto_graf_2,x,y+240);
  247.         move_text(id_texto_musi_1,x,y+320);
  248.         move_text(id_texto_musi_2,x,y+360);
  249.         move_text(id_copia_texto,320,y+440);
  250.         FRAME;
  251.     UNTIL (estado_programa==1)
  252.     fade_off();
  253.     // Borra los textos y descarga el fichero de gráficos
  254.     delete_text(all_text);
  255.     unload_fpg(fichero_grafico);
  256.     estado_programa=1;    // Retorna al menú principal a estado de programa titulo
  257. END
  258.  
  259. //-----------------------------------------------------------------------------
  260. //  Proceso juego
  261. //  Selecciona las variables de acuerdo al modo de juego
  262. //-----------------------------------------------------------------------------
  263.  
  264. PROCESS juego();
  265.  
  266. BEGIN
  267.     estado_programa=-2;             // Cambia el estado del programa para ejecutar este proceso solo una vez
  268.     // Reinicia las varibles usadas en el juego
  269.     nuevo_estado=0;
  270.     turno=1;
  271.     toques=1;
  272.     objetivo=0;
  273.  
  274.     set_mode(m320x200);             // Selecciona el modo de vídeo
  275.     fichero_grafico=load_fpg("chapas\chapas.fpg");      // Carga el fichero de gráficos
  276.  
  277.     // Inicia el movimiento de pantalla (scroll)
  278.     start_scroll(0,fichero_grafico,mapa_grafico,0,0,3); // Plano 0, Región 0, todas las direcciones
  279.     load_pal("chapas\chapas.fpg");  // Carga la paleta de colores correcta
  280.     fade_on();                      // Enciende la pantalla
  281.  
  282.     moviendose=TRUE;        // La cámara no esta parada
  283.  
  284.     comienzo_juego();       // Comienza los procesos
  285.     // De estos procesos coge los identificadores para uso futuro
  286.     id_camara=camara_principal();
  287.     id_proceso_direccion=direccion_chapa();
  288.     id_proceso_inclinacion=inclinacion_chapa();
  289.     id_proceso_fuerza=fuerza_chapa();
  290.  
  291.     // Mueve la camara hasta la primera chapa
  292.     cambia_movimiento(id_chapa[0].x-160,id_chapa[0].y-100); // Cambia la cámara mirando hacia la primera chapa
  293.  
  294.     // Muestra los datos del juego
  295.     write(fuente3,2,2,0,"Turno");
  296.     write_int(fuente3,70,2,0,&turno);
  297.     write(fuente3,2,22,0,"Tiros");
  298.     write_int(fuente3,70,22,0,&toques);
  299.  
  300.     FRAME;
  301.     LOOP
  302.         // Comprueba si alguno ha llegado a la línea de meta
  303.         contador0=0;
  304.         WHILE (contador0<num_jugadores)
  305.             IF (id_chapa[contador0].vuelta_actual<vueltas)
  306.                 contador0++;
  307.             ELSE
  308.                 BREAK;
  309.             END
  310.         END
  311.  
  312.         // Mira si se acabo el juego
  313.         IF (contador0<num_jugadores)
  314.             nuevo_estado=1;     // Vuelve al menú principal
  315.             BREAK;
  316.         END
  317.  
  318.         // Mira si se pulso la tecla escape
  319.         IF (key(_esc))
  320.             nuevo_estado=1;    // Vuelve al menú principal
  321.             BREAK;
  322.         END
  323.  
  324.         FRAME;
  325.  
  326.     END
  327.  
  328.     // Elimina todos los procesos
  329.     signal(type chapa_jugador,s_kill_tree);
  330.     signal(type rival,s_kill_tree);
  331.     signal(id_camara,s_kill);
  332.     signal(id_proceso_direccion,s_kill_tree);
  333.     signal(id_proceso_inclinacion,s_kill_tree);
  334.     signal(id_proceso_fuerza,s_kill_tree);
  335.  
  336.     stop_scroll(0);             // Para el movimiento de pantalla (scroll)
  337.     fade_off();                 // Apaga la pantalla
  338.     delete_text(all_text);      // Elimina todos los textos
  339.     unload_fpg(fichero_grafico);// Descarga el fichero de gráficos
  340.     estado_programa=nuevo_estado;
  341. END
  342.  
  343. //-----------------------------------------------------------------------------
  344. //  Proceso comienzo_juego
  345. //  Carga los valores iniciales
  346. //-----------------------------------------------------------------------------
  347.  
  348. PROCESS comienzo_juego();
  349.  
  350. PRIVATE
  351.     jugador;     // Jugador que empieza (0=jugador 1, 1=jugador 2 o CPU)
  352.  
  353. BEGIN
  354.  
  355.     // Elige que jugador empezara
  356.     IF (num_jugadores==1)                       // Mira primero si solo juega un jugador
  357.         id_chapa[0]=chapa_jugador(1);           // Si es solo uno, empieza él
  358.     ELSE                                        // Si no el número de jugadores es 2
  359.         jugador=rand(0,num_jugadores-1);        // Elige al azar quien empieza
  360.         IF (jugador==0)                         // Si ha salido 0, empieza el primer jugador
  361.             id_chapa[0]=chapa_jugador(1);       // Se asigna la primera chapa como primero
  362.             IF (modo_juego==2)                  // Comprueba el modo de juego
  363.                 id_chapa[1]=chapa_jugador(2);   // El segundo es el otro jugador
  364.             ELSE
  365.                 id_chapa[1]=rival(2);           // O si no es el segundo es el ordenador
  366.             END
  367.         ELSE                                    // Si no ha salido 1, empieza el segundo jugador
  368.             IF (modo_juego==2)                  // Comprueba el modo de juego
  369.                 id_chapa[1]=chapa_jugador(1);   // El segundo en tirar es el primer jugador
  370.             ELSE
  371.                 id_chapa[1]=rival(1);           // El segundo en tirar es el ordenador
  372.             END
  373.             id_chapa[0]=chapa_jugador(2);       // El primero en tirar es el segundo jugador
  374.         END
  375.     END
  376. END
  377.  
  378. //-----------------------------------------------------------------------------
  379. //  Proceso posicion_chequeo
  380. //  Comprueba la posición de la chapa
  381. //-----------------------------------------------------------------------------
  382.  
  383. PROCESS posicion_chequeo(identificador);
  384.  
  385. PRIVATE
  386.     color;  // Color del mapa de texturas
  387.  
  388. BEGIN
  389.  
  390.     // Coge el color del mapa de texturas
  391.     color=map_get_pixel(fichero_grafico,mapa_deteccion_choque,(identificador.x)/2,(identificador.y)/2);
  392.  
  393.     // Realiza la acción en consecuencia del color cogido
  394.     SWITCH (color)
  395.         CASE color_fuera:       // Ha salido fuera
  396.             identificador.fuera=TRUE;
  397.         END
  398.         CASE color_objetos:
  399.             identificador.fuera=TRUE;
  400.         END                     // Ha dado con un objeto (= fuera)
  401.         CASE color_control_1:
  402.             // Comprueba que no ha salido fuera
  403.             IF (NOT identificador.fuera)
  404.                 identificador.control[0]=TRUE;
  405.             END
  406.         END                     // Ha llegado al control zona 1
  407.         CASE color_control_2:
  408.             // Comprueba que no ha salido fuera y que paso por el control zona 1
  409.             IF (NOT identificador.fuera AND identificador.control[0])
  410.                 identificador.control[1]=TRUE;
  411.             END
  412.         END                     // Ha llegado al control zona 2
  413.         CASE color_control_3:
  414.             // Comprueba que no ha salido fuera y que paso por el control zona 2
  415.             IF (NOT identificador.fuera AND identificador.control[1])
  416.                 identificador.control[2]=TRUE;
  417.             END
  418.         END                     // Ha llegado al control zona 3
  419.         CASE color_meta:
  420.             // Comprueba que no ha salido fuera y que paso por el control zona 3
  421.             IF (NOT identificador.fuera AND identificador.control[2])
  422.                 identificador.control[2]=identificador.control[1]=identificador.control[0]=FALSE;
  423.                 identificador.vuelta_actual++;
  424.             END                 // Ha llegado a la zona de meta
  425.         END
  426.     END
  427. END
  428.  
  429. //-----------------------------------------------------------------------------
  430. //  Proceso calcula_movimiento
  431. //  Calcula la posición de la chapa dependiendo de los datos de la chapa
  432. //-----------------------------------------------------------------------------
  433.  
  434. PROCESS calcula_movimiento();
  435.  
  436. PRIVATE
  437.     angulo_anterior;     // Ultimo ángulo
  438.     distancia_anterior;  // Ultima distancia
  439.  
  440. BEGIN
  441.  
  442.     // Coge el tipo de movimiento del proceso que lo llamo
  443.     SWITCH (father.movimiento);
  444.  
  445.         CASE 1,2:   // Lanzamiento o colisión
  446.  
  447.             // Mueve la chapa 2 puntos
  448.             father.x_resol+=get_distx(father.direccion,2000);
  449.             father.y_resol+=get_disty(father.direccion,2000);
  450.             // Comprueba si se ha salido o ha llegado a un punto de meta
  451.             posicion_chequeo(father);
  452.             // Actualiza las coordenadas según los resultados
  453.             father.x=father.x_resol/1000;
  454.             father.y=father.y_resol/1000;
  455.         END
  456.  
  457.         CASE 3,4:   // Retorna de lanzamiento erroneo
  458.             // Coge las coordenadas del proceso que lo llamo (la chapa)
  459.             x=father.x;
  460.             y=father.y;
  461.             // Coge el angulo y la distancia que han sido erroneos
  462.             angulo_anterior=get_angle(father.id_pos_ant);
  463.             distancia_anterior=get_dist(father.id_pos_ant);
  464.             // Comprueba si ha llegado ya a su posición anterior
  465.             IF (distancia_anterior<velocidad_anterior)
  466.                 // Actualiza las coordenadas de la chapa
  467.                 father.x=father.id_pos_ant.x;
  468.                 father.y=father.id_pos_ant.y;
  469.                 // Quita el identificador de fuera y la dirección
  470.                 father.fuera=FALSE;
  471.                 father.direccion=0;
  472.                 // Se cambia el turno
  473.                 IF (father.mi_turno==turno AND father.movimiento==3)
  474.                     turno++;
  475.                     IF (turno>num_jugadores) turno=1; END
  476.                 END
  477.                 father.movimiento=0;
  478.                 signal(father.id_pos_ant,s_kill);   // Quita la posición anterior (erronea)
  479.             ELSE
  480.                 // Si no mueve la chapa hasta su posición anterior
  481.                 father.x+=get_distx(angulo_anterior,velocidad_anterior);
  482.                 father.y+=get_disty(angulo_anterior,velocidad_anterior);
  483.             END
  484.             // Actualiza coordenadas
  485.             father.x_resol=father.x*1000;
  486.             father.y_resol=father.y*1000;
  487.         END
  488.         DEFAULT:
  489.         END
  490.     END
  491.  
  492.     // Mira el limite izquierdo del mapa
  493.     IF (father.x<10)
  494.         father.movimiento=3;      // Retorna el movimiento (tiro)
  495.         father.fuerza=0;
  496.         father.x=10;
  497.         father.x_resol=10000;
  498.         father.direccion=0;
  499.         father.inclinacion=0;
  500.     END
  501.  
  502.     // Mira el limite derecho del mapa
  503.     IF (father.x>ancho_mapa-10)
  504.         father.movimiento=3;      // Retorna el movimiento (tiro)
  505.         father.fuerza=0;
  506.         father.x=ancho_mapa-10;
  507.         father.x_resol=(ancho_mapa-10)*1000;
  508.         father.direccion=0;
  509.         father.inclinacion=0;
  510.     END
  511.  
  512.     // Mira el limite superior de la pantalla
  513.     IF (father.y<10)
  514.         father.movimiento=3;      // Quita el ultimo movimiento
  515.         father.fuerza=0;
  516.         father.y=10;
  517.         father.y_resol=10000;
  518.         father.direccion=0;
  519.         father.inclinacion=0;
  520.     END
  521.  
  522.     // Comprueba el limite superior de la pantalla
  523.     IF (father.y>alto_mapa-10)
  524.         father.movimiento=3;      // Retorna el movimiento
  525.         father.fuerza=0;
  526.         father.y=alto_mapa-10;
  527.         father.y_resol=(alto_mapa-10)*1000;
  528.         father.direccion=0;
  529.         father.inclinacion=0;
  530.     END
  531.  
  532. END
  533.  
  534. //-----------------------------------------------------------------------------
  535. //  Proceso cambia_movimiento
  536. //  Realiza los movimientos de la cámara
  537. //-----------------------------------------------------------------------------
  538.  
  539. PROCESS cambia_movimiento(x,y);
  540.  
  541. BEGIN
  542.  
  543.     // El movimiento esta limitado a la resolución
  544.     // de la pantalla (320x200) y al tamaño del mapa
  545.     IF (x<0)                    // Comprueba el lado izquierdo
  546.         x=0;
  547.     ELSE                        // Comprueba el lado derecho
  548.         IF (x>ancho_mapa-320)
  549.             x=ancho_mapa-320;
  550.         END
  551.     END
  552.     IF (y<0)                    // Comprueba el lado superior
  553.         y=0;
  554.     ELSE                        // Comprueba el lado inferior
  555.         IF (y>alto_mapa-200)
  556.             y=alto_mapa-200;
  557.         END
  558.     END
  559.  
  560.     // Actualiza la cámara dependiendo de las coordenadas de este proceso
  561.     camara_x=x;
  562.     camara_y=y;
  563. END
  564.  
  565. //-----------------------------------------------------------------------------
  566. //  Proceso direccion_chapa
  567. //  Muestra la dirección de la chapa
  568. //-----------------------------------------------------------------------------
  569.  
  570. PROCESS direccion_chapa();
  571.  
  572. BEGIN
  573.     file=fichero_grafico;   // Selecciona el fichero gráfico
  574.     ctype=c_scroll;         // Introduce al proceso dentro del scroll
  575.     // Cambia distinta variables predefinidas
  576.     z=-1;
  577.     priority=-1;
  578.     size=50;
  579.  
  580.     LOOP
  581.          // El indicador esta rotando alrededor de la chapa
  582.         IF (objetivo<>0)
  583.  
  584.             // El objetivo es es identificador de la chapa
  585.             // y el indicador coge sus coordenadas respecto a la misma
  586.             x=objetivo.x+get_distx(objetivo.direccion,24);
  587.             y=objetivo.y+get_disty(objetivo.direccion,24);
  588.  
  589.             // Coge el ángulo respecto a la chapa
  590.             angle=objetivo.direccion;
  591.  
  592.             // Cambia el gráfico dependiendo de la chapa
  593.             IF (objetivo.mi_turno==1)
  594.                 graph=400;
  595.             ELSE
  596.                 graph=401;
  597.             END
  598.         ELSE
  599.             graph=0;        // Ningún indicador es mostrado esta moviendose
  600.         END
  601.         FRAME;
  602.     END
  603. END
  604.  
  605. //-----------------------------------------------------------------------------
  606. //  Proceso inclinacion_fondo
  607. //  Muestra el fondo de pantalla de la inclinación de la chapa
  608. //-----------------------------------------------------------------------------
  609.  
  610. PROCESS inclinacion_fondo();
  611.  
  612. BEGIN
  613.     file=fichero_grafico;
  614.     graph=200;              // Elige el gráfico
  615.     x=father.x;             // Coge las coordenadas del proceso que los llamo
  616.     y=father.y;
  617.     z=-2;
  618.     LOOP
  619.         FRAME;
  620.     END
  621. END
  622.  
  623. //-----------------------------------------------------------------------------
  624. //  Proceso inclinacion_chapa
  625. //  Muestra el marcador de la inclinación de la chapa
  626. //-----------------------------------------------------------------------------
  627.  
  628. PROCESS inclinacion_chapa();
  629.  
  630. BEGIN
  631.     file=fichero_grafico;
  632.     graph=201;          // Elige el gráfico a usar
  633.     x=281;              // Pone la coordenadas
  634.     y=38;
  635.     z=-3;               // Ponlo por encima del fondo
  636.     priority=-1;
  637.     inclinacion_fondo();// Crea el fondo del marcador
  638.  
  639.     LOOP
  640.         // Comprueba si se esta tirando
  641.         IF (objetivo<>0)
  642.             // Cambia el ángulo en relación a la inclinación elegida
  643.             angle=(objetivo.inclinacion/2);
  644.         ELSE
  645.             // Se esta tirando, no eligieno inclinación
  646.             angle=0;
  647.         END
  648.         FRAME;
  649.     END
  650. END
  651.  
  652. //-----------------------------------------------------------------------------
  653. //  Proceso fondo_fuerza
  654. //  Muestra el gráfico de fondo de la fuerza de la chapa
  655. //-----------------------------------------------------------------------------
  656.  
  657. PROCESS fondo_fuerza();
  658.  
  659. BEGIN
  660.     file=fichero_grafico;
  661.     graph=300;              // Se selecciona el gráficos
  662.     x=father.x;             // Coge las coordenadas del proceso que lo llamo
  663.     y=father.y;
  664.     z=-2;
  665.     LOOP
  666.         FRAME;
  667.     END
  668. END
  669.  
  670. //-----------------------------------------------------------------------------
  671. //  Proceso fuerza_chapa
  672. //  Muestra el indicador de fuerza de la chapa
  673. //-----------------------------------------------------------------------------
  674.  
  675.  
  676. PROCESS fuerza_chapa();
  677.  
  678. BEGIN
  679.     file=fichero_grafico;
  680.     graph=301;      // Selecciona el gráfico a usar
  681.     x=281;          // Selecciona las coordenadas
  682.     y=161;
  683.     z=-3;           // Ponlo por encima del fondo que tiene
  684.     priority=-1;
  685.     fondo_fuerza(); // Crea el fondo del marcador
  686.     LOOP
  687.         IF (objetivo<>0)
  688.             // Selecciona el ángulo respecto a la fuerza
  689.             angle=-((objetivo.fuerza-fuerza_minima)*3*pi)/(2*(poder_maximo-fuerza_minima));
  690.         ELSE
  691.             // Se esta tirando y no eligiendo la fuerza
  692.             angle=0;
  693.         END
  694.         FRAME;
  695.     END
  696. END
  697.  
  698. //----------------------------------------------------------------------------
  699. //  Proceso chapa_jugador
  700. //  Maneja las acciones de la chapa
  701. //----------------------------------------------------------------------------
  702.  
  703. PROCESS chapa_jugador(mi_turno);
  704.  
  705. PRIVATE
  706.     // Para la barra de lanzamientos
  707.     fuerza_cargada=FALSE;   // SPACE o ENTER esta pulsada
  708.     fuerza_arriba=TRUE;     // Oscila entre MINIMO-MAXIMO (Arriba o Abajo)
  709.  
  710. BEGIN
  711.  
  712.     file=fichero_grafico;
  713.     graph=17;               // Se selecciona el gráfico
  714.     flags=0;
  715.     // Coge las coordenadas de la tabla
  716.     x=posicion_inicial_x[mi_turno-1];
  717.     y=posicion_inicial_y[mi_turno-1];
  718.     // Crea otras coordenadas pero multiplicadas por 1000
  719.     x_resol=x*1000;
  720.     y_resol=y*1000;
  721.     ctype=c_scroll;           // Coordenadas absolutas sobre el mapa
  722.     FRAME;
  723.  
  724.     LOOP
  725.  
  726.         // Lee las teclas si es el turno apropiado
  727.         IF (turno==mi_turno AND movimiento==0)      // Prepara el lanzamiento
  728.             objetivo=id;                            // Guarda en la variable objetivo el identificador
  729.             WHILE (moviendose)                      // Repite hasta que acabe de moverse
  730.                 FRAME;
  731.             END
  732.  
  733.             IF (key(_o) OR key(_left))      // Selecciona dirección
  734.                 direccion=direccion+(pi/32);
  735.             END
  736.             IF (key(_p) OR key(_right))
  737.                 direccion=direccion-(pi/32);
  738.             END
  739.             IF (key(_a) OR key(_down))      // Selecciona inclinación
  740.                 inclinacion=inclinacion+pi/8;
  741.                 IF (inclinacion>inclinacion_maxima)
  742.                     inclinacion=inclinacion_maxima;
  743.                 END
  744.             END
  745.             IF (key(_q) OR key(_up))
  746.                 inclinacion=inclinacion-pi/8;
  747.                 IF (inclinacion<inclinacion_minima)
  748.                     inclinacion=inclinacion_minima;
  749.                 END
  750.             END
  751.  
  752.             // Incrementa fuerza
  753.             IF (key(_space) OR key(_enter))
  754.                 IF (fuerza==fuerza_minima AND canal==-1)
  755.                     canal=sound(sonido1,256,492);
  756.                 END
  757.                 fuerza_cargada=TRUE;
  758.                 IF (fuerza_arriba)
  759.                     fuerza=fuerza+2;
  760.                     IF (fuerza>poder_maximo)
  761.                         fuerza_arriba=FALSE;
  762.                         fuerza=poder_maximo;
  763.                     END
  764.                 ELSE
  765.                     fuerza=fuerza-2;
  766.                     IF (fuerza<fuerza_minima)
  767.                         fuerza=fuerza_minima;
  768.                         fuerza_arriba=TRUE;
  769.                     END
  770.                 END
  771.                 change_sound(canal,256,512-fuerza*10);
  772.             END
  773.  
  774.             // Cuando no esta pulsado ENTER ni SPACE y tiene fuerza, comienza el movimiento
  775.             IF ((NOT key(_space) AND NOT key(_enter)) AND fuerza_cargada)
  776.                 stop_sound(canal);          // Detiene cualquier sonido
  777.                 canal=-1;                   // Y pone un sonido nuevo
  778.                 sound(sonido2,132+fuerza*30,700);
  779.                 id_pos_ant=punto(x,y);      // Graba la posición actual
  780.                 num_lanzamiento++;          // Incrementa el contador de lanzamientos
  781.                 fuerza_cargada=FALSE;       // Reinicia las variables necesarias
  782.                 fuera=FALSE;
  783.                 movimiento=1;               // Esta moviendose
  784.                 fuerza_arriba=TRUE;
  785.                 inc_inclinacion=(-inclinacion*2)/fuerza;
  786.                 objetivo=0;                 // Indica que ya no esta eligiendo parametros de tiro
  787.                 fuerza_ini=fuerza;
  788.             END
  789.             toques=num_lanzamiento;         // Para mostrarlo en la pantalla
  790.         END
  791.  
  792.         IF (movimiento<>0)
  793.             animacion=66-animacion;         // Anima la chapa
  794.             SWITCH (movimiento)
  795.                 CASE 1,2:                   // Tiro o colisión
  796.                     inclinacion+=inc_inclinacion;
  797.                     direccion+=inc_inclinacion;
  798.  
  799.                     // Lanzamos de 2 en 2 pixels (puntos)
  800.                     FOR (contador0=0;contador0<fuerza;contador0+=2)
  801.                         calcula_movimiento();
  802.  
  803.                         // Comprueba colisiones
  804.                         IF(fuera AND fuerza==fuerza_ini)
  805.                             fuera=FALSE;    // Ya no esta fuera
  806.                         END
  807.                         IF (movimiento==1 AND modo_juego==3 AND (colision_chapa=collision(TYPE rival)))
  808.                             impacto();      // Ha chocado contra la chapa del ordenador
  809.                         END
  810.                         IF (modo_juego==2)
  811.                             WHILE ((colision_chapa=collision(TYPE chapa_jugador)))
  812.                                 // Ha chocado con el otro jugador
  813.                                 IF (colision_chapa<>id) impacto(); END
  814.                             END
  815.                         END
  816.                     END
  817.                     fuerza-=2;
  818.                     // Decrementa fuerza y comprueba si ha acabado
  819.                     IF (fuerza<=0)
  820.                         fuerza=fuerza_minima;
  821.                         IF (fuera)
  822.                             IF (movimiento<3) // Movimiento anterior (retorna movimiento)
  823.                                 movimiento+=2;
  824.                             END
  825.                         ELSE
  826.                             IF (turno==mi_turno AND movimiento==1)  // Cambia el turno
  827.                                 turno++;
  828.                                 IF (turno>num_jugadores)
  829.                                     turno=1;
  830.                                 END
  831.                             END
  832.                             signal(id_pos_ant,s_kill);
  833.                             movimiento=0;
  834.                         END
  835.                     END
  836.                 END
  837.                 CASE 3:
  838.                     calcula_movimiento();   // Antes del lanzamiento
  839.                 END
  840.                 CASE 4:
  841.                     calcula_movimiento();   // Antes de la colisión
  842.                     IF (modo_juego==3 AND (colision_chapa=collision(TYPE rival)))
  843.                         IF (colision_chapa.movimiento<>3)
  844.                             impacto();      // Ha chocado contra el ordenador
  845.                         END
  846.                     END
  847.                     IF (modo_juego==2)
  848.                         WHILE ((colision_chapa=collision(TYPE chapa_jugador)))
  849.                             IF (colision_chapa<>id AND colision_chapa.movimiento<>3)
  850.                                 impacto();  // Ha chocado contra la otra chapa
  851.                             END
  852.                         END
  853.                     END
  854.                 END
  855.             END
  856.         END
  857.  
  858.         // Limita la dirección entre PI y -PI
  859.         IF (direccion>pi)
  860.             direccion-=2*pi;
  861.         END
  862.         IF (direccion<-pi)
  863.             direccion+=2*pi;
  864.         END
  865.         // Calcula el gráfico de la chapa de acuerdo al ángulo y la animación
  866.         cambia_grafico(id);
  867.  
  868.         IF (turno==mi_turno)
  869.             IF (movimiento==0)
  870.                 camara();       // Cámara elíptica de selección
  871.             ELSE
  872.                 camara_2();     // Cámara que sigue a la chapa
  873.             END
  874.         END
  875.         FRAME;
  876.     END
  877. END
  878.  
  879. //-----------------------------------------------------------------------------
  880. //  Proceso impacto
  881. //  Acciones de colisión
  882. //-----------------------------------------------------------------------------
  883.  
  884. PROCESS impacto();
  885.  
  886. PRIVATE
  887.     ángulo0;    // Guarda ángulos entre chapas
  888.  
  889. BEGIN
  890.     // Hace el sonido de choque
  891.     sound(sonido3,512,512);
  892.  
  893.     // Actualiza las coordenadas con el proceso que lo llamo
  894.     x=father.x;
  895.     y=father.y;
  896.  
  897.     // Coge los datos de la chapa con la que ha chocado
  898.     father.colision_chapa.id_pos_ant=punto(father.colision_chapa.x,father.colision_chapa.y);
  899.     ángulo0=get_angle(father.colision_chapa);            // Separa las chapas
  900.  
  901.     // Halla las nuevas coordenadas de la chapa y las actualiza
  902.     father.colision_chapa.x=x+get_distx(ángulo0,28);
  903.     father.colision_chapa.x_resol=father.colision_chapa.x*1000;
  904.     father.colision_chapa.y=y+get_disty(ángulo0,28);
  905.     father.colision_chapa.y_resol=father.colision_chapa.y*1000;
  906.     father.colision_chapa.fuera=FALSE;
  907.  
  908.     // Comprueba que no  halla chocado, ni llegado a la meta
  909.     posicion_chequeo(father.colision_chapa);
  910.  
  911.     // Si todavia le queda fuerza a la chapa que choco
  912.     IF (father.fuerza>fuerza_minima)
  913.         // Actualiza los datos de la chapa que choco
  914.         father.colision_chapa.fuerza=father.fuerza/2;
  915.         father.colision_chapa.direccion=ángulo0;
  916.         father.colision_chapa.movimiento=2;            // Impacto
  917.         father.colision_chapa.inclinacion=0;
  918.         father.colision_chapa.inc_inclinacion=0;
  919.  
  920.         // Modifica los datos de la chapa que choco
  921.         father.fuerza-=(father.fuerza/2);
  922.         father.inc_inclinacion=(-father.inclinacion*2)/father.fuerza;
  923.         father.direccion-=(ángulo0-father.direccion);
  924.     ELSE
  925.         IF (NOT father.colision_chapa.fuera)
  926.             signal(father.colision_chapa.id_pos_ant,s_kill);     // Elimina la posición anterior
  927.         ELSE
  928.             father.colision_chapa.movimiento=4;        // Deja el movimiento en colisión
  929.         END
  930.     END
  931. END
  932.  
  933. //-----------------------------------------------------------------------------
  934. //  Proceso cambia_grafico
  935. //  Elige y pone el gráfico de la chapa
  936. //-----------------------------------------------------------------------------
  937.  
  938. PROCESS cambia_grafico(identificador);
  939.  
  940. BEGIN
  941.  
  942.     // Cambia el gráfico dependiendo de la inclinacion
  943.     identificador.graph=(identificador.inclinacion)*8/pi;
  944.     IF (identificador.graph<-16)
  945.         identificador.graph=-16;
  946.     END
  947.     IF (identificador.graph>15)
  948.         identificador.graph=15;
  949.     END
  950.     // Si la inclinacion es 0 la dirección no es usada (graph=0) pero se usa en la animación
  951.     IF ((identificador.graph)<>0)
  952.         identificador.angle=identificador.direccion;
  953.         identificador.graph+=17;
  954.     ELSE
  955.         identificador.angle=0;
  956.         identificador.graph+=identificador.animacion;
  957.     END
  958. END
  959.  
  960. //-----------------------------------------------------------------------------
  961. //  Proceso camara
  962. //  Coloca la cámara
  963. //-----------------------------------------------------------------------------
  964.  
  965. PROCESS camara();
  966.  
  967. BEGIN
  968.     // Coge las coordenadas del proceso que lo llamo en forma circular
  969.     x=father.x+get_distx(father.direccion,140)-160;
  970.     y=father.y+get_disty(father.direccion,80)-100;
  971.     // Cuadra la cámara con los bordes de pantalla
  972.     cambia_movimiento(x,y);
  973. END
  974.  
  975. //-----------------------------------------------------------------------------
  976. //  Proceso camara_2
  977. //  Coloca la cámara
  978. //-----------------------------------------------------------------------------
  979.  
  980. PROCESS camara_2();
  981.  
  982. PRIVATE
  983.     inc_x;  // Distancia x entre la cámara y la chapa
  984.     inc_y;  // Distancia y entre la cámara y la chapa
  985.  
  986. BEGIN
  987.     // Coge los incrementos horizontales y verticales
  988.     inc_x=father.x-scroll.x0;
  989.     inc_y=father.y-scroll.y0;
  990.  
  991.     // Comprueba el movimiento horizontal
  992.     IF (inc_x>240 AND (father.direccion>-pi/2 OR father.direccion<pi/2 OR father.movimiento==3))
  993.         // Movimiento a la derecha
  994.         inc_x-=240;
  995.     ELSE
  996.         IF (inc_x<80 AND (father.direccion<-pi/2 OR father.direccion>pi/2 OR father.movimiento==3))
  997.             // Movimiento a la izquierda
  998.             inc_x-=80;
  999.         ELSE
  1000.             inc_x=0;    // Si da con un borde no hay movimientos
  1001.         END
  1002.     END
  1003.  
  1004.     // Comprueba el movimiento vertical
  1005.  
  1006.     IF (inc_y>120 AND (father.direccion>-pi OR father.direccion<0 OR father.movimiento==3))
  1007.         // Movimiento hacia abajo
  1008.         inc_y-=120;
  1009.     ELSE
  1010.         IF (inc_y<80 AND (father.direccion>0 OR father.direccion<pi OR father.movimiento==3))
  1011.         // Movimiento de pantalla hacia arriba
  1012.             inc_y-=80;
  1013.         ELSE
  1014.             inc_y=0;    // Si da con el borde no hay movimientos
  1015.         END
  1016.     END
  1017.  
  1018.     // Limita el movimiento al tamaño del mapa
  1019.     IF (scroll.x0+inc_x>ancho_mapa-320)
  1020.         inc_x=ancho_mapa-320-scroll.x0;
  1021.     END
  1022.     IF (scroll.x0+inc_x<0)
  1023.         inc_x=-scroll.x0;
  1024.     END
  1025.     IF (scroll.y0+inc_y>alto_mapa-200)
  1026.         inc_y=alto_mapa-200-scroll.y0;
  1027.     END
  1028.     IF (scroll.y0+inc_y<0)
  1029.         inc_y=-scroll.y0;
  1030.     END
  1031.     // Cambia el movimiento
  1032.     cambia_movimiento(scroll.x0+inc_x,scroll.y0+inc_y);
  1033. END
  1034.  
  1035. //-----------------------------------------------------------------------------
  1036. //  Proceso punto_control
  1037. //  Esto es usado para calcular distancia, y guarda puntos de referencia
  1038. //-----------------------------------------------------------------------------
  1039.  
  1040. PROCESS punto_control(punto_n);
  1041.  
  1042. BEGIN
  1043.     // Coge las coordenadas del punto de control del mapa
  1044.     get_point(fichero_grafico,mapa_grafico,punto_n,&x,&y);
  1045.     LOOP
  1046.         FRAME;
  1047.     END
  1048. END
  1049.  
  1050. //-----------------------------------------------------------------------------
  1051. //  Proceso rival
  1052. //  Controla la chapa de la CPU
  1053. //-----------------------------------------------------------------------------
  1054. PROCESS rival(mi_turno);
  1055.  
  1056. PRIVATE
  1057.     temporal_x;         // Crea variables temporales para simular el movimiento
  1058.     temporal_y;
  1059.     temporal_vuelta;
  1060.     temporal_control[2];
  1061.     temporal_fuerza;
  1062.     temporal_direccion;
  1063.     id_punto_control;
  1064.     punto_actual=ultimo_punto;
  1065.     punto_avance=0;     // Puntos de lanzamiento actual
  1066.     encabeza=1;         // Mira detrás
  1067.     distancia0;
  1068.     distancia1;
  1069.     distancia2;
  1070.     falta=FALSE;        // Lanzamiento fallido
  1071.  
  1072. BEGIN
  1073.     file=fichero_grafico;
  1074.     graph=17;           // Selecciona el gráfico
  1075.     ctype=c_scroll;     // Introduce al proceso dentro del scroll
  1076.     // Selecciona la posición inicial según el turno
  1077.     x=posicion_inicial_x[mi_turno-1];
  1078.     y=posicion_inicial_y[mi_turno-1];
  1079.     x_resol=x*1000;
  1080.     y_resol=y*1000;          // Guarda las coordenadas multiplicadas por 1000
  1081.  
  1082.     LOOP
  1083.         IF (turno==mi_turno AND movimiento==0)
  1084.             cambia_movimiento(x-160,y-100);
  1085.             toques=num_lanzamiento;
  1086.             FRAME;          // Actualiza la cámara
  1087.             WHILE (moviendose)
  1088.                 FRAME;
  1089.             END
  1090.  
  1091.             // Calcula el punto de control mas cercano a la chapa
  1092.             // Un punto que este delante del punto actual
  1093.             IF (punto_actual>1)
  1094.                 id_punto_control=punto_control(punto_actual-1);
  1095.             ELSE
  1096.                 id_punto_control=punto_control(ultimo_punto);
  1097.             END
  1098.             distancia0=get_dist(id_punto_control);
  1099.             signal(id_punto_control,s_kill);
  1100.  
  1101.             // Punto presente
  1102.             id_punto_control=punto_control(punto_actual);
  1103.             distancia1=get_dist(id_punto_control);
  1104.             signal(id_punto_control,s_kill);
  1105.  
  1106.             // Un punto delante del punto actual
  1107.             IF (punto_actual<ultimo_punto)
  1108.                 id_punto_control=punto_control(punto_actual+1);
  1109.             ELSE
  1110.                 id_punto_control=punto_control(1);
  1111.             END
  1112.             distancia2=get_dist(id_punto_control);
  1113.             signal(id_punto_control,s_kill);
  1114.             encabeza=1;
  1115.  
  1116.             WHILE (encabeza<>0)
  1117.                 IF (encabeza==1)           // Delante
  1118.                     punto_actual++;
  1119.                     IF (punto_actual>ultimo_punto)
  1120.                         punto_actual=1;
  1121.                     END
  1122.                     distancia0=distancia1;
  1123.                     distancia1=distancia2;
  1124.  
  1125.                     // Un punto después del punto actual
  1126.                     IF (punto_actual<ultimo_punto)
  1127.                         id_punto_control=punto_control(punto_actual+1);
  1128.                     ELSE
  1129.                         id_punto_control=punto_control(1);
  1130.                     END
  1131.                     distancia2=get_dist(id_punto_control);
  1132.                     signal(id_punto_control,s_kill);
  1133.  
  1134.                 ELSE                    // Detrás
  1135.                     punto_actual--;
  1136.                     IF (punto_actual<1)
  1137.                         punto_actual=ultimo_punto;
  1138.                     END
  1139.                     distancia2=distancia1;
  1140.                     distancia1=distancia0;
  1141.  
  1142.                     // Un punto después del punto actual
  1143.                     IF (punto_actual>1)
  1144.                         id_punto_control=punto_control(punto_actual-1);
  1145.                     ELSE
  1146.                         id_punto_control=punto_control(ultimo_punto);
  1147.                     END
  1148.                     distancia0=get_dist(id_punto_control);
  1149.                     signal(id_punto_control,s_kill);
  1150.                 END
  1151.  
  1152.                 // Comprueba que puede seguir o que ha llegado a meta
  1153.                 IF (encabeza==1)        // Avanzando
  1154.                     IF (distancia0<distancia2)
  1155.                         punto_actual--;
  1156.                         IF (punto_actual<1)
  1157.                             punto_actual=ultimo_punto;
  1158.                         END
  1159.                         encabeza=0;     // Hemos terminado
  1160.                     END
  1161.                 ELSE                    // Atrasando
  1162.                     IF (distancia0>distancia2)
  1163.                         punto_actual++;
  1164.                         IF (punto_actual>ultimo_punto)
  1165.                             punto_actual=1;
  1166.                         END
  1167.                         encabeza=0;     // Hemos terminado
  1168.                     END
  1169.                 END
  1170.             END
  1171.             // Si ese punto se puede tirar, lo elige como punto maximo
  1172.             IF (NOT falta)
  1173.                 punto_avance=avance_maximo;
  1174.             END
  1175.  
  1176.             REPEAT
  1177.                 FRAME;
  1178.                 // Haya el identificador del punto a donde tirar
  1179.                 IF ((punto_actual+punto_avance)>ultimo_punto)
  1180.                     id_punto_control=punto_control(punto_actual+punto_avance-ultimo_punto);
  1181.                 ELSE
  1182.                     id_punto_control=punto_control(punto_actual+punto_avance);
  1183.                 END
  1184.  
  1185.                 // Calcula la distancia
  1186.                 distancia0=get_dist(id_punto_control);
  1187.  
  1188.                 // Calcula la dirección
  1189.                 direccion=get_angle(id_punto_control);
  1190.                 signal(id_punto_control,s_kill);
  1191.  
  1192.                 // Calcula la fuerza
  1193.                 fuerza=fuerza_minima;
  1194.                 WHILE (distancia0>((fuerza+2)*fuerza/4))
  1195.                     fuerza+=2;
  1196.                     IF (fuerza>poder_maximo)
  1197.                         BREAK;
  1198.                     END
  1199.                 END
  1200.  
  1201.                 IF (fuerza<=poder_maximo)   // Simula el lanzamiento
  1202.                     movimiento=1;
  1203.                     fuera=FALSE;
  1204.                     temporal_x=x;
  1205.                     temporal_y=y;
  1206.                     temporal_vuelta=vuelta_actual;
  1207.                     temporal_control[0]=control[0];
  1208.                     temporal_control[1]=control[1];
  1209.                     temporal_control[2]=control[2];
  1210.                     temporal_fuerza=fuerza;
  1211.                     temporal_direccion=direccion;
  1212.  
  1213.                     // Simula el lanzamiento
  1214.                     WHILE (movimiento==1)
  1215.                         inclinacion+=inc_inclinacion;
  1216.                         direccion+=inc_inclinacion;
  1217.  
  1218.                         // Lanzamos de 2 en 2 pixels(puntos)
  1219.                         FOR (contador0=0;contador0<fuerza;contador0+=2)
  1220.                             calcula_movimiento();
  1221.                             IF (fuera)
  1222.                                 movimiento=0;   // Movimiento invalido. Para la simulación
  1223.                                 BREAK;
  1224.                             END
  1225.                         END
  1226.  
  1227.                         fuerza-=2;          // Decrementa la fuerza
  1228.                         IF (fuerza<=0)
  1229.                             fuerza=fuerza_minima;
  1230.                             movimiento=0;   // Fin del movimiento
  1231.                         END
  1232.                     END
  1233.                     // Actualiza los datos de la chapa
  1234.                     x=temporal_x;
  1235.                     y=temporal_y;
  1236.                     x_resol=x*1000;
  1237.                     y_resol=y*1000;
  1238.                     vuelta_actual=temporal_vuelta;
  1239.                     control[0]=temporal_control[0];
  1240.                     control[1]=temporal_control[1];
  1241.                     control[2]=temporal_control[2];
  1242.                 ELSE
  1243.                     fuera=TRUE;             // Lanzamiento invalido (mucha fuerza)
  1244.                 END
  1245.                 signal(id_punto_control,s_kill);
  1246.                 IF (fuera) punto_avance--; END
  1247.             UNTIL (fuera==FALSE OR punto_avance==0)
  1248.  
  1249.             FRAME;
  1250.             // Incrementa el número de tiros
  1251.             num_lanzamiento++;
  1252.             // Reinicia variables
  1253.             fuerza=temporal_fuerza;
  1254.             direccion=temporal_direccion;
  1255.             inclinacion=0;
  1256.             movimiento=1;
  1257.             id_pos_ant=punto(x,y);              // Recoge la posición actual
  1258.             fuera=FALSE;
  1259.             falta=FALSE;
  1260.             toques=num_lanzamiento;
  1261.             sound(sonido2,132+fuerza*30,700);   // Sonido de lanzamiento
  1262.         END
  1263.  
  1264.         IF (movimiento<>0)
  1265.             animacion=66-animacion;             // Anima la chapa
  1266.             SWITCH (movimiento);
  1267.  
  1268.                 CASE 1,2:
  1269.                     inclinacion+=inc_inclinacion;   // Lanzamiento o colisión
  1270.                     direccion+=inc_inclinacion;
  1271.  
  1272.                     // Lanzamos de 2 en 2 pixels(puntos)
  1273.                     FOR (contador0=0;contador0<fuerza;contador0+=2)
  1274.                         calcula_movimiento();
  1275.  
  1276.                         // Comprueba colisiones
  1277.                         IF (movimiento==1)
  1278.                             IF ((colision_chapa=collision(TYPE chapa_jugador)))
  1279.                                 impacto();
  1280.                             END
  1281.                         END
  1282.                     END
  1283.  
  1284.                     fuerza-=2;       // Decrementa la fuerza
  1285.                     IF (fuerza<=0)   // hasta que se para
  1286.                         fuerza=fuerza_minima;
  1287.  
  1288.                         IF (fuera)    // Vuelve al movimiento anterior
  1289.                             IF (movimiento<3) movimiento+=2; END
  1290.                         ELSE
  1291.                             IF (turno==mi_turno AND movimiento==1)
  1292.                                 turno++;
  1293.                                 IF (turno>num_jugadores) turno=1; END
  1294.                             END
  1295.                             signal(id_pos_ant,s_kill); // Elimina la posición anterior
  1296.                             movimiento=0;
  1297.                         END
  1298.                     END
  1299.                 END
  1300.  
  1301.                 CASE 3:
  1302.                     calcula_movimiento(); // Vuelve al lanzamiento anterior
  1303.                     falta=TRUE;
  1304.                 END
  1305.  
  1306.                 CASE 4:
  1307.                     calcula_movimiento();
  1308.                     IF ((colision_chapa=collision(TYPE chapa_jugador)))
  1309.                         impacto();       // Ha chocado con otra chapa
  1310.                     END
  1311.                 END
  1312.             END
  1313.  
  1314.         END
  1315.  
  1316.         // Calcula el gráfico de la chapa
  1317.         cambia_grafico(id);
  1318.         // Selecciona la camara que sigue a la chapa
  1319.         IF (turno==mi_turno AND movimiento<>0) camara_2(); END
  1320.         FRAME;
  1321.     END
  1322. END
  1323.  
  1324. //---------------------------------------------------------------------
  1325. // Proceso punto
  1326. // Es usado para guarda puntos y hallar distancia
  1327. //---------------------------------------------------------------------
  1328.  
  1329. PROCESS punto(x,y);
  1330.  
  1331. BEGIN
  1332.     LOOP        // Graba punto en x,y
  1333.         FRAME;  // No se cambia por fget... por el uso de variables que guardan identificadores
  1334.     END
  1335. END
  1336.  
  1337. //-----------------------------------------------------------------------------
  1338. //  Proceso camara_principal
  1339. //  Controla el movimiento del juego
  1340. //-----------------------------------------------------------------------------
  1341.  
  1342. PROCESS camara_principal();
  1343.  
  1344. PRIVATE
  1345.  
  1346.     distancia;      // Guarda la distancia de donde esta a donde deberia estar
  1347.     inc_x;          // Incremento en el movimiento horizontal y vertical
  1348.     inc_y;
  1349.     angulo_avance;  // Guarda el ángulo de avance de la cámara
  1350.  
  1351. BEGIN
  1352.     priority=-2;    // Es el ultimo proceso en ejecutarse
  1353.  
  1354.     scroll.x0=0;    // Pone las coordenadas a cero la primera vez
  1355.     scroll.y0=0;
  1356.  
  1357.     LOOP
  1358.         x=scroll.x0;// Coge las coordenadas de donde esta ahora la cámara
  1359.         y=scroll.y0;
  1360.  
  1361.             // Calcula la distancia a donde debería estar
  1362.             distancia=fget_dist(x,y,camara_x,camara_y);
  1363.  
  1364.             // Si cerca no se mueve sino que se actualiza directamente
  1365.             IF (distancia<=20)
  1366.                 scroll.x0=camara_x;
  1367.                 scroll.y0=camara_y;
  1368.                 moviendose=0;
  1369.             ELSE    // Si no se mueve la camara en la dirección correcta
  1370.                 moviendose=1;
  1371.                 angulo_avance=fget_angle(x,y,camara_x,camara_y);
  1372.                 inc_x=get_distx(angulo_avance,20);
  1373.                 inc_y=get_disty(angulo_avance,20);
  1374.                 scroll.x0+=inc_x;
  1375.                 scroll.y0+=inc_y;
  1376.             END
  1377.         FRAME;
  1378.  
  1379.     END
  1380. END
  1381.  
  1382.  
  1383.  
  1384.