Астероиды, C#, 3D и OpenGL
Сегодняшний проект – простой пример использования OpenGL и C#/WinForm для создания игры начального уровня. Что в ней нравится, так это то, что она действительно очень простая, с легко понимаемым кодом, и с ней легко начать работать…
Трехмерная игра начального уровня «Астероиды» на openGL с C#
Эта статья предназначена для начинающих, кто хочет приступить к программированию трехмерных игр, но не знает, с чего начать. Игра сделана на OpenGL с использованием VS2008 и маленького графического движка, созданного мною и называющегося Shadowengine. Она имеет лишь основное, что должно быть у игры: счет, уровни сложности и живой счетчик. Всё это занимает небольшое число строк кода с простыми и понятными целями.
Первой проблемой, с которой я столкнулся, была сцена, которая должна выглядеть как дальний космос. Для нее я сделал фон черным. В OpenGL это достигается следующим образом:
...
Счет – это число, увеличивающееся со временем, и скорость его роста каждый раз увеличивается с переходом на следующий уровень. Уровень увеличивается через каждые 450 кадров.
Последней проблемой, с которой я столкнулся, были столкновения с астероидом. Я выделил для корабля три позиции (одну для корпуса корабля и две для крыльев) и каждый раз проверял расстояния между всеми астероидами и этими тремя позициями. Если расстояние оказывалось меньше заранее заданной величины, регистрировалось столкновение.
В проекте шесть классов:
- AsteroidGenerator . cs – Он управляет появлением в случайном месте астероида случайного размера и скорости. В нем есть метод, определяющий было или нет столкновение между кораблем и астероидом.
- Asteroid . cs – Он управляет всем, имеющим отношение к астероиду: движением, выбором текстуры, прорисовкой и другими параметрами.
- Star . cs – Класс содержит метод создания случайных белых точек и их прорисовки.
- Camera . cs – Класс управляет выбором камеры пользователя и задает правильную перспективу сцены.
- SpaceShip . cs – Этот класс содержит методы и атрибуты, имеющие отношение к космическому кораблю: перемещения, прорисовка и т. д.
- Controller . cs – Этот класс управляет инициализацией игры, ее логикой и содержит все классы, необходимые для запуска игры. Вот фрагмент кода:
- ...
Main . cs – Это форма, содержащая все визуальные компоненты игры. Она включает класс Controllerи предоставляет игроку информацию об всех элементах управления. В ней есть таймер, периодически перерисовывающий сцену и код для загрузки текстуры и объекта.
...
Хотя игра написана для VS2008, у меня она прекрасно загрузилась в VS2010 (и была конвертирована). После загрузки она скомпилировалась и запустилась с первого раза…
Игра очень проста. Используя клавиши WASD, вы уворачиваетесь от налетающих астероидов.
И хотя комментарии и строковые переменные выполнены не на английском языке, код вполне понятен:
public Main()
{
InitializeComponent();
hdc = (uint)pnlViewPort.Handle;
string error = "";
//Comando de inicializacion de la ventana grafica
OpenGLControl.OpenGLInit(ref hdc, pnlViewPort.Width, pnlViewPort.Height, ref error);
//inicia la posicion de la camara asi como define en angulo de perspectiva,etc etc
controladora.Camara.SetPerspective();
if (error != "")
{
MessageBox.Show("Something happened");
}
#region lights
//Configuracion de las luces
float[] materialAmbient = { 0.5F, 0.5F, 0.5F, 1.0F };
float[] materialDiffuse = { 1f, 1f, 1f, 1.0f };
float[] materialSpecular = { 1.0F, 1.0F, 1.0F, 1.0F };
//brillo del material
float[] materialShininess = { 1.0F };
//posicion de la luz
float[] ambientLightPosition = { 10F, -10F, 10F, 1.0F };
// intensidad de la luz en RGB
float[] lightAmbient = { 0.85F, 0.85F, 0.85F, 1.0F };
Lighting.MaterialAmbient = materialAmbient;
Lighting.MaterialDiffuse = materialDiffuse;
Lighting.MaterialSpecular = materialSpecular;
Lighting.MaterialShininess = materialShininess;
Lighting.AmbientLightPosition = ambientLightPosition;
Lighting.LightAmbient = lightAmbient;
#endregion
//Habilita las luces
Lighting.SetupLighting();
//cargar texturas
ContentManager.SetModelList("modelos\\");
ContentManager.LoadModels();
ContentManager.SetTextureList("texturas\\");
ContentManager.LoadTextures();
//AudioPlayback.SoundDir = "sonidos\\";
//AudioPlayback.LoadSounds();
controladora.CreateObjects();
//Color de fondo
Gl.glClearColor(0, 0, 0, 1);
//red green blue alpha
Gl.glShadeModel(Gl.GL_SMOOTH);
}
private void tmrPaint_Tick(object sender, EventArgs e)
{
// limpia opengl
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
//dibuja la escena
controladora.DrawScene();
//cambia los buffer
Winapi.SwapBuffers(hdc);
//termina de pintar
Gl.glFlush();
if (started)
{
score += 1;
count1++;
count2++;
levelCount++;
if (levelCount == 450)
{
level++;
AsteroidGenerator.GenerateAsteroid(35, false);
lblLevel.Text = level.ToString();
levelCount = 0;
}
if (count1 == 4)
{
lblScore.Text = score.ToString();
count1 = 0;
lives = controladora.Nave.Vidas;
}
if (count2 == 20)
{
ShowLife(lives);
count2 = 0;
if (lives == 0)
{
started = false;
MessageBox.Show("Game Over");
controladora.ResetGame();
score = 0;
level = 1;
lives = 3;
started = true;
count1 = 0;
count2 = 0;
lblLevel.Text = level.ToString();
}
}
}
}
Если вы задумываетесь над написанием трехмерных игр, в космосе или нет, этот проект – хорошая стартовая точка для вас…