![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Нужен совет к 2D аркаде! [Delphi]
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 оружия.