Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Нужен совет к 2D аркаде! [Delphi]


Страницы:   1 2 3

ZAROLF ©   (2003-12-14 16:49:00) 

Вообщем дела такие, надо оружие подогнать под выстрел. Мало того в четырёх разных положениях:стоя влево,стоя вправо,сидя влево,сидя вправо.
И все это оказалось не так просто, обычный "angle" всеголишь разворачивал
спрайт, а спрайт этот анимированый.

И вот под каждое положение нужно чтото подобное:

if isButton1 in MainForm.DXInput.States then //здесь типа выстрел
   begin
     with TShoot2.Create(Engine) do
     begin
       PixelCheck := True;
       Image := MainForm.ImageList.Items.Find('Shoot2');
       X := Self.X+Self.Width  -40;
       Y := Self.Y+Self.Height -38;
       Width := Image.Width;
       Height := Image.Height;
   end;
 end;

constructor TShoot2.Create(AParent: TSprite);
begin
inherited Create(AParent);
 Image := MainForm.ImageList.Items.Find('Shoot2');
 Width := Image.Width;
 Height := Image.Height;
end;

Procedure TShoot2.DoMove(MoveCount: Integer);
Begin
inherited DoMove(MoveCount);
if y<= 0 then Dead;
if y>= 480 then Dead;
x:=x+5;
if m mod 1 = 0 then
if AnimCount<5 then inc(AnimCount) else AnimCount:=0;
AnimPos:= AnimCount;
end;


ZAROLF   (2003-12-19 14:53:00) [21]

>SoulSilver ©   (19.12.03 13:41) [24]
>P.S. У меня это работает...
-----------------------------------------------------------------
Благодарю за совет - действительно работает, игруха скоро будет готова. Сейчас работаю над AI - довольно недурной, хочу заставить
самонаводящуюся ракету обходить препятствия.


SoulSilver   (2003-12-19 13:41:00) [22]

2 ZAROLF ©  

if (клавиша стрелять) then begin
if (перезарядка > какого-то числа) then begin
Создаем пулю begin
X := Player.X+(Player.Width/2);
Y := Player.Y+(Player.Height/2);
end;
end;
end;

if (клавиша стрелять) and (клавиша сидеть) then begin
if (перезарядка > какого-то числа) then begin
Создаем пулю begin
X := Player.X+(Player.Width/2);
Y := Player.Y+(Player.Height/2+чего-то);
end;
end;
end;

P.S. У меня это работает...


ZAROLF   (2003-12-19 13:17:00) [23]

SoulSilver ©   (19.12.03 12:19) [22]
А летят в два слоя это как? (прости мое невежество) :-)
-----------------------------------------------------------------
Да нужно когда садишся(смещать по Y вниз) как то заглушить координаты из положения стоя. А то пули летят поверху и по низу.


SoulSilver   (2003-12-19 12:19:00) [24]

2 ZAROLF ©:
if P1Direct = -1 then X := Player.X+(Player.Width/2-5);
if P1Direct = 1 then X := Player.X+(Player.Width/2+5);

Проще говоря когда игрок нажимает клавишу влево, то P1Direct= - 1, а когда нажимает клавишу вправо, то P1Direct = 1, а затем когда игрок нажимает клавишу стрельбы, то пуля по идее должа вылетать из дула, так вот +5 и -5 в коде - это просто координаты дула, для красоты короче, а else я вообще тут не использую и не понимаю зачем он нужен в данном случае.
На счет стрельбы из положения сидя я скажу, что есть элементарный способ: когда игрок нажимает клавишу вниз, то картинка персонажа меняется на "положение сидя", оружие смешается вниз по Y, но так как у тебя нет класса оружия и патроны создаются из самого героя, то просто необходимо создавать пули со смещением по Y. Я считаю, что ты намудрил с функцией и двумя классами, но если оно работает, то ничего плохого в этом нет. А летят в два слоя это как? (прости мое невежество) :-)


ZAROLF   (2003-12-18 16:18:00) [25]

Я уже решил эту проблему своим способом:

TShoot1Left = class(TImageSprite)
  protected
   procedure DoCollision(Sprite: TSprite; var Done: Boolean); override;
   procedure DoMove(MoveCount: Integer); override;
  public
   constructor Create(AParent: TSprite); override;
   destructor Destroy; override;
 end;

 TShoot1Right = class(TImageSprite)
  protected
   procedure DoCollision(Sprite: TSprite; var Done: Boolean); override;
   procedure DoMove(MoveCount: Integer); override;
  public
   constructor Create(AParent: TSprite); override;
   destructor Destroy; override;
 end;

