Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Аналоговые часы на as3 - вопрос по реализации! (http://www.flasher.ru/forum/showthread.php?t=146059)

tsarapkabel 27.10.2010 23:25

Аналоговые часы на as3 - вопрос по реализации!
 
Вложений: 1
Приветиус!

Сделал часы, но до конца недоработал, меня уже давно терзают сомнения по поводу правильности реализации!

Это одно из моих первых "произведений", поэтому выглядит довольно странно.

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

Код AS3:

package {
        import flash.display.Sprite;
        import flash.events.Event;
        import mx.core.BitmapAsset;
 
 
 
        public class KanjiClock extends Sprite {
 
                [Embed(source = "kanji_clock.jpg")] //подключаем jpg
                var ClockDial:Class;
 
                private var secHand:Sprite;
                private var minHand:Sprite;
                private var hourHand:Sprite;
 
                private var secContainer:Sprite;
                private var minContainer:Sprite;
                private var hourContainer:Sprite;
 
 
                public function KanjiClock ():void {
 
                        var dial:BitmapAsset = new ClockDial(); //объявляем переменную от Embed source
                        stage.addChild (dial);        //добавляем циферблат (jpg) на сцену
 
                        var centerCircle:Sprite = new Sprite(); //центральный кружок
                        centerCircle.graphics.beginFill (0x000000);
                        centerCircle.graphics.drawCircle (148, 148, 7);
                        centerCircle.graphics.endFill();
 
                        secContainer =  new Sprite(); //контейнер для секундной стрелки
                        secContainer.x = 148;
                        secContainer.y = 148;
                        secContainer.rotation = 180;
 
                        minContainer =  new Sprite(); //контейнер для минутной стрелки
                        minContainer.x = 148;
                        minContainer.y = 148;
                        minContainer.rotation = 180;
 
                        hourContainer =  new Sprite(); //контейнер для часовой стрелки
                        hourContainer.x = 148;
                        hourContainer.y = 148;
                        hourContainer.rotation = 180;
 
                        secHand = new Sprite(); //секундная стрелка
                        secHand.graphics.lineStyle (.1, 0x000000);
                        secHand.graphics.beginFill (0x0066CC);
                        secHand.graphics.drawRect (0, 0, 4, 100);
                        secHand.graphics.endFill();
                        secHand.x = - 2;
                        secHand.y = 0;
 
                        minHand = new Sprite(); //минутная стрелка
                        minHand.graphics.lineStyle (.1, 0x000000);
                        minHand.graphics.beginFill (0x650099);
                        minHand.graphics.drawRect (0, 0, 6, 80);
                        minHand.graphics.endFill();
                        minHand.x = - 3;
                        minHand.y = 0;
 
                        hourHand = new Sprite(); //часовая стрелка
                        hourHand.graphics.lineStyle (.1, 0x000000);
                        hourHand.graphics.beginFill (0x660000);
                        hourHand.graphics.drawRect (0, 0, 8, 60);
                        hourHand.graphics.endFill();
                        hourHand.x = - 4;
                        hourHand.y = 0;
 
                        //добавляем стрелки в их контейнеры
                        secContainer.addChild (secHand);
                        minContainer.addChild (minHand);
                        hourContainer.addChild (hourHand);
 
                        //добавляем на stage контейнеры со стрелками и кружок в центр
                        stage.addChild (hourContainer);
                        stage.addChild (minContainer);
                        stage.addChild (secContainer);
                        stage.addChild (centerCircle);
 
                        stage.addEventListener (Event.ENTER_FRAME, onEnterFrame, false, 0, true);
 
 
                        function onEnterFrame (e:Event):void {
 
                                var currentDate:Date = new Date();
                                var sec:Number = currentDate.getUTCSeconds();
                                var min:Number = currentDate.getUTCMinutes();
                                var hour:Number = currentDate.getUTCHours();
 
                                //добавляем вращение контейнерам
                                secContainer.rotation = 180+6*sec;
                                minContainer.rotation = 180+6*min + sec*0.1;
                                hourContainer.rotation = 180+30*(hour+4) + min/2;
                        }
 
                }
 
        }
 
}

Насколько это безграмотно?

Нужен ли здесь метатег Embed или можно было обойтись простым loader'ом?

Да и вообще буду рад любому мнению! :drinks:

udaaff 27.10.2010 23:39

То что UTC — это так надо?

deamoK 27.10.2010 23:40

Не догнал зачем контейнеры Оо
В спрайте самом и рисовать
Для часов, имхо, лучше использовать Timer, а не ИнтеФрейм, тк сомневаюсь, что у вас частота кадров 1фпс

tsarapkabel 28.10.2010 01:00

Вложений: 1
2 udaaff

* В дальнейшем планировал добавить стандарт: Нью-Йорк, Токио и Лондон.
А вообще согласен - для данного случая можно и местное взять.


2 deamoK

* Частота кадров стоит 24 (как-то не задумываясь поставил).
Если можно - поподробнее, чем Timer лучше, почему не setInterval или не EnterFrame?

* В спрайте и рисую, просто если вращать спрайт, то вращение будет не совсем правильным для стрелки толщиной более 1 пикселя.
Представь как вращается стрелка вокруг красной точки (см рисунок).

Wolsh 28.10.2010 02:22

А нарисовать стрелку так чтобы ее ось была в (0, 0) - никак? Отрицательные координаты никто не отменял)))

