PDA

Просмотр полной версии : Сетка и движение клипов для MouseMove события


in4core
15.04.2010, 15:16
Вот 2 скрина на первом видим сетку из квадратиков. На втором тоже сетка, но с местом где квадраты расположены рандомно. Идея :
По onMouseMove ( к мышке аттачиться сначала некая область скажем круг, 100*100) все клипы попавшие в эту область, плавно, рандомно расходятся. При передвижении мышки дальше, клипы отошедшие с области , плавно возвращаются обратно, а новые клипы попавшие в область рандомно расходятся. И т.д.

Нужна помощь как это делается.

П.с. пока идея пришла такая. По маус мув, в цикле запоминется начальное значение, затем с помощью Math.random() все расходится ( если hitTest = true); а потом возвращаем начальное значение. НО в этом то и проблема, что маус мув идет постоянно и клипы не успевают получить начального значения. Может стоит попробовать следующее : На клипе писнуть ролловер и роллаут действия, При ролловер - рандомно расходимся, при роллОут - сходимся обратно. Тогда можно легко задействовать каждый клип,НО опять же косяк - если уж рандомно разошелся, то роллОут не сработает, ибо будет уже находится мышка в не области клипа :(

Вообщем жду ващей помощи....

П.с. и еще вопрос - если я такими мелкими клипами буду заливать области типа 1600*1200 - плеер крякнется от такой нагрузки или нет?

Tahion
15.04.2010, 15:22
Почитайте блог Волгоградец :)

in4core
15.04.2010, 18:32
Ну там все по АС3. меня 2й интересует. Ниче не нашел

samana
16.04.2010, 14:11
Может как то так:
import mx.transitions.Tween;
import mx.transitions.easing.*;
for (var i = 0; i < 5; i++) {
for (var j = 0; j < 5; j++) {
var p = _root.attachMovie("clip", "clip" + i + j, _root.getNextHighestDepth());
p._x = 40 + j * 40;
p._y = 40 + i * 40;
p.startX = p._x;
p.startY = p._y;
p.go = false;
p.onMouseMove = function() {
this.dis = Math.sqrt(Math.pow(_xmouse - this.startX, 2) + Math.pow(_ymouse - this.startY, 2));
if (this.dis < 50 && this.go == false) {
this.go = true;
this.tx.stop();
this.ty.stop();
this.rot.stop();
this.tx = new Tween(this, "_x", Elastic.easeOut, this._x, this.startX + random(100) - 50, 50);
this.ty = new Tween(this, "_y", Elastic.easeOut, this._y, this.startY + random(100) - 50, 50);
this.rot = new Tween(this, "_rotation", Elastic.easeOut, this._rotation, random(360), 50);

}
if (this.dis > 50) {
this.go = false;
this.tx.stop();
this.ty.stop();
this.rot.stop();
this.tx = new Tween(this, "_x", Regular.easeOut, this._x, this.startX, 10);
this.ty = new Tween(this, "_y", Regular.easeOut, this._y, this.startY, 10);
this.rot = new Tween(this, "_rotation", Regular.easeOut, this._rotation, 0, 10);

}
};

}}

in4core
16.04.2010, 15:43
То что надо спасибо))) Вот если залить сцену огромную такими мувиками, как думаешь тормазнет. или такая тема ничего сташного не сделает?

samana
16.04.2010, 17:28
Думаю тормознёт ещё как!!! В примере всего 5/5, а когда пробовал 10/10 тормозило уже отлично. (

in4core
16.04.2010, 17:53
Это фигово((( придется видимо отказаться от такого бекграунда

Hauts
16.04.2010, 18:21
Можно оптимизировать, отказываться еще рано.

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

p.onMouseMove = onMouseMoveHandler;
...
function onMouseMoveHandler(){
this.dis = ...
}

in4core
16.04.2010, 18:26
Поробуем. о результатх буду сообщать. интересно что получится. ведь тема для БГ очень интересная

Tahion
17.04.2010, 00:07
И еще октазатся от математических функций хотябы от Pow если он часто используется) и от твинеров

in4core
17.04.2010, 00:25
Ну тогда ваще от всего отказаться и получится КУКИШЬ с маслом

Добавлено через 4 минуты
Кстати в моем случае сетка будет гдето 50*25. максимум 100*50. Это из расчета что БГ будет резиновым, с максимальным разрешением 2500*1500. 2500/ 25 = 100 клипов по x в одну строку. А если клипы поболее сдлеать то и на 50 можно сойтись ))) думаю не так уж это и страшно 50*25 = 1100 клипов. Всего то XDDD

