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

TEI 22.12.2016 19:21

Проверка времени
 
Вечер добрый,

Мне необходимо постоянно получать время на устройстве пользователя, для создания отсчета таймеров.

Код AS3:

var _date:Date;
_date = new Date();
_date.getTime();

Время фиксируется при создании объекта. Поэтому приходится для каждой проверке создавать объект снова и снова. Как оптимизировать данную функцию?

При создании таймера я сохраню текущее время таким же способом

Код AS3:

var mysave:SharedObject = SharedObject.getLocal("SharedObject");
mysave.data.myTime=_date.getTime();


caseyryan 22.12.2016 20:57

Для чего это нужно оптимизировать? Если тебе нужно только лишь запомнить время создания объекта, вряд ли это будет тонким местом в программе

TEI 22.12.2016 21:03

Цитата:

Сообщение от caseyryan (Сообщение 1198176)
Для чего это нужно оптимизировать? Если тебе нужно только лишь запомнить время создания объекта, вряд ли это будет тонким местом в программе

Запомнить, да. Суть вопроса в постоянной проверке текущего времени на устройстве.
Не может ли постоянное создание нового объекта Date вызвать утечку памяти?

Код AS3:

_date = new Date();
_date.getTime();


undefined 22.12.2016 21:06

если дата нужна только для замера промежутков времени можно попробовать
getTimer
правда не уверен что он там внутри не создает ничего.

Партизан 22.12.2016 21:09

Есть функция getTimer() которая возвращает время с момента запуска. Т.е. дату можно запросить один раз при запуске, запомнить значение getTimer() на тот момент и потом прибавлять к сохраненной дате разницу между первым запросом и текущим.

TEI 22.12.2016 21:37

Мне нужно время не с момента запуска игры, а глобальное время. 22.12.2016 21:33
Чтобы отмерять в мобильной игрушке когда игрок запустил постройку здания(например), на завершение которого нужно 10 часов. И соответственно отображать разницу. Я просто обнаружил, что текущее время инициализируется лишь создании объекта, а не каждый раз когда я к нему обращуюсь

undefined 22.12.2016 21:47

создавай new Date раз в секунду(по таймеру) и не парься

Tails 22.12.2016 23:03

TEI,
Партизан дело говорит.

undefined 22.12.2016 23:50

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

caseyryan 23.12.2016 06:07

Цитата:

насколько я понял интервал может быть растянут на несколько сессий в этом случае действительно использовать getTimer проблематично.
Чем проблематично?
Ничего же не мешает при старте сессии создавать новый Date, а потом опять юзать getTimer()

Партизан 23.12.2016 09:52

Цитата:

Сообщение от TEI (Сообщение 1198180)
Мне нужно время не с момента запуска игры, а глобальное время. 22.12.2016 21:33

Вам уже кучу постов с вариантами решения через getTimer() написали. В документации по Date() от Adobe так же рекомендуют использование getTimer()
Цитата:

Чтобы вычислить относительное или прошедшее время, воспользуйтесь методом getTimer() из пакета flash.utils.
Если этого мало для вашей задачи, оставьте как есть. Единственное, рекомендую принудительно удалять созданный экземпляр Date.

faraday 23.12.2016 14:04

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

Tails 23.12.2016 14:47

Код AS3:

package pocket.clock
{
        import flash.utils.getTimer;
 
        /**
        * Игровые часы.
        * Содержит текущее время, которое берётся из системы пользователя.
        * Можно синхронизировать часы, указав собственное текущее время.
        * @author Roman A.V.
        */

        public class Clock
        {
 
                // Приват
                private var _runDate:Number;
 
                /**
                * Создать часы.
                * Текущее время берётся из системы пользователя.
                */

                public function Clock()
                {
 
                        // Инициализация.
                        // Получаем системное время:
                        _runDate = new Date().time;
 
                        // Вычитаем уже прошедшее время, так-как используем дату как точку отсчёта:
                        _runDate -= getTimer();
 
                        // Не может быть NaN или меньше 0:
                        if (isNaN(_runDate) || _runDate < 0)
                                _runDate = 0;
                }
 
                // ПАБЛИК
                /**
                * Синхронизировать текущее время.
                * Передайте текущее время, если требуется синхронизировать часы.
                * Этот вызов также изменит значение переменной <code>runDate</code>.
                * @param        time Миллисекунды, прошедшие с 1 января 1970 года.
                */

                public function setCurrentTime(time:Number):void
                {
                        _runDate = time - getTimer();
 
                        // Не может быть NaN или меньше 0:
                        if (isNaN(_runDate) || _runDate < 0)
                                _runDate = 0;
                }
 
                // ГЕТТЕРЫ
                /**
                * Дата запуска приложения. (mc)
                * Указывает дату, когда было запущено текущее приложение.
                * Миллисекунды, прошедшие с 1 января 1970 года.
                * Не может быть NaN или меньше 0.
                */

                public function get runDate():Number
                {
                        return _runDate;
                }
 
                /**
                * Текущее время. (mc)
                * Возвращает количество миллисекунд, прошедших на момент вызова с 1 января 1970 года.
                * Не может быть NaN.
                */

                public function get currentTime():Number
                {
                        return _runDate + getTimer();
                }
        }
}