//здесь выстрел
if (isButton1 in MainForm.DXInput.States) and (CanShoot(0)) then
begin
with TShoot1Left.Create(Engine) do
begin
PixelCheck := True;
Image := MainForm.ImageList.Items.Find('Shoot1');
Y := Player.Y+(Player.Height/4+2);
Width := Image.Width;
Height := Image.Height;
if Direct = -1 then
X := Player.X+(Player.Width/2-30)
else
if Direct = 1 then
begin
with TShoot1Right.Create(Engine) do
begin
PixelCheck := True;
Image := MainForm.ImageList.Items.Find('Shoot1');
X := Player.X+(Player.Width/2+24);
Y := Player.Y+(Player.Height/4+2);
Width := Image.Width;
Height := Image.Height;
//collision;
end;
end;
end;
end;
end;

Вот что я не пойму в твоём коде это:

if P1Direct = -1 then X := Player.X+(Player.Width/2-5);
if P1Direct = 1 then X := Player.X+(Player.Width/2+5);

как они у тебя подразделяются без "else" ?
-----------------------------------------------------------------
2.
Далее, мне нужен алтернативный способ стрелять сидя, как можно
проще сделать. Я вот пробовал через "Can":

function TPlayer.CanShoot(t:shortint): boolean;
begin
result:=true;
case t of
0: if ((isButton1 in MainForm.DXInput.States)and(isDown in MainForm.DXInput.States))then
begin
with TShoot1Left.Create(Engine) do
begin
PixelCheck := True;
Image := MainForm.ImageList.Items.Find('Shoot1');
Y := Player.Y+(Player.Height/2.4+2);
Width := Image.Width;
Height := Image.Height;
if Direct = -1 then
X := Player.X+(Player.Width/2-30)
else
if Direct = 1 then
begin
with TShoot1Right.Create(Engine) do
begin
PixelCheck := True;
Image := MainForm.ImageList.Items.Find('Shoot1');
X := Player.X+(Player.Width/2+24);
Y := Player.Y+(Player.Height/2.4+2);
Width := Image.Width;
Height := Image.Height;
end;
end;
end;
end;
end;
end;

... и знаеш чё получается, пули летят в два слоя.
Может сообразим как сделать более правильно.


SoulSilver   (2003-12-18 15:13:00) [26]

type

TPlayer = class(TImageSprite)
protected
procedure DoCollision(Sprite: TSprite; var Done: Boolean); override;
procedure DoMove(MoveCount: Integer); override;
end;

TWeapon = class(TImageSpriteEx)
protected
procedure DoMove(MoveCount: Integer); override;
procedure DoDraw; override;
end;

TWeapon04_Rocket = class(TImageSpriteEx)
protected
procedure DoCollision(Sprite: TSprite; var Done: Boolean); override;
procedure DoMove(MoveCount: Integer); override;
procedure DoDraw; override;
end;

var

Player: TSprite; //Игрок
Weapon: TWeapon; //Оружие
Weapon04_Rocket: array[0..999] of TWeapon04_Rocket; //Массив рокет
P1Direct: integer; //Направление героя (влево/вправо)
P1Reload: integer; //Значение текущей перезарядки
P1MaxReload: integer; //Значение перезарядки, чтобы патрон выстрелил
P1Clip: integer; //Обойма


Пошли процедуры

//Отображение оружия Игрока
procedure TWeapon.DoDraw;
Begin
Image.Drawrotate(MainForm.DXDraw.Surface,round(Player.WorldX)+16,round(Player.WorldY)+16,image.width,image.height,round( animpos),0.5,0.5,Angle);
end;

//Движение и стрельба оружия Игрока1
procedure TWeapon.DoMove(MoveCount: Integer);
begin
inherited DoMove(MoveCount);
if isButton3 in MainForm.DXInput.States then
begin

if P1Direct = -1 then begin //Если игрок повернут влево, то
if P1Reload > P1MaxReload then begin //Если оружие перезарядилось, то
MainForm.DXWaveList.Items.Find('weapon04_rocketlauncher').Play(false); //Проигрываем звук выстрела
Weapon04_Rocket[n] := TWeapon04_Rocket.Create(MainForm.DXSpriteEngine.Engine); //Создаем рокету
with TWeapon04_Rocket(Weapon04_Rocket[n]) do
begin
Image := MainForm.ImageList.Items.Find('weapon04_rocket');
Width := 8;
Height := 8;
if P1Direct = -1 then X := Player.X+(Player.Width/2-5);
if P1Direct = 1 then X := Player.X+(Player.Width/2+5);
Y := Player.Y+(Player.Height/2+3);
Z := 5;
Angle := Weapon.Angle;
AnimSpeed := 100/3000;
Animlooped := true;
AnimStart := 0;
AnimCount := 17;
PixelCheck := false;
Collisioned := true;
end;
P1Reload := 0; //Присваеваем "переменной перезарядки" значению 0
dec(P1Clip); //Уменьшаем на один патрон в обойме
end;
end;
end;
end;

