Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Поиск рулит! Сообщения за день Все разделы прочитаны
 

Вернуться   Форум Flasher.ru > Блоги > HardCoder

Рейтинг: 5.00. Голосов: 3.

Еще один способ создания изометрического мира(Часть2 - Совершенствуемся)

Запись от HardCoder размещена 25.01.2012 в 18:41
Обновил(-а) HardCoder 26.01.2012 в 20:02

Здравствуйте, уважаемые коллеги. В предыдущей статье я рассказал о том как создавать клеточный фон для игр, о том как преобразовывать экранные координаты в изометрические и сортировать их по глубинах в списке отображения.
Учитывая замечания и советы - эти классы были немного переделаны и в изометрическую систему была добавлена третья координата. Получился своего рода фреймворк домашнего производства.
И так, пример: http://megaswf.com/serve/2010617

Представляю вам пакет "isometrics", в который входит несколько классов, цель которых:
  1. Упростить создание фона на основе клеток.
  2. Упростить создание изометрического контейнера, в котором находятся разные изометрические обьекты.
  3. Упростить сортировку этих обьектов в контейнере по глубинам в дисплей листе.
А именно, цель пакета - избавить разработчика от лишних вычислений, предоставив ему возможность оперировать лишь изометрическими координатами различных обьектов, не задумываясь о том как они будут отображаться на экране, полностью отдавшись работе над логикой игры.

Недостатком является то, что алгоритм сортировки не учитывает геометрические размеры сортируемых обьектов. Поэтому нельзя создавать обьекты прямоугольной, или другой формы. Сортировка происходит по точкам. Чем ближе точка к зрителю - тем выше глубина обьекта, и наоборот. Чтобы создать обьект произвольной формы - необходимо его разделить на несколько частей, и поместить каждую часть на нужные координаты так чтобы они выглядели как одно целое.
То что алгоритм сортировки не учитывает геометрические размеры сортируемых обьектов, не значит что их надо создавать как угодно. Тут есть своя тонкость. Необходимо иметь пространственное воображение, и при создании каждого обьекта (будь то коробка, дерево, человек, дом) нужно представлять его как куб. Вернее не совсем куб, так как основа должна быть квадратной формы, а высота произвольная (см. рисунок 3). Дальше буду это называть "ограничительный куб". Его размеры нам будут нужны для определения столкновений с другими предметами.

Система координат, которой оперирует фреймворк показана на рисунке 1. Угол между осями isoX, isoZ и экранной осью X составляет приблизительно 26.6° (см. рисунок 2 - как создавать клетки).

Класс IsoTile

public class IsoTile extends Sprite - представляет клетку. Клетка, в отличии от предмета, не имеет высоты и она не должна обязательно добавляться в изометрический контейнер. Родителем клеток может быть любой экранный обьект. Также, у нее нет координат по оси isoY. То есть - она всегда находится на высоте 0. Все стороны клетки должны быть равны. Если клетку спроектировать на экран - то ее стороны должны быть наклонены под углом 26.6°. Этот угол можно изменить, задав в конструкторах клеток или обьектов нужный нам угол(в радианах). Тогда все расчеты изометрии будут происходить под этим углом. Соответственно, клетки и предметы нужно создавать под этим углом. Мне нравится угол 26.6°, так как с ним очень удобно создавать клетки.

Конструктор:
public function IsoTile(graphicObject:DisplayObject, zenithAngle:Number = 0.4636476090008062) - создает новую клетку.
Параметры:
  • graphicObject - графический обьект (рисунок клетки).
  • zenithAngle - угол между осью isoX(isoZ) и экранной осью X в радианах. По умолчанию приблизительно 26.6° (см. рисунок1, 2).
Свойства:
  • graphicObject:DisplayObject - графический обьект(рисунок клетки). Может быть MovieClip, Sprite, Bitmap - чем угодно.
  • isoWidth:int [статическое][только для чтения] - ширина клетки вдоль изометрических осей. Определяется автоматически при создании первой клетки в приложении.
  • isoX:Number, isoZ:Number - координаты клетки по изометрических осях. При задании этих координат - автоматически изменяются экранные координаты. Если необходимо изменить обе координаты одновременно - нужно использовать метод setIsoPosition();
