Pull to refresh

Пьеса «Разработка многопользовательской сетевой игры.» Часть 4: Переходим в 3D

Reading time 6 min
Views 9K
Piccy.info - Free Image Hosting

Часть 1: Архитектура
Часть 2: Протокол
Часть 3: Клиент-серверное взаимодействие

В последнее время работаю с 11 flash на примере движка AWAY3D 4. Информации на русском по этому движку очень мало. На хабре о нем практически ничего нет. Вот решил написать пару статей об этом очень интересном продукте. Писать про простые кружки и кубики не совсем интересно. Не люблю обсуждать сферических коней в вакууме.
В общем решил сделать описание движка на боле менее реальном примере. Переведем нашу игру в топдаун 3D шутер. И продолжим разработку, но уже с применением 3D технологий.
Конечно я в курсе, что есть движок Alternativa3D. Но мне их продукт не нравится по многим причинам. Обсуждать их в статье не будем, если есть вопросы, добро пожаловать в каменты.

В общем будем делать альтернативу альтернативе…



Итак, что мы хотим получить?

Перевести нашу 2D мультиплеер игру в 3D.

Приступим.

Мы будет использовать следующие технологии:

Flash 11, в качестве платформы
AWAY3D 4, в качестве 3D движка
FlashDevelop 4 в качестве среды разработки
Blender 2.61 в качестве редактора игровых объектов и мира в целом.

Почему именно AWAY3D? Все просто, исходники доступны на Gihub. Библиотека активно развивается (коммиты очень частые) и вы всегда можете что-то исправить или дополнить. Ну а потом отправить это им для внесения в исходники. Комьюнити будет вам благодарно. Плюс достаточно большие возможности самой библиотеки. Плюс по ней есть книги.

Что такое AWAY3D 4? Это 3D библиотека для 11 флеша, что означает отображение объектов посредством GPU видеокарты. Это дает нам возможность показывать на сцене сложные объекты с освещением, различными эффектами… и все это с приличной скоростью.
Надо заметить, что у AWAY3D есть версия для Flash10, в которой отображение производятся с помощью программного рендеринга. Так как в этом случае все расчеты ложатся на плечи CPU, то скорость многократно падает. Ну и возможности в выводе различных эффектов многократно уменьшаются. Но эта версия может быть полезна для несложных проектов. Ибо 11-й Flash только вышел и не у всех еще установлен. Да и не все видеокарты его поддерживают.
Но ситуация улучшается с каждым днем, поэтому мы, находясь на острие прогресса, будем использовать последнюю версию для 11-го флеша.
Для интересующихся, подробности можно почитать тут features

С архитектурой проекта особенно заморачиваться не будем. Цель статьи не руководство по программированию, а знакомство с технологиями. В дальнейшем, если статьи найдут отзыв у читателей, возможно продолжение в виде рефакторинга с улучшением архитектуры… ну и вообще, развитием проекта.

Чтобы избежать проблем, необходимо убедиться, что у вас установлены последнии версии flash и FlashDevelop. Это гарантирует корректную компиляцию и запуск исходников.

AWAY3D основа



Создадим во FlashDevelop проект AS3 и подключим к нему библиотеку AWAY3D. Подключение движка предельно простое. Скачиваем с GitHub проекта исходники AWAY3D и копируем их в папку src нашего проекта. Все.

Чтобы в дальнейшем упростить понимание того что происходит на сцене в AWAY3D, приведу картинку, которая поможет с ориентироваться в пространстве сцены.

Piccy.info - Free Image Hosting

На ней изображены координатные оси, как они представлены а движке AWAY3D. Т.е. по умолчанию движение вперед это по Z+, а вверх это Y+.

Базовый принцип работы с движком очень простой. Необходимо проинициализировать сцену View3D. Настроить камеру, при этом мы указываем положение камеры на сцене. Камера это объект отвечающий за отображение нашего взгляда на сцену. Т.е. то, что мы будем видеть на экране, наши глаза так сказать.
Далее надо расположить источник света. Они бывают разные, точечные, рассеянные и т. д. Мы будем использовать точечный источник (свет равномерно распространяется из одной точки во все стороны), он будет изображать солнце. В принципе можно обойтись и без него, но тогда на сцене не будет теней.
Чтобы рассчитать и вывести сцену на экран используется команда view.render(). Ее надо вызывать каждый кадр. Дальше можно создавать объекты на сцене и манипулировать ими.

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

