stobolewski Napisano 12 Lipiec 2013 Napisano 12 Lipiec 2013 Witam, wiem, zaraz mnie zjecie za samą tematykę pytania ale cóż, radzę sobie jak umiem ;D Zrobiłem prostą scenkę, w której za pomocą buttona dodaje się nowe obiekty [sPRITE] do sceny. Po dodaniu takiego obiektu można go przesunąć myszą po scence (wciśnięcie myszy - startDrag(), puszczenie - stopDrag()). Problem w tym, że w momencie utworzenia kolejnego obiektu [sPRITE] tracę możliwość zaznaczenia i przeciągnięcia poprzedniego. PYTANIE: Co zrobić aby dało się swobodnie przeciągać wszystkie obiekciki na scence ?
olaf Napisano 12 Lipiec 2013 Napisano 12 Lipiec 2013 najwidoczniej źle odwołujesz się do obiektu, biorąc tylko ostatni.
stobolewski Napisano 12 Lipiec 2013 Autor Napisano 12 Lipiec 2013 wsadzę część kodu, może to coś wyjaśni :) kod "sceny" import flash.events.MouseEvent; import flash.events.Event; import com.adobe.images.JPGEncoder; btn_middleTable.addEventListener(MouseEvent.CLICK, f_middleIco); btn_bigTable.addEventListener(MouseEvent.CLICK, f_bigIco); btnSave.addEventListener(MouseEvent.CLICK, f_save); function f_middleIco(event:MouseEvent):void { var middle:MiddleIco = new MiddleIco(); middle.x = 20; middle.y = 20; stage.addChild(middle); trace("created"); } function f_bigIco(event:MouseEvent):void { var big:BigIco = new BigIco(); big.x = 20; big.y = 20; stage.addChild(big); trace("created"); } kod obiektu (z oddzielnego pliku) package { import flash.display.MovieClip; import flash.events.MouseEvent; import flash.events.Event; public class BigIco extends MovieClip { public var active:Boolean; public function BigIco() { // constructor code this.addEventListener(Event.ENTER_FRAME, f_move); this.addEventListener(MouseEvent.MOUSE_DOWN,downf); this.addEventListener(MouseEvent.MOUSE_UP,upf); } public function f_move(e:Event) { if(active==true) { startDrag(); } else if(active==false) { stopDrag(); } } public function downf(e:MouseEvent) { active = true; } public function upf(e:MouseEvent) { active = false; } } } No i w klasie głównej buttonem tworzę instancje BigIco. W klasie BigIco mam funkcję przesuwania i kończenia przesuwania obiektu. Wielkim programista ze mnie nie jest więc myślałem, że skoro na jednej ikonce coś takiego działa to i na kilku będzie działało a tu zonk :/ funkcje działąją tylko na ostatnio dodanym obrazku. Co ja robię nie tak, albo czego nie wiem a powinienem wiedzieć ?
stobolewski Napisano 15 Lipiec 2013 Autor Napisano 15 Lipiec 2013 (edytowane) Sorka za dubla, ale udało się. Oto rozwiązanie: Klasa główna (z całym kodem - włącznie z datą i zliczaniem ilości miejsc przy stoliczkach). import flash.events.MouseEvent; import flash.events.Event; import com.adobe.images.JPGEncoder; import flash.events.KeyboardEvent; import com.adobe.protocols.dict.Database; var selected_item:int; var big_table:int = 0; var middle_table:int = 0; var little_table:int = 0; var actual_data:Date = new Date(); var the_data = actual_data.getDate(); data_field.text = " " + actual_data; btn_middleTable.addEventListener(MouseEvent.CLICK, f_middleIco); btn_bigTable.addEventListener(MouseEvent.CLICK, f_bigIco); btn_littleTable.addEventListener(MouseEvent.CLICK, f_littleIco); btnSave.addEventListener(MouseEvent.CLICK, f_save); stage.addEventListener(Event.ENTER_FRAME, f_update); stage.addEventListener(MouseEvent.MOUSE_DOWN, B_f_down); stage.addEventListener(MouseEvent.MOUSE_UP, B_f_up); stage.addEventListener(MouseEvent.MOUSE_DOWN, M_f_down); stage.addEventListener(MouseEvent.MOUSE_UP, M_f_up); stage.addEventListener(MouseEvent.MOUSE_DOWN, L_f_down); stage.addEventListener(MouseEvent.MOUSE_UP, L_f_up); function f_update(e:Event) { dStoly.text = ""+big_table; sStoly.text = ""+middle_table; mStoly.text = ""+little_table; razemStoly.text = ""+(big_table+middle_table+little_table); } function L_f_down(e:MouseEvent) { LittleIco.setDownVaue(); trace("down"); trace(LittleIco.active); } function L_f_up(e:MouseEvent) { LittleIco.setUpVaue(); trace("up"); trace(LittleIco.active); } function B_f_down(e:MouseEvent) { BigIco.setDownVaue(); trace("down"); trace(BigIco.active); } function B_f_up(e:MouseEvent) { BigIco.setUpVaue(); trace("up"); trace(BigIco.active); } function M_f_down(e:MouseEvent) { MiddleIco.setDownVaue(); trace("down"); trace(MiddleIco.active); } function M_f_up(e:MouseEvent) { MiddleIco.setUpVaue(); trace("up"); trace(MiddleIco.active); } function f_littleIco(event:MouseEvent):void { var little:LittleIco = new LittleIco(); little.x = 20; little.y = 20; little_table+=4; stage.addChild(little); trace("created"); } function f_middleIco(event:MouseEvent):void { var middle:MiddleIco = new MiddleIco(); middle.x = 20; middle.y = 20; middle_table+=6; stage.addChild(middle); trace("created"); } function f_bigIco(event:MouseEvent):void { var big:BigIco = new BigIco(); big.x = 20; big.y = 20; big_table+=10; stage.addChild(big); trace("created : " + big_table); } function f_save(event:MouseEvent) { var jpgEncoder:JPGEncoder; jpgEncoder = new JPGEncoder(90); var bitmapData:BitmapData = new BitmapData(stage.width, stage.height); bitmapData.draw(stage, new Matrix()); var img = jpgEncoder.encode(bitmapData); var file:FileReference = new FileReference(); file.save(img, "filename.png"); } Klasa pomocnicza (w sumie są 3 klasy na każdą ikonkę stolika oddzielna - zamieszczam tylko jedna bo ich zawartość jest identyczna:) package { import flash.display.MovieClip; import flash.events.MouseEvent; import flash.events.Event; public class BigIco extends MovieClip { static public var active:Boolean; public var over:Boolean; public function BigIco() { // constructor code this.addEventListener(Event.ENTER_FRAME, f_move); this.addEventListener(MouseEvent.MOUSE_OVER, setOverTrue); this.addEventListener(MouseEvent.MOUSE_OUT, setOverFalse); } static public function setUpVaue():void { active = false; } static public function setDownVaue():void { active = true; } public function f_move(e:Event) { if(over) { if(active) {startDrag();} else {stopDrag();} } } public function setOverTrue(e:MouseEvent) { over = true; trace("over"); } public function setOverFalse(e:MouseEvent) { over = false; trace("out"); } } } Teraz pozostaje jeszcze zrobić opcję usuwania zaznaczonego stoliczka ;p. Ps. czy ma ktoś pomysł jak usunąć zaznaczony myszą obiekt ? Szukam czegoś o wyborze dziecka po id (coś w stylu: pobierz id aktualnie zaznaczonego obiektu), dzięki czemu później mógłbym usunąć taki obiekt właśnie za pomocą jego id (np. po wciśniećiu "x"), ale nigdzie nie mogę znaleźć nic przydatnego :/ Tak, wiem że to jest kod spagetti, ale biorąc pod uwagę moje (nie)umiejętności programistyczne inaczej nie umiałęm :/ Edytowane 15 Lipiec 2013 przez stobolewski
olaf Napisano 15 Lipiec 2013 Napisano 15 Lipiec 2013 dobra rada, to nie uzywanie stage. sposobów masz kilka. -mozesz po ID jeżeli potrafisz je zidentyfikować - tata.getChildByName(dziecko.name) -mozesz po poziomie, jeżeli wiesz, że np. zaznaczony jest na górnym poziomie - tata.getChildAt(poziom) -mozesz przypisać mu listener zwiazany z akcjami dla niego - wtedy odwołujesz się do niego jako event.currentTarget -mozesz też definiować zmienną na czas wyboru np. KID=dziecko i przywoływać zmienną KID generalnie dla mnie najwygodniejsze jest tworzenie listenerów dla obiektów i odwoływanie się do nich po np. znajdującym się w nich guziku dla przykładu buton=event.currentTarget; dziecko=parent.buton ale to kwestia własnych preferencji. Wygodne w listenerze dla obiektu jet to, że nie musiałbyś duplikowac klas, co ułatwia pracę.
stobolewski Napisano 15 Lipiec 2013 Autor Napisano 15 Lipiec 2013 olaf. Zapewne masz rację i zapewne piszesz mądrze. Ja z as3 mam do czynienie tyle, że wiem iż on istnieje (i że większość osób go unika). Robię pseudo aranżator bo ... nikt inny w tym miejscu tego nie zrobi :/ Z tego co rozumiem mam identyfikować jakoś obiekty... tylko pytanie jak ? Jak widać tworzę kolejne obiekty (np. 200 stolików), które wg. mnie nie są w żaden sposób identyfikowane (wiem że istnieje coś takiego jak usunięcie "dziecka" po id [rozumuje ze każdy kolejny stolik ma kolejne id]. Nie wiem niestety w jaki sposób mam pobrać id obiektu, który jest aktualnie pod myszą. Właśnie wpadłem na pomysł, że wszystkie te moje "stoliczki / ikony" będę tworzył w oddzielnym pustym movie clipie, może to mi ułatwi ich usuwanie (poprzedni test po wciśnięciu X usunął mi tło programiku ;D). Jako człek nieogarnięty z programowaniem wiedzę czerpię z: http://www.ilike2flash.com/2010/02/detect-key-press-in-actionscript-3.html http://stackoverflow.com/questions/11934569/as3-delete-object-when-clicked itp. rzeczy - sam się dziwie że działają mi te połączenia między klasami ;D Poszukam i pokombinuje, może coś zdziałam.
stobolewski Napisano 15 Lipiec 2013 Autor Napisano 15 Lipiec 2013 (edytowane) Aktualnie... kombinuje jak to zrobić aby usunąć zaznaczony obiekt. Przykładowo tworzę 20 nowych mebli i dochodzę do wniosku że któryś z nich jest niepotrzebny. Trzymam nad nim mysz i przez dwuklik lub wciśnięcie jakis litery kasuję dany obiekt (ten aktualnie pod myszą). W tej chwili wszystkie moje mebelki mam w oddzielnym movie clipie, dzięki czemu mogę za pomocą pętli usunąć wszystkie jego dzieci (przycisk z funkcją reset). Największy problem dla laika to pobranie id obiektu bezpośrednio pod kursorem myszy. Usunięcie takiego obiektu już sobie jakoś zorganizuje. Znalazłem klika przykładów do pobierania ID, ale zawsze mam jakieś błędy o dostępie do funkcji przez instancje (zmieniłem kod więc tego błędu nie wkleję). Przyznam się, że niestety takie błędy niewiele mi mówią. Większość przykładów, na jakie trafiam to usuwanie konkretnego dziecka po nazwie (u mnie nie ma nazw). Przykład: http://www.kirupa.com/forum/showthread.php?279476-getChildIndex() Mam jeszcze coś takiego, ale jeszcze nie rozgryzłem jak to działą (tu pewnie będzie odpowiedz :) http://www.flashandmath.com/intermediate/names/index.html Edytowane 15 Lipiec 2013 przez stobolewski
olaf Napisano 15 Lipiec 2013 Napisano 15 Lipiec 2013 pierwszy etap, to kod, ktory rozpozna Tobie, ze to jest to czego szukasz. Daj mu listenera na rollOver np. tak (moge sie pomylic bo pracuje we wlasnym frameworku i dawno nie uzywalem takich podstawowych funkcji) var M=new mebel; M.name='pantofel' pokoj.addChild(M); M.addEventListener(maus rollover poprawna składnia,rOv) function rOv(e){var M=e.currentTarget; trace('najechałem na skurczybuka, jego imie to:'+M.name)} co da Ci frazę: 'najechałem na skurczybuka, jego imie to:pantofel' Masz juz obiekt we władaniu i teraz rob z nim co chcesz.
deshu Napisano 15 Lipiec 2013 Napisano 15 Lipiec 2013 A konkretnie samo usuwanie: var mainMC:MovieClip //główny mc w którym masz wszystkie meble //petla dodająca listener wszystkim meblom for (var i:uint = 0; i var mebel:* = mainMC.childAt(i); mebel.addEventListener(MouseEvent.DOUBLE_CLICK, onMebelDoubleClick); } //usuwanie przy podwójnym klincieciu function onMebelDoubleClick(e:MouseEvent):void{ var mebel:* = e.currentTarget; mebel.removeEventListener(MouseEvent.DOUBLE_CLICK, onMebelDoubleClick); mebel.parent.removeChild(mebel); // to moze wydawać się dziwne, ale działa:) } Pisałem z głowy, wiec przyjmij to jako metode, a nie gotowy kod:) Nie pamietam tez od której wersji flash obsługuje MouseEvent.DOUBLE_CLICK. Ewentualnie mozesz sobie zrobić ze klikniecie z wciśnietym altem/shiftem/ctrl bedzie usuwać meble.
stobolewski Napisano 15 Lipiec 2013 Autor Napisano 15 Lipiec 2013 (edytowane) Dzięki wielkie za pomoc. Double_click w as3 jest więc nie ma problemu. Teraz pozostaje mi to jakoś wkomponować w mój wspaniały aranżaror ;p Nie wiem kiedy to będzie, ale na 100% dam znać czy się udalo :) zaraz nad tym siadam. A tak swoją drogą. Czy jest jakaś różnica między dodaniem eventu w pętli a dodaniem go przy tworzeniu obiektu ? function f_bigIco(event:MouseEvent):void{ var big:BigIco = new BigIco(); big.x = 20; big.y = 20; big_table+=10; table_holder.addChild(big); big.addEventListener(MouseEvent.DOUBLE_CLICK, f_removeBig); trace("created : " + big_table); } Coś takiego zmajstrowałem (wzorując się na przykłądzie z sieci), ale coś nie chce działać (ale błędów nie ma ;p). WoW, to żyje. Udało się ! dwuklik usuwa wskazany obiekt. Okazało się że dla każdego obiektu trzeba jeszcze odblokować opcję dwukliku :). To się ludkowie ucieszą, jak będą mogli poustawiać stoliczki pod dyktando klienta, a nie tylko wysłać pdf (a i ja może dzięki temu będę miał mniej "problemów" ;) Jak skończę to się pochwalę "efektem" ;p Dzięki wielkie za pomoc :* Edytowane 15 Lipiec 2013 przez stobolewski
deshu Napisano 15 Lipiec 2013 Napisano 15 Lipiec 2013 Spoko, miło jest pomóc:) Pewnie już znasz odpowiedź, ale nie, nie ma różnicy w którym momencie nadasz obiektowi listener. See ya, jak cos to pytaj, mam subskrypcje na wątek.
stobolewski Napisano 16 Lipiec 2013 Autor Napisano 16 Lipiec 2013 (edytowane) A więc pytam ;p. Dlaczego ta funkcja nie działa jeśli dodam do sceny inne rodzaje stoliczków ? W tej chwili mam na stole "mapke" pomieszczenia i dodaje tam 3 rodzaje stolików (wszystkie są zdefiniowane w oddzielnych klasach) - Małe - Średnie - Duże Sposób który mi podałeś działa ale tylko dla dużych stolików (tam dodałem go na samym początku). Postępując zgodnie z ta zasadą zrobiłem podobny schemat dla pozostałych stoliczków, z tym że w dodanym evencie wywołuje funkcje z o innych nawach (np. f_removeBig, f_removeMiddle, f_removeSmall). Działa tylko jedna (znaczy tylko w przypadku jednej funkcji działa double click) :/ czyli mam (fragment kodu) function f_littleIco(event:MouseEvent):void{ var little:LittleIco = new LittleIco(); little.x = 20; little.y = 20; little.doubleClickEnabled=true; little_table+=4; table_holder.addChild(little); little.addEventListener(MouseEvent.DOUBLE_CLICK, f_removeSmall); trace("created"); } function f_middleIco(event:MouseEvent):void { var middle:MiddleIco = new MiddleIco(); middle.x = 20; middle.y = 20; middle.doubleClickEnabled=true; middle_table+=6; table_holder.addChild(middle); middle.addEventListener(MouseEvent.DOUBLE_CLICK, f_removeMiddle); trace("table added, function added..."); trace("created"); } function f_bigIco(event:MouseEvent):void { var big:BigIco = new BigIco(); big.x = 20; big.y = 20; big.doubleClickEnabled=true; big_table+=10; table_holder.addChild(big); big.addEventListener(MouseEvent.DOUBLE_CLICK, f_removeBig); trace("table added, function added..."); trace("created : " + big_table); } function f_removeBig(e:MouseEvent) { trace("event added ..."); var qqq:* = e.currentTarget; qqq.removeEventListener(MouseEvent.DOUBLE_CLICK, f_removeBig); qqq.parent.removeChild(qqq); big_table-=10; } function f_removeMiddle(ev:MouseEvent) { trace("middle function called"); var sredni:* = ev.currentTarget; sredni.removeEventListener(MouseEvent.DOUBLE_CLICK, f_removeMiddle); sredni.parent.removeChild(sredni); middle_table-=6; } function f_removeSmall(e:MouseEvent) { trace("event added ..."); var qqq:* = e.currentTarget; qqq.removeEventListener(MouseEvent.DOUBLE_CLICK, f_removeSmall); qqq.parent.removeChild(qqq); little_table-=4; } działa tylko część dla BigIco :( Dodałem w funkcjach "trace" żeby sprawdzic czy są wywoływane... nie są :/ Wychodzi na to, że z jakiegoś powodu flash nie widzi tych kolejnych kliknięć na innych ikonach (bez względu na to, czy tworzę wszystkie stóły, czy tylko średnie). Problem rozwiązany (googlowanie pomaga) Nie wiem czy to dobra technika ale działa. Wystarczyło dodać 2 linijki do funkcji tworzącej nowe obiekty big.buttonMode = true; big.mouseChildren = false; function f_littleIco(event:MouseEvent):void{ var little:LittleIco = new LittleIco(); little.x = 20; little.y = 20; little.doubleClickEnabled=true; little_table+=4; little.buttonMode = true; little.mouseChildren = false; table_holder.addChild(little); little.addEventListener(MouseEvent.DOUBLE_CLICK, f_removeSmall); trace("created"); } function f_middleIco(event:MouseEvent):void { var middle:MiddleIco = new MiddleIco(); middle.x = 20; middle.y = 20; middle.doubleClickEnabled=true; middle_table+=6; middle.buttonMode = true; middle.mouseChildren = false; table_holder.addChild(middle); middle.addEventListener(MouseEvent.DOUBLE_CLICK, f_removeMiddle); trace("table added, function added..."); trace("created"); } function f_bigIco(event:MouseEvent):void { var big:BigIco = new BigIco(); big.x = 20; big.y = 20; big.doubleClickEnabled=true; big_table+=10; big.buttonMode = true; big.mouseChildren = false; table_holder.addChild(big); big.addEventListener(MouseEvent.DOUBLE_CLICK, f_removeBig); trace("table added, function added..."); trace("created : " + big_table); } Edytowane 16 Lipiec 2013 przez stobolewski
deshu Napisano 16 Lipiec 2013 Napisano 16 Lipiec 2013 Jasne, to dlatego, że gdy masz *.mouseChildren na true, to klikając na obiekt, klikasz de facto na to co ma w sobie - czyli w twoim wypadku pewnie albo obrazek, albo innego MovieClipa. A event Double_Clicka jest nadany tylko na obiekt główny - na jego dzieci nie - dlatego nic się nie działo. Gdy ustawisz mouseChildren na false, cały obiekt jest traktowany jako jedność (dla interakcji myszką).
stobolewski Napisano 16 Lipiec 2013 Autor Napisano 16 Lipiec 2013 Wersja testowa (taka dla mnie ;) wersja beta się kilka w ikonki pod "dostępne stoliki" ;p "Troszeczkę" pracy jeszcze zostało ale coś już działa a to sukces. Dzięki za pomoc.
stobolewski Napisano 16 Lipiec 2013 Autor Napisano 16 Lipiec 2013 jest moc w jakości tła ;D musiałem wydupcyć plan pomieszczenia bo nie wiem co na takie udostępnianie go powiedział by mój "pracodawca" ;).
Rekomendowane odpowiedzi
Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto
Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.
Zarejestruj nowe konto
Załóż nowe konto. To bardzo proste!
Zarejestruj sięZaloguj się
Posiadasz już konto? Zaloguj się poniżej.
Zaloguj się