Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > ActionScript 3 > Работа таймера


Автор: venziver 14.11.2011, 20:13
В моих программах игр написанных в ActionScript таймер практически не работает, так как сразу при запуске программы с таймером, время выполнения каждого обработчика событий начинает увеличиваться движение замедляется и программа зависает. Пример таймера в программе прилагается. Что мне делать? Помогите, кто знает, буду очень признательна

Автор: bars80080 14.11.2011, 21:02
возможно, таймер запускается в цикле или при новом инициализации метода. то есть действует лавинный эффект: первое срабатывание таймера приводит к запуску 10 методов и второму запуску того же таймера. два таймера на следующем ходу запускают 20 методов и ещё 2 таймера. на третьем ходу 40 методов и ещё 4 таймера. и т.д.

Автор: venziver 14.11.2011, 21:57
Спасибо за ответ. У меня есть несколько игр написанных на C++Builder они все работают и везде задействован таймер. Когда я стала переводить эти игры на ActionScript 3 везде таймер стал зависать, хотя код тот же самый, так как С++ и ActionScript это один язык программирования и новый код я не создавала, а только переделывала под платформу Flash. Так что не знаю, что мне делать. Уже целый месяц бьюсь над этим.

Автор: SoWa 15.11.2011, 05:28
venziver, покажи каким кодом ты это дело запускаешь?
+в методе RISFON явно отсутствует некий счетчик i...
Если ты где-то создаешь сотни экземпляров класса DomLab, то и это может быть причиной тормоза.

Автор: venziver 16.11.2011, 22:33
Спасибо всем, что заинтересовались моим вопросом.  Высылаю файл Risdog.as.