tsarapkabel 28.10.2010 02:48

А как же я её потом вращать буду? Я для того и пихаю её в контейнер с отрицательными координатами.
Если я неправильно понял, покажите пожалуйста пример!

Wolsh 28.10.2010 09:46

Код AS1/AS2:

minHand.graphics.drawRect (-3, -3, 6, 80);

Добавлено через 20 минут
Точнее в Вашем случае
Код AS3:

secHand.graphics.drawRect (-2, 0, 4, 100);
minHand.graphics.drawRect (-3, 0, 6, 80);
hourHand.graphics.drawRect (-4, 0, 8, 60);

и никаких контейнеров не надо.

tsarapkabel 28.10.2010 16:03

Wolsh, спасибо большое, код сократился малость.

Код AS3:

package {
        import flash.display.Sprite;
        import mx.core.BitmapAsset;
        import flash.events.Event;
 
 
        public class KanjiClock extends Sprite {
 
                [Embed(source = "kanji_clock.jpg")] //подключаем jpg
                var ClockDial:Class;
 
                private var secHand:Sprite;
                private var minHand:Sprite;
                private var hourHand:Sprite;
 
 
                public function KanjiClock ():void {
 
                        var dial:BitmapAsset = new ClockDial(); //объявляем переменную от Embed source
                        stage.addChild (dial);        //добавляем циферблат (jpg) на сцену
 
                        var centerCircle:Sprite = new Sprite(); //центральный кружок
                        centerCircle.graphics.beginFill (0x000000);
                        centerCircle.graphics.drawCircle (148, 148, 7);
                        centerCircle.graphics.endFill();
 
                        secHand = new Sprite(); //секундная стрелка
                        secHand.graphics.lineStyle (.1, 0x000000);
                        secHand.graphics.beginFill (0x0066CC);
                        secHand.graphics.drawRect (-2, 0, 4, 100);
                        secHand.graphics.endFill();
                        secHand.x = 148;
                        secHand.y = 148;
 
                        minHand = new Sprite(); //минутная стрелка
                        minHand.graphics.lineStyle (.1, 0x000000);
                        minHand.graphics.beginFill (0x650099);
                        minHand.graphics.drawRect (-3, 0, 6, 80);
                        minHand.graphics.endFill();
                        minHand.x = 148;
                        minHand.y = 148;
 
                        hourHand = new Sprite(); //часовая стрелка
                        hourHand.graphics.lineStyle (.1, 0x000000);
                        hourHand.graphics.beginFill (0x660000);
                        hourHand.graphics.drawRect (-4, 0, 8, 60);
                        hourHand.graphics.endFill();
                        hourHand.x = 148;
                        hourHand.y = 148;
 
                        //добавляем стрелки на stage и кружок в центр
                        stage.addChild (hourHand);
                        stage.addChild (minHand);
                        stage.addChild (secHand);
                        stage.addChild (centerCircle);
 
                        stage.addEventListener (Event.ENTER_FRAME, onEnterFrame, false, 0, true);
 
                        function onEnterFrame (e:Event):void {
 
                                var currentDate:Date = new Date();
                                var sec:Number = currentDate.getUTCSeconds();
                                var min:Number = currentDate.getUTCMinutes();
                                var hour:Number = currentDate.getUTCHours();
 
                                //добавляем вращение стрелкам
                                secHand.rotation = 180+6*sec;
                                minHand.rotation = 180+6*min + sec*0.1;
                                hourHand.rotation = 180+30*(hour+4) + min/2;
                        }
 
                }
 
        }
 
}