Tahion
17.04.2010, 00:45
Вобщемто неважно сколько их если делать не этим способом а использоватьф изичискую модель описаную в блоге Волгоградец

in4core
17.04.2010, 00:46
какую модель то блин! Че ты рассказываешь тут сказки! Написано же что все его блоги по АС3!

alexcon314
17.04.2010, 01:05
какую модель то блин! Че ты рассказываешь тут сказки! Написано же что все его блоги по АС3!
Модель - понятие безотносительное к языку реализации. Реализация модели может быть разной, да, на АС3, на АС2, на си++ или джаве... это другой вопрос. Модель одна и та же, она и в африке модель. Ровно также, как "математика - она и в африке математика". Исходя из возможностей языка, модель можно подпилить/поднастроить и даже что-то в ней изменить существенное, удачно или нет - зависит от ваших способностей. В данном случае, я бы заморочился на "модель кулоновского отталкивания с поправкой на рандомную по величине и направлению силу параметризуемого порядка малости по отношению к основной".
ЗЫ. модель - читай физическая модель.

samana
18.04.2010, 01:23
Попробовал сделать по другому, стало быстрее работать, но 1100 всё таки не потянет :o
import mx.transitions.Tween;
import mx.transitions.easing.*;

var scale = 20;//расстояние между клетками
for (var i = 0; i < 25; i++) {
for (var j = 0; j < 25; j++) {
var c = _root.attachMovie("clip", i + "_" + j, _root.getNextHighestDepth());
c._x = 10 + j * scale;
c._y = 10 + i * scale;

c.posX = c._x;
c.posY = c._y;
}
}
fps.swapDepths(_root.getNextHighestDepth())
_root.onMouseMove = function() {

var mJ = Math.floor(_xmouse / scale);
var mI = Math.floor(_ymouse / scale);

for (var tempI = mI - 1; tempI <= mI + 1; tempI++) {
for (var tempJ = mJ - 1; tempJ <= mJ + 1; tempJ++) {
var tc:String = tempI + "_" + tempJ;

_root[tc].tw.stop()
_root[tc].tb.stop();


_root[tc].tw = new Tween(_root[tc], "_x", Regular.easeOut, _root[tc]._x, _root[tc]._x + random(60) - 30,5);
_root[tc].tw = new Tween(_root[tc], "_y", Regular.easeOut, _root[tc]._y, _root[tc]._y + random(60) - 30, 5);
_root[tc].tw = new Tween(_root[tc], "_rotation", Regular.easeOut, _root[tc]._rotation, random(360), 5);
_root[tc].tw.onMotionFinished = function() {
this.obj.tb = new Tween(this.obj, "_x", Regular.easeOut, this.obj._x, this.obj.posX, 5);
this.obj.tb = new Tween(this.obj, "_y", Regular.easeOut, this.obj._y, this.obj.posY, 5);
this.obj.tb = new Tween(this.obj, "_rotation", Elastic.easeOut, this.obj._rotation, 0, 5);

};
}
}

};

in4core
18.04.2010, 01:58
А мы просто уберем ротатион. все же будет лучше.

Добавлено через 1 минуту
Я думаю надо как то избавлятся от циклов для твина. И делать твин отдельно для элемента. например внутри его, однообразный код будет

samana
18.04.2010, 14:03
Там цикл не для твина, а для нахождения ближайших 9 клипов от курсора, просто генерация имён всего 9 итераций ( И вроде твин именно у каждого элемента свой... Но наверняка есть ещё способ повысить скорость, но я даже не знаю с какой ещё стороны подойти...

in4core
18.04.2010, 14:22
Ну самана смотри, а если сделать аттач круг для мышки, некую область которая сама по себе будет захватывать скажем 3*3 клипа. И по хиттесту уже проверять. разве не быстрее выйдет или без разницы?

samana
18.04.2010, 17:38
Тогда получается что нужно будет каждый клип проверять сталкивается ли он с кругом или нет, а это большой цикл выходит...
p.s. может какой профи случайно заглянет сюда и подскажет лучшее решение! Будем надеятся.

in4core
18.04.2010, 18:09
Будем да. Тебе я так понял тоже интересна тема стала?

samana
18.04.2010, 20:49
Да. Хотелось бы тоже узнать как лучше и правильнее делать подобные вещи.

in4core
19.04.2010, 00:20
Эх никто подсказывать нам не хочет)))

