![]() |
|
||||||||||
|
|||||||
|
|
« Предыдущая тема | Следующая тема » |
| Опции темы | Опции просмотра |
|
![]() |
![]() |
|
|
|
|||||
|
Регистрация: Sep 2005
Адрес: Минск
Сообщений: 389
|
Задам вопрос в контексте недавно созданной темы: http://www.flasher.ru/forum/showthread.php?t=206574
Ниже описан применяемый мной алгоритм, но главный вопрос: почему при трейсе 'rand num' не совпадают с 'res num'? Как сделать, чтобы совпадали и логика, заложенная ниже работала верно? import flash.events.Event; var objNum:Number = 10; var objArr:Array = new Array(); var enabledObjArr:Array = new Array(); var prevObjArr:Array = new Array(); // var entFrParam:Number = 0; var entFrParamMax:Number = 60; function mainFunc(e:Event):void { var i:int; // if (entFrParam++ == entFrParamMax) { trace("\n\n///////// rand num:") // entFrParam = 0; // prevObjArr = getRandElements(objArr,4,prevObjArr); // for (i = 0; i < prevObjArr.length; i++) { //trace(prevObjArr[i].name) enabledObjArr.push(prevObjArr[i]); // trace(prevObjArr[i].name); } trace("///////// res num:") } // for (i = 0; i < enabledObjArr.length; i++) { process(enabledObjArr[i], 60); // if (enabledObjArr[i].degree >= 360) { trace(enabledObjArr[i].name); // enabledObjArr.shift(); } } } function getRandElements(arr:Array, n:int, exclude:Array):Array { var i:int; var tmp:Array = arr.concat(); var res:Array = []; // убираем исключаемые for (i = 0; i < exclude.length; i++) { tmp.splice(tmp.indexOf(exclude[i]), 1); } // выбираем из оставшихся рандомно for (i = 0; i < n; i++) { var rnd:int = Math.random() * tmp.length; res.push(tmp[rnd]); tmp.splice(rnd, 1); } // возвращаем нужный массив return res; } function process(obj:Object, speed:Number) { obj.degree += speed; } for (var i = 0; i < objNum; i++) { objArr[i] = new Object(); objArr[i].name = i; objArr[i].degree = 0; } // this.addEventListener(Event.ENTER_FRAME, mainFunc); |
|
|||||
|
на каждом 60м такте вы генерите выборку prevObjArr и все ее элементы добавляете в enabledObjArr
на каждом же такте каждому элементу enabledObjArr увеличиваем degree и при достижении этим degree значения 360 смотрим трейс этого элемента, удаляя при этом первый элемент enabledObjArr ну т.е. где-то до шестого такта (degree<360) мы не видим никакго трейса, а потом видим некий сумбур, организованный с помощью enabledObjArr.shift() в цикле, а дальше снова ничего не видим ( enabledObjArr пуст) до следующего 60го такта.. что за "логика" тут реализована и почему эти трейсы должны совпадать не оч. понятно |
|
|||||
|
Регистрация: Sep 2005
Адрес: Минск
Сообщений: 389
|
Предполагаемая логика следующая:
Первое (rand num) нам показывает случайную выборку из 4 чисел в нужной последовательности, которые мы активировали в п. 2. Допустим это обьекты № 3, 7, 1, 5. По моей логике у обьекта №3 у первого из четырех параметр degree начнет прирост и соответственно у него же первым достигнет 360. Соответственно он первым и должен быть удален из массива и выведен первым в res num. Так это задумывалось. Спасибо тем, кто осилил это длинное обьяснение. Добавлено через 9 минут Еще хочу добавить более цельную концепцию того, что бы я хотел видеть по итогу. Предположим есть 10 обьектов. Каждый при инициализации отрисовывает круг с некоторой скоростью. При 60 fps задача такая: каждую секунду из 10 обьектов выбирать 4 (не пересекающихся с объектами прошлой итерации) и наращивать в них угол до 360 градусов (т.е. по-сути, отрисовывать круг). На этом все, как только круг отрисован, обьекты можно опять обнулять (градусы = 0) и ждать следующей операции по инициализации 4 рандомных обьектов. Получается каждую секунду мы отрисовываем 4 из 10 круга, которые по завершению отрисовки исчезают. Объекты текущей итерации не совпадают с обьектами из предыдущей. На этом все. |
|
|||||
|
ну примерно так все и происходит, только смотреть надо как-то аккуратнее что ли
да, и еще одна ловушка: операции типа удаления элементов массива в цикле по индексу - при удалении все индексы смещаются, а это не всегда легко можно учесть function mainFunc(e:Event):void { var i:int; if (entFrParam++ == entFrParamMax) { trace("------60----prevObjArr:") entFrParam = 0; prevObjArr = getRandElements(objArr, 4, prevObjArr); enabledObjArr = prevObjArr.concat(); for (i = 0; i < prevObjArr.length; i++) { trace(prevObjArr[i].name); } } if (!enabledObjArr.length) return; trace("------1-----enabledObjArr:") for (i = 0; i < enabledObjArr.length; i++) { trace(enabledObjArr[i].name); } for (i = 0; i < enabledObjArr.length; i++) { process(enabledObjArr[i], 60); if (enabledObjArr[i].degree >= 360) { enabledObjArr.splice(i--, 1); } } } ну и, конечно, разруливать функционал объектов какими-то внешними функциями в циклах это, имхо, путь к вывиху мозга.. насоздавал, а дальше когда надо и кого надо запустил, все остальное объект в состоянии решить и сделать сам: package { import flash.display.Sprite; import flash.events.Event; import flash.events.TimerEvent; import flash.utils.Timer; public class Main extends Sprite { private var objNum:Number = 10; private var objArr:Array = []; private var prevObjArr:Array = []; public function Main():void { for (var i:int = 0; i < objNum; i++) { var obj:Obj = new Obj(i); obj.x = 100 + Math.random() * 200; obj.y = 100 + Math.random() * 200; objArr.push(obj); addChild(obj); } var timer:Timer = new Timer(1000); timer.addEventListener(TimerEvent.TIMER, timer_timer); timer.start(); } private function timer_timer(e:TimerEvent):void { prevObjArr = getRandElements(objArr, 4, prevObjArr); trace( "prevObjArr : " + prevObjArr ); for (var i:int = 0; i < prevObjArr.length; i++) { prevObjArr[i].start(); } } private function getRandElements(arr:Array, n:int, exclude:Array):Array { var i:int; var tmp:Array = arr.concat(); var res:Array = []; // убираем исключаемые for (i = 0; i < exclude.length; i++) { tmp.splice(tmp.indexOf(exclude[i]), 1); } // выбираем из оставшихся рандомно for (i = 0; i < n; i++) { var rnd:int = Math.random() * tmp.length; res.push(tmp[rnd]); tmp.splice(rnd, 1); } // возвращаем нужный массив return res; } } } import flash.display.Sprite; import flash.events.Event; ////////////////// class Obj extends Sprite { public var degree:Number = 0; public var id:int; public var speed:Number = 0.2; public var radius:Number = 10; public function Obj(id:int) { super(); this.id = id; } public function start():void { degree = 0; graphics.clear(); graphics.lineStyle(0); graphics.moveTo(radius * Math.cos(degree), radius * Math.sin(degree)); addEventListener(Event.ENTER_FRAME, process); } private function process(e:Event):void { degree += speed; graphics.lineTo(radius * Math.cos(degree), radius * Math.sin(degree)); if (degree >= 2 * Math.PI) { // останавливаем removeEventListener(Event.ENTER_FRAME, process); // ну и что-там еще надо.. graphics.clear(); } } override public function toString():String { return "obj_" + id; } } Последний раз редактировалось silin; 15.02.2014 в 00:20. |
|
|||||
|
Регистрация: Sep 2005
Адрес: Минск
Сообщений: 389
|
Цитата:
На самом деле костыль с функциями в цикле придуман был условно, чтобы максимально быстро передать суть требуемого алгоритма. |
|
|||||
|
>> потом сбивается по каким-то непонятным причинам..
думаю, по причине, что во вновь выбранной партии могут быть экземпляры с ненулевым degree или что-то в этом роде..., отслеживать такие штуки в этих циклах с динамическими объектами как-то безидейно совсем вот так, может быть private function mainFunc(e:Event):void { var i:int; if (entFrParam++ == entFrParamMax) { trace("------60----prevObjArr:") entFrParam = 0; prevObjArr = getRandElements(objArr, 4, prevObjArr); enabledObjArr = prevObjArr.concat(); for (i = 0; i < prevObjArr.length; i++) { prevObjArr[i].degree = 0; trace(prevObjArr[i].name); } } if (!enabledObjArr.length) return; trace("------1-----enabledObjArr:") var tmp:Array = []; for (i = 0; i < enabledObjArr.length; i++) { trace(enabledObjArr[i].name); process(enabledObjArr[i], 60); if (enabledObjArr[i].degree < 360) { tmp.push(enabledObjArr[i]); } } enabledObjArr = tmp; } Последний раз редактировалось silin; 15.02.2014 в 00:56. |
|
|||||
|
Регистрация: Sep 2005
Адрес: Минск
Сообщений: 389
|
Цитата:
Вы красиво обошли подсчет угла переопределением нужного массива и обратным сравнением вот тут: Но в моем случае мне просто необходимо по выполнению условия выполнять некие дополнительные действия. Но именно это условие дает выпадение элемента массива и непонятную ошибку. |
|
|||||
|
>>Но в моем случае мне просто необходимо по выполнению условия выполнять некие дополнительные действия.
в этом же 'сортировочном' цикле положите их в другой список, с которым сотворите эти доп. действия, не путаясь в индексах var tmp:Array = []; var tmp1:Array = []; for (i = 0; i < enabledObjArr.length; i++) { process(enabledObjArr[i], 60); if (enabledObjArr[i].degree < 360) { tmp.push(enabledObjArr[i]); }else { tmp1.push(enabledObjArr[i]); } } зы. ну и повторюсь, совершенно непонятно стремление разместить логику, которая может(должна) быть 'на борту' самих объектов, в каких-то внешних циклах.. |
|
|||||
|
Регистрация: Sep 2005
Адрес: Минск
Сообщений: 389
|
Спасибо за этот совет. Он заставил пересмотреть внутреннюю иерархию классов и методов. Теперь все намного удобнее и логичнее + нет геммора с массивами!
|
![]() |
![]() |
Часовой пояс GMT +4, время: 18:09. |
|
|
« Предыдущая тема | Следующая тема » |
|
|