Понедельник, 06.05.2024
Королевство Delphi
Главное меню
Статьи
Наш опрос
Нравится раздел статьи?
Всего ответов: 68
Статистика
Онлайн всего: 1
Гостей: 1
Пользователей: 0
Форма входа
Главная » Статьи » Графика » DirectX

Изучаем DelphiX. Часть 1: Первая игра

"Как много игр то хороших,
Да только сегодня не до них"
Автор.

Здравствуйте! Сегодня мы создадим первую, и надеюсь не последнюю игрушку, смысл у нас будет такой: Мы - маленький космический корабль, нам надо уничтожить большой статичный космический корабль (прим. автора: "Этот пример научит мыслить по DelphiX`ски").

Ну что, приступим, запускаем Delphi . Вы, надеюсь, предварительно установили DelphiX, тогда ищем в панели с компонентами раздел DelphiX.

Кидаем на форму следующие компоненты:

DXDraw - и проставляем в нем следующие опции в Object Inspector:
Align = alClient - это нужно для того чтобы DXDraw "обтянул" всю форму.
Display = 800x600x16 - почему, спросите вы, не 800x600x24? Да потому что не все видеокарты поддерживают 24 битный режим.
Options-doFullScreen = True, если хочешь чтобы твоя игра была на весь экран, и ещё надо в свойствах формы поставить: BorderStyle = bsnone.

TDXSpriteEngine - Сам движок для работы со спрайтами. В нём нужно только выбрать в поле DXDraw сам DXDraw1.

TDXTimer - Он вообще-то и нужен, чтобы обновлять кадры, но он нам пригодится и для другого. Свойства следующие:
Active Only = False - По-русски: "Быть активным всегда". Смысл: Работает даже если вы, работаете с другим приложением.
Interval = 0 - Частота повторения цикла, должна быть равна 0.

TDXImageList - В этом листе будут у нас хранится все спрайты. Свойства:
DXDraw = DXDraw1
После кликаем на Items: (TPictureCollection), появляется окно Editing DxImagelist1.Items. В нём кликаем по Add New и в Object Inspector в поле "Name" пишем название спрайта, назовем его "pla" - это будет сам игрок, загружаем его с помощью Picture... Игрок у меня будет вот такой:

Только фон чёрный - для прозрачности. Устанавливаю в Object Inspector у данной картинки свойства Transparent = true и TransparentColor = clBlack.
Создаём ещё один спрайт под именем Pula проделываем тоже самое с ним, только TransparentColor = clWhite. Выглядит пуля вот так:

И последнее что нам осталось, добавить этого босса, называем его "BOSS".

TransparentColor = clWhite. На этом с DXImageList мы пока закончили.

TDXInput - Ну, а этот компонент будет отвечать за нажатые клавиши на клавиатуре. В нем никакие изменения делать не будем, только рассмотрим его (на будущее). Кликнем 2 раза по компоненту, и появится TDXInput Editor.

Первая закладка устанавливает свойства джойстика, вторая клавиатуры. Вот закладка со свойствами клавиатуры нам и нужна.

Слева - условное название клавиш, а справа - их значение. Каждому условному названию может быть присвоено 3 клавиши. Всего условных названий 36 штук.

Ну что, теперь приступаем к написанию кода.
Вначале нужно изменить класс формы на TDXForm вот пример:

До:

//...
type
 TForm1 = class(TForm)
 DXDraw1: TDXDraw;
 DXImageList1: TDXImageList;
 DXInput1: TDXInput;
//...

После:

//...
type
 TForm1 = class(TDXForm)
 DXDraw1: TDXDraw;
 DXImageList1: TDXImageList;
 DXInput1: TDXInput
//...

Дальше расписываем классы после implementation.

Вот так:

{$R *.DFM}

type
 TPlayerSprite = class(TImageSprite) //Класс игрока
 protected
 procedure DoMove(MoveCount: Integer); override; // Движение
 end;


 TBoSS = 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;

TPlayerFa = 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;

Далее расписываем каждую процедуру для каждого класса.

Вот образец:

Procedure TPlayerFa.DoMove(MoveCount: Integer);
Begin
 inherited DoMove(MoveCount);
end;

constructor TPlayerFa.Create(AParent: TSprite);
begin
end;

destructor TPlayerFa.Destroy;
begin
 inherited Destroy; // Обязательно 

end;

procedure TPlayerFa.DoCollision(Sprite: TSprite; var Done: Boolean);
begin
end;