Методы:
  • public function setIsoPosition(isoX:Number = 0, isoZ:Number = 0):Vector.<Number> - изменяет позицию клетки в изометрических координатах и автоматически изменяет экранные координаты. Вызывать в случаях, когда нужно изменить две изометрические координаты одновременно. Экономит количество преобразований координат в 2 раза (по сравнению с изменением координат по отдельности). Возвращает вектор экранных координат клетки [screenX, screenY].
    Параметры: isoX - новая координата по оси isoX; isoZ - новая координата по оси isoZ.
Пример
Допустим, в библиотеке у нас есть мувиклип клетки SWCTile. В мувиклипе есть два кадра: травы и асфальта. Нам нужно создать поле из этих клеток 10х15 (isoX x isoZ).
Код AS3:
//создаем спрайт - контейнер для плиток
var tilesContainer:Sprite = new Sprite();
addChild(tilesContainer);
 
var tile:IsoTile;
for (var x:uint = 0; x < 10; x++){
	for(var z:uint = 0; z < 15; z++){
		tile = new IsoTile(new SWCTile());
		tile.setIsoPosition(x*IsoTile.isoWidth, z*IsoTile.isoWidth);
		tilesContainer.addChild(tile);
		//Здесь условие, которое определяет что должно быть изображено:
		//трава, или асфальт
		if(condition){
			(tile.graphicObject as MovieClip).gotoAndStop("asphalt");
		} else {
			(tile.graphicObject as MovieClip).gotoAndStop("grass");
		}
	}
}
//после этого tilesContainer можно отрисовать в битмап(по желанию), если
//клетки больше не понадобятся
Класс IsoContainer

public class IsoContainer extends Sprite - представляет контейнер изометрических обьектов (IsoItem). Для добавления предметов в контейнер необходимо воспользоваться методом addChild(). Контейнер добавит обьект в дисплей лист и автоматически поместит его на нужную глубину. Чтобы удалить обьект - надо использовать метод removeChild(). В контейнер можно добавлять лишь экземпляры класса IsoItem, в противном случае - RTE.
Методы:
  • public function destroy():void - удаляет внутренние слушатели событий контейнера, обьявленные при его создании. Необходимо вызвать, когда контейнер больше не понадобится в приложении, по такой схеме: removeChild(container); container.destroy(); container = null;
Класс IsoItem

public class IsoItem extends Sprite - представляет изометрический предмет. Это обьект который находится в списке отображения изометрического контейнера IsoContainer. Для создания такого обьекта можно создать другой класс и унаследовать его от IsoItem. Или же создать новый обьект IsoItem и определить его свойство graphicObject, которое будет представлять изображение обьекта.

Конструктор:
public function IsoItem(graphicObject:DisplayObject = null, zenithAngle:Number = 0.4636476090008062, sortImmediately:Boolean = false, mouseChildren:Boolean = false) - создает новый предмет, который будет добавлен в изометрический контейнер.
Параметры:
  • graphicObject - графический обьект наполняющий экземпляр IsoItem;
  • zenithAngle - угол между осью isoX(isoZ) и экранной осью X в радианах. По умолчанию приблизительно 26.6° (см. рисунок1, 2).
  • sortImmediately - при добавлении обьекта в дисплей лист отсортировать его немедленно. По умолчанию - false (то есть обект будет отсортирован при следующей перерисовке). Если за один кадр добавляется, например 100 обьектов со значением sortImmediately = true - то за один кадр произойдет 101 сортировка, что не есть хорошо для процессора. Если false - сортировка в кадре произойдет лишь один раз, но обьекты будут на самой высшей глубине, пока не произойдет следующее событие enterFrame, что вызывает не очень красивый эффект. Поэтому - значение этому параметру нужно присваивать в зависимости от обстоятльств;
  • mouseChildren - мышиная активность детей(графических обьектов).
Свойства:
  • isoWidth:Number - ширина предмета по осях isoX, isoZ;
  • isoHeight:Number - высота обьекта по оси isoY;
  • isoWidth и isoHeight - это размеры "ограничительного куба" предмета;
  • graphicObject:DisplayObject - графический обьект "наполняющий" экземпляр IsoItem грфическим содержимим. Может быть MovieClip, Sprite, Bitmap - чем угодно;
  • isoX:Number, isoZ:Number, isoY:Number - координаты по изометрическим осям. При изменении любой из этих координат - автоматически изменяются экранные координаты. Если необходимо изменить две и больше координат одновременно, нужно использовать метод setIsoPosition(), так количество преобразований уменьшится в 2 и три раза соответственно.
