Jump to content
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

Sign in to follow this  
x1co

[Ajuda] Snake a morrer quando colide

Recommended Posts

x1co

Olá Pessoal

Eu estou a fazer um trabalho em pascal para uma disciplina de programação (SDAC - Sistemas Digitais e arquitectura de computadores).

Eu estou a trabalhar num source que encontrei do snake em pascal.

O problema é que a cobra não morre quando bate nela própria, e que queria que o jogo ficasse parecido com o snake do nokia 3310.

Se me podassem ajudar, agradecia :thumbsup:

aqui fica o source, já com algumas alterações que fiz:

program snake;
uses CRt;

Type
   ptpos = ^posicao; { ponteiro para lista circular }
   posicao = record
      ant: ptpos;
      x: integer;
      y: integer;
      prox: ptpos;
   end;

   cab = record
      apont: ptpos;
      corpo: string;
   end;

      var playername:
   record
   nome:string;
   pontos:integer ;
   end;


    s: string;
   opc: char;
   opaux: char;
   h, v, cont, apagax, apagay: integer;
   prim, p, pultimo: ptpos;
   comidaX, comidaY, opx, opy, opz: integer;
   tamanhoc: integer;
   vidas: integer;
   dificuldade: integer;
   jogador, nome: string;
   cabeca: cab;
   f: text;
   pontos: integer;
   velocidade: integer; { tempo de dalay }
   tempo: integer   ;

c: char  ;
i: integer;









procedure ListaCircular;
begin
{Cria uma lista circular duplamente encadada com 15 elementos
que o tamanho m'e1ximo da cobra cada elemento comtem uma
cordenada (x,y) de onde a cobra esta passando}
   new(prim);
   prim^.x := 2;
   prim^.y := 4;
   p := prim;
   for cont := 1 to 200 do
   begin
      new(pultimo);
      pultimo^.x := 2;
      pultimo^.y := 4;
      p^.prox := pultimo;
      pultimo^.ant := p;
      p := pultimo;
   end;
   pultimo^.prox := prim;
   prim^.ant := pultimo;
   cabeca.apont := prim;
end;

procedure PreencheCorpo;
var i, a, b: integer;
   aux: string;
begin
   aux := '';
   a := length(jogador);
   if (dificuldade = 1) and (a = 25) then
      dificuldade := 2;
   if (dificuldade = 2) and (a = 50) then
      dificuldade := 3;

   if a < 200 then
      for i := a to 200 do
      begin
         aux := aux + 'O';
      end;
   cabeca.corpo := '@OO' + aux;
end;

procedure Inicializa;
begin



   delay(1000);
   clrscr;
   playername.pontos := 0;
   dificuldade := 1;
   vidas := 1;
   { jogador := 'Francisco Costa'; }
   preenchecorpo;
   tamanhoc := 3;
   velocidade := 90;
   opc := 'a';
   opx := 0;
   opy := 80;
end;


procedure AtualizaVariaveis;
begin
   textcolor(14);
   gotoxy(18,2); write(pontos);
   gotoxy(45,2); write(dificuldade);
   gotoxy(67,2); write(vidas);
   begin
   gotoxy(70,2); write (tempo,' seg');

    tempo := tempo + 1;
       end;


end;

procedure linhaH(posicaox, posicaoy, tamanho: integer);
var a: integer;
begin
   a := posicaox;
   while a < (posicaox + tamanho) do
   begin
      gotoxy(a,posicaoy);
      write('#');
      a := a + 1;
   end;
end;

procedure linhaV(posicaox, posicaoy, tamanho: integer);
var a: integer;
begin
   for a := posicaoy to (posicaoy + tamanho) do
   begin
      gotoxy(posicaox,a);
      write('#');
   end;
end;