Добавлено через 33 секунды
Вон парень советует модель волгоградца поглядеть. Ты не смотрел? Может там ответ. я просто АС3 плохо читаю еще

samana
20.04.2010, 00:52
Ага, посмотрел Волгоградца. Конечно !!! Здорово! Эх, надо было мне хорошо учится в школе... (

in4core
20.04.2010, 01:07
)))) отлично))) тоесть не помогло?

AzagThoth
20.04.2010, 01:14
Может я конечно вообще не прав, но мысли есть такие. Что если мы знаем примерно какую область занимает один квадрат.(Знаем ведь? - знаем)
Мы знаем координаты мыши. -> Мы можем знать какие квадраты в относительной близости к мыше. Значит нам нужно при создании бекгрануда из квадратов писать это дело в удобно читабельный массив(двухмерный массив т.е. где есть строка и столбец) и при создании каждого квадрата писать ему в доп свойства дефолтные значения x,y. Ну и что-то делать при onMouseMove. По идее сам принцип наверное должен быть такой. Могу попробовать чего собрать, но это наверное уже завтра.

in4core
20.04.2010, 02:00
Поробуй , но по прочтению все равно, ты идешь по пути где сцена 1600* и выше умрет от таких клипов. А нужно чтобы незаметно они висели и никого не трогали. Ведь это бекграунд и все. просто красивый)))

samana
20.04.2010, 03:26
Может я конечно вообще не прав, но мысли есть такие. Что если мы знаем примерно какую область занимает один квадрат.(Знаем ведь? - знаем)
Мы знаем координаты мыши. -> Мы можем знать какие квадраты в относительной близости к мыше. Значит нам нужно при создании бекгрануда из квадратов писать это дело в удобно читабельный массив(двухмерный массив т.е. где есть строка и столбец) и при создании каждого квадрата писать ему в доп свойства дефолтные значения x,y. Ну и что-то делать при onMouseMove. По идее сам принцип наверное должен быть такой. Могу попробовать чего собрать, но это наверное уже завтра.
Дело в том, что как раз так я и сделал, там выше где то код. Проблема в твинах, они тормозят (

AzagThoth
20.04.2010, 04:19
В общем я набросал нечто. Конечно получилось гадко и неоптимально ни разу ну уж лучше так чем никак. Не сомневаюсь что можно довести до ума если немного попыхтеть. В общем прошу любить и жаловать :)

var st:Number=40;//=ширина=высота атачимого мувиклипа
var prilip:Number=1;//сколько мувиклипов должны прилипать

i=Math.floor(Stage.width/st);
j=Math.floor(Stage.height/st);

var arr:Array=[];
var znak1:Number=null;
var znak=0;

for(var y=0; y<i; y++){
arr[y]=[];
if(znak==0){
znak=1;
} else if(znak==1){
znak=0;
}
znak1=znak;
for(var z=0; z<j; z++){
if(znak==0){
znak=1;
} else if(znak==1){
znak=0;
}
if(znak==1){
arr[y][z]=attachMovie("kub","kub"+y+z,getNextHighestDepth(),{_x:y*st, _y:z*st});
arr[y][z].defaultX=arr[y][z]._x;
arr[y][z].defaultY=arr[y][z]._y;
arr[y][z].defaultMesto=true;
}
}
znak=znak1;
}


onMouseMove=function():Void{
i=Math.round(_xmouse/st);
j=Math.round(_ymouse/st);
for(var y=i-prilip;y<i+prilip;y++){
for(var z=j-prilip;z<j+prilip;z++){
if(arr[y][z]!=undefined){
arr[y][z]._x=_xmouse;
arr[y][z]._y=_ymouse;
arr[y][z].defaultMesto=false;
}
}
}
defaultMove();
}