Методы:
  • public function setIsoPosition(isoX:Number = 0, isoZ:Number = 0, isoY:Number = 0):Vector.<Number> - изменяет позицию обьекта в изометрических координатах и автоматически изменяет экранные координаты. Вызывать в случаях, когда нужно изменить две или больше изометрических координат одновременно. Экономит количество преобразований координат в 3 раза (по сравнению с изменением координат по отдельности). Возвращает вектор экранных координат обьекта в контейнере [screenX, screenY];
  • public function setScreenPosition(x:Number = 0, y:Number = 0):Vector.<Number> - изменяет позицию обьекта в экранных координатах и автоматически изменяет изометрические координаты. Вызывать в случаях, когда нужно изменить две экранные координаты одновременно. Экономит количество преобразований координат в 2 раза (по сравнению с изменением x или y по отдельности). Возвращает вектор изометрических координат обьекта в контейнере [isoX, isoZ, isoY];
  • public function hitTesItem(item:IsoItem):Boolean - определяет, пересекается ли "ограничительный куб" обьекта с "кубом" другого (переданного) обьекта. Параметр item - исследуемый на пересечение другой обьект.
Пример:
Допустим в библиотеке есть мувиклип самолета SWCPlane. В этом мувиклипе еще один мувиклип с instance name: "engine". Этот мувик engine отвечает за изображение огня из сопла самолета. Когда нажата клавиша вперед - огонь увеличивается.
Также в библиотеке есть мувиклип коробки SWCBox. В этом мувике два кадра: зеленая коробка и красная.
Код AS3:
//создаем контейнер для предметов
var container:IsoContainer = new IsoContainer();
addChild(container);
 
//создаем самолет
var plane:Plane = new Plane();
plane.setIsoPosition(150, 100, 50);
 
//создаем коробку
var box:IsoItem = new IsoItem(new SWCBox());
box.setIsoPosition(300, 200, 0);
box.isoWidth = 40;
box.isoHeight = 40;
//делаем коробку зеленой
(box.graphicObject as MovieClip).gotoAndStop("green");
 
//добавляем наши предметы в контейнер и они 
//автоматически поместятся на нужную глубину
container.addChild(plane);
container.addChild(box);
 
//так надо управлять графическими обьектами предметов:
plane.planeMovie.engine.gotoAndStop(2);
(box.graphicObject as MovieClip).gotoAndStop("red");
 
//чтобы самолет переместиь, например, на isoX = 100, нужно:
plane.isoX = 100;
//чтобы самолет переместиь, например, на isoX = 100,
//isoZ = 200, isoY = 0, нужно
plane.setIsoPosition(100, 200);
 
//Класс самолета
internal class Plane extends IsoItem {
	//мувиклип самолета
	internal var planeMovie:SWCPlane;
 
	public function Plane(){
		super();
		//задаем размеры "ограничительного куба" самолета
		this.isoHeight = 15;
		this.isoWidth = 40;
		planeMovie = new SWCPlane();
		planeMovie.engine.gotoAndStop(1);		
	}
}
К статье прилагается архив с пакетом "isometrics", а также исходники к примеру, который вы видели в самом начале.
Внимание! Касается начинающих разработчиков: исходник с "самолетом" - это лишь пример того как пользоваться пакетом isometrics, а не то как создавать игры.

Спасибо за внимание.
Изображения
Тип файла: jpg 1.jpg (9.2 Кб, 1129 просмотров)
Тип файла: jpg 2.jpg (6.6 Кб, 1086 просмотров)
Тип файла: jpg 3.jpg (13.3 Кб, 913 просмотров)
Вложения
Тип файла: zip isometrics.zip (6.3 Кб, 241 просмотров)
Тип файла: zip IsoSort3D.zip (149.6 Кб, 217 просмотров)
Всего комментариев 27

Комментарии

Старый 25.01.2012 21:10 Dukobpa3 вне форума
Dukobpa3
 
