Форум 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=178268)

Astraport 18.04.2012 11:49

Как создавать колесо типа рулетки?
 
Требуется создать компонент, который представляет из себя круг разделенный на сектора. Каждый сектор должен быть отдельным элементом, т. к. он взаимодействует с другим Flex компонентом (шарик) например через hitTest, имеет свой цвет и текст направленный по радиусу (иногда и иконкой/картинкой). Все это должно создаваться из XML-данных (каждый итем это отдельный сектор с цветом, надписью (иногда и иконкой/картинкой) и разными свойствами сектора).

Посоветуйте, как лучше все организовать и может быть есть примеры?

anmelegov 18.04.2012 12:09

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

Astraport 18.04.2012 12:35

Цитата:

у тебя если шарик будет между полями останавливаться то хиттест будет срабатывать для 2-х полей...
Мне это и нужно. Я потом буду считать кол-во хиттестов для каждого из полей.

Вот нашел два примера: http://www.kirupa.com/forum/showthre...ing-pie-slices
http://deviltechie.wordpress.com/201...sing-flex-as3/

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

А второй пример выдает вообще странную ошибку:
1084: Syntax error: expecting rightparen before theta.
Код AS3:

for (var theta:Number = startAngle; theta < endAngle; theta += Math.min(step, endAngle – theta)) {
                                        holder.graphics.lineTo(xpos + segmentRadius * Math.cos(theta), ypos + segmentRadius * Math.sin(theta));
                                }

Откуда там взяться этой ошибке... При этом практически идентичный код в первом варианте этой ошибки не выдает.

Добавлено через 4 минуты
Мне вот сейчас пришла идея. А что если использовать флексовский компонент Pie Chart, я как-то использовал его для кругового таймера.
Вот как регистрировать соприкосновения шарика и секторов в этом случае?

anmelegov 18.04.2012 12:50

не проще считать в градусах сколько шарик пролетел?

Astraport 18.04.2012 12:57

Цитата:

не проще считать в градусах сколько шарик пролетел?
Не можешь пояснить?
Вот у меня компонент - окружность разбитая на сектора. Как можно математически определить находится ли в текущем кадре шарик над сектором? А если учесть, что окружность должна ещё и вращаться.
Мне кажется хиттест проще.

anmelegov 18.04.2012 14:04

находишь угол между центром рулетки и шариком (с помощью atan2), потом находишь угол на который повернулось колесо рулетки и определяешь в каком секторе находится шарик... но если ты считаешь все секторы которые пересекает шарик, то конечно банальное сравнение координат через хиттест, проще чем арктангенс =)

NikolyA 18.04.2012 15:08

Цитата:

Сообщение от anmelegov (Сообщение 1075645)
находишь угол между центром рулетки и шариком (с помощью atan2), потом находишь угол на который повернулось колесо рулетки и определяешь в каком секторе находится шарик... но если ты считаешь все секторы которые пересекает шарик, то конечно банальное сравнение координат через хиттест, проще чем арктангенс =)

а теперь что сказал, изобрази программным способом

Wolsh 18.04.2012 15:21

по поводу рисования
http://flasher.ru/forum/showpost.php...21&postcount=8

PainKiller 18.04.2012 22:01

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

Astraport 22.04.2012 21:23

Возвращаясь к вопросу.

С секторами получилось отлично. Теперь хочу позиционировать текстовые поля также как спицы рулеточного колеса - ровно посредине каждого сектора, а получается все криво. Или надписи не отцентрованы по секторам или вообще пропадает половина. Вот скрин:

[IMG]http://*************/clip/m0/1335111274-clip-59kb.jpg[/IMG]

Класс сектора:
Код AS3:

