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

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

Оценить эту запись

Простой fps мувик

Запись от treety размещена 26.01.2011 в 20:19

1. Создаём простой мувиклип с текстовым полем "fps_tf" длинной в 120 кадров
2. Вставляем в первый кадр этот код:
Код AS3:
var fps_int = setInterval(checkFPS, 1000);
function checkFPS () {
	fps_tf.htmlText = ""+(currentFrame);
	gotoAndPlay(1);
	clearInterval (fps_int);
}
вроде работает

этот клип можно совать в любой новый проект без изменений
Всего комментариев 21

Комментарии

Старый 26.01.2011 22:15 Hauts вне форума
Hauts
 
Аватар для Hauts
А в одном кадре слабо?
Старый 26.01.2011 22:19 Psycho Tiger вне форума
Psycho Tiger
 
Аватар для Psycho Tiger
5+.
Я бы никогда не додумался до такого. Честно.
Старый 26.01.2011 22:34 iNils вне форума
iNils
 
Аватар для iNils
Если бы setInterval срабатывал 100% точно, то это бы работало.
Старый 26.01.2011 22:35 КорДум вне форума
КорДум
 
Аватар для КорДум
Ага, и зачем я целый класс писал для этого, когда можно вот так, в мувике, прям в кадре...
Старый 27.01.2011 00:03 iNils вне форума
iNils
 
Аватар для iNils
Интервал обычно срабатывает позже, чем нужно, где-то на 10-30 мс (это без нагрузки). За это время анимация уйдет дальше и фпс будет больше фактического. Но самое интересное будет на фпс близких к 120, там запаздывание приведет к тому, что анимация сбросится сама на первый кадр, и тут начнется вакханалия. Будет назначен новый таймер, а индекс старого будет утерян. И работать будут уже два таймера.
Поэтому:
1. Нужно делать таймлайн гораздо больше, чем 120 кадров. Например 240, что бы уж наверняка
2. Корректировать результат.
Код AS3:
var fps_int:int = setInterval(checkFPS, 1000);
var timer:Number = getTimer ();
function checkFPS() {
	var delta:int = getTimer () - timer;
	var cf:int = currentFrame;
	var fps:Number = cf * 1000/delta;
	trace(delta, cf,fps);
	clearInterval(fps_int);
	gotoAndPlay(1);
}
Выставил предельный fps равный 31. Результат.
Код:
1013 31 30.60217176702863
1016 30 29.52755905511811
1023 31 30.303030303030305
1023 31 30.303030303030305
1023 31 30.303030303030305
1023 31 30.303030303030305
1026 31 30.214424951267056
1024 31 30.2734375
1019 31 30.42198233562316
1027 31 30.18500486854917
1022 31 30.332681017612526
1023 31 30.303030303030305
1023 31 30.303030303030305
1023 31 30.303030303030305
1027 31 30.18500486854917
1022 31 30.332681017612526
1024 31 30.2734375
1025 31 30.24390243902439
1023 31 30.303030303030305
1025 30 29.26829268292683
Старый 27.01.2011 00:05 КорДум вне форума
КорДум
 
Аватар для КорДум
iNils, ну вы даете Здорово! Все, удаляю класс, делаю клип-fps на 240 кадров!
Старый 27.01.2011 01:00 dark256 вне форума
dark256
 
Аватар для dark256
А зачем вообще нужен этот клип на 120 или 240?

Код AS1/AS2:
var fps = 0
onEnterFrame = function (){++fps }
setint = setInterval(checkFPS, 1000)
function checkFPS() {
	trace("FPS:"+fps)
    fps = 0
}
Старый 27.01.2011 01:39 iNils вне форума
iNils
 
Аватар для iNils
Цитата:
А зачем вообще нужен этот клип на 120 или 240?
Не все любят энтерФрейм. Хотя именно он позволяет считать фпс постоянно (по времени между фреймами) и чисто программно.
Старый 27.01.2011 01:50 Котяра вне форума
Котяра
 
Аватар для Котяра
нашёл тут в закромах старое.. пустой клип с 10-100 кадров. на последнем фрэйме вызов endInterva()
код для ас2 ещё

Код AS3:
import ru.k0t0vich.cards.events.FPSEvent;
import ru.k0t0vich.events.MovieClipEventDispatcher;
/**
 * FPS мерятель - имя  инстанции: commmon.mGame.mCommon.fpsMeter
 * @author k0t0vich
 */
class ru.k0t0vich.cards.views.fps.FPSMeter extends MovieClipEventDispatcher
{
	public var fps:MovieClip;
	public var fpsValue:Number=0;
	public var startTime:Number = 0;
	public var distance:Number = 1;
	public var txt:TextField;
 
	private var totalFPSFrame=1;
	public var alertFPS = 12;
 
