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

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

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

Регистрация: Jun 2006
Сообщений: 69
По умолчанию Гладкая анимация

Пытаюсь создать плавное движение текста, но во время движения он временами дергается и выглядит убого.
Пробовал двумя способами (обычным и блитированием) - результат одинаковый.
Может кто подскажет как можно это исправить.

Пример:
http://stulnikov.com/example/

Код:
Код AS3:
        public class Main extends Sprite 
	{
		[Embed(source = "assets/image.png")] private var SomeImage:Class;
 
		private var item:BitmapData;
		private var itemRect:Rectangle;
		private var screen:BitmapData;
		private var rect:Rectangle;
		private var point:Point;
 
		private var image:Bitmap;
 
		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);
 
			screen = new BitmapData(800, 600, false);
			rect = new Rectangle(0, 0, screen.width, screen.height);
			point = new Point(-100, 100);
			item = new SomeImage().bitmapData;
			itemRect = new Rectangle(0, 0, item.width, item.height);
 
			image = new SomeImage();
			image.x = -100;
			image.y = 100;
 
			addChild(new Bitmap(screen));
			//addChild(image);
 
			addChild(new Stats());
 
			addEventListener(Event.ENTER_FRAME, enterfFrame);
		}
 
		private function enterfFrame(e:Event):void 
		{
			animation1();
			//animation2();
		}
 
		private function animation1():void
		{
			screen.lock();
			screen.fillRect(rect, 0xFFFFFF);
			screen.copyPixels(item, itemRect, point);
			screen.unlock();
			point.x += 5;
		}
 
		private function animation2():void
		{
			image.x += 5;
		}
 
	}
Исходники (FlashDevelop проект):
http://stulnikov.com/example/TestAnimation.rar

Старый 01.10.2011, 03:10
flax4Noob вне форума Посмотреть профиль Отправить личное сообщение для flax4Noob Найти все сообщения от flax4Noob
  № 2  
Ответить с цитированием
flax4Noob
[+1 15.01.11]

Регистрация: Jan 2011
Сообщений: 70
Тебе надо в animation1()
Получить getTimer(), потом от него отнять getTimer() предыдущего кадра. Ты получишь сколько времяни прошло между кадрами.
Дальше, зная время, и взяв скорость из настроек класса (например, 2 пикселя в секунду) ты считаешь на сколько пикселей тебе надо подвинуть текст. Двигаешь, рисуешь. Запоминаешь текущее время.

Вроде все. Должно быть равномерно плавненько.

Добавлено через 2 минуты
а, ну и еще не надо перерисовывать, если расстояние меньше одного пикселя. оО и не надо запоминать такое время.

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

Регистрация: Mar 2010
Адрес: 54.713862552265084 = 20.442724227905273
Сообщений: 449
Отправить сообщение для stweet с помощью Skype™
вы используете "ENTER_FRAME" что зависит от частоты обновления экрана.
что если так:
Код AS3:
package {
 
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	import flash.utils.getTimer;
	import flash.utils.Timer;
 
	public class TestMove extends Sprite {
 
		public function TestMove() {
 
			if (stage) ADDED_TO_STAGE();
			else addEventListener(Event.ADDED_TO_STAGE, ADDED_TO_STAGE);
 
			function ADDED_TO_STAGE(e:Event = null):void {
				removeEventListener(Event.ADDED_TO_STAGE, ADDED_TO_STAGE);
				// start point
 
				var xPos:Number = 100;
				var yPos:Number = 100;
 
				var tf:TextField= new TextField();
					tf.text		= "Clic me!";
					tf.autoSize = TextFieldAutoSize.LEFT;
					tf.setTextFormat(new TextFormat("Arial", 28, 0x808080));
					tf.x = xPos;
					tf.y = yPos;
					addChild(tf);
 
				var speed:Number = 10;
				var delay:Number = 10;
 
				var move:Boolean = true;
 
				var la	:Number = getTimer();
 
				var timer:Timer = new Timer(delay);
					timer.addEventListener(TimerEvent.TIMER, function (e:TimerEvent):void {
						tf.x += speed + (la - getTimer()) * .1;
						if (tf.x >= stage.stageWidth - xPos) tf.x = xPos;
						e.updateAfterEvent();
						la = getTimer();
					});
 
				stage.addEventListener(MouseEvent.MOUSE_DOWN, function(e:MouseEvent):void {
						if (move) timer.start(); else timer.stop();
						move = !move;
					});
			}
		}
	}
}
__________________
Спросишь, дурак на минуту. Если не спросишь, дурак на всю жизнь!

Старый 01.10.2011, 04:05
fljot вне форума Посмотреть профиль Отправить личное сообщение для fljot Найти все сообщения от fljot
  № 4  
Ответить с цитированием
fljot

блогер
Регистрация: Jul 2007
Сообщений: 940
Записей в блоге: 3
Может просто fps поднять? Судя по http://www.greensock.com/blitmask/ copyPixels, действительно, должен быть самым гладким вариантом.