package comps
{
        import flash.display.Loader;
        import flash.display.Shape;
        import flash.display.Sprite;
        import flash.filters.GlowFilter;
        import flash.geom.Matrix;
        import flash.geom.Point;
        import flash.net.URLRequest;
        import flash.text.AntiAliasType;
        import flash.text.Font;
        import flash.text.TextField;
        import flash.text.TextFormat;
        import flash.text.TextFormatAlign;
        import flash.geom.Vector3D;
        import spark.effects.Rotate;
 
        public class Sector extends Sprite
        {
                public var value:String;
                public var names:String;
                public var color:uint;
                private var imageX1:Number;
                private var imageY1:Number;
                private var imageX2:Number;
                private var imageY2:Number;
                [Embed(source="font/SEGOEUIB.TTF", fontFamily="SegoeUI", mimeType="application/x-font", embedAsCFF="false", advancedAntiAliasing="true")]
                private var MoolEmbed:Class;
 
                public function Sector(tip:String, rot:Number, centerX:Number, centerY:Number, innerRadius:Number, outerRadius:Number, startAngle:Number, arcAngle:Number, val:Number, color:uint, alpha:Number, url:String, value:Number, steps:int=20)
                {
                        Font.registerFont(MoolEmbed);
                        var myArc:Sprite = new Sprite();
                        myArc.graphics.lineStyle(2);
                        myArc.graphics.beginFill(color, alpha);
                        drawSolidArc (myArc,centerX, centerY, innerRadius, outerRadius, startAngle, arcAngle, url, steps);
                        myArc.graphics.endFill();
 
                        this.addChild(myArc);
 
                                var myFormat:TextFormat = new TextFormat();
                                myFormat.size = 20;
                                myFormat.align = TextFormatAlign.CENTER;
                                myFormat.font = 'SegoeUI';
                                myFormat.bold = true;
 
                                var myText:TextField = new TextField();
                                myText.defaultTextFormat = myFormat;
                                myText.setTextFormat(myFormat);
                                myText.embedFonts = true;
                                myText.antiAliasType = AntiAliasType.ADVANCED;
                                myText.text = url;
                                this.addChild(myText);
 
                                myText.wordWrap = true;
                                myText.width = 200;
                                myText.height = 20;
//В общем мне нужен совет по этой части кода, как правильно вращать этот текст чтобы он был оцентрован по сектору.
                                textRotation(myText, rot*(22 - value)-rot);
                                trace (rot*value + " " + value);
                                myText.x = imageX1 + 0.01 * (imageX2 - imageX1);
                                myText.y = imageY1 + 0.01 * (imageY2 - imageY1);
 
                                var myGlow:GlowFilter = new GlowFilter();
                                myGlow.color = 0xFFFFFF;
                                myGlow.blurX = 20;
                                myGlow.blurY = 20;
                                myGlow.strength = 2;
                                myText.filters = [myGlow];
                }
 
                private function textRotation (target:TextField, angle:Number):void{
                        var point:Point=new Point(target.x + target.width/2, target.y + target.height/2);
 
                        var m:Matrix=target.transform.matrix;
                        m.tx -= point.x;
                        m.ty -= point.y;
                        m.rotate (angle*(Math.PI/180));
                        m.tx += point.x;
                        m.ty += point.y;
                        target.transform.matrix=m;
                }
 
                private function drawSolidArc (drawObj:Object, centerX:Number, centerY:Number, innerRadius:Number, outerRadius:Number, startAngle:Number, arcAngle:Number, url:String, steps:int=20):void {
                        var twoPI:Number = 2 * Math.PI;
                        var angleStep:Number = arcAngle/steps;
                        var angle:Number, i:int, endAngle:Number;
                        var xx:Number = centerX + Math.cos(startAngle * twoPI) * innerRadius;
                        var yy:Number = centerY + Math.sin(startAngle * twoPI) * innerRadius;
                        var xxInit:Number=xx;
                        var yyInit:Number=yy;
                        drawObj.graphics.moveTo(xx,yy);
                        for(i=1; i<=steps; i++) {
                                angle = (startAngle + i * angleStep) * twoPI;
                                xx = centerX + Math.cos(angle) * innerRadius;
                                yy = centerY + Math.sin(angle) * innerRadius;
                                drawObj.graphics.lineTo(xx,yy);
                                if (i==steps*0.5){
                                        imageX1 = xx;
                                        imageY1 = yy;
                                }
                        }
                        endAngle = startAngle + arcAngle;
                        for(i=0;i<=steps;i++) {
                                angle = (endAngle - i * angleStep) * twoPI;
                                xx = centerX + Math.cos(angle) * outerRadius;
                                yy = centerY + Math.sin(angle) * outerRadius;
                                drawObj.graphics.lineTo(xx,yy);
                                if (i==steps*0.5){
                                        imageX2 = xx;
                                        imageY2 = yy;
                                }
                        }
                        drawObj.graphics.lineTo(xxInit,yyInit);
                }
        }
}

Рисуем колесо:
Код AS3:

sectorsNum = tarotAC.length;
                                for (var i:int = 0; i < sectorsNum; i++){
                                        var arcAngle:Number = - 1/sectorsNum;
                                        var startAngle:Number = arcAngle*i;
                                        var arc:Sector = new Sector(mode, 360/sectorsNum, 0, 0, stageW*0.1, stageW*0.5, startAngle, arcAngle, Number(sectorsNum - i), tarotAC.getItemAt(i).color, 1, tarotAC.getItemAt(i).datas, tarotAC.getItemAt(i).url);
                                        con.addChild(arc);
                                }

Что посоветуете? Спасибо.

Wolsh 22.04.2012 22:08

А не проще было сектора рисовать неповернутыми, и спокойно размещать в них текст?
А потом уже составлять колесо, поворачивая сектора?

Добавлено через 4 минуты
NB Нулевой аркан Таро The Fool – "Глупец", но никак не Joker – "Шут".

Astraport 22.04.2012 22:24

Вложений: 1
Цитата:

А не проще было сектора рисовать неповернутыми, и спокойно размещать в них текст?
А потом уже составлять колесо, поворачивая сектора?
Если честно, я часть кода откуда-то скопировал, т. к. совсем не силен в программном рисовании и особенно во всех этих углах и матрицах.
Цитата:

Нулевой аркан Таро The Fool – "Глупец", но никак не Joker – "Шут".
Ну так это все от автора колоды зависит. Колод Таро сотни и многие названия сильно отличаются от канонических. Там у меня связь с русской колодой будет, автор назвал - Шут.


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

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