	public var lowestFPS = 100;
	public var highestFPS = 0;
 
 
	public var normalColor:Number = 0xFFFFFF;
	public var alertColor:Number = 0xFF0000;
 
 
	public function FPSMeter() 
	{
		this._visible = System.capabilities.isDebugger;
		trace("FPSMeter.FPSMeter");
		normalColor = txt.textColor;
		startTime = getTimer();
		totalFPSFrame= fps._totalframes;
		fps.play();
	}
 
	public function endInterval()
	{
 
		var endTime = getTimer();
		distance = endTime - startTime;
		startTime = endTime;
		fpsValue = int(totalFPSFrame / distance * 1000);
 
		lowestFPS = Math.min(lowestFPS, fpsValue);
		highestFPS = Math.max(highestFPS, fpsValue);
 
		txt.text = String(fpsValue);
		txt.textColor = normalColor;
 
		if (fpsValue < alertFPS) 
		alert();
	}
 
	private function alert():Void
	{
		//dispatchEvent(new FPSEvent(FPSEvent.FPS_ALERT,true,fps));
		// тест
		txt.textColor = alertColor;
	}
 
 
 
}
Старый 27.01.2011 02:03 dark256 вне форума
dark256
 
Аватар для dark256
Цитата:
Не все любят энтерФрейм.
Ясно
Цитата:
нашёл тут в закромах старое..
О боже.... Ну и мОнстровая вещь!
Старый 27.01.2011 02:47 Котяра вне форума
Котяра
 
Аватар для Котяра
Странно, код писался > года назад, но мне почему то не стыдно.. наверное я перестал развиваться
немного выдрано из контекста, но вроде всё понятно должно быть..
правда не пойму зачем
Код AS3:
lowestFPS = Math.min(lowestFPS, fpsValue);
highestFPS = Math.max(highestFPS, fpsValue);
видать хотел их в событии передавать.. не понадобились.
Старый 27.01.2011 12:17 dark256 вне форума
dark256
 
Аватар для dark256
видимо, планировалось графики строить. Али ишшо каку статистику.
Но по мне чем проще тем лучше.
Да и так все понятно, когда вместо расчетных 31 ФПС, фпсметр показывает 10-15
Старый 27.01.2011 14:06 treety вне форума
treety
 
Аватар для treety
Цитата:
Интервал обычно срабатывает позже, чем нужно, где-то на 10-30 мс (это без нагрузки). За это время анимация уйдет дальше и фпс будет больше фактического. Но самое интересное будет на фпс близких к 120, там запаздывание приведет к тому, что анимация сбросится сама на первый кадр, и тут начнется вакханалия. Будет назначен новый таймер, а индекс старого будет утерян. И работать будут уже два таймера.
Поэтому:
1. Нужно делать таймлайн гораздо больше, чем 120 кадров. Например 240, что бы уж наверняка
2. Корректировать результат.
спасибо за корректировку..не подумал о погрешности setInterval'а
а от чего она зависит?

Цитата:
А зачем вообще нужен этот клип на 120 или 240?
не хотел назначать очередной эвент
в данном случае стремился к простоте
Старый 27.01.2011 15:35 iNils вне форума
iNils
 
Аватар для iNils
Цитата:
не подумал о погрешности setInterval'а
а от чего она зависит?
От загрузки. Допустим у вас есть интервал, который вызывается каждые 130 мс. И фпс 20, то есть на каждый кадр 50 мс. И функция, которая выполняется 60 мс. Фпс падает.
Проходит 60 мс - первый кадр. До вызова еще 70 мс.
Следующий кадр, +60 мс, уже 120. До вызова остается 10, поэтому идет еще один кадр, тоже 60 мс. Но интервал не может прервать выполнение функции и ждет ее окончания. То есть + еще 60. Итого 180 мс и только тут интервал может быть вызван.
Старый 27.01.2011 15:38 КорДум вне форума
КорДум
 
Аватар для КорДум
iNils, чем лучше этот подход от обычного метода:
Код AS3:
private function onEnterFrame(event:Event):void {
	var now:int = getTimer();
	var elapsed:int = now - lastFrameTime;
	var fps:int = int(1000 / elapsed + .5);
	lastFrameTime = now;
	trace(fps);
}
?
Старый 27.01.2011 15:54 iNils вне форума
iNils
 
Аватар для iNils
onEnterFrame считается постоянно, и чем больше фпс, тем чаще это происходит. По сути, это бесполезно. Зачем нам обновлять фпс, скажем, 31 раз в секунду?
При этом фпс будет рваным. Скажем 31,28,30,21,30,29,26... Постоянно рывки и сказать, какой фпс в целом сложно. А обновляя его раз в секунду, мы получаем среднее значении, что в принципе и нужно.
Старый 27.01.2011 16:00 КорДум вне форума
КорДум
 
