Dynamic Object Initiation As3

前端 未结 6 1957
被撕碎了的回忆
被撕碎了的回忆 2021-01-17 04:33

I notice in older version of flash you can create an instance of a dynamic class. I am creating a game that will have many different classes that can be displayed on the sta

相关标签:
6条回答
  • 2021-01-17 04:38

    Yes, like I said, to answer your original question, what you have above will work in AS3 as it did in older versions of AS. So if it's not a big deal, you can go with it.

    Overall, I wouldn't say dynamic initialization goes against OOP, per se. However, it just feels a little like a hack. Everytime I start to use something like that, I almost always find a design change that cleanly fixes the problem.

    Of course it's hard to spot that change without knowing a LOT about your application. To take a stab at it:

    Do you even need different classes for each brick?

    Could you just set some property that ultimately changes it's behavior (like this.strength = 2)?

    Then, while iterating through the array you do something like

    for(var brickType:int in brickArray) {
        addBrickToScreenOrWhatever( new Brick(brickType) );
    }
    

    Where the constructor Brick(int) creates a new Brick with a strength equal to that of the parameter.

    0 讨论(0)
  • 2021-01-17 04:40

    Occasionally, I still make calls along the lines of:

    parent["MovieClipName"].someMethod();

    from time to time. So I imagine your code above will work.

    However, whenever I find myself using that syntax, it usually means I need to re-think my approach and use a better, more object-oriented solution.

    So I would suggest that maybe what you really need to do is re-think the factors that are leading you to attempt to use the solution above. Chances are you can reach the same goal in a more object-oriented way.

    Perhaps by using inheritance? Could all of your objects extend from some common parent Object?

    Perhaps by using an interface? If it doesn't make sense for your objects to share the same parent, maybe they all can agree to share some key functions?

    Maybe code along the lines of:

    var tank:Enemy = new Tank();
    var soldier:Enemy = new Soldier();
    
    soldier.attack(target);
    tank.attack(target);
    

    Wnere the tank and soldier classes both extend from (or implement) Enemy like this

    public class Tank extends Enemy
    

    or like this

    public class Tank implements Enemy
    

    and the Enemy class/interface contains the attack method

    0 讨论(0)
  • 2021-01-17 04:45

    I think I am going to go with george's solution. Except I am having a little issue with it. I was trying to do the second example. my code is below. When I call the class directly it works, but when i call by definition. doesnt work. any solution

    package com.objects {
    
        import flash.display.Sprite;
        import flash.events.*;
        import flash.display.Stage;
        import flash.text.TextField;
        import flash.text.TextFormat;
        import flash.text.AntiAliasType;
        import flash.utils.*;
    
        public class Engine extends Sprite {
            private var pad:Paddle;
            private var sRef:Stage;
            private var ball:Ball;
            private var bricks:BrickMap;
            private var brickHolder:Array;
            public var numberOfBricks:Number = 0;
            public var scoreBoard:TextField;
            public var score:Number = 0;
            private var level = 1;
            private var ready:Ready;
    
            public function Engine(stageRef:Stage):void
            {
                addHud();
    
                brickHolder = new Array();
                sRef = stageRef;
                pad = new Paddle();
                pad.x = sRef.stageWidth/2;
                pad.y = 550;
                ball = new Ball();
                ready = new Ready();
                ready.x = sRef.stageWidth/2;
                ready.y = sRef.stageHeight/2;
    
                ready.addEventListener(MouseEvent.CLICK,gameStart);
                addChild(ready);
                bricks = new BrickMap();
    
                generateMap();          
            }
    
            private function generateMap():void
            {
                var mapW:Number = bricks.mapArry[0].length;
                var mapH:Number = bricks.mapArry.length;
                for(var y = 0; y < mapH; y++)
                {
                    brickHolder[y] = new Array();
                    for(var x = 0; x < mapW; x++)
                    {
                        var classRef = getDefinitionByName('Brick2') as Class;
                    var brick:Brick2 = Brick2(new classRef());
                        brick.name = x+""+y;
                        brick.getBall(ball);
                        brick.getEngine(this);
                        brick.x = x * brick.bWidth + brick.bWidth;
                        brick.y = y * brick.bHeight + 100;
                        numberOfBricks += 1;
                        addChild(brick);
    
                    }
                }
            }//End Generate Map
           }
    }
    

    I edited the above to

    var classRef = getDefinitionByName('Brick2') as Class;
    var brick:Brick2 = Brick2(new classRef());
    

    also change import to

    import flash.utils.*;
    
    0 讨论(0)
  • 2021-01-17 04:47

    You can simple if you want to do it for example an editor for a game:

    selectItem(e.target);       
    
    private function selectItem(whatItem:Object):void
    {
        var TemplateObj:Class = getDefinitionByName(getQualifiedClassName(whatItem)) as Class;
        var newItem:* = new TemplateObj();
    
    0 讨论(0)
  • 2021-01-17 04:49

    I think there are 2 ways you can do that:

    1.Using ApplicationDomain.getDefinition('DynamicTemplate')

    something like:

    var DynamicClass:Class = this.loaderInfo.applicationDomain.getDefinition('DynamicTemplate') as Class;
    addChild(new DynamicClass);
    

    You would need to do this when you file has INITialized.

    2.Using getDefinitionByName() :

    var DynamicClass:Class = flash.utils.getDefinitionByName('DynamicTemplate') as Class;
    addChild(new DynamicClass);
    

    If you need a way to get Class names to create new instances of objects, you could use describeType() or go through the instance's constructor, but I reckon you would know your classes anyway.

    var TemplateObj:Class = flash.utils.getDefinitionByName(describeType(yourIntance).@name) as Class;
    var newObj = new TemplateObj();
    var newObj2 = new yourIntance.constructor();
    

    Hope this help, George

    0 讨论(0)
  • 2021-01-17 05:02

    Interfaces is good. I am using an array that maps out how the bricks will be put down on the stage

     mapArry =  [
          [[1],[1],[1],[1],[1],[1],[1],[1],[1],[1]], 
          [[1],[1],[1],[1],[1],[1],[1],[1],[1],[1]],
          [[1],[1],[1],[1],[1],[1],[1],[1],[1],[1]],
          [[1],[1],[1],[1],[1],[1],[1],[1],[1],[1]],
          ];
    

    1 specifies brick type Number 1. but what if the next map has brick type 2 or 3

     mapArry =  [
          [[1],[1],[1],[1],[1],[1],[1],[1],[1],[1]], 
          [[1],[1],[1],[1],[1],[1],[1],[1],[1],[1]],
          [[1],[1],[1],[1],[1],[1],[1],[1],[1],[1]],
          [[2],[2],[2],[2],[2],[2],[2],[2],[2],[2]],
          ];
    

    Again, I loop through the array, getting each brick. how would I use interfaces to supply the given brick ?.

    The only answer I could think of is the create a brickManager class. a class that identifies each type of brick and retrieves them. But I am trying to be more efficient. I would like to know if there is a better way.

    Only thing i could think of is to use dynamic initiations. I didnt know that approach went against oop.

    var newVar = new ["brick"+i]();
    
    0 讨论(0)
提交回复
热议问题