views:

143

answers:

4

Hello!
I was programming in php for a while but it was all procedural-oriented. Now I have a project in Flex 3 and I made a simple script which animates (moves) few objects but I think that I am missing the point of object-oriented programming here because I am repeating some stuff over and over... Maybe it is mixed together with all of confusions I still have regarding AS3, so please tell me is there any 'smarter' way of writing this code:

<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"
    width="100%" height="100%"
    paddingBottom="0" paddingLeft="0" paddingRight="0" paddingTop="0"
    horizontalScrollPolicy="off" verticalScrollPolicy="off"
    creationComplete="init()">

    <mx:Script>
     <![CDATA[
      import mx.events.EffectEvent;

      public var opened1:Boolean;
      public var opened2:Boolean;
      public var opened3:Boolean;
      public var opened4:Boolean;

      [Bindable] public var pgW:Number;

      private function init():void{
       pgW = this.width;

       opened1 = false;
       opened2 = false;
       opened3 = false;
       opened4 = false;

       addListeners();
      }

      private function mouseOver1(event:MouseEvent):void{
       removeListeners();

       if (opened2){
        moveOut.target = txt2;
       }
       if (opened3){
        moveOut.target = txt3;
       }
       if (opened4){
        moveOut.target = txt4;
       }

       moveOut.play();
       setOpened(1);
       moveIn.target = txt1;
       moveIn.play();
      }

      private function mouseOver2(event:MouseEvent):void{
       removeListeners();

       if (opened1){
        moveOut.target = txt1;
       }
       if (opened3){
        moveOut.target = txt3;
       }
       if (opened4){
        moveOut.target = txt4;
       }

       moveOut.play();
       setOpened(2);
       moveIn.target = txt2;
       moveIn.play();
      }

      private function mouseOver3(event:MouseEvent):void{
       removeListeners();

       if (opened1){
        moveOut.target = txt1;
       }
       if (opened2){
        moveOut.target = txt2;
       }
       if (opened4){
        moveOut.target = txt4;
       }

       moveOut.play();
       setOpened(3);
       moveIn.target = txt3;
       moveIn.play();
      }

      private function mouseOver4(event:MouseEvent):void{
       removeListeners();

       if (opened1){
        moveOut.target = txt1;
       }
       if (opened2){
        moveOut.target = txt2;
       }
       if (opened3){
        moveOut.target = txt3;
       }

       moveOut.play();
       setOpened(4);
       moveIn.target = txt4;
       moveIn.play();
      }




      private function addListeners():void{
       btn1.addEventListener(MouseEvent.MOUSE_DOWN, mouseOver1);
       btn2.addEventListener(MouseEvent.MOUSE_DOWN, mouseOver2);
       btn3.addEventListener(MouseEvent.MOUSE_DOWN, mouseOver3);
       btn4.addEventListener(MouseEvent.MOUSE_DOWN, mouseOver4);
      }

      private function removeListeners():void{
       btn1.removeEventListener(MouseEvent.MOUSE_DOWN, mouseOver1);
       btn2.removeEventListener(MouseEvent.MOUSE_DOWN, mouseOver2);
       btn3.removeEventListener(MouseEvent.MOUSE_DOWN, mouseOver3);
       btn4.removeEventListener(MouseEvent.MOUSE_DOWN, mouseOver4);
      }

      private function setOpened(nr:int):void{
       if (nr == 1){
        opened1 = true;
        opened2 = false;
        opened3 = false;
        opened4 = false;
       }
       if (nr == 2){
        opened1 = false;
        opened2 = true;
        opened3 = false;
        opened4 = false;
       }
       if (nr == 3){
        opened1 = false;
        opened2 = false;
        opened3 = true;
        opened4 = false;
       }
       if (nr == 4){
        opened1 = false;
        opened2 = false;
        opened3 = false;
        opened4 = true;
       }
       trace("opened" + nr);
      }

      private function setPositions(event:EffectEvent):void{
       event.effectInstance.target.x = -(pgW);
      }

      private function klik(event:MouseEvent):void {
       event.stopPropagation();
      }
     ]]>
    </mx:Script>

    <mx:Move id="moveIn"
     xFrom="{-pgW}" xTo="0"
     yFrom="0" yTo="0"
     duration="1000"
     effectEnd="addListeners();"/>

    <mx:Move id="moveOut"
     xFrom="0" xTo="0"
     yFrom="0" yTo="250"
     duration="1000"/>


    <mx:Image id="btn1" source="assets/img/32/32-btn1.swf"
      x="0" y="0"
      width="100%"
      click="klik(event)"/>

    <mx:Image id="btn2" source="assets/img/32/32-btn2.swf"
      x="0" y="0"
      width="100%"
      click="klik(event)"/>

    <mx:Image id="btn3" source="assets/img/32/32-btn3.swf"
      x="0" y="0"
      width="100%"
      click="klik(event)"/>

    <mx:Image id="btn4" source="assets/img/32/32-btn4.swf"
      x="0" y="0"
      width="100%"
      click="klik(event)"/>



    <mx:Image id="txt1" source="assets/img/32/32-txt1.swf"
      x="{-pgW}" y="0"
      width="100%"/>

    <mx:Image id="txt2" source="assets/img/32/32-txt2.swf"
      x="{-pgW}" y="0"
      width="100%"/>

    <mx:Image id="txt3" source="assets/img/32/32-txt3.swf"
      x="{-pgW}" y="0"
      width="100%"/>

    <mx:Image id="txt4" source="assets/img/32/32-txt4.swf"
      x="{-pgW}" y="0"
      width="100%"/>
