uses grafix, jinput, utext, tipos, crt; procedure FaseNova;forward; {##############################################################} {# O F F S E T M A P A #} {##############################################################} function OffsetMapa:longint; var i:longint; fich : file of byte; buffer : byte; marca : integer; begin i := 0; Assign(fich, 'runner.exe'); Reset(fich); marca := 0; repeat Read(fich, buffer); inc(i); if buffer = ord('*') then inc(marca) else marca := 0; until (marca = 10); OffsetMapa := i; end; {##############################################################} {# C A R R E G A R E C O R D S #} {##############################################################} procedure CarregaRecords; var fich : file of byte; buffer : byte; begin Assign(fich, 'runner.exe'); Reset(fich); Seek(fich, FileSize(fich)-6); Read(fich, buffer); { centenes } hi_score := buffer * 100; Read(fich, buffer); { decenes } hi_score := hi_score + (buffer * 10); Read(fich, buffer); { unitats } hi_score := hi_score + buffer; Read(fich, buffer); { 1¦ lletra } nom_hi_score := chr(buffer+45); Read(fich, buffer); { 2¦ lletra } nom_hi_score := nom_hi_score + chr(buffer+45); Read(fich, buffer); { 3¦ lletra } nom_hi_score := nom_hi_score + chr(buffer+45); Close(fich); end; {##############################################################} {# G U A R D A R E C O R D S #} {##############################################################} procedure GuardaRecords; var fich : file of byte; buffer : byte; begin Assign(fich, 'runner.exe'); Reset(fich); Seek(fich, FileSize(fich)-6); buffer := score div 100; Write(fich, buffer); { centenes } buffer := (score - (buffer*100)) div 10; Write(fich, buffer); { decenes } buffer := (score - (buffer*10)); Write(fich, buffer); { unitats } buffer := ord(nom_hi_score[1])-45; Write(fich, buffer); { 1¦ lletra } buffer := ord(nom_hi_score[2])-45; Write(fich, buffer); { 2¦ lletra } buffer := ord(nom_hi_score[3])-45; Write(fich, buffer); { 3¦ lletra } Close(fich); end; {##############################################################} {# T R A G A P A N T A L L A #} {##############################################################} procedure TragaPantalla; begin for k:=0 to 23 do begin { despla‡a cap avall } for i:=0 to 39 do for j:=23 downto 1 do begin mem[pant1:(i shl 1)+(j*80)] := mem[pant1:(i shl 1)+((j-1)*80)]; mem[pant1:(i shl 1)+1+(j*80)] := mem[pant1:(i shl 1)+1+((j-1)*80)]; end; espera_VGA;espera_VGA;espera_VGA; move(mem[pant1:0], mem[$B800:0], 2000); GotoXY(1,1); TextBackGround(Blue); TextColor(LightGray); Write('LEVEL ', level:2, ' SCORE ', score:3, ' LIVES ', pepe.vides:1); GotoXY(13,2); Write('HI-SCORE ', hi_score:3, ' ', nom_hi_score); end; end; {##############################################################} {# P O S A R N O M #} {##############################################################} procedure PosarNom; var index : integer; Key : byte; Tecla : Pchar; begin nom_hi_score := '...'; index := 1; PutStringCENTERED(13, 15, 'Enhorabona, has'); PutStringCENTERED(14, 15, 'aconseguit un nou record'); PutStringCENTERED(16, 15, nom_hi_score); repeat if QTeclaPuls then begin Key := AgarrarTecla; Tecla := nomTECLES[Key]; nom_hi_score[index] := Tecla^; inc(index); PutStringCENTERED(16, 15, nom_hi_score); repeat until not(QTeclaPuls); end; until (index = 4); GuardaRecords; end; {##############################################################} {# G A M E O V E R #} {##############################################################} procedure GameOver; begin pepe.vides := 0; TragaPantalla; cls($B800); PutStringCENTERED(10, 15, 'G A M E O V E R'); for i:=0 to 100 do espera_VGA; if score > hi_score then PosarNom; GetPaleta(paleta); FadeDown(0,0,0,0); cls($B800); SetPaleta(paleta); end; {##############################################################} {# F I N A L P A N T A L L A #} {##############################################################} procedure FinalPantalla; begin TragaPantalla; FaseNova; end; {##############################################################} {# M O R T #} {##############################################################} procedure Mort; begin dec(pepe.vides); pepe.posX := 19; pepe.posY := 23; end; {##############################################################} {# M O R T M A L O #} {##############################################################} procedure MortMalo(num: byte); begin malo[num].posX := 39; malo[num].posY := 1; malo[num].color := 3; malo[num].estat := caent; malo[num].IAclock := 0; mapa[malo[num].carrega.posX, malo[num].carrega.posY].tipo := diners; malo[num].carrega.OK := false; malo[num].carrega.posX := 0; malo[num].carrega.posY := 0; end; {##############################################################} {# F O R A D A R #} {##############################################################} procedure Foradar(posX, posY : word); begin { mapa[posX, posY].tipo := buit;} mapa[posX, posY].temps := bloc_out; end; {##############################################################} {# M O U P E P E #} {##############################################################} procedure MouPepe; var hi_ha_malo_baix : boolean; begin if TeclaPuls(KeyQ) then begin if mapa[pepe.posX, pepe.posY].tipo=escala then begin dec(pepe.posY); end; end else if TeclaPuls(KeyA) then begin if (mapa[pepe.posX, pepe.posY+1].tipo=escala) or (mapa[pepe.posX, pepe.posY+1].tipo=buit) then inc(pepe.posY); end; if TeclaPuls(KeyO) then begin if (mapa[pepe.posX-1, pepe.posY].tipo<>pedra) and (pepe.estat<>caent) then dec(pepe.posX); end else if TeclaPuls(KeyP) then begin if (mapa[pepe.posX+1, pepe.posY].tipo<>pedra) and (pepe.estat<>caent) then inc(pepe.posX); end else if TeclaPuls(KeySPACE) then begin if (mapa[pepe.posX-1, pepe.posY+1].tipo=pedra) and (mapa[pepe.posX-1, pepe.posY].tipo<>pedra) and (pepe.estat=normal) then Foradar(pepe.posX-1, pepe.posY+1); end else if TeclaPuls(KeyM) then begin if (mapa[pepe.posX+1, pepe.posY+1].tipo=pedra) and (mapa[pepe.posX+1, pepe.posY].tipo<>pedra) and (pepe.estat=normal) then Foradar(pepe.posX+1, pepe.posY+1); end; if TeclaPuls(KeyH) then begin repeat until not(TeclaPuls(KeyH)); repeat until TeclaPuls(KeyH); repeat until not(TeclaPuls(KeyH)); end; { si no passa res... } pepe.estat := normal; { final pantalla } if pepe.posY = 1 then FinalPantalla; { emparedat } if mapa[pepe.posX, pepe.posY].tipo = pedra then Mort; { agarra diners } if mapa[pepe.posX, pepe.posY].tipo = diners then begin mapa[pepe.posX, pepe.posY].tipo := buit; inc(score); dec(diners_pantalla); end; { bordes X pantalla } if pepe.posX<0 then pepe.posX:=0; if pepe.posX>39 then pepe.posX:=39; { gravetat } if ((mapa[pepe.posX, pepe.posY+1].tipo<>escala) and (mapa[pepe.posX, pepe.posY+1].tipo<>pedra)) and ((mapa[pepe.posX, pepe.posY].tipo=buit) or (mapa[pepe.posX, pepe.posY].tipo=diners)) then begin hi_ha_malo_baix := FALSE; for i:=0 to num_malos-1 do if (pepe.posX = malo[i].posX) and (pepe.posY+1 = malo[i].posY) then hi_ha_malo_baix := TRUE; if not(hi_ha_malo_baix) then begin inc(pepe.posY); pepe.estat := caent; end; end; { bordes Y pantalla } if pepe.posY<0 then pepe.posY:=0; if pepe.posY>24 then pepe.posY:=24; end; {##############################################################} {# S E L E C T E S T A T #} {##############################################################} function SelectEstat(num: byte):byte; var nou_estat : byte; Sestat:byte; x:byte; estat_pX,estat_pY:byte; buscar:byte; begin nou_estat := 0; Sestat:=0; if mapa[malo[num].posX+1, malo[num].posY].tipo <> pedra then nou_estat := nou_estat+dreta; if mapa[malo[num].posX-1, malo[num].posY].tipo <> pedra then nou_estat := nou_estat+esquerra; if mapa[malo[num].posX, malo[num].posY].tipo = escala then nou_estat := nou_estat + pujar; if mapa[malo[num].posX, malo[num].posY+1].tipo = escala then nou_estat := nou_estat + baixar; if nou_estat=0 then Sestat:=10; {no pot moure's} if malo[num].posX>pepe.posX then estat_pX:=esquerra else estat_pX:=dreta; if malo[num].posY>pepe.posY then estat_pY:=pujar else estat_pY:=baixar; x:=random(4); buscar:=random(100); if (buscar<50) and ((nou_estat and estat_PX=estat_PX) or (nou_estat and estat_PY=estat_PY)) then begin if (nou_estat and estat_PX=estat_PX) then Sestat:=estat_PX else Sestat:=estat_PY; end else repeat case x of 0:if nou_estat and dreta =dreta then Sestat:=dreta; 1:if nou_estat and esquerra =esquerra then Sestat:=esquerra; 2:if nou_estat and pujar =pujar then Sestat:=pujar; 3:if nou_estat and baixar =baixar then Sestat:=baixar; end; inc(x); x:=x and $03; until Sestat<>0; SelectEstat:=Sestat; if (mapa[malo[num].posX, malo[num].posY+1].tipo <> pedra) and (mapa[malo[num].posX, malo[num].posY+1].tipo <> escala) then SelectEstat:=caent; end; {##############################################################} {# A G A F A R E S C A L A #} {##############################################################} function AgafarEscala(num:byte):byte; var x:byte; ag:boolean; estat:byte; begin estat:=malo[num].estat; if (estat=dreta) or (estat=esquerra) then begin x:=random(100); if x<80 then ag:=True else ag:=false; if ag then begin if (mapa[malo[num].posX, malo[num].posY].tipo = escala) then estat:=pujar else if (mapa[malo[num].posX, malo[num].posY+1].tipo = escala) then estat:=baixar; end; end; AgafarEscala:=estat; end; {##############################################################} {# M O U M A L O S #} {##############################################################} procedure MouMalos; begin for i:=0 to num_malos-1 do begin if malo[i].IAclock = 0 then malo[i].estat := SelectEstat(i); malo[i].estat:=AgafarEscala(i); if ((mapa[malo[i].posX, malo[i].posY+1].tipo <> pedra) and (mapa[malo[i].posX, malo[i].posY+1].tipo <> escala)) and (mapa[malo[i].posX, malo[i].posY].tipo <> corda) then malo[i].estat:=caent; if ((mapa[malo[i].posX, malo[i].posY+1].tipo = pedra) or (mapa[malo[i].posX, malo[i].posY+1].tipo = escala)) and (malo[i].estat=caent) then malo[i].estat:=SelectEstat(i); if ((mapa[malo[i].posX, malo[i].posY].tipo = buit) and (malo[i].estat=pujar)) then malo[i].estat:=SelectEstat(i); if ((mapa[malo[i].posX, malo[i].posY+1].tipo = pedra) and (malo[i].estat=baixar)) then malo[i].estat:=SelectEstat(i); case malo[i].estat of dreta : inc(malo[i].posX); esquerra : dec(malo[i].posX); pujar : dec(malo[i].posY); baixar : inc(malo[i].posY); caent : inc(malo[i].posY); end; { bordes X } if malo[i].posX<0 then begin malo[i].posX:=0; malo[i].estat := dreta; end; if malo[i].posX>39 then begin malo[i].posX:=39; malo[i].estat := esquerra; end; { bordes Y } if malo[i].posY<0 then begin malo[i].posY:=0; end; if malo[i].posY>24 then begin malo[i].posY:=24; end; { agarrar diners } if (mapa[malo[i].posX, malo[i].posY].tipo = diners) and not(malo[i].carrega.OK) then begin mapa[malo[i].posX, malo[i].posY].tipo := buit; malo[i].color := 11; malo[i].carrega.OK := TRUE; malo[i].carrega.posX := malo[i].posX; malo[i].carrega.posY := malo[i].posY; end; { emparedat } if mapa[malo[i].posX, malo[i].posY].tipo = pedra then MortMalo(i); inc(malo[i].IAclock); if malo[i].IAclock = temps_IA then malo[i].IAclock := 0; end; end; {##############################################################} {# C A R R E G A M A P A #} {##############################################################} procedure CarregaMapa; var fich : file of byte; i,j : word; buffer : byte; begin Assign(fich,'runner.exe'); Reset(fich); Seek(fich, (level * 1000)+offset_mapa); for i:=0 to 39 do for j:=0 to 24 do begin Read(fich, buffer); mapa[i,j].tipo:=buffer; for k:=0 to num_items-1 do if llista_items[k] = mapa[i,j].tipo then mapa[i,j].color := color_items[k]; end; Close(fich); end; {##############################################################} {# C H E C K M O R T P E R M A L O S #} {##############################################################} procedure CheckMortPerMalos; begin for i:=0 to num_malos-1 do if (malo[i].posX = pepe.posX) and (malo[i].posY = pepe.posY) then Mort; end; {##############################################################} {# C H E C K M A P A C O M P L E T #} {##############################################################} procedure CheckMapaComplet; begin if diners_pantalla = 0 then for j:=1 to 23 do begin if mapa[0,j].tipo <> pedra then begin mapa[0,j].tipo := escala; mapa[0,j].color := color_escala; end else break; end; end; {##############################################################} {# C H E C K M A P A #} {##############################################################} procedure CheckMapa; begin for i:=0 to 39 do for j:=0 to 24 do begin case mapa[i,j].temps of 0 : begin mapa[i,j].temps := -1; mapa[i,j].tipo := pedra; end; 1,bloc_out-1 : begin mapa[i,j].tipo := bloc3; dec(mapa[i,j].temps) end; 2,bloc_out-2 : begin mapa[i,j].tipo := bloc2; dec(mapa[i,j].temps) end; 3,bloc_out-3 : begin mapa[i,j].tipo := bloc1; dec(mapa[i,j].temps) end; 4,bloc_out-4 : begin mapa[i,j].tipo := buit; dec(mapa[i,j].temps) end; -1 : ; else dec(mapa[i,j].temps) end; end; CheckMapaComplet; end; {##############################################################} {# F A S E N O V A #} {##############################################################} procedure FaseNova; begin inc(level); if level = (num_fases + 1) then level := 1; pepe.posX := 19; pepe.posY := 23; pepe.dibuix := 2; pepe.color := 15; malo[0].posX := 9; malo[0].posY := 2; malo[0].dibuix := ord('X'); malo[0].color := 3; malo[0].carrega.OK := FALSE; malo[0].estat := esquerra; malo[0].IAclock := 0; malo[1].posX := 20; malo[1].posY := 2; malo[1].dibuix := ord('X'); malo[1].color := 3; malo[1].carrega.OK := FALSE; malo[1].estat := esquerra; malo[1].IAclock := 0; malo[2].posX := 39; malo[2].posY := 2; malo[2].dibuix := ord('X'); malo[2].color := 3; malo[2].carrega.OK := FALSE; malo[2].estat := esquerra; malo[2].IAclock := 0; CarregaMapa; clock := 0; diners_pantalla := 0; for i:=0 to 39 do for j:=0 to 24 do begin mapa[i,j].temps := -1; if mapa[i,j].tipo = diners then inc(diners_pantalla); end; end; {##############################################################} {# I N I C I A L I T Z A C I O #} {##############################################################} procedure Inicialitzacio; begin level := 1; pepe.posX := 19; pepe.posY := 23; pepe.dibuix := 2; pepe.color := 15; pepe.vides := 3; malo[0].posX := 9; malo[0].posY := 2; malo[0].dibuix := ord('X'); malo[0].color := 3; malo[0].carrega.OK := FALSE; malo[0].estat := esquerra; malo[0].IAclock := 0; malo[1].posX := 20; malo[1].posY := 2; malo[1].dibuix := ord('X'); malo[1].color := 3; malo[1].carrega.OK := FALSE; malo[1].estat := esquerra; malo[1].IAclock := 0; malo[2].posX := 39; malo[2].posY := 2; malo[2].dibuix := ord('X'); malo[2].color := 3; malo[2].carrega.OK := FALSE; malo[2].estat := esquerra; malo[2].IAclock := 0; CarregaMapa; clock := 0; diners_pantalla := 0; for i:=0 to 39 do for j:=0 to 24 do begin mapa[i,j].temps := -1; if mapa[i,j].tipo = diners then inc(diners_pantalla); end; end; {##############################################################} {# T I T O L #} {##############################################################} procedure Titol; begin getpaleta(paleta); blackout; PutStringCENTERED(10, 15, 'JAILDESIGNER'); PutStringCENTERED(12, 15, 'presenta'); FadeUp(paleta, 1); for i:=0 to 100 do espera_VGA; Fadedown(0,0,0,0); level := 0; CarregaMapa; for i:=0 to 39 do for j:=0 to 24 do begin mem[pant1:(i shl 1)+(j*80)]:=mapa[i,j].tipo; mem[pant1:(i shl 1)+1+(j*80)]:=mapa[i,j].color; end; move(mem[pant1:0], mem[$B800:0], 2000); FadeUp(paleta, 0); for i:=0 to 100 do espera_VGA; for k:=0 to 2 do begin { despla‡a cap amunt } for i:=0 to 39 do for j:=0 to 23 do begin mem[pant1:(i shl 1)+(j*80)] := mem[pant1:(i shl 1)+((j+1)*80)]; mem[pant1:(i shl 1)+1+(j*80)] := mem[pant1:(i shl 1)+1+((j+1)*80)]; end; espera_VGA;espera_VGA;espera_VGA; move(mem[pant1:0], mem[$B800:0], 2000); end; end; {##############################################################} {# M E N U #} {##############################################################} procedure Menu; var num : integer; begin num := 1; PutStringWINDOWED(18, 14, 'COMEN€AR JOC'); PutStringCENTERED(20, 15, 'EIXIR'); repeat repeat until QteclaPuls; if (TeclaPuls(KeyArrowDown)) or (TeclaPuls(KeyA)) then num := 2; if (TeclaPuls(KeyArrowUp)) or (TeclaPuls(KeyQ)) then num := 1; espera_VGA; move(mem[pant1:0], mem[$B800:0], 2000); if num = 1 then begin PutStringWINDOWED(18, 14, 'COMEN€AR JOC'); PutStringCENTERED(20, 15, 'EIXIR'); end else begin PutStringCENTERED(18, 15, 'COMEN€AR JOC'); PutStringWINDOWED(20, 14, 'EIXIR'); end; until TeclaPuls(KeyENTER); if num = 1 then { joc } begin Inicialitzacio; CarregaRecords; repeat MouPepe; CheckMortPerMalos; if (Clock mod 4) = 0 then MouMalos; CheckMortPerMalos; PintaPantalla; CheckMapa; until TeclaPuls(KeyESC) or (Pepe.vides<0); if TeclaPuls(keyESC) then score := 0; GameOver; end; if num = 2 then { menu d'opcions } exit_game := TRUE; end; {##############################################################} begin instalarKB; setmode(1); HideCursor; SetUpVirtual(ptrpant1, pant1); randomize; offset_mapa := OffsetMapa; exit_game := FALSE; Titol; repeat Menu; until exit_game; TancarVirtual(ptrpant1); setmode(3); desinstalarKB; end.