IPB
ЛогинПароль:

> Игра с корабликами, графический режим
Lazzy
сообщение 15.12.2007 17:37
Сообщение #1





Группа: Пользователи
Сообщений: 9
Пол: Мужской
Реальное имя: тьома

Репутация: -  0  +


Привета!
Задача формулировалась преподом довольно размыто, поэтому может присутствовать некоторая вольность в выполнении, что не может не радовать. Смысл в том, чтоб написать на Pascal (к сожалению) игру, в которой есть кораблики, соревнующиеся между собой Препод седой уже, кстати. Он хотел там видеть возможность выбора направления ветра и хода корабликов галсами при встречном ветре, но реализовать управление парусами, по-моему, слишком сложно, а как без этого галсами ходить? Поэтому реализация мне видится так: вид сверху на остров либо замкнутый кольцевой канал, один кораблик с мотором, цель игры - управляя корабликом стрелками пройти дистанцию за наименьшее время. Если у кого-то возникнет желание помочь или вдруг есть какие-то наработки, буду очень признателен.
Вот код:
program MAPA3M;
uses crt, graph;
var
Gd,Gm:integer;
posX,posY:integer;
ch:char;

procedure bereg;
begin
setcolor(yellow);
setfillstyle(7,yellow);
sector(280,200,0,360,100,50);
sector(360,200,0,360,80,80);
sector(280,280,0,360,120,70);
sector(360,280,0,360,60,75);
sector(15,450,0,360,55,80);
sector(260,460,0,360,60,30);
sector(600,470,0,360,150,30);
sector(15,410,0,360,20,80);
sector(30,20,0,360,40,25);
sector(500,0,0,360,90,50);
sector(600,15,0,360,80,50);
sector(630,230,0,130,50,100);
sector(610,160,0,120,50,120);
sector(610,450,0,110,75,100);
sector(650,350,0,220,60,100);
sector(140,15,0,200,80,30);
sector(200,20,0,360,100,50);
sector(60,150,60,220,150,200);
sector(150,30,0,360,100,100);
sector(5,240,30,330,40,90);
sector(630,240,0,360,70,100);
sector(360,5,0,360,100,30);
sector(630,240,110,300,70,100);
sector(0,280,0,360,80,100);
sector(100,470,360,360,120,60);
pieslice(380,420,200,340,100);
end;
begin
clrscr;
Gd:=VGA;
Gm:=VGAhi;
initgraph(Gd,Gm,'');
if graphresult=grok then
begin
bereg;
setcolor(brown);
setfillstyle(1,brown);
posX:=500;
posY:=250;
fillellipse(posX,posY,1,1);
repeat
ch:=readkey;
case ch of
#72:begin posY:=posY-5; fillellipse(posX,posY,1,1);setcolor(black);
setfillstyle(0,black);fillellipse(posX,posY+5,1,1);setcolor(brown);
setfillstyle(1,brown); end;
#75:begin posX:=posX-5; fillellipse(posX,posY,1,1);setcolor(black);
setfillstyle(0,black);fillellipse(posX+5,posY,1,1); setcolor(brown);
setfillstyle(1,brown); end;
#77:begin posX:=posX+5; fillellipse(posX,posY,1,1);setcolor(black);
setfillstyle(0,black);fillellipse(posX-5,posY,1,1);setcolor(brown);
setfillstyle(1,brown); end;
#80:begin posY:=posY+5; fillellipse(posX,posY,1,1);setcolor(black);
setfillstyle(0,black);fillellipse(posX,posY-5,1,1);setcolor(brown);
setfillstyle(1,brown); end;
#27:halt;
end;{case}
until ch=#27;
closegraph;
end
else
writeln(grapherrormsg(graphresult));
end.
Тут нарисованы берега "лагуны" с островом посередине, вид сверху. Кораблик обозначен коричневой точкой и управляется с клавиатуры, это пока все =/ Как видите, нету навыка работы с процедурами, пишется сложно =/
Что конкретно неясно как реализовать:
Как сделать чтоб кораблик при нажатиии клавиши начинал двигаться в направлении нажатой стрелки и не прекращал движение? Сейчас он двигается только, когда стрелка нажата.
Можно ли сделать движение по диагонали? Сейчас судно движется только в четырех направлениях.
Как реализовать крушение кораблика при столкновении с берегом? (Видимо, нужно написать функцию, возвращающую значение цвета пикселов вокруг кораблика, и если эти значения равны значению цвету берега - корабль тонет)
Как с помощью Pascal реализовать счетчик времени? Ведь цель игры - пройти дистанцию за наименьшее время. Искал в учебниках, а там работа только с временем системы. Как сделать, чтоб игрок вводил свое имя и результаты записывались в текстовый файл?
Как сделать скорость кораблика независимой от тактовой частоты? Ведь delay зависит, если не ошибаюсь, от этого параметра, значит на разных компьютерах игра с этой процедурой будет иметь разную скорость?

