PDA

Показать полную графическую версию : [решено] Игра на Pascal


nemo_the_capitain@vk
03-05-2013, 18:57
Собственно, делаю мою первую небольшую игрушку (Top-Down shooter) на PascalABC.net
Почти все сделал, кроме столкновения выстрела с противником и столкновения противника с игроком.
путем проб и ошибок выяснил, что код не реагирует на пересечение спрайтов, хотя должен. Помогите, товарищи, пожалуйста, я уже второй день думаю

uses graphabc, abcobjects;
var obj:objectabc;
health:integer;
wall:objectabc;
blast:objectabc;
score:integer;
enemy: array [1..10] of objectabc;
procedure Move(x,y,mb: integer);
begin
obj.Moveto(x,y);
end;

procedure enemystart;
begin
enemy[1]:=pictureabc.create (random(10,500),-50, 'enemy.png');
enemy[2]:=pictureabc.create (random(10,500),-50, 'enemy.png');
enemy[3]:=pictureabc.create (random(10,500),-50, 'enemy.png');
enemy[4]:=pictureabc.create (random(10,500),-50, 'enemy.png');
enemy[5]:=pictureabc.create (random(10,500),-50, 'enemy.png');
enemy[5]:=pictureabc.create (random(10,500),-50, 'enemy.png');
enemy[6]:=pictureabc.create (random(10,500),-50, 'enemy.png');
enemy[7]:=pictureabc.create (random(10,500),-50, 'enemy.png');
enemy[8]:=pictureabc.create (random(10,500),-50, 'enemy.png');
enemy[9]:=pictureabc.create (random(10,500),-50, 'enemy.png');
enemy[10]:=pictureabc.create (random(10,500),-50, 'enemy.png');
end;


procedure enemymove;
begin
foreach x: objectabc in enemy do
repeat
x.Moveto (x.Left,x.Top+1);
sleep (1);
until x.Intersect (wall)=false
end;


procedure fire (x,y,mb:integer);
begin
if mb=1 then
blast:= pictureabc.Create (obj.Left+25,obj.Top,'blast.png');
repeat
blast.MoveOn (0,-1);
until blast.Intersect (wall)=false
end;


procedure kill; //Не работает выстрел
begin
foreach x:objectabc in enemy do
begin
if x.Intersect (blast)=true then x.Destroy;
score:=score+1;
end;
end;

procedure boom; //Не работает столкновение
begin
foreach x:objectabc in enemy do
begin
if x.Intersect (obj)=true
then
health:=health-10;
x.Destroy;
end;
end;


begin
health:=100;
setwindowsize (539,479);
SetWindowIsFixedSize (true);
setwindowcaption ('Game');
wall:=pictureabc.Create(0,0,'wall.jpg');
obj:=pictureabc.Create(250,440,'ship.png');
Onmousemove:= Move;
Onmousedown:=fire;
repeat
enemystart;
enemymove;
kill;
boom;
until health=0;
write ('Вы умерли, ваши очки: ', score);
end.

lxa85
03-05-2013, 19:21
nemo_the_capitain@vk, не ясна реализация функции x.Intersect ().
Можно получить полный архив игры?

nemo_the_capitain@vk
03-05-2013, 19:31
x.intersect () проверяет пересечение изображений
архив пожалуйста: (http://forum.oszone.net/attachment.php?attachmentid=98364&stc=1&d=1367595135)

lxa85
03-05-2013, 20:35
Чудная какая то среда.
nemo_the_capitain@vk, у вас несколько нарушена логика работы приложения.
repeat
enemystart;
enemymove;
kill;
boom;
until health=0;
Сначала происходит запуск всех 10 самолетов противника (enemystart). Они все доходят до конца экрана, а только затем запускаются процедуры обработки столкновения и попадания выстрелом.
Т.е. процедуры kill и boom надо совместить с процедурой полета самолета противника (enemymove) и с процедурой выстрела (fire) соответственно.
По началу сбивает с толку, что самолет движется (Onmousemove:= Move;) и даже стреляет (Onmousedown:=fire;). Т.е. строго говоря создаются отдельные потоки и они выполняются вполне себе параллельно.
Да, с одной стороны это удобно, с другой не очень - теория прихрамывает.

Полусырой вариант таков:
uses graphabc, abcobjects;
var obj:objectabc;
health:integer;
wall:objectabc;
blast:objectabc;
score:integer;
enemy: array [1..10] of objectabc;
procedure Move(x,y,mb: integer);
begin
obj.Moveto(x,y);
end;

procedure enemystart;
begin
enemy[1]:=pictureabc.create (random(10,500),-50, 'enemy.png');
enemy[2]:=pictureabc.create (random(10,500),-50, 'enemy.png');
enemy[3]:=pictureabc.create (random(10,500),-50, 'enemy.png');
enemy[4]:=pictureabc.create (random(10,500),-50, 'enemy.png');
enemy[5]:=pictureabc.create (random(10,500),-50, 'enemy.png');
enemy[5]:=pictureabc.create (random(10,500),-50, 'enemy.png');
enemy[6]:=pictureabc.create (random(10,500),-50, 'enemy.png');
enemy[7]:=pictureabc.create (random(10,500),-50, 'enemy.png');
enemy[8]:=pictureabc.create (random(10,500),-50, 'enemy.png');
enemy[9]:=pictureabc.create (random(10,500),-50, 'enemy.png');
enemy[10]:=pictureabc.create (random(10,500),-50, 'enemy.png');
end;


procedure shoot; //Не работает выстрел
begin
foreach x:objectabc in enemy do begin
if x.Intersect(blast) then
x.Destroy;
score:=score+1;
end;
end;

procedure boom; //Не работает столкновение
begin
foreach x:objectabc in enemy do begin
if x.Intersect (obj) then
health:=health-10;
x.Destroy;
end;
end;


procedure enemymove;
var flag:boolean;
begin
foreach x: objectabc in enemy do
repeat
flag:=false;
x.Moveto (x.Left,x.Top+1);
if x.Intersect (obj) then begin
health:=health-10;
x.Destroy;
flag:=true;
end;
until not(flag) or not(x.Intersect (wall));
end;


procedure fire (x,y,mb:integer);
begin
if mb=1 then
blast:= pictureabc.Create (obj.Left+25,obj.Top,'blast.png');
repeat
blast.MoveOn (0,-1);
shoot;
until blast.Intersect (wall)=false
end;


begin
health:=100;
setwindowsize (539,479);
SetWindowIsFixedSize (true);
setwindowcaption ('Game');
wall:=pictureabc.Create(0,0,'wall.jpg');
obj:=pictureabc.Create(250,440,'ship.png');
Onmousemove:= Move;
Onmousedown:=fire;
enemystart;
repeat
enemymove;
//kill;
//boom;
until health=0;
write ('Вы умерли, ваши очки: ', score);
end.
Надо ее еще полчаса, час до ума довести и будет вполне себе детская срелялка.




© OSzone.net 2001-2012