А кто что думает по поводу Embed/loader?

EnterFrame для обновления оптимален?

:umnik2:

КорДум 28.10.2010 16:10

Цитата:

EnterFrame для обновления оптимален?
А разве непонятно? обновлять информацию 22-26 раз в секунду или один раз?
Таймер на 1 секунду оптимальнее. Но будут наблюдаться некоторые глюки, как то: между тиками может быть разница больше, чем в одну секунду. Ну и меньше, тоже. Причем это только визуально, время показывать будет правильно в любом случае.
При enterFrame будет плавность тиков, то есть, будут равные интервалы между этими тиками.

deamoK 28.10.2010 18:14

Цитата:

2 deamoK

* Частота кадров стоит 24 (как-то не задумываясь поставил).
Если можно - поподробнее, чем Timer лучше, почему не setInterval или не EnterFrame?

* В спрайте и рисую, просто если вращать спрайт, то вращение будет не совсем правильным для стрелки толщиной более 1 пикселя.
Представь как вращается стрелка вокруг красной точки (см рисунок).
вот пример, наклепал часы без контейнеров и с таймером:

Код AS3:

package  
{
        import flash.display.Shape;
        import flash.display.Sprite;
        import flash.events.TimerEvent;
        import flash.utils.Timer;
 
        public class SimpleTest extends Sprite
        {
                private var minHand:Shape;
                private var secHand:Shape
                private var timer:Timer;
                private var date:Date;
                private var border:Shape;
                private var hourHand:Shape;
 
                private var sec:int;
                private var min:int;
                private var hour:int;
 
                public function SimpleTest()
                {
                        secHand = new Shape();
                        minHand = new Shape();
                        hourHand = new Shape()
                        border = new Shape()
                        timer = new Timer(1000);
 
                        border.graphics.lineStyle(1, 0xCCCCCC);
                        border.graphics.drawCircle(0, 0, 110);
                        border.graphics.beginFill(0);
                        border.graphics.drawCircle(0, 0, 5)
 
                        secHand.graphics.beginFill(0xFF0000);
                        secHand.graphics.drawRect(-1, -100, 2, 120);
 
                        minHand.graphics.beginFill(0);
                        minHand.graphics.drawRect(-2, -80, 4, 80);
 
                        hourHand.graphics.beginFill(0xCCCCCC)
                        hourHand.graphics.drawRect(-3, -60, 6, 60)
 
                        addChild(hourHand);
                        addChild(minHand);
                        addChild(secHand);
                        addChild(border);
 
                        x = y = 300;
                        timer.addEventListener(TimerEvent.TIMER, onTick);
                        timer.start();
                        onTick()
                }
 
                private function onTick(e:TimerEvent = null):void
                {
                        date = new Date();
                        sec = date.getSeconds();
                        min = date.getMinutes();
                        hour = date.getHours();
 
                        secHand.rotation = sec * 6;
                        minHand.rotation = min * 6 + sec / 10;
                        hourHand.rotation = hour * 30 + min / 2;
                }
        }
}



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

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