我注意到在旧版本的flash中你可以创建一个动态类的实例。我正在创建一个游戏,它将有许多不同的类,可以在舞台上显示,但可以不时。我将如何动态调用它们。例如
var newObject = new ["DynamicObject"]();
??
这可能在As3 ??
答案 0 :(得分:3)
我认为有两种方法可以做到:
1.使用ApplicationDomain.getDefinition('DynamicTemplate')
类似的东西:
var DynamicClass:Class = this.loaderInfo.applicationDomain.getDefinition('DynamicTemplate') as Class;
addChild(new DynamicClass);
当您将文件设为INITialized时,您需要执行此操作。
2.使用getDefinitionByName():
var DynamicClass:Class = flash.utils.getDefinitionByName('DynamicTemplate') as Class;
addChild(new DynamicClass);
如果你需要一种方法来获取类名来创建对象的新实例,你可以使用describeType()或者通过实例的构造函数,但我认为无论如何你都会知道你的类。
var TemplateObj:Class = flash.utils.getDefinitionByName(describeType(yourIntance).@name) as Class;
var newObj = new TemplateObj();
var newObj2 = new yourIntance.constructor();
希望这个帮助, 乔治
答案 1 :(得分:2)
有时,我仍然按照以下方式拨打电话:
parent["MovieClipName"].someMethod();
不时。所以我想你上面的代码会起作用。
然而,每当我发现自己使用该语法时,通常意味着我需要重新思考我的方法并使用更好的,更面向对象的解决方案。
所以我建议你真正需要做的就是重新思考导致你尝试使用上述解决方案的因素。您可以通过更加面向对象的方式达到相同的目标。
也许是通过使用继承? 你的所有对象都可以从一些常见的父对象扩展吗?
也许是通过使用界面? 如果你的对象分享同一个父母没有意义,也许他们都同意分享一些关键功能?
也许代码如下:
var tank:Enemy = new Tank();
var soldier:Enemy = new Soldier();
soldier.attack(target);
tank.attack(target);
tank
和soldier
类都可以像这样扩展(或实现)Enemy
public class Tank extends Enemy
或者像这样
public class Tank implements Enemy
并且Enemy类/接口包含attack
方法
答案 2 :(得分:1)
接口很好。我正在使用一个数组来确定如何将砖块放在舞台上
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指定砖类型编号1.但如果下一个地图具有砖类型2或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]],
];
再一次,我遍历数组,获得每一块砖。我如何使用接口来提供给定的砖?。
我能想到的唯一答案是创建一个brickManager类。一个类,用于标识每种类型的砖并检索它们。但我想提高效率。我想知道是否有更好的方法。
我唯一能想到的就是使用动态启动。我不知道这种做法违背了oop。
var newVar = new ["brick"+i]();
答案 3 :(得分:1)
是的,就像我说的那样,回答你原来的问题,上面的内容将在AS3中运行,就像在旧版AS中一样。所以,如果这不是什么大问题,你可以选择它。
总的来说,我不会说动态初始化本身就违背了OOP。然而,它只是感觉有点像黑客。每当我开始使用类似的东西时,我几乎总能找到一个能够彻底解决问题的设计变更。
当然,如果不了解您的申请,很难发现这种变化。抓住它:
你甚至需要为每个砖块使用不同的课程吗?
你能设置一些最终改变它行为的属性(比如this.strength = 2)吗?
然后,在遍历数组时,您可以执行类似
的操作for(var brickType:int in brickArray) {
addBrickToScreenOrWhatever( new Brick(brickType) );
}
构造函数Brick(int)
创建一个强度等于参数强度的新Brick
。
答案 4 :(得分:1)
我想我会选择乔治的解决方案。除了我有一点问题。我试图做第二个例子。我的代码如下。当我直接调用该类时,它可以工作,但是当我按照定义调用时。不起作用。任何解决方案
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
}
}
我将上述内容编辑为
var classRef = getDefinitionByName('Brick2') as Class;
var brick:Brick2 = Brick2(new classRef());
也将导入更改为
import flash.utils.*;
答案 5 :(得分:0)
如果你想做一个简单的游戏编辑器,你可以很简单:
selectItem(e.target);
private function selectItem(whatItem:Object):void
{
var TemplateObj:Class = getDefinitionByName(getQualifiedClassName(whatItem)) as Class;
var newItem:* = new TemplateObj();