Вод код класса который отобразит кубик. Все пояснения есть в коде. Он очень простой.

	public class Main extends Sprite 
	{
		// Это наша сцена
		private var view : View3D;
		
		// Это солнце
		public  var light: PointLight;
		
		// Это игрок
		public  var player: ObjectContainer3D;
		
		public function Main():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			// entry point
			
			// Создадим сцену
			view = new View3D();
			view.camera.y 		 	=  140;
			view.camera.z 		 	= -120;
			view.camera.rotationX 	=  50;
			addChild(view);
			
			// статистика 
			addChild(new AwayStats(view)); 	
			
			// Добавим игрока на сцену
			addPlayer();
			
			stage.addEventListener( Event.ENTER_FRAME, onEnterFrame );
		}
		
		public function addPlayer():void 
		{
			// создадим игрока
			player = new ObjectContainer3D();
			
			// сделаем прикольную текстурку для него
			var bitmapData: BitmapData = new BitmapData(512, 512, false, 0x000000);
			bitmapData.perlinNoise(64, 64, 5, 0, false, true, BitmapDataChannel.RED);
			
			// присвоим текстуру материалу
			var material: BitmapMaterial = new BitmapMaterial(bitmapData);
			
			// создадим геометрическую форму игроку
			var mesh:Mesh = new Cube(material, 50, 50, 50);
			player.addChild(mesh);
			
			view.scene.addChild(player);
		}
		
		public function onEnterFrame( e:Event ):void 
		{
			player.rotationX += .11;
			player.rotationY += .15;
			player.rotationZ += .19;
			
			view.render();
		}
		
	}


В результате, при запуске вы должны увидеть следующую картинку.

Piccy.info - Free Image Hosting

Если это не так, то проверьте все ли вы правильно сделали. Проверьте версии установленных Flash и FlashDevelop.

Теперь когда мы убедились, что проект запускается и работает сделаем вторую базовую вещь в нашей игрушке. А именно, загрузим в игру модель созданную в blender. На этом будет строится весь проект.
В интернете полно уроков работы с blender, поэтому заострять на нем внимание не будем. Просто откроем blender и сделаем в нем модель состоящую из кубика. размером 20 на 20 на 20. Делать сейчас полноценную модель нет смысла. В дальнейших уроках мы возьмем готовую модель, которых в интернете вагон и маленькая тележка. А сейчас нам надо убедиться, что у нас все окружение корректно работает и модели загружаются.
В своем проекте мы будем использовать формат моделей 3DS. После того как вы создали модель, экспортируйте ее в формат 3DS. Получившийся файлик пока положите в папку bin проекта. Так будет проще до него добраться.

Теперь приступим к импорту.

Загрузка объектов в AWAY3D очень проста. Все что надо это класс Loader3D. Он универсальный и загружает все форматы. Ему можно указать в каком именно формате загружем объект, но это не обязательно. Парсеру можно командой Parsers.enableAllBundled(), указать принимать все форматы. Loader3D сам поймет что именно грузим.
В принципе загрузка модели занимает всего 4 строчки кода.


Parsers.enableAllBundled();
loader = new Loader3D();
loader.addEventListener(LoaderEvent.RESOURCE_COMPLETE, onResourceComplete);
loader.load(new URLRequest("model.3ds"));


Здесь мы указали что принимаем все форматы, создали объект Loader3D и указали ему что именно надо загрузить. Событие LoaderEvent.RESOURCE_COMPLETE, сообщит нам что процесс загрузки завершен и с моделью можно работать.
В базовом варианте все просто. Но при загрузке могут возникнуть ошибки или же при загрузке модели, ей нужна будет какая-то обработка. В общем в реальных проектах все сложнее. И для этого в движке есть все. Можно подключить событие LoaderEvent.LOAD_ERROR, оно позволит отловить ошибки загрузки. Или событие LoaderEvent.ASSERT_COMPLETE, которое срабатывает при обработке каждой детали модели. Эти ньюансы мы разберем в следующих уроках когда коснемся подробнее работы с моделями.

Вот рабочий код, загружающий модель на сцену.


public class PlayerLoad
{
	// 3D
	private var view:View3D;
	
	private var main: Main;
	
	// loader
	private var loader:Loader3D;
	
	public function PlayerLoad( view_:View3D, main_: Main ) 
	{
		main = main_;
		
		// получаем ссылку на сцену
		view = view_;
		
		// указываем, что хотим грузить любой формат
		Parsers.enableAllBundled();
		
		loader = new Loader3D();
		loader.addEventListener(LoaderEvent.RESOURCE_COMPLETE, onResourceComplete);
		
		// указываем что грузим
		loader.load(new URLRequest("model.3ds")); 
	}
	
	private function onResourceComplete(e:Event):void 
	{
		// получаем нашу загруженную модель
		main.player = ObjectContainer3D(e.target);
		
		// добавляем модель на сцену
		view.scene.addChild( main.player );			
	}
		
}


так же в классе main необходимо заменить метод addPlayer() на следующий

	public function addPlayer():void 
	{
		// создадим игрока
		var load: PlayerLoad = new PlayerLoad( view, this );
	}


Если вы все правильно сделали, то при запуске увидите белый вращающийся кубик.

Piccy.info - Free Image Hosting

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

Все исходники доступны на Gihub

P.S. Так же в каментах полезно будет указать интересующие вас моменты, на которых стоит заострить внимание.
Tags:
Hubs:
+17
Comments 20
Comments Comments 20

Articles