В общем давно собирался написать статью о написании не очень сложной RPG на GLScene. В качества ориентира были выбраны Heroes 3 или Disciples. Механика будет упрощена и многие моменты опущены, дабы не усложнять статью и дать возможность читателю внести , что то своё. Я не стану выкладывать всё в одной статье , а разобью её на несколько дабы не сваливать всё в кучу. И так наша цель , простая РПГ на GLScene.
Что желательно приготовить ? Вообще в принципе т.к. это первая часть, что GLScene и Delphi\Lazarus будет достаточно, однако для дальнейшие работы хорошо бы иметь навыки работы с графическими редакторами вроде GIMP или PhotoShop, а так же иметь модели\спрайты персонажей и GUI ну или художника который это нарисует.
Часть 1. Создаём мир
И так в это статье мы создадим локацию для нашей игры, а так же подготовим всё для дальнейший работы. Вообще так как это пример то я создам бонально плеин с текстуркой, но я думаю многие смогут сделать например в Максе уровень а потом подгрузить его или вообще собрать его вручную. И так создаём сцену и добавляем то что видим на скрине , ниже объясню что к чему.
И так источники света как полагается из названия для света, GLXYXGrid - сетка пошагавая РПГ же. Plane - это наша земля. DCSelect - дами куб для нашего курсора в сцене GLLines - а это как бы наш курсор DCTarget - тут наша камера DCUnit - тут наши юниты DCGui - в этот дамик мы помещаем все gui, те все спрайты с оформлением DCSpell - в этом кубе у нас все эффекты будут DCMonster - а это у нас для монстра) GLParticleFXRenderer1 - для рендера эффекта У Plane ставим Direction 0 0 1 ,а Position Y=-4 и размеры 40x40. Вот вам текстура на землю. Для камеры Direction 0 0 -1, а Position 0 -2 4. У Сетки ставим Sampling Scale Max 10 Min -10 ,а Step 1. У Lines в Nodes добавлям 0 - 0 0 0 1 - 1 0 0 2 - 1 1 0 3 - 0 1 0 4 - 0 0 0 Т.е. у нас получился квадрат, который у нас и будет своего рода курсором. Теперь касательно GUI вообще у каждого оно свое, я лишь в своём примере использую интерфейс как у WoW (собственно на него от туда и взял спрайты) но вы можете сделать так как вам удобно. Я лично создаю его в ран таме , хотя вы его можете делать в дизайн тайме если вам удобнее.
with TGLHUDSprite(Form1.DCGUI.AddNewChild(TGLHUDSprite)) do begin name := 'HUDSprite_'+inttostr(Form1.DCGUI.Count); Position.X:=49; Position.Y:=Form1.Height-50; Width:=124; Height:=46; //Scale.Y:=5; //Scale.Z:=2; Material.Texture.Image.LoadFromFile(ExtractFilePath(Application.ExeName)+'core/gui_00.bmp'); Material.Texture.Disabled:=false; // Material.Texture.ImageAlpha := tiaSuperBlackTransparent; // Material.Texture.TextureMode := tmReplace; // Material.BlendingMode:= bmTransparency;
end;
Подобным методом я создаю текст with TGLHUDText(Form1.DCGUI.AddNewChild(TGLHUDText)) do begin name:='P1Text0'; BitmapFont:=Form1.GLWindowsBitmapFont1; Position.X:=Form1.Width-100; Position.Y:=Form1.Height-265; ModulateColor.SetColor(255,255,255,1); Text:='Player 1'; end;
Ну и конечно меню Menu:= TMainMenu.Create(DCGUI,GLWindowsBitmapFont2); Menu.AddItem(Menu.MMenu,'New'); Menu.AddItem(Menu.MMenu,'About'); Menu.AddItem(Menu.MMenu,'Close'); Menu.MMenu.Selected:=0;
Ну и на последок добавим вращение камерой и выборки пунктов меню procedure TForm1.GLSceneViewer1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin if ssRight in shift then GLCamera1.MoveAroundTarget(my-y,mx-x); mx:=x; my:=y;
Menu.MMenu.MouseMenuSelect(x,y); if Menu.MMenu.Selected=0 then пишем что у вас там именно )
end;
Кстати можно создать небо с помощью SkyCube, возьмём метод из демки LoadTexture(Matname,Filename : string) : TGLLibMaterial; begin Result := GLMaterialLibrary1.AddTextureMaterial(Matname,mediaPath +'core/sky/'+ Filename); Result.Material.Texture.Disabled := false; Result.Material.Texture.TextureMode := tmDecal; end; А дальше грузим сомо небо With LoadTexture('Left','mountain_east.bmp') do begin Material.BlendingMode := bmTransparency; Material.FrontProperties.Diffuse.Alpha := 0.3;
TextureScale.X := 1; TextureScale.y := 1;
end; With LoadTexture('Right','mountain_west.bmp') do begin Material.BlendingMode := bmTransparency; Material.FrontProperties.Diffuse.Alpha := 0.3;
TextureScale.X := 1; TextureScale.y := 1;
end; With LoadTexture('Front','mountain_south.bmp') do begin Material.BlendingMode := bmTransparency; Material.FrontProperties.Diffuse.Alpha := 0.3;
TextureScale.X := 1; TextureScale.y := 1;
end; With LoadTexture('Back','mountain_north.bmp') do begin Material.BlendingMode := bmTransparency; Material.FrontProperties.Diffuse.Alpha := 0.3;
TextureScale.X := 1; TextureScale.y := 1;
end;
With LoadTexture('Top','mountain_up.bmp') do begin Material.BlendingMode := bmTransparency; Material.FrontProperties.Diffuse.Alpha := 0.3;
TextureScale.X := 1; TextureScale.y := 1;
end; With LoadTexture('Bottom','mountain_down.bmp') do begin Material.BlendingMode := bmTransparency; Material.FrontProperties.Diffuse.Alpha := 0.3;
TextureScale.X := 0.5; TextureScale.y := 0.5;
end;
Хотя можно полениться и вообще небо делать , а сделать так что камера не когда не посмотрит вверх либо сделать небо с помощью SkyDome.
Ну вот и все для начала мы создали как бы мир в следующие статье начнем работать над самой игровой механикой.