//Отображение рокеты Игрока1
procedure TWeapon04_Rocket.DoDraw;
Begin
Image.Drawrotate(MainForm.DXDraw.Surface,round(WorldX),round(WorldY),image.width,image.height,round(animpos),0.5,0.5,Ang le);
end;

//Движение рокеты Игрока1
procedure TWeapon04_Rocket.DoMove(MoveCount: Integer);
var
i: integer;
begin
inherited DoMove(MoveCount);
if X < 0 then Dead;
if X > 800 then Dead;
if Y < 0 then Dead;
if Y > 600 then Dead;

X := X + sin256(Angle) * (Weapon04_rocketStartSpeed/1000)*MoveCount;
Y := Y - cos256(Angle) * (Weapon04_rocketStartSpeed/1000)*MoveCount;
Collision;
end;

//Столкновение рокеты Игрока1
procedure TWeapon04_Rocket.DoCollision(Sprite: TSprite; var Done: Boolean);
begin
if Sprite is TMap then Dead;
end;


Вот так бы я сделал, надеюсь разберешься. Я знаю, как сложно разбираться в чужом коде, но попробуй.


ZAROLF   (2003-12-17 18:36:00) [27]

SoulSilver ©   (17.12.03 18:20) [18]
> Если честно, то я немного не врубаюсб почему так происходит,
> но могу дать пример своего кода, который работает нормально.
> P.S. Приведи код, именно в том месте, где создается патрон
> у игрока
-----------------------------------------------------------------
А я твой код использовал в демке(всё как есть),а мой ничем особенным не блещет - стреляет в одном направлении или x- или x+.

P.S. Лучше приведи пример как бы ты сделал в данном случае (в моей игре),чтобы стрелять во все стороны "x"-+, и сидя желательно тоже.


SoulSilver   (2003-12-17 18:20:00) [28]

Если честно, то я немного не врубаюсб почему так происходит, но могу дать пример своего кода, который работает нормально.
P.S. Приведи код, именно в том месте, где создается патрон у игрока


ZAROLF   (2003-12-17 18:03:00) [29]

SoulSilver ©
>Пули то у тебя не анимированные или я чего-то не догоняю...
-----------------------------------------------------------------
Дык это выстрел ракеты - которую выпускает враг,это я просто пример выставлял.

Дык всётаки в чём проблема с оружием у плеера.


SoulSilver   (2003-12-17 17:51:00) [30]

2 ZAROLF ©  
Посмотрел,  да увидел наконец, что не так у тебя. Скажи, а для чего у тебя

Procedure TShoot2.DoMove(MoveCount: Integer);
Begin
inherited DoMove(MoveCount);
if y<= 0 then Dead;
if y>= 480 then Dead;
x:=x+5;
if m mod 1 = 0 then //Вот от сюда
if AnimCount<5 then inc(AnimCount) else AnimCount:=0;
AnimPos:= AnimCount;
//До сюда
end;

Пули то у тебя не анимированные или я чего-то не догоняю...


ZAROLF   (2003-12-17 14:02:00) [31]

SoulSilver ©   (17.12.03 13:41) [14]
>Сори, но не распаковывается архив, пришли, если можешь рар или >экзешник.
-----------------------------------------------------------------
Отправляю в SFX. 337 килов.


SoulSilver   (2003-12-17 13:41:00) [32]

2 ZAROLF ©
!   C:\Games\Archive\ChaosindaHouse\Demo.zip: Either multipart or corrupt ZIP archive
!   Cannot execute "C:\WINDOWS\TEMP\Rar$EX01.743\Demo.exe"

Сори, но не распаковывается архив, пришли, если можешь рар или экзешник.


ZAROLF   (2003-12-17 13:32:00) [33]

SoulSilver   (17.12.03 12:05) [12]
> Я немного не понимаю, можешь прислать демку и посмотрим.
-----------------------------------------------------------------
Демку тебе выслал проверь ящик.


SoulSilver   (2003-12-17 12:05:00) [34]

> ZAROLF ©
Я немного не понимаю, можешь прислать демку и посмотрим.


