home *** CD-ROM | disk | FTP | other *** search
/ MASPC 1 / MASPC_1.iso / Demos / Demo DIV / DATA / PRG / JUEGOS / SPEED.PRG < prev    next >
Encoding:
Text File  |  1997-12-01  |  37.7 KB  |  1,138 lines

  1.  
  2. //------------------------------------------------------------------------------
  3. //TITULO:      SPEED_FOR_DUMMIES
  4. //AUTOR:       DANIEL NAVARRO
  5. //FECHA        1/15/97
  6. //------------------------------------------------------------------------------
  7.  
  8. PROGRAM Speed_for_dummies;
  9.  
  10. GLOBAL
  11.     coche_1[]=8,-12,-11,10,11,12,13,14,-13; // Graficos para xgraph
  12.     coche_2[]=8,-22,-21,20,21,22,23,24,-23; // Son rotatorios en ángulos de 45 grados
  13.     coche_3[]=8,-32,-31,30,31,32,33,34,-33;
  14.     coche_4[]=8,-42,-41,40,41,42,43,44,-43;
  15.  
  16.     numero;             // Numero de puntos de control
  17.     primer_punto=44;    // Punto de control de la meta
  18.  
  19.     sluces;             // Identificadores de sonido
  20.     smotor;
  21.     scrash;
  22.     scoli;
  23.  
  24.     canal[4];           // Identificadores de canal de sonido
  25.  
  26.     opcion;             // Opcion del menu
  27.  
  28.     primero;            // Graficos de los coches del podium
  29.     segundo;
  30.     tercero;
  31.     cuarto;
  32.     nivel=0;            // Nivel de dificultad con textos
  33.     tnivel[]="FACIL","MEDIO","DIFICIL";
  34.  
  35.     recorrido=0;        // Numero de recorrido y textos
  36.     trecorrido[]="BOSQUE","DESIERTO";
  37.  
  38.     vueltas=0;          // Numero de vueltas y textos
  39.     tvueltas[]="3 VUELTAS","6 VUELTAS","9 VUELTAS";
  40.     tvueltas2[]="/3","/6","/9";
  41.  
  42.     velocidad_coches_ordenador; // En centesimas de pixel
  43.  
  44. LOCAL
  45.     velocidad;          // Velocidad coche
  46.     max_velocidad;      // Maxima velocidad
  47.     pos;                // Posicion del coche (1..4)
  48.     vuelta;             // Numero de vuelta
  49.     contador_vuelta;    // Vuelta (solo 1..n)
  50.     donde;              // Donde esta el coche coche
  51.     punto;              // Cercania al punto de control
  52.  
  53. PRIVATE
  54.     coche1;             // Identificador coche uno
  55.     coche2;             // Identificador coche dos
  56.     coche3;             // Identificador coche tres
  57.     coche4;             // Identificador coche cuatro
  58.     idobjetos;          // Identificador de objetos
  59.     fin_usuario=FALSE;  // Controla la pulsacion de la tecla de escape
  60.  
  61. BEGIN
  62.  
  63.     // Carga sonidos
  64.     sluces=load_pcm("speed\barco.pcm",0);
  65.     smotor=load_pcm("speed\tractor.pcm",1);
  66.     scrash=load_pcm("speed\choque.pcm",0);
  67.     scoli=load_pcm("speed\metal7.pcm",0);
  68.  
  69.     set_fps(32,0);  // Selecciona velocidad de muestreo
  70.  
  71.     // Carga graficos
  72.     load_fpg("speed\speed.fpg");
  73.     load_fpg("speed\pantalla.fpg");
  74.  
  75.     // Carga graficos
  76.     load_fnt("speed\menu.fnt");
  77.     load_fnt("speed\g_numero.fnt");
  78.     load_fnt("speed\g_mayusc.fnt");
  79.  
  80.     LOOP                        // Bucle principal
  81.  
  82.         load_pal("speed\pantalla.fpg"); // Carga la paleta correcta
  83.         fade_on();                      // Enciende la pantalla
  84.         put_screen(1,1);                // Pone el fondo de pantalla
  85.  
  86.         // Presentacion
  87.         file=1;
  88.         graph=5;                        // Selecciona el grafico de presentacion
  89.         flags=0;
  90.         x=160;
  91.         y=100;
  92.  
  93.         FROM size=0 TO 95 STEP 5;       // Acerca el titulo (mayor tamaño)
  94.             FRAME;
  95.         END
  96.  
  97.         menu();                         // Crea el menu principal
  98.  
  99.  
  100.         FROM size=100 TO 62 STEP -2;    // Rota el titulo y colocalo en su sitio
  101.             angle-=pi/10;
  102.             x+=5;
  103.             y+=3;
  104.             FRAME;
  105.         END
  106.  
  107.         graph=6;                            // Selecciona otro titulo de presentacion
  108.         size=100;                           // Pone valores correctos
  109.         angle=0;
  110.  
  111.         minicoche(26,128);                  // Crea el cursor en forma de minicoche
  112.  
  113.         opcion=0;                           // Pone a 0 la variable de opciones
  114.  
  115.         REPEAT                              // Bucle del menu
  116.             IF (key(_enter) OR key (_space) OR key (_control))
  117.                 opcion=(son.y-110)/18;      // Toma la posicion del minicoche
  118.             END
  119.             IF (key(_esc))                  // Si se pulsa la tecla escape, sale del programa
  120.                 opcion=4;
  121.             END
  122.             IF (opcion==3)
  123.                 menu_opciones();            // Va al menu de opciones
  124.                 opcion=0;
  125.             END
  126.             FRAME;
  127.         UNTIL (opcion<>0)
  128.  
  129.         signal(TYPE minicoche,s_kill);      // Elimina los procesos del menu
  130.         signal(TYPE menu,s_kill_tree);
  131.  
  132.         fade_off();                         // Apaga la pantalla
  133.         timer=0;
  134.         IF (opcion==4)                      // Sale al dos
  135.             put_screen(1,2);                // Imprime creditos
  136.             graph=0;                        // Borra el grafico de presentacion
  137.  
  138.             // Pone los textos de creditos
  139.             write (1,120,50,4,"- CREDITOS -");
  140.             write (1,120,75,4,"PROGRAMADOR:");
  141.             write (1,120,90,4,"DANIEL NAVARRO");
  142.             write (1,120,110,4,"GRAFICOS:");
  143.             write (1,120,125,4,"RAFAEL BARRASO");
  144.             write (1,120,145,4,"SONIDOS:");
  145.             write (1,120,160,4,"LUIS SUREDA");
  146.             write (1,120,180,4,"DIV GAMES STUDIO");
  147.             fade_on();
  148.  
  149.             // Repite hasta que se pulse una tecla
  150.             REPEAT
  151.                 FRAME;
  152.             UNTIL (scan_code<>0)
  153.             // Apaga la pantalla, borra los textos y sale del programa
  154.             fade_off();
  155.             delete_text(all_text);
  156.             exit("Gracias por jugar!",0);
  157.             FRAME;
  158.         END
  159.  
  160.         // Pone valores iniciales
  161.         velocidad_coches_ordenador=500+nivel*100;
  162.  
  163.         IF (recorrido==0)                   // Carga recorrido elegido
  164.             load_fpg("speed\bosque.fpg");
  165.             load_pal("speed\bosque.fpg");
  166.             numero=194;
  167.         ELSE
  168.             load_fpg("speed\desierto.fpg");
  169.             load_pal("speed\desierto.fpg");
  170.             numero=192;
  171.         END
  172.         canal[0]=sound(smotor,100,256);     // Inicia el sonido de motores
  173.         canal[1]=sound(smotor,100,256);
  174.  
  175.         clear_screen();                     // Borra el fondo de la pantalla
  176.  
  177.         IF (opcion==1)                      // Un jugador
  178.             canal[2]=sound(smotor,100,256);
  179.             canal[3]=sound(smotor,100,150);
  180.             define_region(1,0,0,320,64);    // Crea una region para el horizonte (montañas)
  181.             start_scroll(0,2,101,0,1,15);   // Crea el horizonte del fondo (scroll)
  182.             start_mode7(0,2,100,0,0,64);    // Crea el suelo
  183.             m7.color=203;                   // Pone diversos parametros del modo 7
  184.             m7.height=128;
  185.             m7.focus=224;
  186.  
  187.             // Crea el coche del jugador
  188.             coche1=jugador(&coche_1,0,primer_punto,_left,_right,_up,_down);
  189.  
  190.             m7.camera=coche1;               // La camara sigue al coche del jugador
  191.  
  192.             // Crea los coches manejador por el ordenador
  193.             coche2=coche(&coche_2,primer_punto+1);
  194.             coche3=coche(&coche_3,primer_punto+2);
  195.             coche4=coche(&coche_4,primer_punto+3);
  196.  
  197.             // Pone los mensajes de posicion y numero de vueltas
  198.             write(3,160,0,1,"POS");
  199.             write_int(2,160,14,1,&coche1.pos);
  200.             write(3,278,0,1,"VUELTA");
  201.             write(2,290,14,1,tvueltas2[vueltas]);
  202.             write_int(2,254,14,1,&coche1.contador_vuelta);
  203.  
  204.         ELSE                                // Dos jugadores
  205.             canal[2]=sound(smotor,100,150);
  206.             canal[3]=sound(smotor,100,150);
  207.  
  208.             define_region(1,0,0,320,16);    // Crea la region para el horizonte
  209.             define_region(2,0,0,320,99);    // Crea la region para carretera
  210.             define_region(3,0,100,320,16);  // Crea otra region para el horizonte
  211.             define_region(4,0,100,320,99);  // Crea una region para la otra carretera
  212.             start_scroll(0,2,101,0,1,15);   // Crea dos horizontes uno para cada jugador (scroll)
  213.             start_scroll(1,2,101,0,3,15);
  214.             start_mode7(0,2,100,0,2,16);    // Crea dos suelos con la carreteras (modo 7)
  215.             start_mode7(1,2,100,0,4,16);
  216.             scroll.y0=48;                   // Inicializa parametros del horizontes
  217.             scroll[1].y0=48;
  218.             m7.color=203;                   // Inicializa valores para los modos 7
  219.             m7.height=78;
  220.             m7.focus=224;
  221.             m7[1].color=203;
  222.             m7[1].height=78;
  223.             m7[1].focus=224;
  224.  
  225.             // Crea los coches de los jugadores
  226.             coche1=jugador(&coche_1,0,primer_punto,_left,_right,_up,_down);
  227.             coche2=jugador(&coche_2,1,primer_punto+1,_r,_t,_q,_a);
  228.             m7[0].camera=coche1;
  229.             m7[1].camera=coche2;             // Posiciona las camaras
  230.  
  231.             // Crea los coches manejados por el ordenador
  232.             coche3=coche(&coche_3,primer_punto+2);
  233.             coche4=coche(&coche_4,primer_punto+3);
  234.  
  235.             // Imprime los mensajes de posicion y numero de vueltas
  236.             write(3,140,-4,1,"POS");
  237.             write_int(3,170,-4,1,&coche1.pos);
  238.             write(3,140,96,1,"POS");
  239.             write_int(3,170,96,1,&coche2.pos);
  240.             write(3,260,-4,1,"VTA");
  241.             write(3,300,-4,1,tvueltas2[vueltas]);
  242.             write_int(3,285,-4,1,&coche1.contador_vuelta);
  243.             write(3,260,96,1,"VTA");
  244.             write(3,300,96,1,tvueltas2[vueltas]);
  245.             write_int(3,285,96,1,&coche2.contador_vuelta);
  246.  
  247.         END
  248.  
  249.         // Crea  los objetos del mapa
  250.         FROM z=0 TO 9;
  251.             get_point(2,100,z,&x,&y);   // Coge el punto de control del mapa
  252.             objeto(200,x,y);            // Y crea el objeto
  253.         END
  254.  
  255.         FROM z=10 TO 14;                // Crea más objetos con otros gráficos
  256.             get_point(2,100,z,&x,&y);
  257.             objeto(201,x,y);
  258.         END
  259.         FROM z=15 TO 19;
  260.             get_point(2,100,z,&x,&y);
  261.             objeto(202,x,y);
  262.         END
  263.  
  264.         minimapa();      // Muestra el minimapa del recorrido
  265.         fade_on();
  266.         priority=-1;
  267.         file=0;
  268.         graph=200;      // Pone el grafico para el semaforo
  269.         x=160;          // Y sus coordenadas
  270.         y=100;
  271.         z=-512;
  272.  
  273.         REPEAT
  274.  
  275.             // Pone las posiciones (orden de llegada) en los coches todos a uno
  276.             coche1.pos=1;
  277.             coche2.pos=1;
  278.             coche3.pos=1;
  279.             coche4.pos=1;
  280.             // Y los coloca segun orden de salida
  281.             IF (coche1.donde>coche2.donde)
  282.                 coche2.pos++;
  283.             ELSE
  284.                 coche1.pos++;
  285.             END
  286.             IF (coche1.donde>coche3.donde)
  287.                 coche3.pos++;
  288.             ELSE
  289.                 coche1.pos++;
  290.             END
  291.             IF (coche1.donde>coche4.donde)
  292.                 coche4.pos++;
  293.             ELSE
  294.                 coche1.pos++;
  295.             END
  296.  
  297.             IF (coche2.donde>coche3.donde)
  298.                 coche3.pos++;
  299.             ELSE
  300.                 coche2.pos++;
  301.             END
  302.             IF (coche2.donde>coche4.donde)
  303.                 coche4.pos++;
  304.             ELSE
  305.                 coche2.pos++;
  306.             END
  307.             IF (coche3.donde>coche4.donde)
  308.                 coche4.pos++;
  309.             ELSE
  310.                 coche3.pos++;
  311.             END
  312.  
  313.             // Sube o baja la velocidad de los coches controlados por el ordenador
  314.             // Dependiendo de si van detras o delante del coche de los jugadores
  315.             IF (opcion==1)
  316.                 IF (coche1.pos==1)
  317.                     IF (coche4.max_velocidad<velocidad_coches_ordenador+64)
  318.                         coche2.max_velocidad++;
  319.                         coche3.max_velocidad++;
  320.                         coche4.max_velocidad++;
  321.                     END
  322.                 END
  323.                 IF (coche1.pos==4)
  324.                     IF (coche4.max_velocidad>velocidad_coches_ordenador-64)
  325.                         coche2.max_velocidad--;
  326.                         coche3.max_velocidad--;
  327.                         coche4.max_velocidad--;
  328.                     END
  329.                 END
  330.             ELSE
  331.                 IF (coche1.pos+coche2.pos==3)
  332.                     IF (coche4.max_velocidad<velocidad_coches_ordenador+64)
  333.                         coche3.max_velocidad++;
  334.                         coche4.max_velocidad++;
  335.                     END
  336.                 END
  337.                 IF (coche1.pos+coche2.pos==7)
  338.                     IF (coche4.max_velocidad>velocidad_coches_ordenador-64)
  339.                         coche3.max_velocidad--;
  340.                         coche4.max_velocidad--;
  341.                     END
  342.                 END
  343.                 IF (coche1.pos<coche2.pos)
  344.                     coche1.max_velocidad=700;
  345.                     coche2.max_velocidad=900;
  346.                 ELSE
  347.                     coche1.max_velocidad=900;
  348.                     coche2.max_velocidad=700;
  349.                 END
  350.             END
  351.  
  352.             // Controla el semaforo inicial
  353.             IF (timer>800 AND timer<900)
  354.                 graph=0;
  355.                 signal(idobjetos,s_kill);
  356.                 timer=900;
  357.             ELSE
  358.                 IF (timer>600 AND timer<700)
  359.                     sound(sluces,1000,500);
  360.                     sound(sluces,1000,256);
  361.                     idobjetos.x+=56;
  362.  
  363.                     idobjetos.graph++;
  364.                     flags=4;
  365.                     timer=700;
  366.                 ELSE
  367.                     IF (timer>400 AND timer<500)
  368.                         sound(sluces,200,256);
  369.                         idobjetos.x+=56;
  370.                         timer=500;
  371.                     ELSE
  372.                         IF (timer>200 AND timer<300)
  373.                             sound(sluces,200,256);
  374.                             idobjetos=objeto2(201,103,100,-600); // Luz verde
  375.                             timer=300;
  376.                         END
  377.                     END
  378.                 END
  379.             END
  380.  
  381.             // Lee la tecla escape y pone la variable de salida a True(Verdadero)
  382.             IF (key(_esc)) fin_usuario=TRUE; END
  383.  
  384.             FRAME;
  385.         // Repite hasta que el o los coches protagonistas acaben o se pulse la tecla escape y el usuario acabe
  386.         UNTIL ((coche1.vuelta==vueltas*3+4 AND opcion==1) OR (coche1.vuelta>=vueltas*3+4 AND coche2.vuelta>=vueltas*3+4) OR fin_usuario)
  387.  
  388.         IF (fin_usuario)    // Si se ha acabado por la tecla escape apaga la pantalla (a negro)
  389.             fade_off();
  390.         ELSE                // Si es porque se acabo la carrera apaga la pantalla de otra manera
  391.             fade(0,0,0,1);
  392.             WHILE (fading)  // Espera hasta que se apage la pantalla
  393.                 FRAME;
  394.             END
  395.         END
  396.  
  397.         // Elimina todos los procesos, horizontes(scroll) o modos 7 del juego
  398.         unload_fpg(2);
  399.         graph=0;
  400.         signal(id,s_kill_tree);
  401.         signal(id,s_wakeup);
  402.         delete_text(all_text);
  403.         stop_sound(all_sound);
  404.         stop_scroll(0);
  405.         stop_scroll(1);
  406.         stop_mode7(0);
  407.         stop_mode7(1);
  408.  
  409.         // Podium
  410.         IF (NOT fin_usuario)
  411.             put_screen(0,400);                  // Pone la pantalla de fondo
  412.             objeto2(401,119,163,0);              // Podium
  413.  
  414.             // Enseña los mensaje de Ganador o Perdedor
  415.             IF (opcion==1)
  416.                 IF (coche1.pos==1)
  417.                     objeto2(402,160,16,0);       // Ha ganado
  418.                 ELSE
  419.                     objeto2(403,160,16,0);       // Ha perdido
  420.                 END
  421.             ELSE
  422.                 IF (coche1.pos==1)
  423.                     objeto2(404,168,34,0);       // Jugador 1 ha ganado
  424.                 ELSE
  425.                     IF (coche2.pos==1)
  426.                         objeto2(405,168,34,0);   // Jugador 2 ha ganado
  427.                     ELSE
  428.                         objeto2(406,160,16,0);   // Han perdido
  429.                     END
  430.                 END
  431.             END
  432.  
  433.             // Informacion del recorrido
  434.             write(3,260,76,4,trecorrido[recorrido]);
  435.             write(3,260,92,4,tnivel[nivel]);
  436.             write(3,260,108,4,tvueltas[vueltas]);
  437.  
  438.             // Muestra los coches en el podium
  439.             selecciona_posicion(coche1.pos,coche1.xgraph);
  440.             selecciona_posicion(coche2.pos,coche2.xgraph);
  441.             selecciona_posicion(coche3.pos,coche3.xgraph);
  442.             selecciona_posicion(coche4.pos,coche4.xgraph);
  443.             podium_coches(primero,120,118);
  444.             podium_coches(segundo,120-80,118+16);
  445.             podium_coches(tercero,120+80,118+32);
  446.             objeto2([cuarto+3],280,220,1);     // Coche destruido (el ultimo)
  447.             fade_on();
  448.  
  449.             // Espera a pulsar la tecla enter
  450.             WHILE (NOT key(_esc) AND NOT key(_enter))
  451.                 humo(280+rand(-8,8),210+rand(-8,8));
  452.                 FRAME;
  453.             END
  454.  
  455.             // Borra y elimina todos los procesos en pantalla
  456.             fade_off();
  457.             delete_text(all_text);
  458.             signal(id,s_kill_tree);
  459.             signal(id,s_wakeup);
  460.         ELSE
  461.             fin_usuario=FALSE;
  462.         END
  463.     END
  464. END
  465.  
  466. //------------------------------------------------------------------------------
  467. // Proceso menu_opciones
  468. // Controla el menu de opciones
  469. //------------------------------------------------------------------------------
  470.  
  471. PROCESS menu_opciones();
  472.  
  473. PRIVATE
  474.     texto[3];               // Identificadores para texto
  475.     enter_presionado=FALSE; // Controla la pulsacion de la tecla -enter-
  476.  
  477. BEGIN
  478.  
  479.     // Escribe los textos de las opciones
  480.     texto[0]=write(1,0,0,4,tnivel[nivel]);
  481.     texto[1]=write(1,0,0,4,trecorrido[recorrido]);
  482.     texto[2]=write(1,0,0,4,tvueltas[vueltas]);
  483.     texto[3]=write(1,0,0,4,"SALIR");
  484.  
  485.     // Para otros procesos
  486.     signal(father,s_freeze);
  487.     signal(TYPE minicoche,s_sleep);
  488.  
  489.     file=1;
  490.     graph=7;
  491.     x=104;
  492.     y=-40;              // Selecciona grafico y coordenadas
  493.     sombra_menu();      // Crea una sombra al menu
  494.     WHILE (y<45)        // Baja el menu con los textos
  495.         y+=4;
  496.         move_text(texto[0],104,y-28);
  497.         move_text(texto[1],104,y-28+18);
  498.         move_text(texto[2],104,y-28+18*2);
  499.         move_text(texto[3],104,y-28+18*3);
  500.         FRAME;
  501.     END
  502.     minicoche(26,21);     // Pone dos cursores uno a cada lado
  503.     minicoche(182,21);
  504.     LOOP
  505.         IF (key(_enter))                // Comprueba si se pulsa la tecla enter (intro)
  506.             IF (NOT enter_presionado)   // Hace que se ejecute solo una vez
  507.                 SWITCH ((son.y-3)/18);  // Coge la posicion del cursor
  508.                     CASE 1:
  509.                         delete_text(texto[0]);  // Borra texto antiguo
  510.                         nivel=(nivel+1)%3;      // Cambia el nivel de dificultad
  511.                         texto[0]=write(1,104,y-28,4,tnivel[nivel]);
  512.                     END
  513.                     CASE 2:
  514.                         delete_text(texto[1]);
  515.                         recorrido=++recorrido MOD 2;    // Cambia el recorrido
  516.                         texto[1]=write(1,104,y-28+18,4,trecorrido[recorrido]);
  517.                     END
  518.                     CASE 3:
  519.                         delete_text(texto[2]);
  520.                         vueltas=++vueltas MOD 3;      // Cambia el numero de vueltas
  521.                         texto[2]=write(1,104,y-28+18*2,4,tvueltas[vueltas]);
  522.                     END
  523.                     DEFAULT:
  524.                         BREAK;                  // Sale del menú de opciones
  525.                     END
  526.                 END
  527.                 enter_presionado=TRUE;          // Hace que se ejecute solo una vez
  528.             END
  529.         ELSE
  530.             enter_presionado=FALSE;
  531.         END
  532.         IF (key(_esc))                          // Si se pulsa escape se sale del menu
  533.             BREAK;
  534.         END
  535.         FRAME;
  536.     END
  537.     signal(TYPE minicoche,s_sleep);             // Duerme a los procesos minicoches
  538.     FROM y=45 TO -40 STEP -4;        // Sube el menu
  539.         move_text(texto[0],104,y-28);
  540.         move_text(texto[1],104,y-28+18);
  541.         move_text(texto[2],104,y-28+18*2);
  542.         move_text(texto[3],104,y-28+18*3);
  543.         FRAME;
  544.     END
  545.  
  546.     // Borra todos los procesos del menu de opciones
  547.     delete_text(all_text);
  548.     signal(father,s_wakeup);
  549.     signal(TYPE minicoche,s_wakeup);
  550.     signal(id,s_kill_tree);
  551. END
  552.  
  553. //------------------------------------------------------------------------------
  554. // Proceso objeto
  555. // Muestra un grafico cogiendo sus datos como parametros
  556. //------------------------------------------------------------------------------
  557.  
  558. PROCESS objeto2(graph,x,y,z);
  559.  
  560. BEGIN
  561.     LOOP
  562.         FRAME;
  563.     END
  564. END
  565.  
  566. //------------------------------------------------------------------------------
  567. // Proceso podium_coches
  568. // Muestra los graficos del coche en el podium
  569. //------------------------------------------------------------------------------
  570.  
  571. PROCESS podium_coches(xgraph,x,y);
  572.  
  573. BEGIN
  574.     size=50;            // A la mitad de tamaño
  575.     LOOP
  576.         angle+=pi/12;   // Rota el grafico
  577.         FRAME;
  578.     END
  579. END
  580.  
  581. //------------------------------------------------------------------------------
  582. // Proceso selecciona_posicion
  583. // Selecciona la posicion de los coches en el podium
  584. //------------------------------------------------------------------------------
  585.  
  586. PROCESS selecciona_posicion(pos,xgraph);
  587.  
  588. BEGIN
  589.     SWITCH (pos);           // Asigna las tablas de gráficos según la posición
  590.         CASE 1:
  591.             primero=xgraph;
  592.         END
  593.         CASE 2:
  594.             segundo=xgraph;
  595.         END
  596.         CASE 3:
  597.             tercero=xgraph;
  598.         END
  599.         CASE 4:
  600.             cuarto=xgraph;
  601.         END
  602.     END
  603. END
  604.  
  605. //------------------------------------------------------------------------------
  606. // Proceso menu
  607. // Muestra los graficos del menu
  608. //------------------------------------------------------------------------------
  609.  
  610. PROCESS menu();
  611.  
  612. BEGIN
  613.     file=1;
  614.     graph=3;
  615.     x=104;
  616.     y=155;                      // Selecciona grafico y coordenadas
  617.     sombra_menu();              // Crea una sombra al menu
  618.  
  619.     FROM size=0 TO 95 STEP 5;
  620.         FRAME;                  // Haz el menu cada vez mas grande hasta su tamaño
  621.     END
  622.     LOOP
  623.         FRAME;
  624.     END
  625. END
  626.  
  627. //------------------------------------------------------------------------------
  628. // Proceso sombra_menu
  629. // Muestra una sombra en los menus
  630. //------------------------------------------------------------------------------
  631.  
  632. PROCESS sombra_menu();
  633.  
  634. BEGIN
  635.     FRAME(0);   // Espera al proceso de menu que lo ha llamado
  636.     file=1;
  637.     graph=4;
  638.     flags=4;    // Pone transparencia
  639.     z=1;        // Lo pone al fondo
  640.     priority=-1;
  641.     LOOP
  642.         x=father.x;
  643.         y=father.y;
  644.         size=father.size;
  645.         FRAME;             // Selecciona respecto al menu que lo llamo
  646.     END
  647. END
  648.  
  649. //------------------------------------------------------------------------------
  650. // Proceso minicoche
  651. // Muestra y controla el cursor ( coche pequeño)
  652. //------------------------------------------------------------------------------
  653.  
  654. PROCESS minicoche(x,arriba);
  655.  
  656. PRIVATE
  657.     cont_graficos=0;    // Contador de gráficos
  658.  
  659. BEGIN
  660.     file=1;
  661.     y=arriba;   // Coordenada vertical inicial
  662.     LOOP     // Lee teclas
  663.         IF (key(_down)AND y<arriba+18*3)
  664.             y+=18;  // Baja
  665.         END
  666.         IF (key(_up)AND y>arriba)
  667.             y-=18;  // SUbe
  668.         END
  669.         cont_graficos++;
  670.         cont_graficos=cont_graficos MOD 8; // Hace que vaya de 8 en 8
  671.         graph=10+cont_graficos;     // Anima el grafico
  672.         FRAME(200);
  673.     END
  674. END
  675.  
  676. //------------------------------------------------------------------------------
  677. // Proceso jugador
  678. // Maneja el coche del jugador
  679. // Entradas:
  680. //      pant             = numero de movimiento horizontal
  681. //      punto            = Punto de control de comienzo
  682. //      izquierda..abajo = teclas de control
  683. //------------------------------------------------------------------------------
  684.  
  685. PROCESS jugador(xgraph,pant,punto,izquierda,derecha,arriba,abajo);
  686.  
  687. PRIVATE
  688.     hvelocidad; // Altura para los saltos de los coches
  689.     color;      // Mapa de textura
  690.     id2;        // Identificador de coches
  691.     contador0;  // Contador de uso general y distancia entre coches
  692.     s_volumen;  // Volumen de los sonidos
  693.     cont_canal; // Contador de canal
  694.  
  695. BEGIN
  696.     // Inicia las variables
  697.     max_velocidad=800;
  698.     velocidad=0;
  699.     vuelta=1;
  700.  
  701.     // Coge la posición de salida de un punto de control
  702.     get_point(2,100,punto,&x,&y);
  703.  
  704.     // Pone las coordenadas con resolucion (*100)
  705.     resolution=100;
  706.     x=x*resolution;
  707.     y=y*resolution;
  708.     ctype=c_m7;                 // Coge la posicion de inicio
  709.  
  710.     sombra();                   // Crea la sombra del coche
  711.     bola([xgraph+7]+1,id);      // Crea los graficos del mapa pequeño
  712.  
  713.     donde=busca_donde();        // Toma la posicion en carrera inicial
  714.     WHILE (timer<700)           // Espera a acabar el semaforo
  715.         FRAME;
  716.     END
  717.  
  718.     LOOP
  719.         // Cambia el sonido del motor dependiendo de la velocidad
  720.         change_sound(canal[3-pant],200,abs(velocidad)+150);
  721.  
  722.         // Mira en que posición de carrera esta
  723.         donde=busca_donde();
  724.  
  725.         IF (key(izquierda))                     // Comprueba la tecla usada para la izquierda
  726.             scroll[pant].x0-=max_velocidad/64;  // Mueve el horizonte
  727.             angle+=pi/(51200/max_velocidad);    // Cambia la direccion del coche
  728.         END
  729.  
  730.         IF (key(derecha))                       // Comprueba la tecla usada para la derecha
  731.             scroll[pant].x0+=max_velocidad/64;
  732.             angle-=pi/(51200/max_velocidad);
  733.         END
  734.  
  735.         // Comprueba la tecla usada para arriba (acelerar)
  736.         IF (key(arriba)AND velocidad<max_velocidad)
  737.             velocidad+=max_velocidad/50;    // Acelera
  738.         END
  739.  
  740.         // Comprueba la tecla usada para arriba (frenar)
  741.         IF (key(abajo)AND velocidad>-max_velocidad/2)
  742.             velocidad-=max_velocidad/50;    // Frena
  743.         END
  744.  
  745.         advance(velocidad);                 // Hace avanzar al coche
  746.  
  747.         // Limites de velocidad
  748.         IF (velocidad>max_velocidad/100)
  749.             velocidad-=max_velocidad/100;
  750.         ELSE
  751.             IF (velocidad<-max_velocidad/100)
  752.                 velocidad+=max_velocidad/100;
  753.             ELSE
  754.                 velocidad=0;
  755.             END
  756.         END
  757.  
  758.         // Colision entre los coches manejados por el jugador
  759.         IF (id2=get_id(TYPE jugador))   // Coge el identificador del jugador
  760.             contador0=get_dist(id2);    // Mira si esta a menos de 16 puntos
  761.             IF (contador0<1600)         // Han chocado
  762.                 IF(timer[2]>60)         // Pone el sonido de colision
  763.                     timer[2]=0;
  764.                     sound(scoli,500,256);
  765.                 END
  766.  
  767.                 IF (donde<id2.donde)    // El coche esta por detras
  768.                     IF (velocidad>0)
  769.                         velocidad=velocidad*9/10;   // Frena un poco
  770.                     END
  771.                 ELSE
  772.                     IF (id2.velocidad>0)
  773.                         id2.velocidad=id2.velocidad*9/10;
  774.                     END
  775.                 END
  776.                 IF (rand(0,10)==0)                  // De vez en cuando echa humo
  777.                     humo((x+id2.x)/200,(y+id2.y)/200);
  778.                 END
  779.             END
  780.         END
  781.  
  782.         // Colisiona con los coches manejados por el ordenador
  783.         cont_canal=0;
  784.         WHILE (id2=get_id(TYPE coche))
  785.             contador0=get_dist(id2);    // Coge la distancia hasta el coche del ordenador
  786.             s_volumen=contador0/16;     // Sonido de motor
  787.             IF (s_volumen>600) s_volumen=600; END
  788.             change_sound(canal[cont_canal],600-s_volumen,700);
  789.             cont_canal++;
  790.             IF (contador0<1600)         // Hay colision
  791.                 IF(timer[1]>60)         // Para el sonido de colision
  792.                     timer[1]=0;
  793.                     sound(scoli,500,256);
  794.                 END
  795.                 IF (donde<id2.donde)
  796.                     IF (velocidad>0)
  797.                         velocidad=velocidad*9/10;   // Frena al coche
  798.                     END
  799.                 ELSE
  800.                     IF (id2.velocidad>0)
  801.                         id2.velocidad=id2.velocidad*9/10;
  802.                     END
  803.                 END
  804.                 // Hecha un poco de humo aleatoriamente
  805.                 IF (rand(0,10)==0)
  806.                     humo((x+id2.x)/200,(y+id2.y)/200);
  807.                 END
  808.             END
  809.         END
  810.  
  811.         // Coge el color del mapa de durezas de donde esta el coche
  812.         color=map_get_pixel(2,100,x/100,y/100);
  813.  
  814.         IF (color<208 AND color>191)    // Comprueba si se ha salido de la carretera
  815.             sound(scrash,1000,256);
  816.             change_sound(canal[3-pant],100,150); // Cambia el sonido de motor
  817.             // Hace un poco de humo
  818.             FROM contador0=0 TO 9;
  819.                 humo(x/100+rand(-8,8),y/100+rand(-8,8));
  820.             END
  821.  
  822.             velocidad=-velocidad/6;     // Quita velocidad
  823.             hvelocidad=24;
  824.             REPEAT                      // Hace que haga un salto
  825.                 FRAME;
  826.                 advance(velocidad);
  827.                 height+=hvelocidad;
  828.                 hvelocidad-=4;
  829.             UNTIL (height<0)
  830.  
  831.             height=12;
  832.             hvelocidad=12;
  833.             REPEAT                      // Hace otros saltos más pequeños
  834.  
  835.                 FRAME;
  836.                 advance(velocidad);
  837.                 height+=hvelocidad;
  838.                 hvelocidad-=4;
  839.             UNTIL (height<0)
  840.  
  841.             height=0;
  842.         END
  843.         FRAME;
  844.     END
  845. END
  846.  
  847. //------------------------------------------------------------------------------
  848. // Proceso sombra
  849. // Crea la sombra de los coches
  850. //------------------------------------------------------------------------------
  851.  
  852. PROCESS sombra();
  853.  
  854. BEGIN
  855.     ctype=c_m7;
  856.     graph=100;
  857.     flags=4;        // Selecciona grafico
  858.     resolution=100; // Pone la resolución de coordenadad igual que el proceso padre
  859.     priority=-1;    // Hace que el proceso despues del coche
  860.     z=1;            // Pinta por debajo del coche
  861.     LOOP
  862.         x=father.x; // Sigue al coche
  863.         y=father.y;
  864.         FRAME;
  865.     END
  866. END
  867.  
  868. //------------------------------------------------------------------------------
  869. // Proceso humo
  870. // Crea el humo del coche
  871. //------------------------------------------------------------------------------
  872.  
  873. PROCESS humo(x,y);
  874.  
  875. BEGIN
  876.     ctype=father.ctype; // Dentro del modo 7, como el padre
  877.     graph=101;
  878.     flags=4;            // Seleccion grafico
  879.     REPEAT
  880.         IF (ctype==c_m7)
  881.             height+=4;  // Altura del modo 7
  882.         ELSE
  883.             y-=2;       // Altura en la pantalla
  884.         END
  885.         size-=5;        // Cada vez mas pequeño
  886.  
  887.         FRAME;
  888.     UNTIL (size<=0)
  889. END
  890.  
  891. //------------------------------------------------------------------------------
  892. // Proceso coche
  893. // Controla coches manejados por el ordenador
  894. // Entradas: punto = Punto de control de inicio
  895. //------------------------------------------------------------------------------
  896.  
  897. PROCESS coche(xgraph,punto);
  898.  
  899. PRIVATE
  900.     siguiente_p;    // Siguiente punto de control
  901.     siguiente_p_x;  // Coordenadas de siguiente punto de control
  902.     siguiente_p_y;
  903.  
  904. BEGIN
  905.     // Reincia variables
  906.     max_velocidad=velocidad_coches_ordenador;
  907.     velocidad=0;
  908.     vuelta=1;
  909.  
  910.     get_point(2,100,punto,&x,&y);   // Coge la posicion inicial
  911.     siguiente_p=punto+2;            // Coge el siguiente punto de control
  912.  
  913.     resolution=100;
  914.     x*=resolution;
  915.     y*=resolution;
  916.     ctype=c_m7;                     // Pone coordenadas
  917.  
  918.     sombra();               // Crea la sombra del coche
  919.     bola([xgraph+7]+1,id);  // Crea la bola del minimapa del coche
  920.  
  921.     // Coge el siguiente punto de control en el mapa de modo 7
  922.     get_point(2,100,siguiente_p,&siguiente_p_x,&siguiente_p_y);
  923.     siguiente_p_x*=100;
  924.     siguiente_p_y*=100;
  925.  
  926.     donde=busca_donde();    // Toma la posicion en la carrera inicial
  927.     WHILE (timer<700)       // Espera a la señal del semaforo
  928.         FRAME;
  929.     END
  930.  
  931.     LOOP
  932.  
  933.         // Mira en que posición se encuentra el coche en la carrera
  934.         donde=busca_donde();
  935.  
  936.         // Halla y guarda el ángulo del siguiente punto de control dentro del mapa de modo 7
  937.         angle=fget_angle(x,y,siguiente_p_x,siguiente_p_y);
  938.  
  939.         advance(velocidad);             // Mueve el coche en el ángulo elegido
  940.  
  941.         IF (velocidad<max_velocidad)    // Limites de velocidad
  942.             velocidad+=10;
  943.         END
  944.         IF (velocidad>max_velocidad)
  945.             velocidad=max_velocidad;
  946.         END
  947.  
  948.         // Cuando el coche esta cerca del punto de control
  949.         IF (fget_dist(x,y,siguiente_p_x,siguiente_p_y)<1600)
  950.             siguiente_p+=2;             // Incrementa el contador de puntos de control
  951.  
  952.             IF (rand(0,8)==0)           // Cambia la trayectoria
  953.                 siguiente_p=(siguiente_p&-2)+rand(0,1);
  954.             END
  955.  
  956.             IF (siguiente_p>=primer_punto+numero) // Avanza una vuelta
  957.                 siguiente_p-=numero;
  958.             END
  959.  
  960.             // Coge el siguiente punto de control
  961.             get_point(2,100,siguiente_p,&siguiente_p_x,&siguiente_p_y);
  962.             siguiente_p_x*=100;
  963.             siguiente_p_y*=100;
  964.         END
  965.         FRAME;
  966.     END
  967. END
  968.  
  969. //------------------------------------------------------------------------------
  970. // Proceso objeto
  971. // Pone los objetos dentro del recorrido
  972. //------------------------------------------------------------------------------
  973.  
  974. PROCESS objeto(graph,x,y);
  975.  
  976. BEGIN
  977.     file=2;
  978.     ctype=c_m7;    // Selecciona fichero y tipo de scroll
  979.     LOOP
  980.         FRAME;
  981.     END
  982. END
  983.  
  984. //------------------------------------------------------------------------------
  985. // Proceso minimapa
  986. // Muestra un pequeño mapa
  987. //------------------------------------------------------------------------------
  988.  
  989. PROCESS minimapa();
  990.  
  991. BEGIN
  992.     x=36;
  993.     y=36;
  994.     file=2;
  995.     z=1;
  996.     flags=4;
  997.     graph=104;          // Selecciona grafico y coordenadas
  998.  
  999.     IF (opcion==2)      // Para dos jugadores
  1000.         CLONE
  1001.             y+=100;     // Crea otro minimapa más abajo
  1002.         END
  1003.     END
  1004.  
  1005.     LOOP
  1006.         FRAME;
  1007.     END
  1008. END
  1009.  
  1010. //------------------------------------------------------------------------------
  1011. // Proceso bola
  1012. // Muestra los coches que son bolas en el minimapa
  1013. //------------------------------------------------------------------------------
  1014.  
  1015. PROCESS bola(graph,idcoche);
  1016.  
  1017. PRIVATE
  1018.     coord_y=0;      // Posicion y
  1019.  
  1020. BEGIN
  1021.     IF (opcion==2)          // Para dos jugadores
  1022.         CLONE
  1023.             coord_y=100;    // Crea otra bola más abajo
  1024.         END
  1025.     END
  1026.  
  1027.     LOOP
  1028.         x=idcoche.x/1600+4;
  1029.         y=idcoche.y/1600+4+coord_y;     // Actualiza coordenadas respecto al coche
  1030.         FRAME;
  1031.     END
  1032. END
  1033.  
  1034. //------------------------------------------------------------------------------
  1035. // Proceso busca_donde
  1036. // Retorna la posicion dentro de la carrera
  1037. //------------------------------------------------------------------------------
  1038.  
  1039. PROCESS busca_donde();
  1040.  
  1041. PRIVATE
  1042.     distancia=0;    // Distancia al punto de control
  1043.  
  1044.     min_punto=0;    // Posiciones de los puntos dentro de la carrera
  1045.     min_donde1=0;
  1046.     min_donde2=0;
  1047.     min_donde3=0;
  1048.  
  1049.     min_distancia1=-1; // Distancia a min_donde1
  1050.     min_distancia2=-1; // Distancia a min_donde2
  1051.     min_distancia3=-1; // Distancia a min_donde3
  1052.  
  1053.  
  1054. BEGIN
  1055.     vuelta=father.vuelta;
  1056.     punto=(father.punto&-2)-10; // Coge 5 puntos de control por detras y por delante
  1057.  
  1058.     IF (punto<primer_punto)     // Mueve una vuelta para atras
  1059.         punto+=numero;
  1060.         vuelta--;
  1061.     END
  1062.  
  1063.     FROM z=0 TO 10;             // Coge los tres puntos de control mas cercanos
  1064.         get_point(2,100,punto,&x,&y);
  1065.  
  1066.         distancia=fget_dist(father.x/100,father.y/100,x,y);
  1067.  
  1068.         IF (distancia>512)      // Si el punto esta muy lejos
  1069.             distancia=0;        // No lo cojas
  1070.         ELSE
  1071.             distancia=512-distancia;
  1072.         END
  1073.  
  1074.         // Ordena las distancias segun cercania
  1075.         IF (distancia>min_distancia1)
  1076.             min_donde3=min_donde2;
  1077.             min_distancia3=min_distancia2;
  1078.             min_donde2=min_donde1;
  1079.             min_distancia2=min_distancia1;
  1080.             min_punto=punto;
  1081.             min_donde1=punto+vuelta*200;
  1082.             min_distancia1=distancia;
  1083.         ELSE
  1084.             IF (distancia>min_distancia2)
  1085.                 min_donde3=min_donde2;
  1086.                 min_distancia3=min_distancia2;
  1087.                 min_donde2=punto+vuelta*200;
  1088.                 min_distancia2=distancia;
  1089.             ELSE
  1090.                 IF (distancia>min_distancia3)
  1091.                     min_donde3=punto+vuelta*200;
  1092.                     min_distancia3=distancia;
  1093.                 END
  1094.  
  1095.             END
  1096.         END
  1097.         IF ((punto+=2)>=primer_punto+numero)    // Avanza una vuelta
  1098.             punto-=numero;
  1099.             vuelta++;
  1100.         END
  1101.     END
  1102.  
  1103.     // Controla el paso por meta
  1104.     IF (min_punto+numero/2<father.punto)        // Hacia delante
  1105.         father.vuelta++;
  1106.     END
  1107.  
  1108.     IF (min_punto>father.punto+numero/2)        // Hacia atras
  1109.         father.vuelta--;
  1110.     END
  1111.  
  1112.     // Normaliza las vueltas
  1113.     IF (father.vuelta<1)
  1114.         father.contador_vuelta=1;
  1115.     ELSE
  1116.         IF (father.vuelta>vueltas*3+3)
  1117.             father.contador_vuelta=vueltas*3+3;
  1118.         ELSE
  1119.             father.contador_vuelta=father.vuelta;
  1120.         END
  1121.     END
  1122.  
  1123.     // Actualiza el punto del proceso que le ha llamado
  1124.     father.punto=min_punto;
  1125.  
  1126.     distancia=min_distancia1+min_distancia2+min_distancia3;
  1127.  
  1128.     IF (distancia<>0)    // Interpola los puntos (hace media ponderada)
  1129.         donde=(min_donde1*100*min_distancia1+min_donde2*100*min_distancia2+min_donde3*100*min_distancia3)/distancia;
  1130.     ELSE
  1131.         donde=min_donde3;
  1132.     END
  1133.  
  1134.     RETURN(donde);      // Retorna el punto donde se encuentra
  1135.  
  1136. END
  1137.  
  1138.