Автор: Simplifier 5.1.2012, 00:13
все дело в том, что твой код - это пи*ц, извиняюсь за выражение. и дело явно не в таймере. добавь хотя бы очистку холста в начало метода RISFON: rism.graphics.clear(); У as3 производительность явно пониже, чем у с++, поэтому ему трудно переварить такой неоптимизированный код((

Автор: venziver 13.1.2012, 23:53
Цитата(Simplifier @ 5.1.2012,  00:13)
все дело в том, что твой код - это пи*ц, извиняюсь за выражение. и дело явно не в таймере. добавь хотя бы очистку холста в начало метода RISFON: rism.graphics.clear(); У as3 производительность явно пониже, чем у с++, поэтому ему трудно переварить такой неоптимизированный код((

Спасибо за ответ Simplifier. Эту проблему я решила. Оказывается я не удаляла в таймере объект rism, который представляет собой синий фон с дождинками величиной с экран программы и каждое выполнение таймера рисовало новый объект rism с двигающимися дождинками. Получалось,что сколько было повторений таймеров столько и было объектов rism на которых двигались дождинки. Поэтому всё это с каждым разом работало всё медленнее пока не зависало. Для правильной работы необходимо в каждом таймере не только убирать объект rism из очереди высвечиваемых объектов но и удалять этот объект полностью: rism=null; removchild(rism); Правильный файл я прикрепила.  Но у меня новая проблема. В таймере плохо двигаютя растовые изображения. В этот файл я добавила машинку-растовое изображение, так вот она не двигается плавно по экрану, а дёргается и мигает. Движение не получается. Пожалуйста помогите решить эту проблему. С уважением venziver поздравляю всех с новым годом.

Автор: Simplifier 18.1.2012, 19:04
Рад был помочь) Тебя тоже с новым годом
Не вижу никакого прикрепленного файла. Код в студию, в общем)

Автор: venziver 26.1.2012, 10:57
Извините,прикрепляю код vtnziver.

Автор: Simplifier 26.1.2012, 22:38
Цитата

Код

private static var W = 792;
private static var H = 516;
private static var COLDG = 70; //колич.дождинок


Это ты объявила переменные статическими, т.е. к ним можно обращаться через класс, а не через экземпляр класса; например так: trace(Risdog.COLDG); вместо trace(this.COLDG);
Но тут это вроде бы не требуется, вероятно ты хотела объявить их константами (чтобы нельзя было изменять их значение после объявления). Константы объявляются так (декларацию типов заодно добавил):
Код

private const W:int = 792;
private const H:int = 516;
private const COLDG:int = 70; //колич.дождинок

Учитывая, что фон не анимируется, логично сделать его отдельным объектом, чтоб не приходилось его каждый раз перерисовывать: private var sky:Shape = new Shape;//небо
В каждом кадре удалять и создавать новый холст для рисования дождя тоже вряд ли является оптимальным вариантом. Лучше использовать один и тот же объект, но в каждом кадре очищать его от старой графики. Делается это с помощью метода clear() класса Graphics: rism.graphics.clear();
Цитата

Получалось,что сколько было повторений таймеров столько и было объектов rism на которых двигались дождинки. 

Объект rism был один, просто новая графика в нем рисовалась поверх старой. А ее надо было удалять (графику, а не сам объект)

Загружать картинку с твоей машинкой в каждом кадре я тоже смысла не вижу. Лучше вынести загрузку в конструктор.
Еще, вместо 2х массивов для кординат х и у, мне было бы удобней использовать один, в котором будут храниться точки (экземпляры класса Point)
Ну и имена переменных у тебя не очень человекопонятные. Всякие там xm, ym, dd, ti, aa, которые мало что говорят об их назначении. Код трудно читать(
В общем, минимально правленный код будет выглядеть примерно так:
Код

package {
    import flash.display.*; //для рисования
    import flash.utils.*;
    import flash.events.*; //для прерываний
    import flash.net.*;
    
    public class Risdog extends Sprite {
        private const W:uint = 792;
        private const H:uint = 516;
        private const COLDG:uint = 70; //колич.дождинок
        private var timer:Timer; //таймер
        private var masx:Array = new Array(COLDG); //массив коор-т дождинок
        private var masy:Array = new Array(COLDG);
        private var ti:int;
        private var sky:Shape = new Shape;//небо
        private var rism:Shape = new Shape;//рис.векторных.изображ.
        private var loader:Loader = new Loader();
        private var skyColor:uint = 0x0000ff; //цвет неба
        private var dropColor:uint = 0x000066; //цвет капель дождя
        
        public function Risdog() { //конструктор
            sky.graphics.beginFill(skyColor);
            sky.graphics.drawRect(0, 0, W, H);
            sky.graphics.endFill();
            
            addChild(sky);//добавим небо на сцену
            addChild(loader);//добавим загрузчик картинки на сцену
            addChild(rism);//объект для рисования дождя
            loader.y = 400;
            loader.load(new URLRequest("mash.gif"));
            
            var a1:int, a2:int, b:int;
            for (var j:uint = 0; j <= COLDG - 1; j++) { //формирование массива дождинок
                a1 = 50 + Math.random() * W + 50;
                masx[j] = a1;
                a2 = 5 + Math.random() * H;
                masy[j] = a2;
            }
            //обработка события щелчёк мыши
            //addEventListener(MouseEvent.CLICK, fl_MouseClickHandler);//непонятно зачем нужен этот хендлер. видимо, использовался при отладке
            timer = new Timer(50, 0); //частота таймера
            //обработка события таймер
            timer.addEventListener(TimerEvent.TIMER, timeFon);
            //рис.фон на котором нарисованы косые палочки-капли дождя
            RISFON();
            //включаем таймер;
            timer.start();
        }
        
        //ф-ция рис.фон
        private function RISFON():void {
            rism.graphics.clear();
            rism.graphics.lineStyle(2, dropColor, 1);
            var f1:int;
            for (var i:uint = 0; i <= COLDG - 1; i++) { //рис.дождинки;
                if (masy[i] >= H + 20 || masx[i] < 50) { //если дождинка за фоном,формируем новую
                    f1 = Math.random() * W + 100;
                    masx[i] = f1;
                    masy[i] = -40;
                }
                rism.graphics.moveTo(masx[i], masy[i]);
                rism.graphics.lineTo(masx[i] - 15, masy[i] + 15);
                rism.graphics.endFill();
                //движение дождинок;
                masx[i] -= 5;
                masy[i] += 10;
            }
            
            loader.x += 6;
            if (loader.x > W + 100) {
                loader.x = -loader.width;
            }
        }
        
        //ф-ция обраб.события таймер,движение 
        private function timeFon(e:TimerEvent):void {
            //рис.фон,где дождинки сдвигаютя 
            RISFON();
            ti++;
            trace(ti);
        }
    }
}

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)