Thor   (2003-12-16 19:59:00) [35]


> ZAROLF ©   (16.12.03 18:13) [10]

на gamedev.ru был цикл статей про игру на delphiX и я делал стрелялку. вроде все нормально вылетало. (оружие поворачивалось)


ZAROLF   (2003-12-16 18:13:00) [36]

>SoulSilver   (16.12.03 15:27) [9]
>Всё вроде, это код из моей игры, тоже 2D Аркады. Когда >напишешь, выложи тут игру, посмотрим.
-----------------------------------------------------------------
Тут одна загвоздка, персонаж может только идти и стрелять одновременно. По отдельности нехочет ни двигаться ни стрелять.

Да, скинуть демку я могу тебе на только на mail.


SoulSilver   (2003-12-16 15:27:00) [37]

Вот пример, для начала создаем класс пули, хотя я думаю что ты это всё знаешь, но всё-равно:

//Класс пули Игрока
TBullet = class(TImageSpriteEx)//Для того, чтобы был параметр Angle
protected
procedure DoCollision(Sprite: TSprite; var Done: Boolean); override;
procedure DoMove(MoveCount: Integer); override;
procedure DoDraw; override;
end;


Далее в процедуре DoMove оружияпишем, в тот момент, когда нажимаем клавишу(стреляем), создается пуля:

AngleCorrective:=random(3); //Это для того, чтобы у пуль был разлет(небольшой), опиши в var'е
Bullet := TBullet.Create(MainForm.DXSpriteEngine.Engine);
with TBullet(Bullet) do
begin
Image := MainForm.ImageList.Items.Find('bullet');
Width := 2;
Height := 2;
if PDirect = -1 then X := Player.X+(Player.Width/2-3); //Это я сделал для того, чтобы, если игрок стоит и смотрит влево(PDirect = -1, то пуля создается возле дула оружия(у меня это координата по X описана выше)
if PDirect = 1 then X := Player.X+(Player.Width/2+3);//Тоже самое, но если стоит и повернут вправо
Y := Player.Y+(Player.Height/2+2); //Здесь поправка по Y, для красоты
Z := 5;
//Далее, конечно можно было 'case' использовать, ну да ладно, это собственно небольшой разлет пули, ну понял, поправка угла полета пули  
if P1GunAngleCorrective = 0 then Angle:=Weapon.Angle;
if P1GunAngleCorrective = 1 then Angle:=Weapon.Angle+1;
if P1GunAngleCorrective = 2 then Angle:=Weapon.Angle-1;
PixelCheck := false;
Collisioned := true;
end;


Далее процедуры пули:

procedure TBullet.DoDraw; //Тут идет отображение пули и поворот картинки соответственно углу её полета
begin
Image.Drawrotate(MainForm.DXDraw.Surface,round(WorldX),round(WorldY),image.width,image.height,round(animpos),0.5,0.5,Ang le);
end;

procedure TBullet.DoMove(MoveCount: Integer);
begin
inherited DoMove(MoveCount);
if X < 0 then Dead;
if X > 800 then Dead;
if Y < 0 then Dead;
if Y > 600 then Dead;
X := X + sin256(Angle) * (bulletSpeed/1000)*MoveCount; //BulletSpeed - это компонента, влияющая на скорость пули, присвой ей чего-нибудь
Y := Y - cos256(Angle) * (bulletSpeed/1000)*MoveCount;
Collision;
end;

procedure TBullet.DoCollision(Sprite: TSprite; var Done: Boolean);
begin
if Sprite is TMap then Dead; //При столкновении пули с картой - убиваем её
end;


Всё вроде, это код из моей игры, тоже 2D Аркады. Когда напишешь, выложи тут игру, посмотрим.


ZAROLF   (2003-12-15 14:58:00) [38]

> SoulSilver   (15.12.03 14:47) [6]
> У пули есть параметри Angle? Если есть, то я не вижу проблемы,
> а для красоты подгони немного точку вылета пули по Y под
> координату положения стровола по Y в горизонтальном положении,
> при вылете пули присваивай Angle пули - Angle оружия.
-----------------------------------------------------------------

А пример бы написал, а то я уже это пробовал делать - неполучается.


Niklto   (2003-12-15 14:49:00) [39]

A her ego znaet


SoulSilver   (2003-12-15 14:47:00) [40]

У пули есть параметри Angle? Если есть, то я не вижу проблемы, а для красоты подгони немного точку вылета пули по Y под координату положения стровола по Y в горизонтальном положении, при вылете пули присваивай Angle пули - Angle оружия.


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо