Меня сегодня убили С помощью Вольвы сдала программку с графикой на 5 ^_^
Но сегодня дали курсавик. Змейка. Полистала тут форум, одни исходники.
Хочется написать самой, ну или кусочки кодов украсть.
Объекты еще не проходили, но без них думаю неполучится написать. Если не трудно.
Можете помочь сделать игрушку... Объяснить с чего начать, привести парочку примеров ( Я НЕ КОГО НЕ ЗАСТАВЛЯЮ НИЧЕГО ДЕЛАТЬ, ПРОСТО ПРОШУ ПОМОЧЬ, КОМУ НЕ ТЯЖЕЛО) кусочков кодов и для чего они служат, просто совести не хватит взять чужое, и впихнуть, да и сама должна понять, как такое делается...
М | Пожалуйста, измени заголовок (Правила, п.8) |
graph+crt режимы.
Добавлено через 1 мин.
Что-то типа
(Модуль + основная программа)
Прикрепленные файлы
SOLITER.PAS ( 16.34 килобайт )
Кол-во скачиваний: 753
TEXTURE.PAS ( 6.62 килобайт )
Кол-во скачиваний: 630
М | Спасибо |
Называется Очередь.
На самом деле, FIFO не обязательно. Если не жалко памяти и есть возможность хранить состояния всех точек поля (экрана), то может быть даже проще.
Вот простенькая реализация змейки с FIFO, я сейчас набросал с учетом твоих требований (юниты, текст с возможностью подключения графики). Управление на стрелочках, конец игры при ударе в стенку, самопересечения допускаются пока. Поиграйся и попробуй разобраться. А потом можно будет и без фифы сделать - кстати, так даже проще отлавливать самопересечения.
Файл FIFO.pas
unit FIFO;
interface
const
lMax=$1000;
procedure Put(x,y: integer);
procedure Get(var x,y: integer);
implementation
var
u,v: array[0..lMax-1]of integer;
i,j,h,t,l: integer;
procedure Put(x,y: integer);
begin
if l<lMax then begin
Inc(l);
h:=(h+1) mod lMax;
u[h]:=x;
v[h]:=y
end
end;
procedure Get(var x,y: integer);
begin
if l>0 then begin
Dec(l);
x:=u[t];
y:=v[t];
t:=(t+1) mod lMax
end
end;
begin
h:=0;
t:=1;
l:=0
end.
unit Board;
interface
uses CRT;
type
tMode=(No,Gr,Tx);
tPict=(Noth,Head,Bond,Rabb);
const
TxPict: array[tPict]of char=(' ','%','0','@');
var
Mode: tMode;
procedure SetMode(m: tMode);
function MinX: integer;
function MaxX: integer;
function MinY: integer;
function MaxY: integer;
procedure ShowBoard;
procedure Show(p: tPict; x,y:integer);
implementation
procedure SetMode(m: tMode);
begin
Mode:=m
end;
function MinX: integer;
begin
case Mode of
Gr: ;
Tx: MinX:=Lo(WindMin)+1;
end
end;
function MaxX: integer;
begin
case Mode of
Gr: ;
Tx: MaxX:=Lo(WindMax)+1;
end
end;
function MinY: integer;
begin
case Mode of
Gr: ;
Tx: MinY:=Hi(WindMin)+1;
end
end;
function MaxY: integer;
begin
case Mode of
Gr: ;
Tx: MaxY:=Hi(WindMax)+1;
end
end;
procedure ShowBoard;
begin
case Mode of
Gr: ;
Tx: ClrScr;
end
end;
procedure Show(p: tPict; x,y: integer);
begin
case Mode of
Gr: ;
Tx: begin
GoToXY(x,y);
Write(TxPict[p])
end
end
end;
begin
Mode:=No
end.
uses FIFO,Board,Dos,CRT;
var
i,x,y,u,v,x1,Rx,Ry,y1,x2,y2,sx,sy: integer;
t,dt: LongInt;
c: char;
e: boolean;
function Time: LongInt;
var
m,d,h,mi,s,s1:word;
l:LongInt;
begin
GetDate(h,m,d,mi);GetTime(h,mi,s,s1);l:=d;
Time:=(((l*24+h)*60+mi)*60+s)*100+s1
end;
begin
SetMode(Tx);
ShowBoard;
x1:=MinX;
x2:=MaxX;
y1:=MinY;
y2:=MaxY;
for i:=x1 to x2 do begin
GoToXY(i,y1);
Write('*');
GoToXY(i,y2);
Write('*');
end;
Inc(y1);
Dec(y2);
for i:=y1 to y2 do begin
GoToXY(x1,i);
Write('*');
GoToXY(x2,i);
Write('*');
end;
Inc(x1);
Dec(x2);
x:=x1;
y:=(y1+y2) div 2+1;
Show(Head,x,y);
Put(x,y);
sx:=1;
sy:=0;
Rx:=10;
Ry:=y;
t:=Time;
dt:=15;
e:=true;
repeat
if e then begin
Show(Rabb,Rx,Ry);
e:=false
end;
t:=t+dt;
Show(Bond,x,y);
x:=x+sx;
y:=y+sy;
Show(Head,x,y);
Put(x,y);
if (x<>Rx)or(y<>Ry) then begin
Get(u,v);
Show(Noth,u,v)
end
else begin
Rx:=Random(x2-x1-1)+x1+1;
Ry:=Random(y2-y1-1)+y1+1;
e:=true
end;
repeat until Time>t;
if KeyPressed then begin
c:=ReadKey;
if c=#0 then begin
c:=ReadKey;
case c of
#72: if sy<>1 then begin
sx:=0;
sy:=-1
end;
#75: if sx<>1 then begin
sx:=-1;
sy:=0
end;
#77: if sx<>-1 then begin
sx:=1;
sy:=0
end;
#80: if sy<>-1 then begin
sx:=0;
sy:=1
end
end
end
end
until (x<x1)or(y<y1)or(x>x2)or(y>y2)
end.
Спасибо, пойду разбираться потихоньку.
Приболела
Если рисовать змейку в текстовом режиме, то я бы рисовал её из треугольничков (#16, #17, #30, #31), указывающих на следующий сегмент. Конечно, запоминать где голова и хвост - всё равно надо. Зато сразу самопересечения легко обнаруживать. Конечно, при условии, что у нас есть возможность узнать, какой символ изображён на экране по таким-то координатам. Не знаю, какая процедура за это отвечает, в принципе можно обратиться к видеопамяти.
Ребят я конечно понимаю, что вы тут все уже профи, я учу паскаль только 3 месяца....
по этому не сильно "матюкайтесь" ))
плохо знаю структуры и т.п
Какое конкретно слово если непонятно - спрашивайте.
В общем вот примерная реализация того, что я имел в виду:
uses
CRT;
const
sLeft = #17;
sRight = #16;
sUp = #30;
sDown = #31;
sHead = '%';
sApple = '@';
kUp = #72;
kLeft = #75;
kDown = #80;
kRight = #77;
type
TScreenSymbol = record
Symbol: char;
Color: byte;
end;
var
Key, ScanKey: char;
Time: longint absolute $0040: $006C;
T: longint;
HeadX, HeadY, TailX, TailY: integer;
Direction: (dUp, dLeft, dDown, dRight);
Screen: array [0 .. 49, 0 .. 79] of TScreenSymbol absolute $B800: $0000;
Lost, Win: boolean;
oldTail: char;
x, y, c: integer;
begin
randomize;
TextMode(259);
ClrScr;
HeadX := 40;
HeadY := 40;
TailX := 40;
TailY := 41;
Direction := dUp;
Screen[HeadY, HeadX].Symbol := sHead;
Screen[HeadY, HeadX].Color := 14;
Screen[TailY, TailX].Symbol := sUp;
Screen[TailY, TailX].Color := 2;
Screen[HeadY - 10, HeadX].Symbol := sApple;
Screen[HeadY - 10, HeadX].Color := 4;
Lost := false;
repeat
if KeyPressed then begin
Key := ReadKey;
if Key = #0 then ScanKey := ReadKey
else ScanKey := #0;
end else begin
Key := #0;
ScanKey := #0;
end;
while T = Time do;
T := Time;
case ScanKey of
kUp: if Direction <> dDown then Direction := dUp;
kLeft: if Direction <> dRight then Direction := dLeft;
kDown: if Direction <> dUp then Direction := dDown;
kRight: if Direction <> dLeft then Direction := dRight;
end;
case Direction of
dUp: begin
Screen[HeadY, HeadX].Symbol := sUp;
Screen[HeadY, HeadX].Color := 2;
dec(HeadY);
if HeadY < 0 then Lost := True;
end;
dLeft: begin
Screen[HeadY, HeadX].Symbol := sLeft;
Screen[HeadY, HeadX].Color := 2;
dec(HeadX);
if HeadX < 0 then Lost := True;
end;
dDown: begin
Screen[HeadY, HeadX].Symbol := sDown;
Screen[HeadY, HeadX].Color := 2;
inc(HeadY);
if HeadY >= 50 then Lost := True;
end;
dRight: begin
Screen[HeadY, HeadX].Symbol := sRight;
Screen[HeadY, HeadX].Color := 2;
inc(HeadX);
if HeadX >= 80 then Lost := True;
end;
end;
case Screen[HeadY, HeadX].Symbol of
sUp, sLeft, sDown, sRight: Lost := True;
sApple: begin
c := 0;
repeat
inc©;
if c = 1000 then Win := True;
x := random(80);
y := random(50);
until (Screen[y, x].Symbol = ' ') or (c >= 1000);
Screen[y, x].Symbol := sApple;
Screen[y, x].Color := 4;
end;
else begin
oldTail := Screen[TailY, TailX].Symbol;
Screen[TailY, TailX].Symbol := ' ';
case oldTail of
sUp: dec(TailY);
sLeft: dec(TailX);
sDown: inc(TailY);
sRight: inc(TailX);
end;
end;
end;
Screen[HeadY, HeadX].Symbol := sHead;
Screen[HeadY, HeadX].Color := 14;
until (Key = #27) or Lost or Win;
if Lost then WriteLn('You have lost!');
if Win then WriteLn('You win!!!');
end.
Ага, спасибо.
А можно я немного обнаглею? мне очень понравилась та змейка которую я прикрепляла, где-то в нете нашла.
МОжет кто-то туда добавить коментариев? ООоооччень прошу )) хочу узнать , как там и что работает и что делается в той или иной процедуре
Ну тогда можеш коменты к своей програмке написать ? плиз)
п.с. в игре нужен щетчик очков, и несколько уровней сложности.
п.с. Уровни сложности я так поняла нужно прописывать через /delay? (скорость перемешения змейки) только как ?
Коментарии попробую, но только после оптимизации, а то кейсов у меня в коде многовато.
Лучше скажи, что конкретно непонятно.
А вот делэя не надо. Я зря что ли переменную Time ввёл? Вот специально чтобы не было зависимости скорости игры от мощности процессора.
Счётчик очков и нарастание сложности в код вполне вставляется, но я этого делать не буду, в конце концов не мне задание дали.
Счётчик делается простым выводом на экран процедурой Write, естественно надо указать куда выводить при помощи GotoXY.
Тут правда нюанс - эта надпись будет затираться змейкой. Поэтому её надо ограничить, не позволяя ей заходить на верхние 2 строчки (1я строчка для отображения состояния, 2я строчка - "заборчик" для наглядности), и соответственно в условие проигрыша добавить.
Сложность делается, например, так - всё, что связано с движениями змейки, заключается в условный оператор
if T mod Level = 0 then begin ... end
То есть змейка будет двигаться не каждый такт игры, а только в тот, чей номер делится на Level. Значение 1 - максимальный уровень сложности, чем больше значение, тем медленнее двигается змейка.
TarasBer, на мой взгляд неправильно учить новичка использовать прямое обращение к системной и аппаратной памяти. Это, кроме всего прочего, вызовет удивление преподавателя (это скорее слова к DarkMoonSIde). Очень рекомендую переделать на обращение через DOS и стандартные модули.
Поправилась. Вроде и силы появились. Я хочу задать несколько вопросов. Пожалуйсто, если сможете
1) Как сделать игровое поле? т.е. сделать часть экрана полем для "действий змейки" и часть для отоброжения очков и количества жизней (пример кода)
2)Как сделать рандомное появление квадратиков на этом поле, и увеличение змейки на один квадратик, если она "кушает" этот квадратик.
3)Как сделать ,что бы если длина змейки была 14 квадратиков, то начинался новый уровень (скорость змейки увеличивалась)
4) Как сделать несколько уровней и что-бы можно было ставить припятствия, и если змейка в него врезалась=смерть )
5)Как прописать сами движения змейки, на экране.
Пожалуйсто приведите примеры...потому что сухой код я не могу еще воспринимать, и без комментариев к коду я мало что понимаю
Ну игровое поле так и делаешь. Просто принудительно пишешь, что если HeadY < 2 то типа всё - врезались.
Чтоб змейка росла - на самом дела надо просто, чтобы он именно в момент поедания яблока НЕ сдвигала хвост.
Препятствия - ну просто на экране рисуешь плюсики, и в то место, где проверяется самопересечение (а там проеряется, что на месте головы стоит определённый символ), добавляешь ещё и символ стенки.
Чтобы уровень начинался - ну считай длину, потом когда достигла определённой длины, увеличиваешь сложность и всё заново начинаешь.
Коментарии - гм, в 100-строчном коде, неслабо наполненном водой?
Кстати, я тут подумал - а ведь будет зрелищнее, если задать режим не 80х50, а 40х25.
TarasBer а можеш написать примерную реализацию кодов к моим пунктам ? все равно не могу понять как написать..
Было, и сама пыталась сделать что то, хотя бы что бы двигалось подобие на червячек.
Буду сегодня вечером дома- напишу что не понятно из кода Lapp'a
Мне всё-таки непонятно, что в моём коде непонятно.
эм... задам вопрос: для замедления змейки использовать gettime и подключать лишний модуль, или всётаки использовать delay? ато ответа утвердительного так и не увидел