Заранее спасибо.
Файл pas в аттаче.


Прикрепленные файлы
Прикрепленный файл  _.PAS ( 2.16 килобайт ) Кол-во скачиваний: 130200
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
 
 Ответить  Открыть новую тему 
Ответов
Гость
сообщение 22.06.2008 12:58
Сообщение #2


Гость






Программа была мною еще доработана - появилась анимация крушения и анимация поворота. Однако при доработке не удалось сохранить первоначальную стройную структуру, предложенную andriano. Видимо, эта проблема вызвана отсутствием навыка в построении блок-схем. Надеюсь услышать коструктивную критику
program MAPA3M;
uses crt, graph;
var
Gd,Gm:integer;
posX,posY,i,k,n:integer;
ch:char;
dir,ldir,choice:integer;
m:array [1..6] of pointtype;
const z=10;{zaderzgka}
function checkcollision(posX,posY:integer):boolean;
begin
checkcollision:=false;
if (getpixel(posX+8,posY+3)=darkgray) or (getpixel(posX-8,posY-3)=darkgray) or
(getpixel(posX+3,posY+8)=darkgray) or (getpixel(posX-3,posY-8)=darkgray) or
(getpixel(posX+8,posY-3)=darkgray) or (getpixel(posX-8,posY+3)=darkgray) or
(getpixel(posX-3,posY+8)=darkgray) or (getpixel(posX+3,posY-8)=darkgray)
then
checkcollision := true;
end;

function Menu(Params: string): integer;
var
Count: integer;
Strings: array [0 .. 15] of string [127];
i: integer;
Ch: char;
X, Y, H: integer;
begin
Count := 1;
Strings[0] := '';
for i := 1 to Length(Params) do begin
if Params[i] = #13 then begin
Inc(Count);
Strings[Count - 1] := '';
end else begin
Strings[Count - 1] := Strings[Count - 1] + Params[i];
end;
end;
SetTextJustify(CenterText, CenterText);
H := TextHeight('A') + 10;
ClearDevice;
SetColor(WHITE);
for i := 0 to Count - 1 do
OutTextXY(GetMaxX div 2,
GetMaxY div 2 - (Count - 1) * H div 2 - H div 4 + i * H, Strings[i]);
i := 0;
repeat
SetColor(GREEN);
X := TextWidth(Strings[i]) + 10;
Y := TextHeight(Strings[i]) + 10;
Rectangle(GetMaxX div 2 - X div 2,
GetMaxY div 2 - (Count - 1) * H div 2 + i * H - Y div 2,
GetMaxX div 2 + X div 2,
GetMaxY div 2 - (Count - 1) * H div 2 + i * H + Y div 2);
ch := readkey;
SetColor(BLACK);
X := TextWidth(Strings[i]) + 10;
Y := TextHeight(Strings[i]) + 10;
Rectangle(GetMaxX div 2 - X div 2,
GetMaxY div 2 - (Count - 1) * H div 2 + i * H - Y div 2,
GetMaxX div 2 + X div 2,
GetMaxY div 2 - (Count - 1) * H div 2 + i * H + Y div 2);
case ch of
#0: case ReadKey of
#72: begin Dec(i);
if i < 0 then
i := Count - 1;
end;
#80: begin
Inc(i);
if i >= Count then
i := 0;
end;
end;
end;
until ch = #13;
Menu := i;
end;

procedure delay(Wait:word); assembler;
asm
mov ax,Wait
mov dx,1000
mul dx
mov cx,dx
mov dx,ax
mov ah,$86
int $15
end;


