Извините, ничего не найдено.

Не расстраивайся! Лучше выпей чайку!
Регистрация
Справка
Календарь

Вернуться   forum.boolean.name > Программирование игр для компьютеров > BlitzMax > FAQ и уроки

Ответ
 
Опции темы
Старый 19.06.2008, 14:09   #31
GoodWin
ПроЭктировщик
 
Регистрация: 14.08.2006
Сообщений: 105
Написано 15 полезных сообщений
(для 19 пользователей)
Ответ: Увеличиваем производительность игры или как убить лишние коллизии. Советы новичкам.

Можно банально брать каждый астероид и по списку проверять, не столкнулся ли он с другими. Этот подход возможен только при малом количестве проверяемых объектов. Если объектов много (как планируется в нашем случае), то подобная проверка загрузить процессор на полную и все будет тормозить. Более правильный подход проверять на столкновение не со всеми существующими объектами, а только с теми, что находятся «рядом». Как выяснить кто «рядом»? Один из простых вариантов «Виртуальная сетка», нужно разлинеить игровое поле и для каждого сектора (клеточки) создать список объектов, которые сейчас в нем находятся. Для проверки столкновения мы будем перебирать только те объекты, которые находятся в том же секторе, что и проверяемый объект.
Пример:
[IMG]file:///D:/Downloads/AsteroidStormHtml/images/test4.jpg[/IMG]
Астероид под номером 1 находится в клетке A1, и проверки с кем он столкнулся, не будет вообще, т.к. больше в этом секторе никого нет. Для астероида 2, будет проверка всех, кто пересекает сектор B1, это астероиды 3 и 4.
Таким образом, количество проверок на столкновение уменьшается в сотни раз (особенно для большого поля, как у нас, и при большом количестве объектов). При создании объекта, определяем, какому сектору он принадлежит, и регистрируем его там, а при передвижении переписываем. Размер сектора выбрать можно любой, и у слишком маленького и у слишком большого есть свои преимущества и недостатки. Для простоты расчетов, я решил взять такой, чтобы самый крупный объект не пересекал более 4-х секторов. У нас самая крупная земля, ширина 197, она неподвижна, если ее разместить в вершине одного сектора, то чтобы перекрыть 4 сектора, один сектор будет в 100 точек.
Для определения, какие сектора пересекает объект нужно представить его в виде квадрата, и проверить в каком секторе находится каждый из его углов. Добавляем в базовый класс basic_object хеш
public var sectors:Object; // какие сектора пересекает объект
Лучше делать Object а не массив, чтобы не пробегаться по нему проверяя не добавили ли мы один и тот же сектор дважды.
И пишем функцию пересчета секторов
// Пересчитывает, какие сектора пересекает объект
public function CalcSectors():void {
var dx:Number, dy:Number;
var x1:Number, y1:Number;
var s:String;
sectors = new Object(); // сбрасываем список секторов
for (dx=-1; dx<=1; dx+=2){
for (dy=-1; dy<=1; dy+=2){
// вычисляем координату угла (центр+радиус)
x1 = x + radius*dx;
y1 = y + radius*dy;
// название сектора будет в виде "x_y"
s = Math.floor(x1/100)+"_"+Math.floor(y1/100);
sectors[s]=true; // запоминаем этот сектор
}
}
}
Маленькое отступление. Мне стало интересно, почему при добавлении числа к строке “строка”+Number, его не нужно преобразовывать в строку toString() ? Написал маленькую проверку:
var s:String="1";
var num:Number=4;
s+=num;
num+=s;
trace("s="+s+", num="+num); // s=14, num=414
Ни каких ошибок компилятор не выдал. Это что же получается, все как раньше? Переменная num по пути из Number стала String и в результате получили “414” вместо ожидаемых “18” или хотя бы ошибки компиляции?! Нафига тогда вообще типы переменных нужны? Что-то я не понял.
Вернемся к астероидам. В главном классе sky нужно создать хеш всех секторов, в которых побывали наши объекты, и прописать в них ссылки на сами объекты.
// Объявляем переменную для хранения секторов
var all_sectors:Object; // сектора со ссылками на объекты в них
. . .
// в конструкторе инициализируем
all_sectors = new Object();
. . .
// В функции вброса новых астероидов
// Просим пересчитать в какие сектора попал объект
new_asteroid.CalcSectors();
// добавим в эти сектора ссылку на объект
for each (s in new_asteroid.sectors){
if (!all_sectors[s]){ // такого сектора еще не было, создадим
all_sectors[s] = new Object();
}
all_sectors[s][new_asteroid.name] = new_asteroid;
}
А в функции Update, где мы перемещаем все объекты, нужно вставлять пересчет секторов и проверку на столкновения.
public function Update(e : Event):void {
var s:String, obj2:basic_object;
// Проходим по всему массиву созданных объектов
// и заставляем каждого сдвинуться в своем направлении
for each (var obj:basic_object in all_moving){
// перед тем, как сдвинуться удалим запись об этом объекте из секторов
for (s in obj.sectors){
delete all_sectors[s][obj.name];
}
// смещаемся
obj.move();
// Просим пересчитать в какие сектора попал объект
obj.CalcSectors();
// Проверяем столкновения со всеми объектами, которые есть в новых секторах
for (s in obj.sectors){
if (all_sectors[s]){ // такой сектор есть
for each (obj2 in all_sectors[s]) { // проверяем на столкновение
if (obj.CheckCollision(obj2)){ // столкнулись
// делаем отскок
resolve(obj, obj2);
}
}
} else { // нет такого сектора
all_sectors[s] = new Object(); // теперь будет
}
// регистрируемся в этом секторе
all_sectors[s][obj.name]=obj;
}
}
}
Статья ессно не моя... но мож ккому пригодится и написана для АкшионСкрипт 3 для флеша... но принцип можно взять....

Ниже в аттаче полный урок
Вложения
Тип файла: zip AsteroidStormHtml.zip (155.7 Кб, 770 просмотров)
(Offline)
 
Ответить с цитированием
Ответ


Опции темы

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Выкладываем советы zheland BlitzMax 17 19.09.2008 11:01
производительность smersh 3D-программирование 5 20.05.2007 13:02
Помогите убить баг... Raiter 2D-программирование 10 07.04.2007 22:07
Цвет. (Советы и ИМХО) moka Создание текстур 0 16.01.2007 08:43
полезные советы jimon Болтовня 28 23.11.2005 21:31


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


vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot
Style crйe par Allan - vBulletin-Ressources.com