faraday 23.12.2016 16:47

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

Tails 23.12.2016 17:04

faraday
Нет, не наблюдал. Какого рода рассинхрон? Разница постепенно накапливается или фиксированная с самого начала?

faraday 23.12.2016 17:22

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

caseyryan 23.12.2016 17:43

Цитата:

Сообщение от faraday (Сообщение 1198199)
постепенно, когда расхждение больше 10 секунд - синхронизирует с сервом, и через пару минут рассинхрон опять. бывает где-то у 5% игроков, на протяжении всей сессии

Может у них дико тормозит все?
Хотя, сдается мне, ошибка в коде

faraday 23.12.2016 18:01

Врядли в таком коде может быть ошибка. расхождения дает как getTimer, так и new Date().getTime(), сетер добавлен как вынужденая мера именно из-за постоянных расхождений, так больше не что не влияет. приходится добавлять время в каждый ответ сервера, и синхронизировать каждый таймер в момент инициализации и завершения. геморой на ровном месте
Код AS3:

        public static function init(time:int) {
                        serverTime = time;
                        timer.start();
                        timer.addEventListener(TimerEvent.TIMER, updateTime);
                }
                private static function updateTime(t:TimerEvent = null) {
                        _now = elapse + timeDiff;
                        dispatchEventWith(Clock.TICK, false, serverTime);
                }
                public static function set serverTime(time:int):void{
                        timeDiff = time - elapse;
                        updateTime();
                }
                public static function get serverTime():int{
                        return _now;
                }       
                static public function get elapse():int
                {
                        return Math.floor(getTimer() / 1000);
                }


Партизан 23.12.2016 18:24

Цитата:

Сообщение от faraday (Сообщение 1198202)
Врядли в таком коде может быть ошибка.

Думаю если округлять до 5 секунд расхождение будет еще больше...

undefined 23.12.2016 18:29

Цитата:

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

faraday 23.12.2016 19:09

Цитата:

Сообщение от Партизан (Сообщение 1198203)
Думаю если округлять до 5 секунд расхождение будет еще больше...

округление тут никак не влияет, разница не накапливается. бывает отставание и на минуту

Партизан 23.12.2016 19:26

Цитата:

Сообщение от faraday (Сообщение 1198207)
округление тут никак не влияет, разница не накапливается. бывает отставание и на минуту

Т.е. вперед они не убегают, да?

faraday 23.12.2016 19:31

иногда и вперед уходят, но реже

Tails 23.12.2016 20:03

faraday,
Не надо считать время таймером! Так конечно, гарантированно будет расхождение. Изучите листинг приведённого мною класса. Там вообще нет никакого таймера.

faraday 23.12.2016 20:32

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

Tails 23.12.2016 20:35

Вообще не надо считать текущее время и сохранять его в переменную. Считайте текущее время от фиксированной отметки тогда, когда это нужно. Тут как минимум, не учитываются пикосекунды. Ещё расходы на саму операцию сложения и сохранения накладываются и увеличиваются с каждым тиком.

faraday 23.12.2016 20:44

я пробовал вариант без сохранения с гетером getTime()+timeDiff, результат тот же. А почему расход увеличивается с каждм тиком, если каждый тик оно так же отсчитывает от getTimer(), и разве точность времени не ограничена тут миллисекундами, почему пико?
Вы пробовали сверять время клиента с сервером, раз в несоклько минут и сохранять результат при дельте? я тоже долгое время не подозревал о существовании проблемы, и у меня всегда все работало и работает норм.

Tails 23.12.2016 20:59

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

Используйте мой пример. В нём рассинхронизация если и будет, то только из-за реально не корректной работы getTimer(), ну или если клиент находится в гравитационной яме. (Теорию относительности никто не отменял)

faraday 23.12.2016 21:44

Хм, так а где у меня использование предыдущего результата? берется дельта высчитанная при инициализации, и новое значение getTimer. Я в свое время остановился на том, что проблемма все таки в не идеальности Эвм, в коментах тут разъясняется http://www.flasher.ru/forum/blog.php?b=368

Tails 23.12.2016 23:58

Да, не используешь. Мудрёный у тебя код конечно. Из-за реализации через таймер, в любом случае падает точность часов до частоты срабатывания таймера. А срабатывание таймера может снижаться при переходе приложения в неактивное состояние. Это нужно учесть.

Но сам код выглядит рабочим. Если погрешность постоянно растёт без синхронизации, то, скорее всего, бажит getTimer. Вроде wvxvw ещё говорил, что getTimer в некоторых ос может вернуть и того - отрицательное значение! (При определённых обстоятельствах.)

undefined 24.12.2016 00:21

Цитата:

А срабатывание таймера может снижаться при переходе приложения в неактивное состояние.
Тоже так думал.На самом деле нифига.В браузере по крайней мере.

faraday 24.12.2016 00:31

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


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

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