Аватар для Dukobpa3
Два вопроса:
1. Почему предметы только квадратные, в чем сложность сделать прямоугольные, тем более что ты сам объяснил как это можно сделать с костылями (ну мол составные объекты, резать на клетки, может это в двиг лучше всунуть изначально).
2. Почему изометрия только 45град. Можно сделать это настраиваемым параметром. Например во всех наших проектах изометрия 0.66% (2/3)

А в общем и целом лучше предыдущего варианта Уже можно пользоваться. Подробнее еще не вникал, погляжу мож отпишусь еще.
Старый 25.01.2012 21:42 HardCoder вне форума
HardCoder
 
Аватар для HardCoder
Цитата:
Почему предметы только квадратные, в чем сложность сделать прямоугольные
Как писал выше - сортировка каждого обьекта происходит по его точке регистрации. Если обьект будет прямоугольным, то его самая дальняя точка будет далеко от точки регистрации. И когда будет происходить сортировка - алгоритм не будет знать что дальняя часть обьекта находится дальше от зрителя. Он его отсортирует согласно точки регистрации обьекта, которая ближе/дальше к зрителю. Поэтому обьект наложиться на другой обьект тогда, когда он не должен это делать, или ПОД другой обьект(хотя тоже не должен это делать). Поэтому нужно использовать другой подход. Я несколько дней ломал голову как это сделать, но почти ничего не вышло.Поэтому остановился на том что обьекты должны быть квадратные, круглые, короче - равносторонними.
Цитата:
Почему изометрия только 45град. Можно сделать это настраиваемым параметром. Например во всех наших проектах изометрия 0.66%
Про 45град не понял. А настраивать угол можно. Надо в классе IsoTransformer изменить константу ALPHA под нужный угол (в радианах) - и вся изометрия будет пересчитываться под этим углом 26.6°, 30°, 50° как угодно. Но только обьекты тогда надо создавать под таким же углом. Угол 26.6° мне нравится тем, что клетки удобно создавать, и векторные линии смотрятся сглаженее.
PS: Статью отредактировал: обьяснить как изменить угол. Спасибо за подсказку.
Обновил(-а) HardCoder 25.01.2012 в 21:52
Старый 25.01.2012 23:15 TanaTiX вне форума
TanaTiX
 
Аватар для TanaTiX
Цитата:
А настраивать угол можно. Надо в классе IsoTransformer изменить константу ALPHA под нужный угол (в радианах)
а другого названия для константы, отвечающей за наклон не нашлось?
Старый 25.01.2012 23:44 HardCoder вне форума
HardCoder
 
Аватар для HardCoder
Дело в том, что идею с изменением угла подкинул Dukobpa3. Изначально ALPHA - это private константа в internal классе, спрятанном от разработчика. А так как этот класс состоит лишь из одной приватной константы и двух internal методов, то не особо важно, как она будет называться - здесь не запутаешься. Этому классу по барабану что этот угол значит, его дело - с помощью этого угла проделать некие математические операции. Это его единственная личная фишка, которая других не должна касаться.
Старый 26.01.2012 00:21 TanaTiX вне форума
TanaTiX
 
Аватар для TanaTiX
Это как в машине давить на тормоз, а там дворники включаются. Я вижу переменную, которая называется, к примеру, "цвет", значит при ее изменении должно происходить изменение цвета, а не текста где-то там. К тому же переименовать - это занимает меньше минуты времени. А (пред)история не важна.
Старый 26.01.2012 03:41 Dukobpa3 вне форума
Dukobpa3
 
Аватар для Dukobpa3
Цитата:
Надо в классе IsoTransformer изменить константу ALPHA под нужный угол (в радианах)
Как самый простой вариант сделать сеттер вместо константы, а можно в конструктор каждому объекту втулить.

Насчет сортировки достаточно глубину высчитывать не так как ты считаешь - суммой икса и игрека, а тупо по порядку зигзагообразно. Я кажись этот механизм описывал в той теме с которой это началось))
Таким образом у каждого объекта будет его уникальная глубина и большой объект будет иметь глубину самой ближней к пользователю точки, размеры будут пофигу, так как все размеры будут считаться в клетках, что-то типа 2х3 клетки.

