Приветствую Вас Гость | RSS

Меню сайта

Реклама

Категории раздела
Bitmap [50]
Canvas [0]
DirectX и DelphiX [39]
GIF [3]
ICO [24]
JPEG [14]
MetaFile [6]
OpenGL [9]
ScreenSaver и ScreenMate [13]
Векторная графика [2]
Графика [37]
Изображения [0]
Картография [6]
Компоненты и Графика [0]
Создание игр [17]
Цвета и Палитра [0]
Шрифты [0]

Наш опрос
Какие компоненты добавлять больше?
Всего ответов: 49

Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0

Форма входа

Главная » Статьи » Графика и Игры » DirectX и DelphiX

Изучаем DelphiX - Часть 2 - Усложняем нашу игру
Прежде чем начать, объясню решение Д/З:

1. Сделайте так, чтобы при уходе патрона из зоны видимости он уничтожался:

Это очень легко сделать достаточно в процедуру DoMove патрона вставить:

if y<= 0 then Dead;
if y>= 600 then Dead;

Нужно это для того, чтобы повысилось качество игры.

2. Сделайте, чтобы патроны стреляли очередями, а не кучами как у меня:

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

В класс с плеером добавляем две переменные, он теперь выглядит так (я добавил комментарии к тем строчкам которые изменились):

TPlayerSprite = class(TImageSprite)
Private
lngpolet:integer; //расстояние которое пролетела пуля
oldlngpolet:integer; //расстояние которое пролетела предыдущая пуля
protected
procedure
DoMove(MoveCount: Integer); override;
end;
Процедура DoMove класса PlayerSprite изменяется следующим образом:
Procedure TPlayerSprite.DoMove(MoveCount: Integer);
Begin
inherited
DoMove(MoveCount);
if isLeft in Form1.DXInput1.States then x:=x-5;
if isRight in Form1.DXInput1.States then X:=x+5;
if isup in Form1.DXInput1.States then
begin
if
lngpolet-oldlngpolet<=250 then // Если расстояние между пулями меньше 250,
// то пуля не создаётся
begin
Inc(lngpolet);
with TPlayerFa.Create(Engine) do
begin
PixelCheck := True;
Image := form1.dxImageList1.Items.Find('Pula');
X := Self.X+Self.Width -40;
Y := Self.Y+Self.Height -80;
Width := Image.Width;
Height := Image.Height;
end;
oldlngpolet := lngpolet; //после создания пули - последняя становится первой
end;
end;
if y <= form1.DXDraw1.SurfaceHeight-image.Height then
y := form1.DXDraw1.SurfaceHeight-image.Height;
if x <= form1.DXDraw1.SurfaceWidth -image.Width then
x := form1.DXDraw1.SurfaceWidth -image.Width;
if y >= 0 then
y := 1;
if x >= 0 then
x:=1;
lngpolet := lngpolet + MoveCount; // расстояние увеличиваем, когда пуля движется
end;

Вот и всё, что требовалось сделать.

В этой части вы узнаете:
1. Создание анимации.
2. Создание примитивного AI.
3. Создадим простенькие взрывы.

Создание анимации.

Анимация в DelphiX строится следующим образом:


Это пример покадровой анимации. У каждого кадра должен быть одинаковый размер.

В данной ситуации:
Ширина: 40
Высота: 38

Давайте теперь, применим ее к нашей игре.
Идём в DXImageList, находим наш спрайт Pula и загружаем картинку с анимацией. Далее устанавливаем свойства спрайта следующим образом:


и в процедуре DoMove класса PlayerSprite изменяем код следующим образом:

Procedure TPlayerSprite.DoMove(MoveCount: Integer);
begin
inherited
DoMove(MoveCount);
if isLeft in Form1.DXInput1.States then x:=x-5;
if isRight in Form1.DXInput1.States then X:=x+5;
if isup in Form1.DXInput1.States then
begin
if
lngpolet-oldlngpolet<=250 then
begin
Inc(lngpolet);
with TPlayerFa.Create(Engine) do
begin
PixelCheck := True;
Image := form1.dxImageList1.Items.Find('Pula');
X := Self.X+Self.Width -40;
Y := Self.Y+Self.Height -80;
Width := Image.Width;
Height := Image.Height;
AnimCount := Image.PatternCount; //число кадров
AnimLooped := True; //повторять ли анимацию
AnimSpeed := 10 / 1000; //скорость анимации
end;
oldlngpolet := lngpolet;
end;
end;
if y <= form1.DXDraw1.SurfaceHeight-image.Height then
y := form1.DXDraw1.SurfaceHeight-image.Height;
if x <= form1.DXDraw1.SurfaceWidth -image.Width then
x := form1.DXDraw1.SurfaceWidth -image.Width;
if y >= 0 then
y := 1;
if x >= 0 then
x:=1;
lngpolet := lngpolet + MoveCount;
end;

Можно проделать тоже самое с другими классами для придания реалистичности игры.

Cоздание примитивного AI.

Для начала маленько улучшим наш класс плеера, добавим в него столкновение, и он теперь выглядит следующим образом:

