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

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 22.02.2010, 15:28
zaidite вне форума Посмотреть профиль Отправить личное сообщение для zaidite Найти все сообщения от zaidite
  № 1  
Ответить с цитированием
zaidite

Регистрация: Dec 2008
Сообщений: 41
По умолчанию Оптимизация общей производительности в игре

Всем привет.
В создаваемой игре в определённый момент резко встал вопрос производительности. Надумал один ход, хочу обсудить, прежде чем игруху переделывать.
По ходу разработки, в игре накопились моменты, где применяется EnterFrame и Timer. Понятно, что каждый такой Event отъедает свой кусок производительности. А если взять и написать один класс, который будет задавать событие EnterFrame и Timer, так сказать централизовано, а если нужно какой нибудь метод запускать ЕнтерФреймом или Таймером, передаём метод в этот класс с нужными параметрами и один класс для всей игрухи будет это делать. Плюс сюда ещё можно и EVENT_RENDER прикрутить каким нибудь боком. Что-бы прорисовывать только по факту готовых данных для визуализации.
У кого какие соображения по данному варианту?
Может кто-нибудь какие другие хитрости знает по организации максимальной производительности в играх...
З.Ы. Игруха - экономическая стратегия (типа сим-сити) с массой активных объектов на экране и кучей жителей постоянно бродящим по улицам.

Старый 22.02.2010, 16:07
expl вне форума Посмотреть профиль Отправить личное сообщение для expl Найти все сообщения от expl
  № 2  
Ответить с цитированием
expl

блогер
Регистрация: Feb 2006
Сообщений: 1,474
Записей в блоге: 3
Цитата:
А если взять и написать один класс, который будет задавать событие EnterFrame и Timer, так сказать централизовано, а если нужно какой нибудь метод запускать ЕнтерФреймом или Таймером, передаём метод в этот класс с нужными параметрами и один класс для всей игрухи будет это делать
Ниче не даст =)
(Если, конечно, не считать жуткого леса if-ов в этом перегруженном классе)
Тут сложно что-то конкретное посоветовать, но стандартных направления 2:
- обновляем все не в каждом кадре в ЕНТЕРФРЕЙМЕ, а только если данные изменились;
- реиспользуем все объекты, которые можно реиспользовать
объект не нужен - положили в пул
объект понадобился - не создаем новый, а достаем из пула (в особенности касается BitmapData).

Старый 22.02.2010, 16:22
ps_spectre вне форума Посмотреть профиль Отправить личное сообщение для ps_spectre Найти все сообщения от ps_spectre
  № 3  
Ответить с цитированием
ps_spectre
 
Аватар для ps_spectre

блогер
Регистрация: Jan 2010
Адрес: Киев
Сообщений: 156
Записей в блоге: 4
Отправить сообщение для ps_spectre с помощью Skype™
Как уже выше заметили - использовать пулы (неизменяемый список объектов) как минимум, чтобы работы сборщику мусора было как можно меньше.
Второе - вывод на экран нужно оптимизировать => как можно меньше использовать DisplayObject (Sprites, MovieClips, etc...). В самом простом случае - 1 битмап на стейдже, в который, каждый кадр, рендерим нужные объекты ручками, самое быстрое - copyPixels() у BitmapData.

Старый 22.02.2010, 16:41
expl вне форума Посмотреть профиль Отправить личное сообщение для expl Найти все сообщения от expl
  № 4  
Ответить с цитированием
expl

блогер
Регистрация: Feb 2006
Сообщений: 1,474
Записей в блоге: 3
Цитата:
В самом простом случае - 1 битмап на стейдже, в который, каждый кадр, рендерим нужные объекты ручками, самое быстрое - copyPixels() у BitmapData.
Спорный подход, по-крайней мере нигде не видел такого для игры с большим количеством объектов на экране

Это выглядит как "делаем сами руками то, что флешплеер делает нативно".

Другое дело - весь фон, который редко меняется, отрисовывать на битмапе размером с экран, а при скроллировании его дорисовывать только куски с боков, а сам двигать с помощью метода scroll() у BitmapData