function defaultMove():Void{
for(var i=0; i<arr.length; i++){
for(var j=0; j<arr[i].length; j++){
if(arr[i][j].defaultMesto==false){
if(arr[i][j].defaultX>arr[i][j]._x){
arr[i][j]._x++;
} else if(arr[i][j].defaultX<arr[i][j]._x){
arr[i][j]._x--;
}
if(arr[i][j].defaultY>arr[i][j]._y){
arr[i][j]._y++;
} else if(arr[i][j].defaultY<arr[i][j]._y){
arr[i][j]._y--;
}
rX=Math.abs(arr[i][j].defaultX-arr[i][j]._x);
rY=Math.abs(arr[i][j].defaultY-arr[i][j]._y);
if(rX+rY<st/4){
arr[i][j]._x=arr[i][j].defaultX;
arr[i][j]._y=arr[i][j].defaultY;
arr[i][j].defaultMesto=true;
}
}
}
}
}

Лично у меня сие уродство не тормозит ни разу. Время на писанину примерно минут 20 ушло. :)
Конечно не совсем по ТЗ, но идея вроде близка. Ну хотя бы отчасти :)

Добавлено через 6 часов 30 минут
Собственно способ ещё убыстрить работу этой ерунды это играться не со свойством defaultMesto которое я зачем то придумал, а писать например все сдвиженые мувиклипы в отдельный массив, и функцией defaultMove() возвращать обратно мувиклипы которые в этом массиве и сам массив планомерно чистить. Если не устраивает запуска функции при движении то можно запускать её с n-м интервалом. Вроде всё правильно. Ну а дальше только привести во вменямый вид сам код :) По крайней мере я ощущаю что его можно сократить раза в два-три наверное без ущерба функциональности.

samana
20.04.2010, 12:23
AzagThoth, к сожалению ваш вариант у меня тормозит, но это конечно мой комп старый уже.
И ещё один вариант. Сделал без твинов, а анимация кубика сделана в ручную, пару вариантов который выбирается рандомно.
var scale = 20;//расстояние между клетками
for (var i = 0; i < 25; i++) {
for (var j = 0; j < 50; j++) {
var c = _root.attachMovie("clip", i + "_" + j, _root.getNextHighestDepth());
c._x = 10 + j * scale;
c._y = 10 + i * scale;
}
}
fps.swapDepths(_root.getNextHighestDepth());
_root.onMouseMove = function() {


var mJ = Math.floor(_xmouse / scale);
var mI = Math.floor(_ymouse / scale);

for (var tempI = mI - 1; tempI <= mI + 1; tempI++) {
for (var tempJ = mJ - 1; tempJ <= mJ + 1; tempJ++) {
var tc:String = tempI + "_" + tempJ;

var rand = [1, 31, 61, 91];
var randCheck = rand[random(rand.length - 1)];
if (_root[tc]._currentframe == 1) {
_root[tc]._rotation = 90 * random(5);
_root[tc].gotoAndPlay(randCheck);
}
}
}
updateAfterEvent();

};

AzagThoth
20.04.2010, 13:23
Не знаю, может быть просто потому у Вас тормозит, что оно не оптимизировано. В общем я тогда постараюсь как-то поулучшать этот вариант и выложу что-то более вменяемое. Но идея у меня пока всё равно та же. Программно рисовать движения и рулить массивами.

AzagThoth
20.04.2010, 14:34
var st:Number = 40;//=ширина=высота атачимого мувиклипа
var prilip:Number = 2;//сколько мувиклипов должны прилипать
var shag:Number=1;

i = Math.floor(Stage.width/st);
j = Math.floor(Stage.height/st);

var arr:Array = [];
var arr2:Array = [];
var znak1:Number = null;
var znak = 0;

for (var y = 0; y<i; y++) {
arr[y] = [];
if (znak == 0) {
znak = 1;
} else if (znak == 1) {
znak = 0;
}
znak1 = znak;
for (var z = 0; z<j; z++) {
if (znak == 0) {
znak = 1;
} else if (znak == 1) {
znak = 0;
}
if (znak == 1) {
arr[y][z] = attachMovie("kub", "kub"+y+"|"+z, getNextHighestDepth(), {_x:(y*st), _y:(z*st), _width:st, _height:st });
arr[y][z].defaultX = arr[y][z]._x;
arr[y][z].defaultY = arr[y][z]._y;
}
}
znak = znak1;
}