TPlayerSprite = class(TImageSprite)
private
lngpolet:integer;
oldlngpolet:integer;
protected
procedure
DoMove(MoveCount: Integer); override;
//добавляем
procedure DoCollision(Sprite: TSprite; var Done: Boolean); override;
end;
Далее создаём процедуру DoCollision и вставляем в неё следующее:
procedure TPlayerSprite.DoCollision(Sprite: TSprite; var Done: Boolean);
begin
if
Sprite is TPlayerFa then Dead;
Collision;
end;
Дальше пред implementation добавляем 1 переменную:
 plx:double; //X плеера
Далее обновим класс TPlayerFa и он станет таким:
TPlayerFa = class(TImageSprite)
private
stril:Integer; // Как вы заметили, добавилась переменная
protected
procedure
DoCollision(Sprite: TSprite; var Done: Boolean); override;
procedure DoMove(MoveCount: Integer); override;
public
constructor
Create(AParent: TSprite); override;
destructor Destroy; override;
end;
А в TPlayerFa добавляем строчку:
Procedure TPlayerFa.DoMove(MoveCount: Integer);
begin
y:=y-stril; // когда стреляет игрок, с этой скоростью будет двигаться пуля
y:=y+stri; // когда стреляет AI, с этой скоростью будет двигаться пуля
if y>= 0 then Dead;
if y<= 600 then Dead;
end;
А процедура TBoSS.DoMove становиться такой:
Procedure TBoSS.DoMove(MoveCount: Integer);
begin
inherited
DoMove(MoveCount);
if x<= 600 then I:= false;
if x>= 0 then I:= true;
if i= true then X := X+5;
if i= false then X := X-5;
if plx=x then //если равна х плеера стреляем
begin
with
TPlayerFa.Create(Engine) do
begin
PixelCheck := True;
Image := form1.dxImageList1.Items.Find('Pula');
X := Self.X+Self.Width-70;
Y := Self.Y+Self.Height+10;
Width := Image.Width;
Height := Image.Height;
stril:=5; //скорость патрона
end;
end;
Collision;
end;
И естественно полнеет и TPlayerSprite:
Procedure TPlayerSprite.DoMove(MoveCount: Integer);
begin
inherited
DoMove(MoveCount);
plx:=x; //чтобы наш комп видел нашего плеера
if isLeft in Form1.DXInput1.States then
begin
x:=x-5;
plx:=x;
end;
if isRight in Form1.DXInput1.States then
begin
X:=x+5;
plx:=x;
end;
if isup in Form1.DXInput1.States then
begin
if
lngpolet-oldlngpolet<=250 then
begin
Inc(lngpolet);
with TPlayerFa.Create(Engine) do
begin
PixelCheck := True;
Image := form1.dxImageList1.Items.Find('Pula');
X := Self.X+Self.Width -40;
Y := Self.Y+Self.Height -80 ;
Width := Image.Width;
Height := Image.Height;
stril:=-4;
end;
oldlngpolet := lngpolet;
end;
end;
if y <= form1.DXDraw1.SurfaceHeight-image.Height then
y := form1.DXDraw1.SurfaceHeight-image.Height;
if x <= form1.DXDraw1.SurfaceWidth -image.Width then
x := form1.DXDraw1.SurfaceWidth -image.Width;
if y >= 0 then
y := 1;
if x >= 0 then
x:=1;
lngpolet := lngpolet + MoveCount;
Collision;
end;
И поменялся конструктор PlayerFa:
constructor TPlayerFa.Create(AParent: TSprite);
begin
inherited
Create(AParent);
Image := form1.DXImageList1.Items.Find('Pula');
Width := Image.Width;
Height := Image.Height;
AnimCount := Image.PatternCount; //число кадров
AnimLooped := True; //повторять ли анимацию
AnimSpeed:= 10 / 1000;
Collision;
end;

Создадим простенькие взрывы.

Для начала загрузим спрайт взрыва в DXImageList вот он:


Назовём его "ex" и установим размер кадра на 32Х48 (PatternHeight - PatternWidth)

Дальше, в класс TPlayerSprite в private добавляем procedure Hit; и создаём обработчик:

procedure TplayerSprite.Hit;
begin
Collisioned := False;
Image := Form1.dxImageList1.Items.Find('Ex');
Width := Image.Width;
Height := Image.Height;
AnimCount := Image.PatternCount;
AnimLooped := False;
AnimSpeed := 15/1000;
AnimPos := 0;
end;
и в процедуре TPlayerSprite.DoCollision вставляем следущий код:
procedure TPlayerSprite.DoCollision(Sprite: TSprite; var Done: Boolean);
begin
if
sprite is Tplayerfa then
begin
TPlayerSprite(Sprite).Hit;
dead;
end;
Done := False;
end;
Этот код надо разместить и в Tboss. DoCollision. И под конец маленький бонус: Можно создать бэкграунд, без создания нового класса достаточно в FormCreate написать:
 with TBackgroundSprite.Create(DXSpriteEngine1.Engine) do
begin
SetMapSize(1,1);
Image := dxImageList1.Items.Find('bgr');
Z:= -2;
Tile := True;
end;

Где bgr спрайт-бэкграунд.
Вот мой БГ:


Категория: DirectX и DelphiX | Добавил: Angel (12.07.2008)
Просмотров: 335 | Рейтинг: 0.0/0
  Delphi Lab   Главная   Регистрация   Вход  
Интересная Цитата

Поиск

Магазин


Copyright MyCorp © 2025 Хостинг от uCoz