А перерисовывать самому кучу и так постоянно перерендеривающихся объектов - неужели это действительно быстрее?
(еще, вдобавок, придется лепить систему, обрабатывающую клики мышью - у нас же один битмап на экране)


Последний раз редактировалось expl; 22.02.2010 в 16:59.
Старый 22.02.2010, 17:17
ps_spectre вне форума Посмотреть профиль Отправить личное сообщение для ps_spectre Найти все сообщения от ps_spectre
  № 5  
Ответить с цитированием
ps_spectre
 
Аватар для ps_spectre

блогер
Регистрация: Jan 2010
Адрес: Киев
Сообщений: 156
Записей в блоге: 4
Отправить сообщение для ps_spectre с помощью Skype™
expl, не, ну понятное дело, в крайности кидаться не стоит, просто как пример обозначил, что можно рисовать в битмапу, которая на стейдже с помощью copyPixels(); А вообще, кстати, зависит от типа игры, так что если правильно все написать, то будет быстрее, в некоторых случаях. А по-поводу системы - особо лепить ничего не надо, координаты нам известны при щелчке, и те объекты, которые могут реагировать на щелчок - координаты мы тоже знаем, поэтому сложности не возникает никакой.

Старый 22.02.2010, 17:28
zaidite вне форума Посмотреть профиль Отправить личное сообщение для zaidite Найти все сообщения от zaidite
  № 6  
Ответить с цитированием
zaidite

Регистрация: Dec 2008
Сообщений: 41
Цитата:
Сообщение от expl Посмотреть сообщение
- реиспользуем все объекты, которые можно реиспользовать
объект не нужен - положили в пул
объект понадобился - не создаем новый, а достаем из пула (в особенности касается BitmapData).
Можете пояснить, не совсем понятно что такое пул.

ps_spectre,
А по поводу отрисовки в битмап, можете подсказать возможно ли что-бы:
1. Делались все необходимые вычисления в игре,
2. Потом применялись изменения в сцене.
3. Потом всё одним махом в битмап и отобразить на сцене..

Как думаете, так будет прирост производительности?

Старый 22.02.2010, 17:35
Партизан вне форума Посмотреть профиль Отправить личное сообщение для Партизан Найти все сообщения от Партизан
  № 7  
Ответить с цитированием
Партизан
 
Аватар для Партизан

блогер
Регистрация: Nov 2007
Адрес: Almaty, Moscow
Сообщений: 396
Записей в блоге: 5
Отправить сообщение для Партизан с помощью Skype™
Цитата:
Сообщение от zaidite Посмотреть сообщение
...написать один класс, который будет задавать событие EnterFrame и Timer, так сказать централизовано, а если нужно какой нибудь метод запускать ЕнтерФреймом или Таймером, передаём метод в этот класс с нужными параметрами и один класс для всей игрухи будет это делать.
Примерно то же самое и происходит когда вы подписываетесь на событие
Вы передаете имя функции которая вызовется при событии... Грубо говоря - при событии EnterFrame вызывается for each по массиву переданных вами ранее функций... А с предполагаемым вашим подходом после этого еще и ваш класс начнет ту же логику по второму кругу.

Старый 22.02.2010, 17:54
ps_spectre вне форума Посмотреть профиль Отправить личное сообщение для ps_spectre Найти все сообщения от ps_spectre
  № 8  
Ответить с цитированием
ps_spectre
 
Аватар для ps_spectre

блогер
Регистрация: Jan 2010
Адрес: Киев
Сообщений: 156
Записей в блоге: 4
Отправить сообщение для ps_spectre с помощью Skype™
zaidite, как выше заметил expl, всех до единого объекта не имеет смысла выводить таким образом, но например, если нам надо вывести 1000 пуль* например на сцену, то лучше иметь один спрайт пульки, массив из 1000 созданных пуль, в цикле пробежаться от 0 до кол-ва видимых пуль на сцене и отрисовать их в битмапу.

*пуля = bullet = ее не надо вращать, менять ей цвет и т.д. (в простом случае), поэтому, в этом случае, однозначно лучше на экран отображать ручками.