procedure GeraTela;
begin
   opx := 0;  {ope'e7'f5es x e y que fazem a cobra se movimentar para baixo}
   opy := 80;
   h := 2;
   v := 4;
   clrscr;

   AtualizaVariaveis;





   textcolor(15);
   gotoxy(10,2); write('Pontos:');
   gotoxy(32,2); write('Dificuldade:');
   gotoxy(60,2); write('Vidas:');
   gotoxy(1,4);

   textcolor(11);
   linhaH(1,4,79);
   linhaH(1,24,79);
   linhaV(1,5,19);
   linhaV(79,5,19);
end;


procedure Apaga;
var papaga: ptpos;
begin
   textcolor(10);
   papaga := pultimo;
   gotoxy(papaga^.x,papaga^.y);
   write('*');
   textcolor(0);
   papaga := pultimo;
   papaga := pultimo^.ant;
   apagax := papaga^.x;
   apagay := papaga^.y;
   gotoxy(apagax,apagay);
   write('*');
   textcolor(10);
end;

procedure TamanhoCobra (tam : integer);
begin
   pultimo := cabeca.apont; {faz o final da cobra amumentar}
   for cont := 1 to tam do
     pultimo := pultimo^.ant;
end;


procedure Telainicial;
var
  posx, posy, i: integer;
begin
   posx := 20;
   posy := 2;

   clrscr;

   textcolor(12);
   gotoxy(posx+13,posy);  writeln('--- Snake Shake ---');


   textcolor(7);
   gotoxy(posx+11,posy+5); writeln('Insira o seu nome');
   readln(nome);

   textcolor(15);
   gotoxy(posx+7,posy+8); writeln('Pressione ENTER para comecar');

   textcolor(11);
   linhaH(1,  posy+14, 40);
   linhaH(1,  posy+22, 40);
   linhaV(1,  posy+15, 6);
   linhaV(40, posy+15, 6);

   textcolor(12);
   gotoxy(45,posy+16); writeln('COMANDOS:');
   textcolor(15);
   gotoxy(48,posy+18); writeln('SETAS movimentam a cobra');
   gotoxy(48,posy+19); writeln('ESC para Sair');
   gotoxy(48,posy+20); writeln('P para Pausa');
   textcolor(7);
   gotoxy(posx+30,posy+11);

   textcolor(13);
   linhaH(1,  posy+14, 80);
   linhaH(1,  posy+22, 80);
   linhaV(1,  posy+15, 6);
   linhaV(80, posy+15, 6);

   textcolor(8);
   gotoxy(3,posy+16); writeln ('High Score:');
   begin
   assign (f, 'f:\\pascal\asda\scorexd1.txt');
    reset (f);

    i:=1;
	while NOT Eof (f) do
	begin
	readln (f, s);
 gotoxy(3,posy+17+i);
 textcolor(9);
writeln(s);
	 i:=i+1;
 end;
	close(f);
	readln ;
  	end;


   readkey;
end;

procedure ComecarNovamente;
var i: integer;

procedure gameover;
var posx,posy: integer;
begin
posx := 22;
posy := 5;
gotoxy(posx+15,posy+10);
writeln('GAME OVER');
gotoxy(posx+11,posy+5) ;
writeln('O seu score é:', pontos);


{ gotoxy(posx-2,posy+16); writeln('Pressione qualquer tecla para CONTINUAR ',i);}
end;






begin
{ reseta a posi'e7'e3o da cobra para o canto superior esquerdo}
p := pultimo;
for i := 1 to 15 do begin
p^.x := 2;
p^.y := 4;
p := p^.prox;
end;



tamanhoC := 3;

tamanhoCobra(tamanhoC); {coloca a cobra com o tamanho 3}


textcolor(7);
gotoxy(67,2); write(vidas);
if vidas = 0 then begin

i := 9;   {quantidade de seguntos restante}
while (i >= 0)  do begin
textcolor(red);
gameover;
delay(400);
textcolor(7); {cinza claro}
gameover;
delay(600);
i := i -1;
if keypressed then
i := -1;
  end;

inicializa;

end;
geratela;
   end;

procedure verificaPosicao; { verifca a posica'e3o de colisa'e3o }
begin
   if (cabeca.apont^.x > 77) or (cabeca.apont^.x < 2) or (cabeca.apont^.y > 23) or (cabeca.apont^.y < 5) then
   begin
      vidas := vidas -1;
      comecarnovamente;
   end;
