Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Вращение объекта вне зависимости от положения курсора относительно него (http://www.flasher.ru/forum/showthread.php?t=182004)

AlliAS 09.07.2012 12:57

Вращение объекта вне зависимости от положения курсора относительно него
 
Здравствуйте. Существует код вращения объекта вокруг своей оси вслед за курсором:
Код AS3:

var dy:Number = mouseY - obj.y;   
var dx:Number = mouseX - obj.x; 
var radians:Number = Math.atan2(dy,dx)
var degrees:Number = radians / (Math.PI / 180);
obj.rotation = degrees;

В этом коде все хорошо, но курсор приходится перемещать вокруг объекта, а требуется, чтобы вращение осуществлялось вне зависимости от положения курсора относительно объекта. То-есть если где-то на сцене совершается вращательное движение курсором, то объект вращается вслед за ним. Как реализовать подобное?

strangedk 09.07.2012 13:07

Вероятно что функция-обработчик событий мыши подписана на сам объект, а должна быть подписана например на stage

caseyryan 09.07.2012 13:10

А по-моему все нормально подписано. Если я правильно понял, автору нужно вращать курсором где-то вообще в стороне от объекта, и чтобы объект при этом так же крутился. Т.е. не смотрел постоянно на курсор, а просто повторял его движения.

Первое что приходит в голову, покадрово записывать положения мыши, сравнивать предыдущее положение с текущим, и по этим параметрам определять направление вращения. А по разнице величин определять скорость вращения.

Storfus13 09.07.2012 13:46

Попробуйте так
Код AS3:

var moldX:Number = 0;
var moldY:Number = 0;
 
stage.addEventListener(MouseEvent.MOUSE_MOVE, objMove);
function objMove(e:MouseEvent):void{
 
var dy:Number = (mouseY - moldY) * 20
var dx:Number = (mouseX - moldX) * 20
if(dy == 0 || dx == 0)
        return;
var radians:Number = Math.atan2(dy,dx)
var degrees:Number = radians / (Math.PI / 180);
obj.rotation = degrees / 2;
 
moldY = mouseY;
moldX = mouseX;
}

Коэффициенты 20 и 2 для сглаживания дерганья объекта при малом смещении курсора. Правильнее их вычислять в зависимости от движения курсора, как предложено в предыдущем посте.

AlliAS 09.07.2012 14:09

Storfus13, Спасибо, работает, правда очень дёргано, если курсор двигать медленно, даже со "сглаживанием", попробую использовать твины.

expl 09.07.2012 15:31

Так постабильнее (вычисляет направление вращения по 3-м точкам):
Код AS3:

package 
{
        import flash.display.DisplayObject;
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.events.MouseEvent;
        import flash.geom.Point;
 
        public class Main extends Sprite
        {
 
                public function Main():void
                {
                        if (stage) init();
                        else addEventListener(Event.ADDED_TO_STAGE, init);
                }
 
                private var _object:Sprite;
 
                private function init(e:Event = null):void
                {
                        _object = new Sprite();
                        _object.graphics.lineStyle(1, 0xff0000);
                        _object.graphics.lineTo(100, 100);
                        _object.x = 250;
                        _object.y = 250;
                        addChild(_object);
 
                        _rotation = _object.rotation;
                        stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
                }
 
                private var _points:Array = [];
                private var _rotation:Number;
 
                private function onMouseMove(event:MouseEvent):void
                {               
                        _points.push(new Point(mouseX, mouseY));
                        if (_points.length < 4)
                        {
                                return;
                        }
                        if (_points.length > 4)
                        {
                                _points.shift();
                        }
                        var p0:Point = _points[0];
                        var p1:Point = _points[1];
                        var p2:Point = _points[2];
                        var p3:Point = _points[3];
                        var p01xp12:Number = (p1.x - p0.x) * (p2.y - p1.y) - (p1.y - p0.y) * (p2.x - p1.x);
                        var p12xp23:Number = (p2.x - p1.x) * (p3.y - p2.y) - (p2.y - p1.y) * (p3.x - p2.x);
                        _rotation += (p01xp12 + p12xp23) * .5;
                        _object.rotation = _rotation;
                }
 
        }
 
}

Наверно тут нужно еще условный радиус учитывать, по которому в текущий момент вращают мышку

AlliAS 09.07.2012 16:03

Работает, но тоже как-то странно (то очень резко, то медленно). Вообще основная идея - сделать окно принятия решения как в игре Mass Effect:
http://www.cravingtech.com/blog/wp-c.../2008/06/2.jpg
Там курсор вращается очень плавно. Есть идеи как это сделано?

expl 09.07.2012 16:47

Описывая анимацию давать ссылку на статическую картинку - это 5 баллов. Я понимаю, конечно, что 50% населения обязано было в нее играть, но от этого проще не становится.

AlliAS 09.07.2012 17:19

Виноват, объясняю принцип работы:
В центре снизу расположено колесо состоящее из 6-ти сегментов, в его центре - курсор, при совершении вращательных движений мышью он вращается от сегмента к сегменту относительно центра колеса, по часовой или против часовой стрелки, в зависимости от движения мыши. Вращается плавно, без рывков. Начиная с некоторого небольшого радиуса (около 30 пикселов), скорость вращения не зависит от размера описываемых мышью кругов, один круг мышью - один полный поворот курсора на 360*. Если же описываемый круг имеет радиус меньше 30 пикселов, то вращение практически не происходит. Тот сегмент, на который направлен курсор - подсвечивается, так-же как и соответствующая сегменту надпись (вариант ответа). При клике левой кнопкой происходит выполнение действия назначенного на подсвеченный вариант, и диалог пропадает. Вроде всё

Еще одна версия диалога: http://gamepart.ru/sites/default/fil...ect-325695.jpg

vizgl 12.07.2012 19:19

Тоже возникла сейчас такая задача.
Приведенные выше методы, работают не так, как хочется.

CyberDude 12.07.2012 20:35

Почему бы не подписать сцену на событие MouseDown а затем, по сему событию сохранять координаты точки, и относительно этой точки считать угол?

vizgl 13.07.2012 00:31

Цитата:

Сообщение от CyberDude (Сообщение 1088454)
Почему бы не подписать сцену на событие MouseDown а затем, по сему событию сохранять координаты точки, и относительно этой точки считать угол?

у меня, чтобы крутить обьект, по нему нужно сначала кликнуть и потом делать вращательные движения мышкой в любом месте

expl 13.07.2012 00:33

Цитата:

у меня, чтобы крутить обьект, по нему нужно сначала кликнуть и потом делать вращательные движения мышкой в любом месте
А в чём удобство то такого подхода? Всмысле чтобы перестать крутить надо еще раз кликнуть чтоли? Дык ведь придется аккуратно назад подводить, чтобы не повернуть еще раз. Цель вызвать раздражение у юзера?

Krusty 13.07.2012 00:47

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

Wolsh 13.07.2012 00:47

По поводу масс эффекта думаю надо создавать виртуальный центр, вокруг которого считать поворот.
Играл давно и не помню, как там активизируется слежение за мышью — сразу при появлении меню, или надо нажать мышь и вращать, а потом отпустить когда подсветится на нужном пункте... Не важно, есть момент когда начинается слежение за движением мыши. В этот момент на круговом меню какой-то пункт "выбран", то есть "курсор меню" находится на каком-то секторе окружности. Создаем виртуальное представление окружности для мышки, то есть определяем центр окружности так, чтобы положение мыши "сейчас" было в том же секторе этой виртуальной окружности, что и "курсор меню" в реальной окружности. И далее вычисляем угол при движении мыши относительно этого виртуального центра.
Ну а плавность я думаю твинами можно обеспечить.

vizgl 13.07.2012 03:37

Да, как вариант строить окружность по 3 последним точкам и проверять относительно её центра, в какую сторону пользователь вращает курсор. Попробую и отпишусь о результатах.

Добавлено через 9 часов 48 минут
Сделал так:
Есть массив(очередь) из 3 точек(координаты курсора), через определенное время(например 100 мс), выбрасываем первую точку и добавляем последнюю(текущие координаты курсора). Еще храним предыдущую позицию курсора, записывается на каждом шаге.
Теперь рассчитываем центр окружности по таким точкам: 1) точка с индексом 0 в массиве координат, 2) предыдущая позиция курсора, 3) текущая позиция.
Находим угол поворота между предыдущей позицией курсора и текущей относительно центра окружности. Этот угол и будет коэффициентом поворота. Можно попробовать рассчитывать этот коэффициент как расстояние между пред. и текущей координатами курсора.

Можно еще попробовать строить окружность по другим точкам, покрутить время удаления/добавления точек и т.д.


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

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