22 Replies Latest reply on Jan 22, 2009 2:49 PM by VarioPegged

    Object-oriented advice please

    Handycam Level 1
      OK, I made this "game": http://www.craftstylish.com/ultimate-sewing-room-contest

      It was very popular. I now need to extend it a bit, and use it in other contexts. My question regards the object I am adding when the user adds furniture (for example). Right now, I have a class that gets instantiated by clicking on the thumbnail of the item, with is in a list component with a custom renderer with this:

      private function makeItem(e:ListEvent):void {
      imagePath = 'assets/'+e.currentTarget.selectedItem.img;
      var item:GameItem = new GameItem();
      item.filePath = imagePath;
      item.sfxPath = sfxPath;
      item.x = 100;
      item.y = 100;
      furniture.addChild(item);
      }

      Where "img" is the XML of the path to the full size image, and GameItem is my class.

      Although this obviously works, I am running into problems of scalability since some events in the GameItem class need to communicate with the parent app, like:

      private function deleteMe(e:MouseEvent):void {
      Application.application.furniture.removeChild(e.currentTarget.parent)
      deleteSound.play();
      }

      This handler is assigner to the "X" close button, which tells "furniture" (the container in the main app that holds all these items) to remove the parent of the close button (the piece of furniture).

      This strikes me as a little kludgy. Is there a cleaner way to instantiate game items, where such an item can each contain code to delete itself, show custom tooltip, or swap its image?

      Thanks.
        • 1. Re: Object-oriented advice please
          rtalton Level 4
          Dispatch a custom event from the GameItem class which the main app can listen for, and react to. This way you won't need to call a function in the main app from the GameItem class and it won't be dependent on the main app for its behavior(s).
          • 2. Re: Object-oriented advice please
            Level 7

            "Handycam" <webforumsuser@macromedia.com> wrote in message
            news:gl7ig0$2ac$1@forums.macromedia.com...
            > OK, I made this "game":
            > http://www.craftstylish.com/ultimate-sewing-room-contest
            >
            > It was very popular. I now need to extend it a bit, and use it in other
            > contexts. My question regards the object I am adding when the user adds
            > furniture (for example). Right now, I have a class that gets instantiated
            > by
            > clicking on the thumbnail of the item, with is in a list component with a
            > custom renderer with this:
            >
            > private function makeItem(e:ListEvent):void {
            > imagePath = 'assets/'+e.currentTarget.selectedItem.img;
            > var item:GameItem = new GameItem();
            > item.filePath = imagePath;
            > item.sfxPath = sfxPath;
            > item.x = 100;
            > item.y = 100;
            > furniture.addChild(item);
            > }
            >
            > Where "img" is the XML of the path to the full size image, and GameItem is
            > my
            > class.
            >
            > Although this obviously works, I am running into problems of scalability
            > since
            > some events in the GameItem class need to communicate with the parent app,
            > like:
            >
            > private function deleteMe(e:MouseEvent):void {
            > Application.application.furniture.removeChild(e.currentTarget.parent)
            > deleteSound.play();
            > }

            I'd suggest that you make a custom class that extends one of the Containers
            and contains an Image. Give it the ability to dispatch a "deleteMe" event,
            and then dispatch that when someone clicks the X button, then handle that
            event by removing event.currentTarget. Give your custom class an imagePath
            property with a getter and setter. When the setter is called, change the
            source on your image.

            A few suggestions I had from trying to play the game:

            1) I expected that the furniture would act like the curtains, floor,
            etc.--if I selected a new item of furniture from a category, it would
            replace the old one, not just stack on top of it.
            2) The orientation of my furniture didn't match the orientation of my
            room, and there was nowhere in the room I could drag it that it didn't just
            look "stuck on." If you're not going to have different image paths to match
            the room or some way to "rotate" the furniture to align it with the walls,
            you may want to consider just using an angle for all of the rooms that looks
            good with the angle the furniture pictures already have.
            3) It seemed to me that some of the curtain patterns scaled differently
            from others. At any rate, looking at the larger swatch didn't give me a
            very good idea of what the curtains would look like with the swatch shrunk
            down, so I wound up trying more of the swatches than I really should have
            needed to. You might want to consider showing the swatch at the size it
            will display on the curtains.

            HTH;

            Amy
            >
            > This handler is assigner to the "X" close button, which tells "furniture"
            > (the
            > container in the main app that holds all these items) to remove the parent
            > of
            > the close button (the piece of furniture).
            >
            > This strikes me as a little kludgy. Is there a cleaner way to instantiate
            > game items, where such an item can each contain code to delete itself,
            > show
            > custom tooltip, or swap its image?
            >
            > Thanks.
            >


            • 3. Re: Object-oriented advice please
              Handycam Level 1
              Thanks for the suggestions Amy.

              1) the sponsors of the game wanted the ability to keep stacking

              2) yes, that was a bummer. We had to use the client's own photos of their products, and the angle was different for all of them, which makes for the "glued on" look. The original game used CGI furniture that was matched to the background better. Fortunately, they didn't seem to mind.
              • 4. Re: Object-oriented advice please
                Handycam Level 1
                Can you please give me a good example of creating a custom event here? all the examples I have found needless complicate their code by including this concept in a complicated app rather than focusing on it separately.
                • 5. Re: Object-oriented advice please
                  rtalton Level 4
                  This just scratches the surface of what you could do.
                  • 6. Re: Object-oriented advice please
                    ntsiii Level 3
                    There is some terminology confusion associated with "Custom Event".

                    One type is as rtalton shows, which is really a standard "Event" with a custom name.

                    Another type of custom event actually subclasses event. This lets you add properties that can carry data in them.

                    The first option is obviously much simpler, and it is easy to forget that one can access any publicly exposed property on the dispatching component instance via the event.target property.

                    There are OOP theory considerations between the two approaches.
                    • 7. Re: Object-oriented advice please
                      Level 7

                      "Handycam" <webforumsuser@macromedia.com> wrote in message
                      news:gl7p4i$afh$1@forums.macromedia.com...
                      > Can you please give me a good example of creating a custom event here?
                      > all the
                      > examples I have found needless complicate their code by including this
                      > concept
                      > in a complicated app rather than focusing on it separately.

                      You may want to consider picking up the book "Actionscript 3 Design
                      Patterns." It starts with simple examples and makes them more complex.

                      HTH;

                      Amy


                      • 8. Re: Object-oriented advice please
                        Handycam Level 1
                        Thanks for your help folks, almost there.

                        As suggested, I have created a custom event:

                        package com.events
                        {
                         import flash.events.Event;
                         public class DeleteItem extends Event
                        {
                        public static const DELETE:String = "delete";
                        public function DeleteItem( type:String ){
                        super( type, true )
                        }
                        public override function clone():Event {
                        return new DeleteItem(type);
                        }
                        }
                         }

                        And the dispatcher in the close button handler:

                        private function deleteMe(e:MouseEvent):void {
                        deleteSound.play();
                        this.dispatchEvent(new DeleteItem(DeleteItem.DELETE));
                        }

                        And the handler in the main app:

                        private function deleteItemHandler(e:Event):void {
                        furniture.removeChild(e.currentTarget);
                        trace("delete button clicked");
                        }

                        The event is getting there, since I see the trace statement, but the compiler does not like the furniture.removeChild(e.currentTarget), it says 1118: Implicit coercion of a value with static type Object to a possibly unrelated type flash.display:DisplayObject.

                        What am I missing here?
                        • 9. Re: Object-oriented advice please
                          Level 7

                          "Handycam" <webforumsuser@macromedia.com> wrote in message
                          news:gl9vgt$3bg$1@forums.macromedia.com...


                          > The event is getting there, since I see the trace statement, but the
                          > compiler
                          > does not like the furniture.removeChild(e.currentTarget), it says 1118:
                          > Implicit coercion of a value with static type Object to a possibly
                          > unrelated
                          > type flash.display:DisplayObject.

                          furniture.removeChild(e.currentTarget as DisplayObject);

                          Note that you don't have to create a custom event for this:
                          http://flexdiary.blogspot.com/2007/08/dispatching-events.html

                          HTH;

                          Amy


                          • 10. Re: Object-oriented advice please
                            rtalton Level 4
                            e.currentTarget must not be the component then?
                            Debug it and see where the component is in the chain. Maybe e.currentTarget.parent...
                            • 11. Object-oriented advice please
                              Handycam Level 1
                              Thanks amy, yes

                              furniture.removeChild(e.currentTarget as DisplayObject);
                              • 12. Object-oriented advice please
                                Handycam Level 1
                                quote:

                                Give your custom class an imagePath property with a getter and setter. When the setter is called, change the source on your image.


                                I guess I don't fully grasp this getter/setter concept. The class has an imagePath, set to the "front" image. I have created the "left" and "right" buttons, and handlers for them that set the imagePath to the "left" version.

                                private function init():void {
                                itemImage.source = filePath;
                                ...
                                }

                                <mx:Image id="itemImage" width="100%" height="100%" />

                                And so I do:
                                private function rotateLeft():void {
                                imagePath="leftImage.png";
                                }

                                But the image does not change.
                                • 13. Re: Object-oriented advice please
                                  Handycam Level 1
                                  Never mind, I just set the var to be bindable and then bound the image source to it.
                                  • 14. Re: Object-oriented advice please
                                    Handycam Level 1
                                    quote:

                                    Originally posted by: Newsgroup User
                                    Note that you don't have to create a custom event for this:
                                    http://flexdiary.blogspot.com/2007/08/dispatching-events.html



                                    But I just tried
                                    this.dispatchEvent(new Event("bringToFront"));

                                    and

                                    item.addEventListener(bringToFront, bringToFrontHandler);

                                    And the editor flags the listener as an error:
                                    1120: Access of undefined property bringToFront.


                                    • 15. Re: Object-oriented advice please
                                      rtalton Level 4
                                      Try double quotes around the event name.
                                      • 16. Object-oriented advice please
                                        Handycam Level 1
                                        I noticed the update on Amy's site and added:
                                        <mx:Metadata>
                                        [Event(name="bringToFront", type="flash.events.Event")]
                                        </mx:Metadata>

                                        But this give me the compiler error:
                                        1084: Syntax error: expecting rightparen before type.

                                        UPDATE: I deleted everything and re-typed from scratch and it stopped complaining. I am still getting the 1120 error on the main application.
                                        • 17. Re: Object-oriented advice please
                                          rtalton Level 4
                                          I meant in your listener:
                                          item.addEventListener("bringToFront", bringToFrontHandler);
                                          • 18. Re: Object-oriented advice please
                                            Handycam Level 1
                                            quote:

                                            Originally posted by: rtalton
                                            Try double quotes around the event name.


                                            I still get the 1120 error.
                                            • 19. Re: Object-oriented advice please
                                              rtalton Level 4
                                              Dunno.
                                              Try the event code sample I posted yesterday.
                                              • 20. Re: Object-oriented advice please
                                                Level 7

                                                "Handycam" <webforumsuser@macromedia.com> wrote in message
                                                news:gla77b$cgc$1@forums.macromedia.com...
                                                >
                                                quote:

                                                Originally posted by: Newsgroup User
                                                > Note that you don't have to create a custom event for this:
                                                > http://flexdiary.blogspot.com/2007/08/dispatching-events.html
                                                >

                                                >
                                                > But I just tried
                                                > this.dispatchEvent(new Event("bringToFront"));
                                                >
                                                > and
                                                >
                                                > item.addEventListener(bringToFront, bringToFrontHandler);

                                                Try
                                                item.addEventListener('bringToFront', bringToFrontHandler);

                                                HTH;

                                                Amy


                                                • 21. Re: Object-oriented advice please
                                                  Level 7

                                                  "Handycam" <webforumsuser@macromedia.com> wrote in message
                                                  news:gla87r$dnk$1@forums.macromedia.com...
                                                  >I noticed the update on Amy's site and added:
                                                  > <mx:Metadata>
                                                  > [Event(name="bringToFront", type="flash.events.Event")]
                                                  > </mx:Metadata>
                                                  >
                                                  > But this give me the compiler error:
                                                  > 1084: Syntax error: expecting rightparen before type.
                                                  >

                                                  You can leave off the type unless it's a special type of event (like
                                                  custom). I don't see an actual error in what you've posted, so there might
                                                  be something else going on in your file that is manifesting in this line.

                                                  For more info, check out
                                                  http://www.adobe.com/livedocs/flex/3/html/metadata_3.html#159710

                                                  HTH;

                                                  Amy


                                                  • 22. Object-oriented advice please
                                                    VarioPegged Level 2
                                                    Could you post some of the code from the main app to help pinpoint the 1120 error?

                                                    Looking at sample code earlier in this thread, please note that metadata tags for events are only necessary if you're going to define your event listeners declaratively within MXML. This is so the compiler knows what to look for. If you're adding event listeners directly via ActionScript, it's not necessary to have metadata event tags in either MXML components or AS classes.

                                                    TS