onMouseMove = function ():Void {
i = Math.round(_xmouse/st);
j = Math.round(_ymouse/st);
for (var y = i-prilip; y<i+prilip; y++) {
for (var z = j-prilip; z<j+prilip; z++) {
if (arr[y][z] != undefined) {
arr[y][z]._x = _xmouse;
arr[y][z]._y = _ymouse;
arr2.push(arr[y][z]);
}
}
}
};


function defaultMove():Void {
for (var i = 0; i<arr2.length; i++) {
if (arr2[i].defaultX>arr2[i]._x) {
arr2[i]._x+=shag;
} else if (arr2[i].defaultX<arr2[i]._x) {
arr2[i]._x-=shag;
}
if (arr2[i].defaultY>arr2[i]._y) {
arr2[i]._y+=shag;
} else if (arr2[i].defaultY<arr2[i]._y) {
arr2[i]._y-=shag;
}
rX = Math.abs(arr2[i].defaultX-arr2[i]._x);
rY = Math.abs(arr2[i].defaultY-arr2[i]._y);
if (rX+rY<st/10) {
arr2[i]._x = arr2[i].defaultX;
arr2[i]._y = arr2[i].defaultY;
arr2.splice(i,1);
}
}
}

setInterval(defaultMove,10);
Сцену сделал 2000х2000 оно не то что бы тормозит, но в диспетчере задач нагрузка при движении мыши возрастает в флеш плеере с 8 до 60 процентов.

AzagThoth
20.04.2010, 14:44
А вообще мне Ваш вариант больше понравился. Нагрузка возрастает с 8 до 50 процентов. Но на глаз работает более шустро чем то что у меня.

in4core
20.04.2010, 15:48
Да у саманы работает быстро и у меня не тормозит вообще. Самана если не сложно попробуй увеличить кубики до размеров каждый 50*50 или вообще 80*80. И сцену 2000*1500. Поглядим на скорость

samana
21.04.2010, 00:19
А вообще мне Ваш вариант больше понравился. Нагрузка возрастает с 8 до 50 процентов. Но на глаз работает более шустро чем то что у меня.
Спасибо!
in4core С такими параметрами у меня тормозит (

in4core
21.04.2010, 00:50
Все равно квадраты мелкие вышли. Думаю надо 100 или даже 150. А что чем больше размер мувика тем медленнее? странно

samana
21.04.2010, 14:08
Все равно квадраты мелкие вышли. Думаю надо 100 или даже 150.
Тогда попробуй по варьировать с настройками. Можно выбирать разрешене экрана (красная рамка показывает) и размер клетки.
p.s. флешка в большом разрешении, если ничего не видно, то выбрать Show All

in4core
21.04.2010, 20:06
при 100 или 150 ваще не тормазит. Интересно другое, почему у меня 1280 ширина экрана, а у тебя я выставляю 2000 , а она даже не на весь мой экран выходит

samana
21.04.2010, 20:35
Наверно в проигрывателе кликнуть View -> 100%
А может я что-то намудрил....

AzagThoth
21.04.2010, 20:43
samana может конечно глупость спрошу, но как Вы выводите значение fps?

samana
21.04.2010, 20:51
samana может конечно глупость спрошу, но как Вы выводите значение fps?
Мне очень стыдно даже признаваться. Там клип с пустыми 60-ю кадрами, и функция каждую секунду проверяет какой текущий кадр этого клипа, выводит это число и перематывает снова в первый фрейм.

AlexCooper
21.04.2010, 20:57
Можно и так
lastTime = getTimer();
fps = 0;
this.onEnterFrame = function()
{
fps++;

if (getTimer()-lastTime>=1000)
{
lastTime = getTimer();
trace(fps);
fps=0;
}
}

AzagThoth
21.04.2010, 21:02
Спасибо за ответы! В общем я просто думал, а может есть такой метод/функция в языке готовый о котором я не знаю :) В общем понятно, что это дело самописное, спасибо!

samana
21.04.2010, 21:03
Можно и так...
Круто!