Можно использовать и твой вариант, но в таком случае придется одну из координат умножать на некий коэффициент. Что-то типа: 10х + у.
Такой вариант будет адекватно работать только на поле с размером <=10 так как при больших размерах в тех координатах которые дальше 10-и будет месиво. Потому в формулу нужно как-то включать размер поля, чтобы таки у каждого объекта был свой индекс и чтоб он был еще и правильным.

ИМХО проще таки просто по порядку посчитать. Хотя хз, как для большого кол-ва объектов то формула будет работать быстрее. Но нужно ее вывести А мне сейчас влом это делать К тому же идея твоя)
Старый 26.01.2012 03:44 Dukobpa3 вне форума
Dukobpa3
 
Аватар для Dukobpa3
Ну и касательно названий TanaTiX прав.
Во флеше принято высотой называть размеры по игреку, шириной по иксу, для той высоты о которой ты - лучше что-то другое придумать. В английском еще много неиспользованных слов.
Старый 26.01.2012 10:31 HardCoder вне форума
HardCoder
 
Аватар для HardCoder
Для примера мы находимся недалеко от дома длиной в 1 км. За 800м от нас, возле этого дома стоит ларек. Вопрос: почему ларек перекрывает нам некую часть дома, ведь ларек дальше от нас чем дом? Ответ очевиден: ларек ближе чем самая дальняя часть дома, которая находится в км отсюда. Теперь нам надо написать программу которая, учитывая геометрические размеры и координаты обеих зданий - разместит дом ПОД ларек, даже если этот дом находится ближе к зрителю чем ларек.
Я несколько дней выводил разные формулы и мало что получилось. Пробовал сортировать перебором, не перебором... Но так и не смог найти отличительную черту двух зданий, по которой их бы отсортировать. Что в доме и ларьке есть особенного? Как учитывая координаты и геометрические размеры здания найти некоторое уникальное для него свойство, которое и будет отвечать за его глубину? Видать - эта задача не для меня. Так что именно в данном случае остановлюсь на "квадратах".
[IMG]http://************/2390660m.jpg[/IMG]
Цитата:
Во флеше принято высотой называть размеры по игреку, шириной по иксу, для той высоты о которой ты - лучше что-то другое придумать. В английском еще много неиспользованных слов.
А как по мне, то isoHeight - высота обьекта по оси isoY (которая параллельна оси Y) как раз нормальное название. А вот угол ALPHA - согласен, не очень подходит. Но если честно, я и сам не знаю как его назвать: THE_ANGLE_BETWEEN_ISOX_AND_SCREENX_AXIS?
Обновил(-а) HardCoder 26.01.2012 в 10:51
Старый 26.01.2012 11:31 Jewelz вне форума
Jewelz
 
Аватар для Jewelz
если точка регистрации находится в центре объекта и объекты не пересекаются, то можно заставить программу понять примерно так:

L1_index = big_int * L1.y + L1.x;
L2_index = big_int * L2.y + L2.x;

где big_int - некое большое число, (>= ширины карты)

таким образом можно сортировать точки в экранной системе координат
Старый 26.01.2012 12:42 HardCoder вне форума
HardCoder
 
Аватар для HardCoder
Jewelz, если я правильно расшифровал что такое L1, L2, то вот что получится:[IMG]http://************/2383514m.jpg[/IMG]
Старый 26.01.2012 12:54 alatar вне форума
alatar
 
Аватар для alatar
Цитата:
Но так и не смог найти отличительную черту двух зданий, по которой их бы отсортировать. Что в доме и ларьке есть особенного? Как учитывая координаты и геометрические размеры здания найти некоторое уникальное для него свойство, которое и будет отвечать за его глубину?
iso координаты объекта. Т.е. движок должен думать, что он работает с трехмерными объектами, тогда у вас отпадет целых класс проблем.
Старый 26.01.2012 13:18 HardCoder вне форума
HardCoder
 
Аватар для HardCoder
Цитата:
iso координаты объекта.
У меня глубина так и рассчитывается, только обьект воспринимается как точка, а не предмет. Наши глаза находятся в 3Д пространстве высоко над картой и далеко от начальной точки 3Д системы. Красные точки - это точки тоже в 3Д пространстве. По моему способу - дом будет над ларьком на экране (2Д), так как его точка в 3Д ближе в к нашим глазам (которые тоже в 3Д пространстве). Хотя, на экране дом должен быть под под ларьком, потому что он длиннее..
Цитата:
Т.е. движок должен думать, что он работает с трехмерными объектами, тогда у вас отпадет целых класс проблем.
А вот это для меня - высшая материя. Не знаю как учитывать размеры обьектов при сортировке (не по точкам).
Старый 26.01.2012 13:35 alatar вне форума
alatar
 
