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

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

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

Регистрация: Aug 2011
Сообщений: 29
По умолчанию плавный Drag rotation

Привет, пробую реализовать вращение объекта драгом.
Легко сделать, чтобы объект всегда следил за курсором, но мне нужно порционное движение при нажатой мышке.

Как когда пальцем крутишь пластинку на граммофоне.

Для этого напиал следующий код, но запутался, когда и что надо обновлять, подскажите, пожалуйста.

В интернете нашел только либо простые следящие драги, либо handle, которая по сути тоже просто прыгает на курсор при клике.

Попытался изобразить на схеме, что я делаю в коде.

В аттаче файл сцены.


[IMG]http://img440.**************/img440/9692/schemeh.jpg[/IMG]

Код AS3:
var CurX:Number=0;
var CurY:Number=0;
var GunX:Number=0;
var GunY:Number=0;
 
var lengthT:Number=0;
var heightT:Number=0;
 
var angleActual:Number=0;
var anglePast:Number=0;
var angle2rotate:Number=0;
 
 
 
 
GunX=round.x;
GunY=round.y;
 
 
var clicked:Boolean=false;
stage.addEventListener (MouseEvent.MOUSE_DOWN , mouseDownFunc);
 
function mouseDownFunc(e:MouseEvent):Boolean
{
	clicked=true;
 
	return clicked;
 
 
 
}
 
stage.addEventListener (MouseEvent.MOUSE_UP , mouseUpFunc);
 
function mouseUpFunc(e:MouseEvent):Boolean
{
	clicked=false;
 
	return clicked;
}
 
 
addEventListener(Event.ENTER_FRAME, frameUpdate);
function frameUpdate(e:Event):void  
{
	if(clicked)
	{
		lengthT=Math.floor(stage.mouseX-GunX);
		heightT=-(Math.floor(stage.mouseY-GunY));
 
		trace("lengthT",lengthT);
		trace("heightT",heightT);
 
		anglePast=angleActual;
		trace("anglePast",anglePast);
		angleActual=(Math.atan2(lengthT,heightT))*180/Math.PI;
		trace("аngleActual",angleActual);
		angle2rotate=angleActual-anglePast;
		trace("angle2rotate",angle2rotate);
		round.rotation+=angle2rotate;
 
	}
 
 
 
 
 
 
}

Спасибо!
Вложения
Тип файла: zip test1.zip (5.7 Кб, 49 просмотров)

Старый 21.12.2011, 04:22
t4arty вне форума Посмотреть профиль Отправить личное сообщение для t4arty Найти все сообщения от t4arty
  № 2  
Ответить с цитированием
t4arty

Регистрация: May 2010
Адрес: пространство в положении
Сообщений: 219
http://xitri.com посмотрите тут, либо используйте уже написанные движки для физики.

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

Регистрация: Jul 2011
Сообщений: 67
Хм как-то всё скомкано... Но всё-же стоит вычислять anglePast при нажатии кнопки, имхо подписываться лучше на MOUSE_MOVE, angleActual нужна как локальная переменная, не надо её хранить. Почему вы не берёте координаты на прямую у объекта? Что если он будет смещаться во время выполнения?

Обработчик будет выглядеть как-то так:
Код AS3:
function mouseMove(e:MouseEvent):void {
	var currentAng:Number = Math.atan2(mouseY - obj.y, mouseX - obj.x) * 180 / Math.PI;
	obj.rotation += currentAng - oldAng;
	oldAng = currentAng;
}
Обратите внимание, что вы не верно назначили параметры функции Math.atan2(y,x).
Если уж пишите в кадрах, не перемешивайте объявления функций с остальным кодом, вымораживает такое наблюдать, да и лучше не пишите код в кадрах вообще.

Старый 21.12.2011, 13:55
Alex Lexcuk вне форума Посмотреть профиль Отправить личное сообщение для Alex Lexcuk Посетить домашнюю страницу Alex Lexcuk Найти все сообщения от Alex Lexcuk
  № 4  
Ответить с цитированием
Alex Lexcuk