Старый 02.10.2011, 03:39
Kicker вне форума Посмотреть профиль Отправить личное сообщение для Kicker Найти все сообщения от Kicker
  № 5  
Ответить с цитированием
Kicker
 
Аватар для Kicker

Регистрация: Jun 2006
Сообщений: 69
Воспользовался советами - переделал на Timer.
Код AS3:
		var timer:Timer = new Timer(1);
		timer.addEventListener(TimerEvent.TIMER, animation);
		...
 
                private function animation(e:TimerEvent):void
		{
			var time:Number = getTimer() - last;
			point.x += time * .16;
			screen.lock();
			screen.fillRect(rect, 0xFFFFFF);
			screen.copyPixels(item, itemRect, point);
			screen.unlock();
			last = getTimer();
		}
Результат:
http://stulnikov.com/example2/

По моему не особо отличается.

To:fljot
С fps экспериментировал, положительных результатов не добился.

Попробую просто сделать гифку, может красивее получится ))

Старый 02.10.2011, 04:24
in4core вне форума Посмотреть профиль Отправить личное сообщение для in4core Найти все сообщения от in4core
  № 6  
Ответить с цитированием
in4core
[+4 06.05.14]
 
Аватар для in4core

Регистрация: Mar 2009
Сообщений: 4,219
Записей в блоге: 14
Цитата:
Код AS3:
stage.frameRate = 33;
..................
__________________
Марк Tween

Старый 02.10.2011, 06:08
flax4Noob вне форума Посмотреть профиль Отправить личное сообщение для flax4Noob Найти все сообщения от flax4Noob
  № 7  
Ответить с цитированием
flax4Noob
[+1 15.01.11]

Регистрация: Jan 2011
Сообщений: 70
Цитата:
Сообщение от Kicker Посмотреть сообщение
Воспользовался советами - переделал на Timer.
Код AS3:
		var timer:Timer = new Timer(1);
Плакал

Цитата:
Сообщение от Kicker Посмотреть сообщение
Код AS3:
 
			var time:Number = getTimer() - last;
			[skiped]
			last = getTimer();
Результат:[SKIPED]
Ясное дело, что результат соответствует коду. Вы не понимаете схемы работы таймера и, самое главное, схемы анимации. Вам жизненно необходимо сохранять getTimer() в переменную, чтобы "getTimer() - last" учитывало время прорисовки. В вашем варианте оно не учитывается. поэтому, естественно, получаются рывки. И, естественно, вы разочарованы. Попробуйте так:
Код AS3:
var frameTime:uint = getTimer();
var time:Number = frameTime - last;
last = frameTime;
 
и дальше свое колдовство с битмапами.
И таймер ставится в "секунда/1000" => бессмысленно ставить значения ниже 40. Хотя для анимации 25 фпс достаточно 100 поставить.

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

Регистрация: Jun 2006
Сообщений: 69
Действительно туплю.
Стало лучше, но все равно двигается рывками, хоть и равномерными ))

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

Регистрация: Mar 2010
Адрес: 54.713862552265084 = 20.442724227905273
Сообщений: 449
Отправить сообщение для stweet с помощью Skype™
Цитата:
Сообщение от Kicker Посмотреть сообщение
Действительно туплю.
Стало лучше, но все равно двигается рывками, хоть и равномерными ))
Предлагаю ещё раз рассмотреть тот код который дал я и добавить к своим задачам использование методов:
Timer(); Управляем анимацией.
getTimer(); Расчёт времени на перерисовку избегая ошибок в движении.
updateAfterEvent(); Перерисовываем анимацию программно(обновляем экран) т.е. только после того как методы выше выполнили свои задачи.

Добавлено через 5 минут
Цитата:
point.x += time * .16;
у вас тут "time" постоянно разный, естественно будит рывками!
избегая вычитайте "time" из целого числа тогда получите равный интервал после каждой перерисовки экрана.
Цитата:
point.x += (number - time) * .16;
__________________
Спросишь, дурак на минуту. Если не спросишь, дурак на всю жизнь!


Последний раз редактировалось stweet; 02.10.2011 в 16:27.
Старый 02.10.2011, 17:12
-De- вне форума Посмотреть профиль Отправить личное сообщение для -De- Найти все сообщения от -De-
  № 10  
Ответить с цитированием
-De-
 
Аватар для -De-

блогер
Регистрация: Oct 2005
Адрес: Днепродзержинск - город Брежнева и других логопедов
Сообщений: 1,421
Записей в блоге: 4
Отправить сообщение для -De- с помощью ICQ Отправить сообщение для -De- с помощью Skype™
Цитата:
Сообщение от stweet Посмотреть сообщение
у вас тут "time" постоянно разный, естественно будит рывками!
избегая вычитайте "time" из целого числа тогда получите равный интервал после каждой перерисовки экрана.
Так время между перерисовками реально разное. Плюс для анимаций ENTER_FRAME надёжнее таймера, т.к. после него гарантированно идёт перерисовка.
__________________
Бобры отвечают на вопросы не потому, что знают на них ответы; они отвечают потому, что их спрашивают.

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

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

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


 


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


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