end;


procedure criaComida;
begin
   comidaX := 2 +  random(77);
   comidaY := 5 +  random(19);
   textcolor(4);
   {indica o caracter que representarar a comida}
   gotoxy(comidaX,comidaY); write('*');
end;

procedure atualizaComida; {mostra a comida na tela}
begin
   textcolor(4);
   {indica o caracter que representarar a comida}
   gotoxy(comidaX,comidaY); write(cabeca.corpo[tamanhoC+1]);
end;

procedure mudaDificuldade;
begin
   Dificuldade := Dificuldade +1;
   velocidade := velocidade - 20 div dificuldade; { imprime na tela no intervalo que 'e9 10 milisegundo menor que o anterior;}
end;

procedure verificacomida;
begin
   if (cabeca.apont^.x = comidax) and (cabeca.apont^.y = comiday) then
   begin
      CriaComida;
      tamanhoc := tamanhoc +1;
      TamanhoCobra(tamanhoc);
      pontos := pontos + 10;
      if tamanhoc = 15  then
         MudaDificuldade;
   end;
end;

procedure mover(a,b: integer); {faz a cobra se mover para norte(0,1),}
var i: integer;  {sul(0,-1), leste(-1,0) e oeste(1,0)}
q: ptpos;
begin
     cabeca.apont := cabeca.apont^.prox;
   h := h + a;
   v := v + b;
   cabeca.apont^.x := h;
   cabeca.apont^.y := v;
   verificaposicao;
   i := tamanhoc;
   q := cabeca.apont;
   atualizaComida;
   textcolor(10); {cor azul claro da cobra}
   for i := 1 to tamanhoc do
   begin {cria a cobra na tela}
      gotoxy(q^.x,q^.y);
      q := q^.ant;
      write(cabeca.corpo[i]);
   end;
   pultimo := pultimo^.prox;
   verificacomida;
   apaga;
   atualizaVariaveis;
end;





Begin
   TelaInicial;
   Inicializa;
   Geratela;
   CriaComida;
   {esta lista circular comtem os caracteres e a posicao da cobra}
   Listacircular;
   TamanhoCobra(tamanhoc);



   {este e o laco principal do jogo usado para identificar quais sao as teclas usada pelo jogador}
   opc := 'a';
   while (opc <> 's') do
   begin
      if keypressed then
      begin
         opc := readkey;
         {a funcao ord nos fornece qual o codigo ascii da tecla, mas tem um
         problema quando o jogador usa teclas especias tipo as setas do teclado.
         Tem que usar duas variaveis para guardar o codigo dessas teclas
         especias, observando que a primeira variavel sempre fica com o valor 0}
         opz := ord(opc);
         if opz = 0 then
         begin
            opx := opz;
            opc := readkey;
            opz := ord(opc);
            if (opz = 75) or (opz = 77) or (opz = 72) or (opz = 80) then
               opy := opz;
            end;


            {para quando aperta 'p' ficar em pausa}
            if opz = 112 then begin
               opc := 'a';
               opy := 111;
               while (opz <> 112) do
                  if keypressed then
                  begin
                     opc := readkey;
                     opz := ord(opc);
                     if opz = 0 then
                        opz := ord(opc)
                     end;
                  end;

                  if opz = 27 then {para usar ESC quando quiser sair do programa}
                     opc := 's';
                  end
                     else begin
                     if opx = 0 then
                     begin
                        case opy of
                           75: mover(-1,0); { movimentra para esquerda }
                           77: mover(1,0);  { movimenta para direita}
                           72: mover(0,-1); { para cima }
                           80: mover(0,1);  { para baixo }
                            1: comecarnovamente;
                            2: telainicial;

                     end;
                     delay(velocidade);
                 end;
              end;
           end;

               gotoxy(1,40);
             begin
Assign (f, 'scorexd1.txt');
append (f);
writeln (f, nome,':  ', pontos);
close (f);
   end;
   clrscr;
   end.

Share this post


Link to post
Share on other sites
M6

x1xo, tens de ser mais especifico do que isso.

Ninguém aqui vai usar esse código e fazer debug por ti.

A cobra não morre porquê? Já procuraste o bug na tua rotina de detecção de colisão?


10 REM Generation 48K!
20 INPUT "URL:", A$
30 IF A$(1 TO 4) = "HTTP" THEN PRINT "400 Bad Request": GOTO 50
40 PRINT "404 Not Found"
50 PRINT "./M6 @ Portugal a Programar."

 

Share this post


Link to post
Share on other sites
x1co

Mostra so o bocado do código que verifica quando ela bate nela própria

pois é isso, a cobra so morre quando bate nas paredes..

Mas não estou a perceber como fazer para ela morrer quando bate nela propria..

morrer quando bate nas paredes é aqui:

procedure verificaPosicao; { verifca a posica'e3o de colisa'e3o }
begin
   if (cabeca.apont^.x > 77) or (cabeca.apont^.x < 2) or (cabeca.apont^.y > 23) or (cabeca.apont^.y < 5) then
   begin
      vidas := vidas -1;
      comecarnovamente;
   end;
end;

Share this post


Link to post
Share on other sites
M6

Para detectares a colisão com ela própria tens de saber a posição exacta de cada "quadrado" da cobra e verificar se há quaisquer dois "quadrados" da cobra que estão a ocupar a mesma posição.


10 REM Generation 48K!
20 INPUT "URL:", A$
30 IF A$(1 TO 4) = "HTTP" THEN PRINT "400 Bad Request": GOTO 50
40 PRINT "404 Not Found"
50 PRINT "./M6 @ Portugal a Programar."

 

Share this post


Link to post
Share on other sites
Guest

Exactamente como o M6 disse só estas a verificar com as paredes... tens de verificar também com todos os quadrados do corpo da cobra

Share this post


Link to post
Share on other sites
x1co

Exactamente como o M6 disse só estas a verificar com as paredes... tens de verificar também com todos os quadrados do corpo da cobra

alguma ideia de como fazer isso?

Share this post


Link to post
Share on other sites
M6

Não sei porquê "cheira-me" que não foste tu quem fez esse programa...

Se sabes onde desenhar cada "quadrado" da cobra, sabes a posição exacta de cada um.


10 REM Generation 48K!
20 INPUT "URL:", A$
30 IF A$(1 TO 4) = "HTTP" THEN PRINT "400 Bad Request": GOTO 50
40 PRINT "404 Not Found"
50 PRINT "./M6 @ Portugal a Programar."

 

Share this post


Link to post
Share on other sites
x1co

Não sei porquê "cheira-me" que não foste tu quem fez esse programa...

Se sabes onde desenhar cada "quadrado" da cobra, sabes a posição exacta de cada um.

no primeiro post eu disse isto:

Eu estou a fazer um trabalho em pascal para uma disciplina de programação (SDAC - Sistemas Digitais e arquitectura de computadores).

Eu estou a trabalhar num source que encontrei do snake em pascal.

Lógico que não fui eu..

Share this post


Link to post
Share on other sites
M6

Passou-me esse parágrafo, mas fiquei com a ideia de que o código não era teu.

Seja como for, basta encontrares a rotina onde desenhas a cobra e se tentares desenhar dois quadrados na mesma posição, então a cobra bateu nela própria.


10 REM Generation 48K!
20 INPUT "URL:", A$
30 IF A$(1 TO 4) = "HTTP" THEN PRINT "400 Bad Request": GOTO 50
40 PRINT "404 Not Found"
50 PRINT "./M6 @ Portugal a Programar."

 

Share this post


Link to post
Share on other sites
x1co

Passou-me esse parágrafo, mas fiquei com a ideia de que o código não era teu.

Seja como for, basta encontrares a rotina onde desenhas a cobra e se tentares desenhar dois quadrados na mesma posição, então a cobra bateu nela própria.

hum, obrigado.. vou tentar.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.