блогер
Регистрация: Mar 2008
Адрес: Донецк_city
Сообщений: 1,094
Записей в блоге: 5
Тут основная проблема определить в какую сторону надо вращать на данный момент, по часовой или против часовой, для себя я сделал класс, которым пользуюсь по мере необходимости.
Код AS3:
package  
{
	/**
	 * ...
	 * @author Lexcuk
	 */
	public class Rad
	{
		public static var rx:Number = 0;
		public static var ry:Number = 0;
 
		public static const PI:Number = Math.PI;
		public static const PI2:Number = Math.PI + Math.PI;
		public static const PI_DIV_2:Number = Math.PI / 2;
 
 
		public static function rotPoint(ax:Number, ay:Number, rad:Number):void {
			var cosrad:Number = Math.cos(-rad);
			var sinrad:Number = Math.sin(-rad);
			rx = ax * cosrad + ay * sinrad;
			ry = ay * cosrad - ax * sinrad;
		}
 
		public static function getAngl(tx:Number, ty:Number):Number {
			var res:Number = Math.atan2(tx, ty)+PI;
			return -res;
		}
 
		public static function angCorrectRad(_ang:Number):Number {//корректор углов
			if (_ang > -PI && _ang < 0) return _ang;
			if (_ang < PI && _ang > 0) return _ang;
			_ang = _ang % (PI2);
			if (_ang > 0) {
				if (_ang >= PI) _ang =  _ang - PI2;
			}else {
				if (_ang <= - PI) _ang = _ang + PI2;
			}
			return _ang;
		}
	}
 
}
Можно привязываться к этому классу, что бы всегда попадать в принятые рамки, как-то где минус угла -180, где плюс + 180 градусов, и как воспринимать угол 1340 градусов, или радианов. Как пользоваться.
Код AS3:
package  
{
	import flash.display.*;
	import flash.events.*;
	import flash.geom.*;
	import flash.text.*;
 
 
	/**
	 * ...
	 * @author Lexcuk
	 * http://murmadillo.tut.su/m/rad-doc.swf
	 */
	public class Doc extends Sprite
	{
		private var turSp:Sprite;
 
		private var turX:Number = 200;
		private var turY:Number = 150;
 
		private var curRad:Number = 0;
		private var targetRad:Number = 0;
		private var radStep:Number = 0.1;
 
		public function Doc() 
		{
			addChild(turSp = new Sprite());
			turSp.graphics.lineStyle(1, 0x000000);
			turSp.graphics.drawCircle(0, 0, 2);
			turSp.graphics.drawCircle(0, 0, 50);
			turSp.graphics.lineStyle(3, 0xFF0000);
			turSp.graphics.drawCircle( 0, -60, 5);
			addEventListener(Event.ENTER_FRAME, enterFrameHandler);
		}
 
		private function enterFrameHandler(e:Event):void {
			targetRad = Rad.angCorrectRad(Rad.getAngl(stage.mouseX - turX, stage.mouseY - turY));
			curRad = Rad.angCorrectRad(curRad);
 
			var minusRad:Number = Rad.angCorrectRad(targetRad - curRad);
 
			if (Math.abs(minusRad) > Math.PI) {
				minusRad = - Rad.angCorrectRad(curRad - targetRad);
			}
 
			if (Math.abs(minusRad) > radStep) {
				if (minusRad > 0) curRad += radStep; else curRad -= radStep;
			} else curRad = targetRad;
 
			var m:Matrix = turSp.transform.matrix;
			m.identity();
			m.rotate(curRad);
			m.translate(turX, turY);
			turSp.transform.matrix = m;
		}
 
 
	}
 
}
Демо http://murmadillo.tut.su/m/rad-doc.swf
На буржуйском форуме эта штука понравилась
http://www.kirupa.com/forum/showthre...oblem-of-enemy

А вом надо при нажатии мыши ну так можно на событие нажатия кнопки мыши добавлять enterFrame, а при отпусканиии удалять enterFrame слушатель.
__________________
Гоночка


Последний раз редактировалось Alex Lexcuk; 21.12.2011 в 14:00.
Старый 21.12.2011, 17:01
artcraft вне форума Посмотреть профиль Отправить личное сообщение для artcraft Посетить домашнюю страницу artcraft Найти все сообщения от artcraft
  № 5  
Ответить с цитированием
artcraft
 
Аватар для artcraft

блогер
Регистрация: Aug 2005
Адрес: www.artcraft.cz
Сообщений: 1,967
Записей в блоге: 6
Отправить сообщение для artcraft с помощью ICQ
вот игра в утку http://artcraft.cz/fun/duck.html

там нет поясания, но задача такова:
есть круглое озеро с голодной уткой
и лиса на берегу, которая бегает ровно в 4 раза быстрее чем плавает утка,
утке надо попасть на берег и поесть там травы, урвав момент когда рядом нет лисы,
но лиса не спит и изо всех сил пытается подловить утку на берегу

могу поискать исходник, если надо
__________________
Хороший отдых - половина работы.

Старый 22.12.2011, 02:19
reQuiem вне форума Посмотреть профиль Отправить личное сообщение для reQuiem Найти все сообщения от reQuiem
  № 6  
Ответить с цитированием
reQuiem

Регистрация: Aug 2011
Сообщений: 29
t4arty