Аватар для alatar
Посмотрите реализации z-сортировки для 3D движков.
Старый 26.01.2012 15:43 Jewelz вне форума
Jewelz
 
Аватар для Jewelz
HardCoder, у вас x и y наоборот, тогда в формуле поменяйте тоже
Старый 26.01.2012 16:51 Dukobpa3 вне форума
Dukobpa3
 
Аватар для Dukobpa3
http://***********/content/xEoq7tkOhk
Я примерно это имел в виду.
Старый 26.01.2012 17:26 -De- вне форума
-De-
 
Аватар для -De-
Я такое сортировал из соображений "соседние клетки всегда однозначно ниже, либо выше клеток фигуры (две стороны всегда ниже, две выше)" + "неотсортированных клеток нет". Есть у меня в блоге, но похоже оно сложновато для использования вышло (разве что я сам когда-нить таки осилю доделать %).
Старый 26.01.2012 18:40 alatar вне форума
alatar
 
Аватар для alatar
Кстати, константу ALPHA, все-таки, лучше сделать параметром в конструкторе, как советовал Dukobpa3. В игре могут одновременно присутствовать локации с разными проекциями.
Старый 26.01.2012 20:04 HardCoder вне форума
HardCoder
 
Аватар для HardCoder
Цитата:
HardCoder, у вас x и y наоборот, тогда в формуле поменяйте тоже
Ага, ну это то о чем я и говорил: мы получаем индексы точек а не всего предмета. Точка дома ближе к нам, точка ларька - дальше, значит дом будет над ларьком, хотя должно быть наоборот, потому что дом длиннее. Тут надо искать радикально другой подход.
Цитата:
Кстати, константу ALPHA, все-таки, лучше сделать параметром в конструкторе, как советовал Dukobpa3. В игре могут одновременно присутствовать локации с разными проекциями.
Добавил как параметр в конструктор к каждому обьекту (IsoItem). Статью отредактировал. Правда, TanaTiX, я все равно ничего умнее не придумал: назвал параметр zenithAngle...
Старый 26.01.2012 20:07 HardCoder вне форума
HardCoder
 
Аватар для HardCoder
Цитата:
Я такое сортировал из соображений "соседние клетки всегда однозначно ниже, либо выше клеток фигуры (две стороны всегда ниже, две выше)" + "неотсортированных клеток нет". Есть у меня в блоге, но похоже оно сложновато для использования вышло (разве что я сам когда-нить таки осилю доделать %).
Я смотрел этот блог еще давно. Но тут, немного другая задача...
Старый 26.01.2012 20:22 Dukobpa3 вне форума
Dukobpa3
 
Аватар для Dukobpa3
На объект как на точку изначально смотреть не верно.
Объект это объект, пусть даже плоский. Не получится сортировать прямоугольники наравне с квадратами по той же формуле.
А ты пытаешься представить весь большой объект в виде одной лишь точки привязки и удивляешься что что-то не выходит. Этот подход будет работать с объектами имеющими одинаковые размеры, но не будет работать с разноразмерными.

Суть моего предложения если перефразировать в том - чтобы представить каждый объект в виде набора минимальных по размеру таких вот точек. Пусть даже такой точкой будет клетка, или же пиксель. И сортировать по самой ближней к пользователю точке.

Так чтоб практически ничего не менять, можно банально повесить точку привязки с центра на нижний угол. Стопицот проблем отпадет сами собой.
Старый 26.01.2012 20:32 GBee вне форума
GBee
 
Аватар для GBee
А мне все больше нравится. А будет пример управления мышкой?
Старый 26.01.2012 20:35 HardCoder вне форума
HardCoder
 