</mx:Canvas>

Thank you very much for your time!

m.

A: 

Follow some tutorial on architecting applications, use some patterns, try out MVC or MVP, checkout Smartypants IOC

skrat
I would say, at this point, simple OO stuff is much, much more important to learn than patterns/MVC (especially if you're thinking of an MVC framework).
David Wolever
+2  A: 

Your sample code is PERFECT for being OO'ed (made object oriented).

You have four things (which you'll define using one class) which hold a reference to a Button, a text, an open state, etc. So you define one class as an MXML component which holds a button, a text, and any other state and you put the methods ON THAT COMPONENT (in the <mx:Script> block). Plus you initialize the component in it's creationComplete method so that the open variable is false when it finishes the intial drawing. Even your mouseOver method is perfect: you can let the objects decide if they need to do something or not (and the MXML component will automatically have the event handling). Basically, that's what we're going for: the MXML component deals with its own internal state rather than having an external object which has to manage state for a list.

Since the MouseOver method would be put in your MXML component, each would have to hold references to the others. There are many ways to do this, including passing a reference at some point earlier and storing it, or having a static var that holds a list of the other x number of objects.

Hope that makes some sense and helps.

Yar
+2  A: 

Rather do something like. In pseudocode:

init()
  btn[] = create array of buttons
  txt[] = create array of txt
  opened[] = create array of boolean
  opened[] = false
  for each btn
           btn.mouseover = mouseover
           add listeners

mouseover
  remove listeners
  i = find source btn index from event
  moveout.target = movein.target
  moveout.play
  opened[] = false
  opened[i] = true
  movein.target = txt[i]
  movein.play

Probably you won't need the opened variables.

egon
Thanks for your example, I will examine it and try to experiment with it. I accepted the other answer because it is more explained but I'm sure that I will find your answer helpful as much as the other one =)
errata
Doing stuff with arrays or collections is definitely better than what the questioner had, but doing it with OO is just way slicker: the code becomes cleaner and more comprehensible. Just my 2 cents...
Yar
Actually I see no reason to use OO here. I guess it all depends on the situation. Sometimes is the procedural way of doing it easier. OO may be slicker but if you don't think it through (Over OO-ing) it's worse than procedural. When I usually do OO I do everyhting I need all objects and then shrink it down to bare minimum (that means keeping it low on objects) to support all objects and keep the inheritance.
egon
A: 

As a matter of fact, the value of moveOut.target after executing the following code segment will always be txt3 if opened3 is true (irrespective of the values of opened2/3). Is that by design or are opened1/2/3/4 mutually exclusive (only one can be true at a time) or are you missing else statements or ...?

if (opened1){
 moveOut.target = txt1;
}
if (opened2){
 moveOut.target = txt2;
}
if (opened3){
 moveOut.target = txt3;
}
Amarghosh
Ah, yes, it makes sense... But my example was actually working as expected... Although I'm not sure why =)
errata