Хитри весь пролистал, там нет того что мне нужно, сторонние движки в данному случае не хочу, тк тут меня от решения отделяет совсем небольшой затык.


ProxyGreen

Да, но вы написали просто более аккуратный вариант моего кода, в этом случае при клике все равно объект ориентируется на курсор.

Спасибо я у себя поправил с вашими рекомендациями, но проблема осталась.

Мне нужно вращать объект за любое место на столько градусов сколько составило отклонение от начала драга до текущего момента.

Мб а вас не до конца понял? вот мой текущий код.

Код AS3:
var anglePast:Number=round.rotation;
 
var clicked:Boolean=false;
 
stage.addEventListener (MouseEvent.MOUSE_DOWN , mouseDownFunc);
stage.addEventListener (MouseEvent.MOUSE_UP , mouseUpFunc);
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveFunc);
 
function mouseDownFunc(e:MouseEvent):Boolean
{
	clicked=true;
	return clicked;
}
 
function mouseUpFunc(e:MouseEvent):Boolean
{
	clicked=false;
	return clicked;
}
 
function mouseMoveFunc(e:MouseEvent):void 
{
	if(clicked)
	{	
		var currentAng:Number = Math.atan2(mouseY - round.y, mouseX - round.x) * 180 / Math.PI;
		round.rotation += currentAng - anglePast;
		anglePast = currentAng;
	}
}
А в кадре ну просто так быстрее набросать было пример. Потом естественно все будет в классе.



Alex Lexcuk
artcraft


Спасибо, но вы не совсем верно меня поняли. У меня сейчас уже объект ловит правильные градусы но глобально - Повернуть от 0 до текущего угла курсора.
А мне надо угол объекта увеличить на разность между углом курсора на начало драга и углом курсора на текущий момент.
Вложения
Тип файла: zip test2.zip (1.5 Кб, 36 просмотров)

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

Регистрация: Jul 2011
Сообщений: 67
Цитата:
Мб а вас не до конца понял?
Омг. да таки не до конца поняли.
Вот что я имел ввиду:
Код AS3:
	var anglePast:Number;      //подумайте над названиями переменных, да это тоже важно
            var clicked:Boolean=false; // старайтесь использовать по возможности естественные условия
 
            stage.addEventListener (MouseEvent.MOUSE_DOWN , mouseDownFunc);
            stage.addEventListener (MouseEvent.MOUSE_UP , mouseUpFunc);
 
            function mouseDownFunc(e:MouseEvent):Boolean
            {
                //стоит вычислять anglePast при нажатии кнопки, ага
                anglePast = mouseAng(round);
                stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveFunc);
 
            }
            function mouseUpFunc(e:MouseEvent):Boolean
            {
	    stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveFunc);
            }
 
            function mouseMoveFunc(e:MouseEvent):void 
            {
		 var currentAng:Number = mouseAng(round);
		 round.rotation += currentAng - anglePast;
		 anglePast = currentAng;
            }
 
            function mouseAng(obj:DisplayObject):Number{ 
                //все типичные и часто повторяющиеся операции выносите 
                //в отдельные функции
                return Math.atan2(mouseY - obj.y, mouseX - obj.x) * 180 / Math.PI;
            }
Цитата:
А в кадре ну просто так быстрее набросать было пример. Потом естественно все будет в классе.
Избегать кода в IDE нужно хотя-бы из-за отсутствия там вменяемого автокомплита, использовали-бы нормальный редактор, досадных ошибок с тем-же Math.atan2() просто не было бы.

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

модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
Цитата:
//все типичные и часто повторяющиеся операции выносите
//в отдельные функции
Я бы еще добавил – а все константы типа (180 / Math.PI) вычислять один раз, а не делать одно и то же вычисление с обращением к другому классу 100 раз на одно короткое движение.
__________________
Reality.getBounds(this);

Старый 22.12.2011, 11:10
reQuiem вне форума Посмотреть профиль Отправить личное сообщение для reQuiem Найти все сообщения от reQuiem
  № 9  
Ответить с цитированием
reQuiem

Регистрация: Aug 2011
Сообщений: 29
Большое спасибо!
Все учту.

Старый 22.12.2011, 12:20
lovik вне форума Посмотреть профиль Отправить личное сообщение для lovik Найти все сообщения от lovik
  № 10  
Ответить с цитированием
lovik
[+1 03.01.12]
[++1 03.01.12]

Регистрация: Dec 2011
Сообщений: 29
доброго времени суток
Если вас не затруднит распишите подробно формулу вычисления угла поворота объекта в зависимости от положения мыши и что надо увеличивать по событию ентер фрейм чтоб оно двигалось поскольку чет у меня нечего не получается

заранее спасибо

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

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

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


 


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


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