Аватар для HardCoder
Цитата:
А ты пытаешься представить весь большой объект в виде одной лишь точки привязки и удивляешься что что-то не выходит
Я не удивляюсь, а прекрасно понимаю почему так.
Цитата:
Так чтоб практически ничего не менять, можно банально повесить точку привязки с центра на нижний угол. Стопицот проблем отпадет сами собой.
А вот с этим не согласен. Доказывать и рисовать не буду, просто поверь на слово. Перепробовал почти все возможные способы сортировки по точкам, которые пришли на ум. И этот тоже.
Цитата:
Суть моего предложения если перефразировать в том - чтобы представить каждый объект в виде набора минимальных по размеру таких вот точек. Пусть даже такой точкой будет клетка, или же пиксель.
Вот она - гениальная фраза.
Цитата:
И сортировать по самой ближней к пользователю точке.
Возвращаемся опять ко второму пункту. Как бы мы программно не разбивали обьект - он будет одним целым. И нам надо эту целую битмапу или мувиклип поместить на определенную глубину так, чтобы дальняя часть битмапы была под чем-то, а ближняя над чем-то.
Старый 26.01.2012 20:38 HardCoder вне форума
HardCoder
 
Аватар для HardCoder
Цитата:
А мне все больше нравится. А будет пример управления мышкой?
Спасибо. Думаю, не будет . Цель - показать как оперировать изометрическими свойствами обьектов. А где эти свойства изменять: клавиатурой, мышью - не важно...
Старый 26.01.2012 20:52 GBee вне форума
GBee
 
Аватар для GBee
Цитата:
Цель - показать как оперировать изометрическими свойствами обьектов. А где эти свойства изменять: клавиатурой, мышью - не важно...
Я просто думаю, что клавиатурой изменения происходят относительно текущего положения, что просто, по идее, а вот по клику не очень понимаю.
Старый 26.01.2012 21:13 HardCoder вне форума
HardCoder
 
Аватар для HardCoder
Цитата:
Я просто думаю, что клавиатурой изменения происходят относительно текущего положения, что просто, по идее, а вот по клику не очень понимаю.
А вот над этим я как-то не задумывался.
Код AS3:
var container:IsoContainer = new IsoContainer();
 
container.addChild(plane);
..............................................
plane.setScreenPosition(container.mouseX, container.mouseY);
Если мы кликнем по полю - самолет переместится в точку клика, но изменятся лишь его координаты по осях isoX, isoZ, а высота его(isoY) - останется прежней. Мы же кликаем в двумерном пространстве, поэтому не можем по точке клика определить высоту самолета. Так что его высоту (isoY) нужно задать каким-нибудь другим способом. Действительно - не подумал. Но, даже если бы подумал, не представляю себе как определить 3 координаты по точке на экране. Интересно, интересно...
Старый 01.02.2012 22:57 djyamato вне форума
djyamato
 
Аватар для djyamato
как вариант сортировки
"полу BSP Tree"
http://www.flasher.ru/forum/showpost...8&postcount=16
разбить все спрайты (если у Вас спрайты) друг другом чтобы получить минимальные неделимые куски
отсортировать эти куски по степени удаленности
Один из плюсов такого подхода - Вы сможете правильно отсортировать пересекающиеся объекты
Тема тут, может на мысль подтолкнет http://www.flasher.ru/forum/showthre...=173657&page=2
Обновил(-а) djyamato 01.02.2012 в 23:03
Старый 02.02.2012 01:47 elder_Nosferatu вне форума
elder_Nosferatu
 
Аватар для elder_Nosferatu
Цитата:
Если мы кликнем по полю - самолет переместится в точку клика, но изменятся лишь его координаты по осях isoX, isoZ, а высота его(isoY) - останется прежней. Мы же кликаем в двумерном пространстве, поэтому не можем по точке клика определить высоту самолета. Так что его высоту (isoY) нужно задать каким-нибудь другим способом. Действительно - не подумал. Но, даже если бы подумал, не представляю себе как определить 3 координаты по точке на экране. Интересно, интересно...
Мой игровой опыт подсказывает, что летательные апараты либо имеют отдельное управление для высоты полета, либо сами решают на какой высоте им лететь. А по клику мышки вы либо получаете экранную точку, в которой хотите видеть самолет (удобно, если самолет собирает что нить в воздухе), либо экранную точку, которая указывает позицыю на поверхности Iso-сцены, над которой самолет должен пролететь (удобно скидывать бомбы на наземные цели)
 

 


Часовой пояс GMT +4, время: 00:49.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.