::::::::: WITAM!
Publikuj kod aktualnej wersji, bo w downloadyie cyepia si e nieprawidowz tzp MIME. Co wzđcie tam nakrcili_ Wcyesniej sie niecyepial! ;-)
Dodano w nim animowane intro i outro (game over) :>
{============================================
mSnake v. 0.6.5 (C) m33, 2007
============================================
! poczatek 22 IV 2007 !
============================================
! * dla konsoli !
! * na planszy 80 x 25 znakow (ibmpc) !
============================================
ZMIANY & INNOWACJE:
*** dnia 24 IV 2007
* dodano opcje
- wlacz/wylacz zawijanie
- regulacja tempa gry
*** dnia 28 IV 2007
* zmiany
- "odwrocene" zapisu weza
- po narysowaniu glowy
kursor jest przesuwany na nia
- NARESZCIE DODANO JEDZENIE
*** dnia 28 IV 2007
* optymalizacja procedury
losowania xy jedzenia
*** dnia 3 V 2007
* dodanie kolorow
* wykrywanie kolizji z jedzeniem i
losowaniejego nowych xy przesunieto
na koniec glownej petli
*** dnia 14 V 2007
* animowane menu startowe
*** dnia 18 V 2007
* animaowany napi "GAME OVER"
* wydluzono max. dlugosc weza
============================================
ZNANE BUGI:
+ TEST na LINUXie
1. przy szybkich skretach:
- mozna przejsc glowa przez ogon
i dalej grac
- mozna zawrocic w miejscu
co konczy gre
******** PODEJRZENIA co dp powodow:
1. przy szybkich skretach:
- moze miec to zwiazek
ze stosowaniem procedury delay
do chwilowego wstrzymania pracy
============================================}
USES Crt;
CONST
{naspis "SNAKE"}
logo:array [0..9,0..59] of byte=(
(0,8,8,8,8,8,8,8,8,8,8,0,0,8,8,8,8,8,0,0,0,8,8,8,0,0,0,0,0,0,8,8,8,0,0,0,0,0,8,8,8,8,0,0,0,0,8,8,8,8,0,8,8,8,8,8,8,8,8,8),
(8,8,8,8,8,8,8,8,8,8,8,8,0,8,8,8,8,8,0,0,0,8,8,8,0,0,0,0,0,8,8,8,8,8,0,0,0,0,8,8,8,8,0,0,8,8,8,8,8,0,0,8,8,8,8,8,8,8,8,8),
(8,8,8,8,0,0,0,0,8,8,8,8,0,8,8,8,8,8,8,0,0,8,8,8,0,0,0,0,0,8,8,8,8,8,0,0,0,0,8,8,8,8,8,8,8,8,8,0,0,0,0,8,8,8,8,0,0,0,0,0),
(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,8,8,8,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
(8,8,8,8,8,8,8,8,8,8,8,0,0,8,8,8,0,8,8,8,8,8,8,8,0,0,0,8,8,8,8,8,8,8,8,0,0,0,8,8,8,8,8,8,8,8,8,0,0,0,0,8,8,8,8,8,8,8,0,0),
(0,8,8,8,8,8,8,8,8,8,8,8,0,8,8,8,0,8,8,8,8,8,8,8,0,0,0,8,8,8,8,8,8,8,8,8,0,0,8,8,8,8,8,8,8,8,8,8,0,0,0,8,8,8,8,8,8,8,0,0),
(0,0,0,0,0,0,0,0,8,8,8,8,0,8,8,8,0,0,8,8,8,8,8,8,0,0,8,8,8,8,0,0,8,8,8,8,0,0,8,8,8,8,0,0,8,8,8,8,8,0,0,8,8,8,8,0,0,0,0,0),
(8,8,8,8,8,8,8,8,8,8,8,8,0,8,8,8,0,0,8,8,8,8,8,8,0,0,8,8,8,8,0,0,0,8,8,8,8,0,8,8,8,8,0,0,0,8,8,8,8,8,0,8,8,8,8,8,8,8,8,8),
(8,8,8,8,8,8,8,8,8,8,8,0,0,8,8,8,0,0,0,8,8,8,8,8,0,8,8,8,8,0,0,0,0,8,8,8,8,0,8,8,8,8,0,0,0,0,8,8,8,8,0,8,8,8,8,8,8,8,8,8)
);
{napis "GAME OVER"}
g_over: array [0..19,0..72] of byte=
(
(0,0,0,0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,0,0,0,0,0,0,0,8,8,8,8,8,8,0,0,0,0,0,0,0,8,8,8,8,0,0,0,0,0,0,0,0,0,8,8,8,8,8,0,0,0,8,8,8,8,8,8,8,8,8,8,8,8,8,8),
(0,0,0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,0,0,0,0,0,0,0,8,8,8,8,8,8,8,0,0,0,0,0,0,8,8,8,8,8,8,0,0,0,0,0,0,0,8,8,8,8,8,0,0,0,0,8,8,8,8,8,8,8,8,8,8,8,8,8,0),
(0,0,8,8,8,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,8,8,0,8,8,8,8,0,0,0,0,0,0,8,8,8,8,8,8,0,0,0,0,0,0,8,8,8,8,8,8,0,0,0,8,8,8,0,0,0,0,0,0,0,0,0,0,0,0),
(0,0,8,8,8,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,8,8,8,8,0,8,8,8,8,0,0,0,0,0,0,8,8,8,8,8,8,0,0,0,0,0,8,8,8,8,8,8,8,0,0,8,8,8,8,0,0,0,0,0,0,0,0,0,0,0,0),
(0,8,8,8,8,0,0,8,8,8,8,8,8,8,8,8,8,0,0,0,8,8,8,8,8,0,0,8,8,8,8,0,0,0,0,0,8,8,8,0,0,8,8,8,0,0,0,8,8,8,8,8,8,8,0,0,0,8,8,8,8,8,8,8,8,8,0,0,0,0,0,0,0),
(0,8,8,8,8,0,0,0,0,0,0,0,8,8,8,8,0,0,0,0,8,8,8,8,0,0,0,8,8,8,8,0,0,0,0,0,8,8,8,0,0,8,8,8,0,8,8,8,8,0,8,8,8,8,0,0,0,8,8,8,8,0,0,0,0,0,0,0,0,0,0,0,0),
(0,8,8,8,8,0,0,0,0,0,0,0,8,8,8,8,0,0,0,8,8,8,8,8,8,8,8,8,8,8,8,8,0,0,0,8,8,8,8,0,0,8,8,8,8,8,8,8,0,0,8,8,8,0,0,0,8,8,8,8,0,0,0,0,0,0,0,0,0,0,0,0,0),
(8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,0,0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,0,0,0,8,8,8,0,0,0,8,8,8,8,8,8,0,0,8,8,8,8,0,0,0,8,8,8,8,8,8,8,8,8,8,8,8,8,0,0,0,0),
(8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,0,0,8,8,8,8,0,0,0,0,0,0,0,8,8,8,8,0,0,0,8,8,8,0,0,0,0,8,8,8,0,0,0,0,8,8,8,8,0,0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,0,0,0,0),
(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
(0,0,0,0,0,0,0,8,8,8,8,8,8,8,8,8,8,0,0,0,0,0,0,0,8,8,8,0,0,0,0,0,0,0,0,8,8,8,0,0,0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,0,0,8,8,8,8,8,8,8,8,8,8,8,0,0,0,0,0),
(0,0,0,0,0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,0,0,0,0,8,8,8,0,0,0,0,0,0,0,0,8,8,8,0,0,0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,0,0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,0),
(0,0,0,0,8,8,8,8,0,0,0,0,0,0,0,0,8,8,8,8,0,0,0,0,8,8,8,0,0,0,0,0,0,8,8,8,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,8,8,8,8,0),
(0,0,0,0,8,8,8,8,0,0,0,0,0,0,0,0,8,8,8,8,0,0,0,0,8,8,8,8,0,0,0,0,8,8,8,8,0,0,0,0,8,8,8,0,0,0,0,0,0,0,0,0,0,0,0,0,8,8,8,0,0,0,0,0,0,0,0,8,8,8,8,0,0),
(0,0,0,0,8,8,8,0,0,0,0,0,0,0,0,0,8,8,8,0,0,0,0,0,8,8,8,8,0,0,0,8,8,8,8,8,0,0,0,8,8,8,8,8,8,8,8,8,0,0,0,0,0,0,0,0,8,8,8,8,0,0,0,0,0,0,0,8,8,8,8,0,0),
(0,0,0,8,8,8,8,0,0,0,0,0,0,0,0,8,8,8,8,0,0,0,0,0,8,8,8,8,0,0,0,8,8,8,8,0,0,0,0,8,8,8,8,8,8,8,8,8,0,0,0,0,0,0,0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,0,0,0,0),
(0,0,8,8,8,8,0,0,0,0,0,0,0,0,8,8,8,8,0,0,0,0,0,0,8,8,8,8,0,0,8,8,8,0,0,0,0,0,0,8,8,8,8,0,0,0,0,0,0,0,0,0,0,0,0,8,8,8,8,0,0,0,0,0,0,8,8,8,8,0,0,0,0),
(0,0,8,8,8,8,0,0,0,0,0,0,0,0,8,8,8,8,0,0,0,0,0,0,8,8,8,8,0,8,8,8,0,0,0,0,0,0,8,8,8,8,0,0,0,0,0,0,0,0,0,0,0,0,8,8,8,8,8,0,0,0,0,0,0,0,8,8,8,0,0,0,0),
(0,0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,0,0,0,0,0,0,0,8,8,8,8,8,8,8,0,0,0,0,0,0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,0,0,8,8,8,8,0,0,0,0,0,0,0,8,8,8,8,0,0,0,0),
(0,0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,0,0,0,0,0,0,0,0,0,8,8,8,8,8,8,0,0,0,0,0,0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,0,0,0,8,8,8,0,0,0,0,0,0,0,0,8,8,8,0,0,0,0,0)
);
CONST
MAXS = 500; {stala okreslajaca maksymalną dlugosc weza}
TYPE
TSnake = RECORD
how_long: byte; {jak dlugi jest waz}
dir: byte; {jaki jest kierunek weza}
x: array[0..MAXS] of byte; {wspolzedne x segmentow}
y: array[0..MAXS] of byte; {wspolzedne y segmentow}
end;
TFood = RECORD
vis: boolean;
x: byte;
y: byte;
end;
VAR
snake: TSnake; {waz}
food: TFood; {jedzenie}
i: integer; {zmienna wykorzystywana do iteracji}
key: char; {zmienna do przechowywania kodu wcisnietego klawisza}
logic: boolean; {do wszelkich warunkow w petlach}
zawijaj: boolean; {opcja - zawijanie}
speed: integer; {opcja - opoznienie weza}
{------------------------------------------------------------------------------}
Procedure Options;
Begin
Repeat
ClrScr;
TextColor(White);
WriteLn('* OPCJE **********************************************');
WriteLn;
TextColor(LightGray);
if zawijaj=TRUE then WriteLn('[1] - wylacz "zawijanie" planszy')
else WriteLn('[1] - wlacz "zawijanie" planszy');
WriteLn;
WriteLn('[+/-] OPOZNIENIE WEZA: ',speed,' milisekund');
WriteLn;
TextColor(White);
WriteLn('[Esc] - powrot do gry ********************************');
Key:=ReadKey;
case Key of
'1': zawijaj:=not(zawijaj);
'+': speed:=speed+1;
'-': speed:=speed-1;
end;
if speed<1 then speed:=1; {zeby nie zawiesic}
if speed>1000 then speed:=1000; {zeby nie przedobrzyc}
Until Key=#27;
End;
{------------------------------------------------------------------------------}
Procedure Intro;{animowane intro}
Begin
ClrScr;
for i:=0 to 9
do begin
for speed:=0 to 59
do begin
if logo[i,speed]=8 then begin
GoToXY(speed+1,i+1);
case i of
0..1:TextColor(cyan);
2..4:TextColor(lightCyan);
5..6:TextColor(white);
7..9:TextColor(lightGreen);
end;
Write('8');
TextColor(DarkGray);
GoToXY(speed+1,i+1+1);Write('&');
end;
end;
for speed:= 1 to 80 do begin
gotoxy(speed,i+3);
write(' ');
textcolor(white);
gotoxy(speed,i+4);
write('=');
end;
TextColor(Cyan);
WriteLn;
WriteLn('(C) m33, 18 V 2007 ');
WriteLn(' ');
TextColor(White);
WriteLn('plansza 80x25 znakow ');
TextColor(LightGray);
WriteLn(' ');
WriteLn('[8] w gore ');
WriteLn('[2] w dol ');
WriteLn('[4] w lewo ');
WriteLn('[6] w prawo ');
WriteLn('[P] pauza ');
WriteLn('[O] opcje ');
WriteLn('[Esc] koniec');
delay(50);
end;
GoToXY(62,10);
write('v 0.65');
GoToXY(62,10);
Repeat until KeyPressed;
End;
{------------------------------------------------------------------------------}
Procedure Draw_snake; {rysowanie weza}
Begin
for i:= 0 to snake.how_long-1
do
begin
TextColor(LightGreen);
GoToXY(snake.x[i],snake.y[i]);
if i=snake.how_long-1 then begin
write('0'); GoToXY(snake.x[i],snake.y[i]);
end
else write('#');
end;
End;
{------------------------------------------------------------------------------}
Procedure Draw_food; {rysowanie jedzenia}
Begin
if food.vis=TRUE then
begin
GoToXY(food.x,food.y);
TextColor(cyan);
Write('*');
GoToXY(food.x,food.y);
end;
End;
{------------------------------------------------------------------------------}
Procedure Game_over;
Begin
ClrScr;
for i:=0 to 19
do begin
for speed:=0 to 72
do begin
if g_over[i,speed]=8 then begin
GoToXY(speed+5,i+3);
case i of
0,2,4,6,8,10,12,14,16,18:TextColor(Red);
1,3,5,7,9,11,13,15,17,19:TextColor(lightRed);
end;
Write('8');
TextColor(LightGray);
GoToXY(speed+5+1,i+3+1);Write('&');
end;
end;
Delay(50);
if i=9 then delay(250);
end;
Delay(250);
i:=0;
repeat
GoToXY(random(80+1),random(25+1));
write(' ');
if i mod 33 =0 then delay(1);
i:=i+1;
until (i=5000) or (KeyPressed);
ClrScr;
TextColor(White);
WriteLn('punktow: ',snake.how_long-3);
TextColor(LightGray);
halt(0);
End;
{------------------------------------------------------------------------------}
{! MAIN !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}
BEGIN {main}
Intro;
{opcje poczatkowe}
zawijaj:=FALSE;{"zawijanie" wylaczone}
speed:=100; {poczatkowe opoznienie weza}
{snake poczatkowe}
snake.how_long:=3; {poczatkowa dlugosc}
snake.dir:=1; {poczatkowy kierunek - w prawo}
snake.x[2]:=10; {poczatkowa wspolrzedna x "glowy"}
snake.y[2]:=5; {poczatkowa wspolrzedna y "glowy"}
snake.x[1]:=9; {poczatkowa wspolrzedna x elementu "tulowia"}
snake.y[1]:=5; {poczatkowa wspolrzedna y elementu "tulowia"}
snake.x[0]:=9; {tulowia ciag dalszy}
snake.y[0]:=5;
food.vis:=FALSE; {jedzenie na starcie niewidoczne}
RANDOMIZE; {inicjowanie generatora liczb pseudolosowych}
while (1=1) do
Begin{while (1=1)*************************************************************}
while not KeyPressed do
Begin{while not KeyPressed}
for i:=0 to snake.how_long-2
do
begin{przesuwanie "tulowia"}
snake.x[i]:=snake.x[i+1]; snake.y[i]:=snake.y[i+1];
end;
case snake.dir of {przesuwanie "glowy" zgodnie z kierunkiem ruchu}
1:begin snake.x[snake.how_long-1]:=snake.x[snake.how_long-1]+1; end; {1- w prawo}
2:begin snake.y[snake.how_long-1]:=snake.y[snake.how_long-1]+1; end; {2- w dol}
3:begin snake.x[snake.how_long-1]:=snake.x[snake.how_long-1]-1; end; {3- w lewo}
4:begin snake.y[snake.how_long-1]:=snake.y[snake.how_long-1]-1; end; {4- p gore}
end;
{sprawdzanie czy waz się "nie ugryzl"}
for i:=0 to snake.how_long-2 do if snake.x[snake.how_long-1]=snake.x[i] then if snake.y[snake.how_long-1]=snake.y[i] then Game_over;
{---------- TU OPCJE GRY WPLYWAJA ---------------------------------------------}
if zawijaj=FALSE then {opcja "zawijanie" wylaczona}
begin {czy nie uderzyl glowa w ktoras krawedz planszy}
if snake.x[snake.how_long-1]<1 then Game_over;
if snake.y[snake.how_long-1]<1 then Game_over;
if snake.x[snake.how_long-1]>80 then Game_over;
if snake.y[snake.how_long-1]>25 then Game_over;
end
else {opcja "zawijanie" wlaczona}
begin {czesc weza pojawia sie po przeciwnej stronie planszy}
for i:= 0 to snake.how_long-1 do begin
if snake.x[i]=0 then snake.x[i]:=79;
if snake.y[i]=0 then snake.y[i]:=25;
if snake.x[i]=81 then snake.x[i]:=1;
if snake.y[i]=26 then snake.y[i]:=1;
end;
end;
{---------- TU OPCJE GRY WPLYW KONCZA -----------------------------------------}
{---------- kolizja z jedzeniem ----------------------------------------------}
{po wszelkich przesunieciach!!!}
if food.vis=TRUE then { jesli jedzenie widoczne }
begin
if snake.x[snake.how_long-1]=food.x
then if snake.y[snake.how_long-1]=food.y then
begin
snake.how_long:=snake.how_long+1;
case snake.dir of {przyrost weza na dlugosc}
1:begin
snake.x[snake.how_long-1]:=snake.x[snake.how_long-2]+1;
snake.y[snake.how_long-1]:=snake.y[snake.how_long-2];
end;
2:begin
snake.y[snake.how_long-1]:=snake.y[snake.how_long-2]+1;
snake.x[snake.how_long-1]:=snake.x[snake.how_long-2];
end;
3:begin
snake.x[snake.how_long-1]:=snake.x[snake.how_long-2]-1;
snake.y[snake.how_long-1]:=snake.y[snake.how_long-2];
end;
4:begin
snake.y[snake.how_long-1]:=snake.y[snake.how_long-2]-1;
snake.x[snake.how_long-1]:=snake.x[snake.how_long-2];
end;
end;
food.vis:=FALSE; {usuwanie jedzenia z widoku}
end;
end;
{------------------------------------------------------------------------------}
{--- LOSOWANIE xy jedzenia}
if food.vis=FALSE then
if snake.how_long<MAXS {jesli waz nie jest juz za dlugi zeby rosnac}
then
begin
food.vis:=TRUE;
logic:=FALSE;
repeat {tak dlugo dopoki x i y jedzenie nie "wejda" na weza }
food.x:=random(79)+1;
food.y:=random(24)+1;
logic:=TRUE;
i:=0;
while (i<snake.how_long-1)and(logic=TRUE)
do
begin
i:=i+1;
if (food.x=snake.x[i]) then if (food.y=snake.y[i]) then logic:=FALSE;
end;
until logic=TRUE;
end;
{-------------------------}
ClrScr; {Czyszczenie ekranu}
Draw_snake; {rysowanie weza}
Draw_food; {rysowanie jedzenia}
Delay(speed); {odczekaj 100 milisekund - wartosc zmieniasz w opcjach}
End;{while not KeyPressed}
key:=ReadKey; {odczytanie klawisza}
case key of {zmiana snake.dir chyba że gracz chce zmienic kierunek weza na przeciwny od obecnego}
'6': begin if snake.dir<>3 then snake.dir:=1; end;
'4': begin if snake.dir<>1 then snake.dir:=3; end;
'8': begin if snake.dir<>2 then snake.dir:=4; end;
'2': begin if snake.dir<>4 then snake.dir:=2; end;
'P','p': begin
TextColor(LightRed);
ClrScr; GoToXY(30,12);
write('*** PAUSE ***');
repeat until ReadKey in ['p','P'];
end;
'O','o': Options;
#27: begin Game_over; end;
end;
End;{while (1=1) *************************************************************}
END.{main}