В 2019 году вышел новый NeoAxis Engine, и я подумал, что не сделать на нем игру просто некрасиво.
Поэтому я решил сделать на нем пару игр. А начать с самого простого — с шутера. Ну и заодно объяснить, как делаются игры на этом замечательном движке.
Итак, начал я с создания нового пустого проекта и изменил начальный экран игры. Это по стандарту файл Base\UI\Screens\SplashScreen.ui и его cs файл.
В UI просто убрал картинку, отвечающую за название проекта при загрузке (Project). C# файл пришлось больше изменять, убирая из него все, что связанно с той картинкой.
Итоговый вариант C# файла:
Также я заменил файл PoweredBy, изменив его на свое изображение сделанное в фотошопе.
Следующий шаг — изменение дизайна UI, вынужден признать, это заняло достаточно времени.
Изменял я скопированный Base\UI\Styles\Simple.uistyle и его C# файл.
Это оказалось не совсем быстро и просто.
После того, как более-менее настроил стиль ui, изменил его в ui главного меню.
Замечательно, но с ui ещё не закончили.
Сделал PlayScreen, это окошко для выбора уровня:
А вот и код её C# файла:
Обращу внимание на строку "SimulationApp.CurrentUIScreen is PlaySys playsys".
PlaySys это файл загрузки сцены, я скопировал его из Base\UI\Screens\PlayScreen.ui ну и его c# файл.
Все. Мы успешно закончили возиться с основной UI в этой игре. Правда осталось окошко паузы… Но его оставим на потом. Во второй части разберем создание уровня для шутера.
Поэтому я решил сделать на нем пару игр. А начать с самого простого — с шутера. Ну и заодно объяснить, как делаются игры на этом замечательном движке.
Итак, начал я с создания нового пустого проекта и изменил начальный экран игры. Это по стандарту файл Base\UI\Screens\SplashScreen.ui и его cs файл.
В UI просто убрал картинку, отвечающую за название проекта при загрузке (Project). C# файл пришлось больше изменять, убирая из него все, что связанно с той картинкой.
Итоговый вариант C# файла:
SplashScreen.cs
public class SplashScreen : UIControl
{
bool gotoMainMenu;
bool gotoMainMenuUpdated;
[Serialize]
[DefaultValue( 2.0 )]
public double PoweredByTime { get; set; } = 2.0;
[Serialize]
[DefaultValue( 0.5 )]
public double FadingTime { get; set; } = 0.5;
protected override void OnEnabledInSimulation()
{
PreloadImage();
ResetCreateTime();
}
void PreloadImage()
{
if (Components["PoweredBy"] is UIImage image)
{
var v = image.SourceImage;
}
}
protected override void OnUpdate( float delta )
{
base.OnUpdate( delta );
if( EngineApp.ApplicationType == EngineApp.ApplicationTypeEnum.Simulation )
{
if( gotoMainMenuUpdated )
{
SimulationApp.ChangeUIScreen( @"Game/Screens/MainMenu.ui" );
EngineApp.ShowCursor = true;
}
if( Time > GetTotalTime() )
gotoMainMenu = true;
}
}
double GetTotalTime() => 1.0 + FadingTime + PoweredByTime + FadingTime + 1.0 + FadingTime;
void GetImagesTransparency( out double poweredBy, out double project )
{
var curve = new CurveLine();
curve.AddPoint( 0, new Vector3( 0, 0, 0 ) );
curve.AddPoint( 1.0, new Vector3( 0, 0, 0 ) );
curve.AddPoint( 1.0 + FadingTime, new Vector3( 1, 0, 0 ) );
curve.AddPoint( 1.0 + FadingTime + PoweredByTime, new Vector3( 1, 0, 0 ) );
curve.AddPoint( 1.0 + FadingTime + PoweredByTime + FadingTime, new Vector3( 0, 0, 0 ) );
curve.AddPoint( 1.0 + FadingTime + PoweredByTime + FadingTime + 1.0, new Vector3( 0, 0, 0 ) );
curve.AddPoint( 1.0 + FadingTime + PoweredByTime + FadingTime + 1.0 + FadingTime, new Vector3( 0, 1, 0 ) );
var value = curve.CalculateValueByTime( Time );
poweredBy = MathEx.Saturate( value.X );
project = MathEx.Saturate( value.Y );
if( gotoMainMenu )
{
poweredBy = 0;
project = 0;
}
}
void UpdateImagesTransparency()
{
GetImagesTransparency( out var poweredBy, out var project );
if (Components["PoweredBy"] is UIImage image)
image.ColorMultiplier = new ColorValue(1, 1, 1, poweredBy);
}
protected override void OnRenderUI( CanvasRenderer renderer )
{
if( EngineApp.ApplicationType == EngineApp.ApplicationTypeEnum.Simulation )
UpdateImagesTransparency();
base.OnRenderUI( renderer );
if( EngineApp.ApplicationType == EngineApp.ApplicationTypeEnum.Simulation )
{
if( gotoMainMenu )
gotoMainMenuUpdated = true;
EngineApp.ShowCursor = false;
}
}
}
Также я заменил файл PoweredBy, изменив его на свое изображение сделанное в фотошопе.
(Лично по моему это отличное решение, наша картинка выглядит гораздо лучше чем изначальная)
Следующий шаг — изменение дизайна UI, вынужден признать, это заняло достаточно времени.
(Кстати, если кому-то нравится изначальный синий вариант ui — я не спорю. Просто он раздражает лично меня.)
Изменял я скопированный Base\UI\Styles\Simple.uistyle и его C# файл.
Это оказалось не совсем быстро и просто.
После того, как более-менее настроил стиль ui, изменил его в ui главного меню.
Получилось достаточно красиво, после синего стиля этот серый вообще стал для меня идеалом)
Замечательно, но с ui ещё не закончили.
Сделал PlayScreen, это окошко для выбора уровня:
А вот и код её C# файла:
PlayWindow.cs
public class PlayWindow : NeoAxis.UIWindow
{
protected override void OnEnabledInSimulation()
{
const string V = "ExitBtn";
if (Components[V] != null)
((UIButton)Components[V]).Click += Exit;
const string V1 = "Play_1";
if (Components[V1] != null)
((UIButton)Components[V1]).Click += Play;
const string V2 = "Play_2";
if (Components[V2] != null)
((UIButton)Components[V2]).Click += Play;
const string V3 = "Play_3";
if (Components[V3] != null)
((UIButton)Components[V3]).Click += Play;
}
protected void Exit(UIButton sender) => EngineApp.NeedExit = true;
protected void Play(UIButton sender)
{
var playFile = "";
switch (sender.Name)
{
case "Play_1": playFile = @"Game\Scenes\1\level.scene"; break;
case "Play_2": playFile = @"Game\Scenes\2\level.scene"; break;
case "Play_3": playFile = @"Game\Scenes\3\level.scene"; break;
}
if (SimulationApp.ChangeUIScreen(@"Game\Screens\PlaySys.ui"))
{
if (SimulationApp.CurrentUIScreen is PlaySys playsys)
{
playsys.Load(playFile, true);
playsys.ResetCreateTime();
}
}
}
protected override bool OnKeyDown(KeyEvent e)
{
if (e.Key == EKeys.Escape)
{
Dispose();
return true;
}
return base.OnKeyDown(e);
}
}
Обращу внимание на строку "SimulationApp.CurrentUIScreen is PlaySys playsys".
PlaySys это файл загрузки сцены, я скопировал его из Base\UI\Screens\PlayScreen.ui ну и его c# файл.
Все. Мы успешно закончили возиться с основной UI в этой игре. Правда осталось окошко паузы… Но его оставим на потом. Во второй части разберем создание уровня для шутера.