Это нужно проделать с каждым классом, который содержит свои процедуры, указанные в классе.

Далее выбираем компонент DXTimer который уже на форме и в Object Inspector в закладке Events, находим пункт OnTimer. Два раза кликаем по пункту, создаётся процедура DXTimer1Timer, в ней пишем следующие строчки:

if not DXDraw1.CanDraw then exit; // Если нет DirectX выходим
 DXInput1.Update;
 DXSpriteEngine1.Move(LagCount);
 DXSpriteEngine1.Dead;
 DXDraw1.Surface.Fill(0);
 DXSpriteEngine1.Draw;
 DXDraw1.Flip;

Далее:
Кликая на форму в свободное место и Object Inspector в закладке Events, находим OnCreate. Создаём процедуру и пишем в ней:

with TBOSS.Create(Dxspriteengine1.Engine) do
begin
 PixelCheck := True; // для столкновения просчитывает каждую точку
 Image := form1.dxImageList1.Items.Find('BOSS'); //ищем спрайт в ImageList`е
 x:=350; // x координаты 
 y:=10; // y координаты
 Width := Image.Width; //ширина равна ширине спрайта 
 Height := Image.Height; //высота равна высоте спрайта
end;

with TPlayerSprite.Create(Dxspriteengine1.Engine) do
begin
 PixelCheck := True;
 Image := form1.dxImageList1.Items.Find('Pla');
 x:=350;
 y:=500;
 Width := Image.Width;
 Height := Image.Height;
end;

Сейчас объясню, зачем это всё. При создании формы мы создаём все статичные объекты сразу. Ну, что? Теперь можно перейти к процедурам и их заполнению :) Начнём с процедур босса. Они самые простые. Пред implementation в var добавить переменную

i:boolean; //переменная движения в сторону BOSSA

и в свойствах формы OnCreate добавить:

I:=true;

Только после этого пишем следующее:

Procedure TBoSS.DoMove(MoveCount: Integer);
 begin
 inherited DoMove(MoveCount);
 if x>= 700 then I:= true; // когда X>= то туда >>>
 if x<= 0 then I:= false; // когда X<= то туда <<<
 if i= true then X := X+10;
 if i= false then X := X-10;
Collision;
end;

constructor TBOSS.Create(AParent: TSprite); //Здесь всё понятно
begin
 inherited Create(AParent);
 Image := form1.DXImageList1.Items.Find('BOSS');
 Width := Image.Width;
 Height := Image.Height;
end;

destructor TBOSS.Destroy; //тут тоже
begin
 inherited Destroy;
end;

procedure TBoss.DoCollision(Sprite: TSprite; var Done: Boolean);
begin
 // если спрайт сталкивается с Tplayerfa, то умирает
 if Sprite is Tplayerfa then dead;
 Collision; // Включаем столкновение
end;

Ну, вроде, с одним объектом разобрались, переходим к игроку, тут одна процедура

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
 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;
 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;
end;

И, наконец, последнее, это сама пуля и её процедуры:

Procedure TPlayerFa.DoMove(MoveCount: Integer); 
begin
 inherited DoMove(MoveCount);
 y:=y-3; //проще некуда, неправда ли?
end;

procedure TPlayerFa.DoCollision(Sprite: TSprite; var Done: Boolean);
begin
 if Sprite is TBoss then dead;
 Collision;
end;

И на последок, для удобства в Object Inspector в закладке Events находим OnKeyDown, кликаем и пишем:

if Key=VK_ESCAPE then application.Terminate;

При вставке этого кода по нажатию клавиши ESC выходим из приложения.

Вот и всё! Это одно из самых примитивных игр на DelphiX, но ты её сам сделал.

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

Ну и всё, если вы сможете реализовать данные вещи, считайте что вы усвоили урок. Ну а если вы не справитесь с данными задачами, я объясню их решение в следующей части.

Исходный код примера к этому уроку: part1.rar (20,5 кБ) (Проект сделан в Delphi 6)

Автор: Влад Энгельгардт

Получить ссылку на материал

Категория: DirectX | Добавил: Барон (08.12.2011)
Просмотров: 1337 | Теги: DelphiX | Рейтинг: 0.0/0
[ Пожертвования для сайта ] [ Пожаловаться на материал ]

Если вам помог материал сайта кликните по оплаченной рекламе размещенной в центре

Поиск
Категории раздела
DirectX [17]
OpenGL [2]
Игры [15]
Разные [28]
Королевство Delphi © 2010-2024
Яндекс цитирования