procedure
bereg;
begin
cleardevice;
setcolor(darkgray);
setfillstyle(2,darkgray);
{sector(280,200,0,360,100,50);}
sector(360,200,0,360,80,80);
sector(280,280,0,360,120,70);
sector(360,280,0,360,60,75);
sector(15,450,0,360,55,80);
sector(260,460,0,360,60,30);
sector(600,470,0,360,150,30);
sector(15,410,0,360,20,80);
sector(30,20,0,360,40,25);
sector(500,0,0,360,90,50);
sector(600,15,0,360,80,50);
sector(630,230,0,130,50,100);
sector(610,160,0,120,50,120);
sector(610,450,0,110,75,100);
sector(650,350,0,220,60,100);
sector(140,15,0,200,80,30);
sector(200,20,0,360,100,50);
sector(60,150,60,220,150,200);
sector(150,30,0,360,100,100);
sector(5,240,30,330,40,90);
sector(630,240,0,360,70,100);
sector(360,5,0,360,100,30);
sector(630,240,110,300,70,100);
sector(0,280,0,360,80,100);
sector(100,470,360,360,120,60);
pieslice(380,420,200,340,100);
end;
procedure
restore_background(dir:integer);
begin

if dir=0 then
begin
setcolor(brown);
setfillstyle(1,brown);
fillellipse(posX,posY,8,3);
end;
if (dir=2) or (dir=3) then
begin
setcolor(blue);
setfillstyle(0,blue);
fillellipse(posX,posY,14,4);
end;
if (dir=1) or (dir=4) then
begin
setcolor(blue);
setfillstyle(1,blue);
fillellipse(posX,posY,4,14);
end

end;
procedure
moveship(dir:integer);
begin
case dir of
1: posY:=posY-5;
2: posX:=posX-5;
3: posX:=posX+5;
4: posY:=posY+5;
end;{case}
end;{procedure}
procedure drawcollision(dir:integer);
var a,z:integer;
begin
if (dir=1) then
begin
setcolor(blue);
setfillstyle(0,1);
fillellipse(posX,posY+13,4,4);
for z:=0 to 8 do
begin
for a:=0 to 6 do
begin
putpixel(posX+3-a,posY+8-z,blue);
delay(z*500);
end;
end;
end;
if (dir=2) then
begin
setcolor(blue);
setfillstyle(0,1);
fillellipse(posX+13,posY,4,4);
for z:=0 to 8 do
begin
for a:=0 to 6 do
begin
putpixel(posX+8-z,posY+3-a,blue);
delay(z*500);
end;
end;
end;
if (dir=3) then
begin
setcolor(blue);
setfillstyle(0,0);
fillellipse(posX-13,posY,4,4);
for z:=0 to 8 do
begin
for a:=0 to 6 do
begin
putpixel(posX-8+z,posY-3+a,blue);
delay(z*500);
end;
end;
end;
if (dir=4) then
begin
setcolor(blue);
setfillstyle(0,0);
fillellipse(posX,posY-13,4,4);
for z:=0 to 8 do
begin
for a:=0 to 6 do
begin
putpixel(posX-3+a,posY-8+z,blue);
delay(z*500);
end;
end;
end;
end;


procedure draw_ship(dir:integer);
begin
setcolor(brown);
setfillstyle(1,brown);
if (dir=1) then
begin
fillellipse(posX,posY,3,8);
setfillstyle(11,lightgray);
randomize;
setcolor(blue);
fillellipse(posX,posY+10+random(2),3,2);


end;
if (dir=2) then
begin
fillellipse(posX,posY,8,3);
setfillstyle(11,lightgray);
randomize;
setcolor(blue);
fillellipse(posX+10+random(2),posY,2,3);
end;
if (dir=3) then
begin
fillellipse(posX,posY,8,3);
setfillstyle(11,lightgray);
randomize;
setcolor(blue);
fillellipse(posX-10+random(2),posY,2,3);
end;
if (dir=4) then
begin
fillellipse(posX,posY,3,8);
setfillstyle(11,lightgray);
randomize;
setcolor(blue);
fillellipse(posX,posY-10+random(2),3,2);
end;
end;


procedure changedirhv;
begin
for k := 0 to 6 do with m[k] do
begin
x:=trunc(posX+((8-n)*cos(k*1.05)));
y:=trunc(posY-((3+n)*sin(k*1.05)));
end;
setcolor(blue);
setfillstyle(0,blue);
fillellipse(posX,posY,12,12);
setcolor(brown);
setfillstyle(1,brown);
fillpoly(6,m);
delay(z*1900);
end;
procedure changedirvh;
begin
setcolor(brown);
setfillstyle(1,brown);
for k := 0 to 6 do with m[k] do
begin
x:=trunc(posX+((3+n)*cos(k*1.05)));
y:=trunc(posY-((8-n)*sin(k*1.05)));
end;
setcolor(blue);
setfillstyle(0,blue);
fillellipse(posX,posY,12,12);
setcolor(brown);
setfillstyle(1,brown);
fillpoly(6,m);
delay(z*1900);
end;