Аватар для КорДум
Тогда можно сделать таймер. Ну да, мы получим через некоторое время враку, но эта врака будет достаточно мала, чтобы посчитать вычисления верными.
Старый 27.01.2011 17:13 ChuwY вне форума
ChuwY
 
Аватар для ChuwY
А можно так =D (ну ради шутки)
Типа, чтобы раз в секунду, но без таймера и врак.

Код AS3:
public class Main extends MovieClip {
  private var _lastFrameTime:int;
  private var _frameLeft:int;
 
  public function Main() {
    addEventListener(Event.ENTER_FRAME,  onEnterFrame);
    addEventListener(Event.ENTER_FRAME,  moveCircles);
    setInterval(addCircle, 1);  
  }
 
  function addCircle():void{
    var circle : Sprite = new Sprite();
    circle.graphics.beginFill(Math.random()*0xFFFFFF);
    circle.graphics.drawCircle(0, 0, 15);
    circle.x = Math.random()*stage.stageWidth;
    circle.y = Math.random()*stage.stageHeight;
    addChild(circle);
  }
 
  private function moveCircles(event : Event){
    for(var i : int = 0; i < numChildren; i++){
      var child : DisplayObject = getChildAt(i); 
      child.x += 2;
      child.y += 2;
      if(child.x > stage.stageWidth){
        child.x = Math.random()*stage.stageWidth/2;
      }
      if(child.y > stage.stageHeight){
        child.y =  Math.random()*stage.stageHeight/2;
      }
    }	
  }
 
  private function onEnterFrame(event:Event):void {
    if (!_frameLeft) {
      var now     : int = getTimer();
      var elapsed : int = now - _lastFrameTime;
      var fps     : int = int(1000 / elapsed + .5);
      trace(fps);
      _frameLeft = stage.frameRate;
    } else if(_frameLeft == 1){
      _lastFrameTime = getTimer();
    }
    _frameLeft--;
  }
}
Старый 27.01.2011 18:51 Psycho Tiger вне форума
Psycho Tiger
 
Аватар для Psycho Tiger
А есть тесты, которые покажут что да, действительно, пустой мувик работает быстрее чем инкремент поля в хэнделере ENTER_FRAME`а?
Старый 28.01.2011 00:55 suVrik вне форума
suVrik
 
Аватар для suVrik
Код AS1/AS2:
Time = getTimer();
S = 0;
C = 0;
 
var container:MovieClip = this.createEmptyMovieClip("Container", this.getNextHighestDepth());
var label:TextField = container.createTextField("FPS", 1, 0, 0, 200, 22);
 
label.text = "fps - "+S;
 
container.onEnterFrame = function(){
	if(getTimer() >= Time + 1000){
		label.text = "fps - "+S;
		Time = getTimer();
		S = 0;
	}
	S ++;
}
Под AS2 давненько писал. Отображало нормально вроде бы. Без интервалов
Старый 28.01.2011 21:26 treety вне форума
treety
 
Аватар для treety
Цитата:
А есть тесты, которые покажут что да, действительно, пустой мувик работает быстрее чем инкремент поля в хэнделере ENTER_FRAME`а?
любапытства для
в мувике частота кадров 120..чтоб уж совсем мясо
код в кадре:
Код AS3:
this.addEventListener (Event.ENTER_FRAME,ef);
var cnt = 1;
function ef (e){
	cnt++;
	for (var i = 1; i<=100; i++){
		for (var j = 1; j<=100; j++){
			var tmp = Math.random();
		}
	}
	trace (cnt, this.tst.currentFrame);
}
клас для этого мувика:
Код AS3:
package {
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.*;
 
	public dynamic class Main extends MovieClip {
		function Main () {
			var tmp_sp = new Sprite ();
			tmp_sp.addEventListener (Event.ENTER_FRAME, tmpEF);
		}
		var sp_cnt=1;
		function tmpEF (e){
			sp_cnt++;
			for (var i = 1; i<=300; i++){
				for (var j = 1; j<=100; j++){
					var tmp = Math.random();
				}
			}
			trace ("class: "+sp_cnt);
		}
	}
}
и создал пустой клип в 3500 кадров
Код:
class: 2
count: 2
frame: 2
class: 3
count: 3
frame: 3
class: 4
count: 4
frame: 4
...
class: 3498
count: 3498
frame: 3498
class: 3499
count: 3499
frame: 3499
class: 3500
count: 3500
frame: 3500
тютелька в тютельку
тут видимо синхронизация идёт на более низком уровне
получается что никакого значения не имеет
где будет выполнятся инкремент

тут уж вопрос в другом
что из этих трёх моментов будет работать быстрее?
 
Последние записи от treety

 


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


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