тоже самое, если карта состоит из tiles (тайлов), то лучше их отображать не сцену не как sprite или movieClip , а с помощью copyPixels().

www.8bitrocket.com - отсюда можно начать изучать sprite blitting
например - Flash AS3 Speed Tests: Rendering and Update Models

Добавлено через 27 минут
Немного материала по теме:
Tutorial: AS3. The basics of tile sheet animation (or blitting).
Tutorial Update: Basic Blit with Transparency

Tutorial: AS3 Basic Blitting #2 : Rotation - Part 1

Flash CS3: Actionscript 3 (AS3) Game Primer #1: Tile Maps, XML, and bitmapData

Flash CS3: Actionscript 3 (AS3) Game Primer #3: Bitmap Collision Detection


8bitrocket Diatribe: Drawing Vector Primitives into a BitmapData Object in AS2 and AS3.

8bitrocket Diatribe: Tile-based BitmapData Fine Scrolling
Tutorial: N-way tile-based blit fine scrolling in AS3 (part 1)
Tutorial: N-way tile-based blit fine scrolling in AS3 (part 2)

Tutorial: N-way tile-based blit fine scrolling in AS3 (part 3)

Actionscript 3: Tutorial - BitmapData rotation with a matrix

Старый 22.02.2010, 18:27
zaidite вне форума Посмотреть профиль Отправить личное сообщение для zaidite Найти все сообщения от zaidite
  № 9  
Ответить с цитированием
zaidite

Регистрация: Dec 2008
Сообщений: 41
ps_spectre спасибо за ссылки. Мне это уже попадалось... Всё никак до изучения английского не дойду..))) Мне бы такой-же тест но на русском... Увы не нашёл...
Буду копать в сторону copyPixel(). Может какие идеи и появятся...

А по-поводу Ентер Фреймов... Неужели никакой разницы, - создавать 10 новых/разных объектов ЕнтерФрейм в игре для 10 разных ситуаций, или создать один объект ЕнтерФрейм и через него крутить 10 методов в этих ситуациях... Что-то мне не верится...
В общем надо пробовать.


Последний раз редактировалось zaidite; 22.02.2010 в 18:42.
Старый 22.02.2010, 18:50
ps_spectre вне форума Посмотреть профиль Отправить личное сообщение для ps_spectre Найти все сообщения от ps_spectre
  № 10  
Ответить с цитированием
ps_spectre
 
Аватар для ps_spectre

блогер
Регистрация: Jan 2010
Адрес: Киев
Сообщений: 156
Записей в блоге: 4
Отправить сообщение для ps_spectre с помощью Skype™
я делаю примерно так (очень упрощенно)
addEventListener(Event.ENTER_FRAME, gameLoop);
---
Код AS3:
		private function gameLoop(e:Event=null):void 
		{
			if (running) { logic(); render(); }		
		}
		private function logic():void
		{
			for (var i:int = 0; i < MAX_SPRITES; i++) sprites[i].logic();
		}
		private function render():void
		{			
			canvas.lock();	
			canvas.fillRect(rectangle, 0xffffffff);
			for (var i:int = 0; i < MAX_SPRITES; i++) sprites[i].render();
			canvas.unlock();
		}
игровая сущность очень упрощенно так
Код AS3:
import flash.display.BitmapData;	
	import flash.geom.Point;	
	public class GameEntity extends Object
	{			
		private var p:Point;	
		private var velocity:Number;
		public var bitmapdata:BitmapData;
		public var canvas:BitmapData;		
		public function GameEntity(x:Number, y:Number, velocity:Number)
		{	
			this.p = new Point(x, y);
			this.velocity = velocity;
		}		
		public function render():void
		{							
			canvas.copyPixels(
				bitmapdata,
				bitmapdata.rect,
				p, 
				null,
				null,
				true
			);
		}	
		public function logic():void
		{
			if (p.x <= canvas.width) p.x += velocity;
			else p.x = 1;
		}
	}


Последний раз редактировалось ps_spectre; 22.02.2010 в 18:55.
Создать новую тему Ответ Часовой пояс GMT +4, время: 23:13.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

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

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


 


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


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