procedure changedir(dir,ldir:integer);
begin
for n:=0 to 5 do
begin
if ((ldir=2)or(ldir=3)or(ldir=0))and((dir=1)or(dir=4)) then
begin
changedirhv;
moveship(dir);
end;
if ((ldir=1)or(ldir=4))and((dir=2)or(dir=3)) then
begin
changedirvh;
moveship(dir);
end;
end;
if ((ldir=2)and(dir=3))or((ldir=3)and(dir=2)) or
((ldir=1)and(dir=4))or((ldir=4)and(dir=1)) then
delay(z*1900);
end;
{*******************************main*************************************}
begin
clrscr;
Gd:=VGA;
Gm:=VGAhi;
initgraph(Gd,Gm,'');
if graphresult=grok then
begin
choice:=Menu('Play'#13'Exit');
while (choice=0) do
begin
setbkcolor(blue);
cleardevice;
bereg;
posX:=500;
posY:=250;
{draw_ship(2);}
repeat
if keypressed then
begin
ch:=readkey;
case ch of
#72:begin ldir:=dir; dir:=1; changedir(dir,ldir); end;
#75:begin ldir:=dir; dir:=2; changedir(dir,ldir); end;
#77:begin ldir:=dir; dir:=3; changedir(dir,ldir); end;
#80:begin ldir:=dir; dir:=4; changedir(dir,ldir); end;
end; {case ch}
end;
restore_background(dir);
moveship(dir);
draw_ship(dir);
delay(z*1000);
if checkcollision(posX,posY)=true then
begin
drawcollision(dir);
ch:=#27;
setbkcolor(black);
cleardevice;
end;{if..then}
until ch=#27;
choice:=Menu('Play'#13'Exit');
dir:=0;
ch:=' ';
end;
closegraph;
halt;
end
else
writeln(grapherrormsg(graphresult));
end.

Как видно, я вставил ассемблерную вставку для того, чтобы программа работала с одинаковой задержкой на разных машинах, но корабль стал плавать слишком быстро, а при попытке увеличить параметр Delay выдается ошибка "Constant out of range", т. е. эта вставка не подходит, помогите пожалуйста сделать лучше.
Еще возник вопрос: как осуществить движение корабля под разными углами, чтоб он при нажатии клавиши постепенно менял направление движения? С помощью FillEllipse нарисовать такой корабль не получится, видимо, нужно делать с помощью FillPoly, желательно с большим каоличеством вершин. Но главное - неясно, как задать перемещение, т. е. смену координат.
 К началу страницы 
+ Ответить 

Сообщений в этой теме
Lazzy   Игра с корабликами   15.12.2007 17:37
andriano   >Как сделать чтоб кораблик при нажатиии клавиши...   15.12.2007 18:06
Lazzy   andriano, спасибо за обстоятельный ответ. Я попроб...   16.12.2007 3:28
andriano   Именно в этом случае и нужна переменная - в ней бу...   16.12.2007 10:39
Lazzy   andriano, спасибо больщущее! :cool: Благодаря...   18.12.2007 23:19
Lapp   P.S. Как репутацию подымать? :cool: Есть два спо...   19.12.2007 7:20
andriano   По поводу ошибки - ничего сказать не могу, нет у м...   19.12.2007 9:06
spill   Да, Delay зависит от производительности ЦП. Вот мо...   19.02.2008 14:07
andriano   Вообще-то это не очень хороший вариант. Начиная с ...   19.02.2008 20:35
spill   Вопрос в том, как проверить, пропаченый модуль или...   20.02.2008 13:34
andriano   Если на компе с тактовой частотой 200 МГц и выше р...   20.02.2008 19:08
Lazzy   Прошу прощения за долгое отсутствие. Причина ошиб...   24.03.2008 19:10
Lazzy   Я поискал по форуму меню, наткнулся на такую верси...   25.03.2008 19:42
Гость   Программа была мною еще доработана - появилась ани...   22.06.2008 12:58
Lazzy   Предыдущее сообщение мое.   22.06.2008 13:02
renesko1   Поставь 2 задержки подряд...   22.06.2008 13:16
andriano   1. Если планируется отрабатывать несколько различн...   22.06.2008 16:29
Lazzy   Вот что получилось - корабль нарисован из круга, п...   10.10.2008 0:30


 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



- Текстовая версия 6.08.2025 15:10
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"