【问题标题】:Actionscript 3 eventlisteners, hittestobject and arrays of custom objectsActionscript 3 事件监听器、hittestobject 和自定义对象数组
【发布时间】:2014-02-02 14:33:42
【问题描述】:

另一个拼命困在这里的一年级学生。我必须使用 FlashCS 作为我的编码环境。这很糟糕。所以我会尝试一些结构良好且清晰的问题。有:

public var object: symbol1;
public var objectarray: Array = new Array();

在我的主要。然后有一个函数使用计时器并生成一个新对象并将其推送到数组中:

object = new symbol1;
objectarray.push(object)

但是当我 trace() 数组的 .length 时,它会在输出中的每个计时器周期显示两个数组长度数字。如:

1 1 2 2 3 3

等等。这是我的第一个谜。为什么两个不是一个?因为我无法两次调用包含 trace () 的函数。另外我认为我需要能够在 objectarray 离开舞台时将其从 objectarray 中移除,但是 objectarray.pop()如果我在函数中这样使用它似乎不起作用:

if (object.y == stage.stageHeight)
objectarray.pop()

正如我在 .pop() 之前和之后尝试 trace()array.length,但它一直在上升每个定时器周期加一。 另一个更大的问题是我想知道您是否允许将通常放置在任何类的 main 函数下方的 .addEventListeners 放入语句循环中.就像我有

class extends Main {
class function() {
for (var i:Number = 0; i < objectarray.length; i++){
objectarray[i].addEventListener(Event.ENTER_FRAME, collision);}}

然后,如果允许的话,程序似乎无论如何也没有进入同一个类的碰撞函数。

function collision (event:Event) : void{
if (this.hitTestObject(object)){
trace('hit');}}

所以我搜索并最终添加了一个

var clip:MovieClip = MovieClip(e.target);

在函数的第一行,但后来它不起作用,我意识到我不明白它的意思是什么,发生了什么以及这个转换的语法是什么。 非常感谢。 编辑/更新:添加更多我的代码,尽管我讨厌这样复制粘贴。这是当另一个类的对象碰到它时将要改变的符号类

 public class Head extends Main {

        public function Head(){
            this.stop();
            for (var i:Number = 0; i < nicesnowflakearray.length; i++){
                nicesnowflakearray[i].addEventListener(Event.ENTER_FRAME, snowhit);
            }
        }

        public function snowhit(event:Event) : void {
            if (this.hitTestObject(nicesnowflake)){ 
//I changed this line to (e.currentTarget.hitTestObject(nicesnowflake)) as Atriace suggested, but nothing changed, and I just don't understand why my version wouldn't work.
                trace("hit");
            }
        }

这是生成应该击中 Head 对象的对象的类:

public class Main extends MovieClip {
        public var nicesnowflake: fallingsnow;
        var nicesnowflakespawntimer: Timer = new Timer(1000);
        public var nicesnowflakearray: Array = new Array(); 
        public function Main() {
            nicesnowflakespawntimer.addEventListener(TimerEvent.TIMER, nicesnowflakespawn);
            nicesnowflakespawntimer.start();
        }

        public function nicesnowflakespawn(event:TimerEvent) : void {
            nicesnowflake = new fallingsnow;
            nicesnowflake.x = Math.random()* stage.stageWidth;
            nicesnowflake.y = - stage.stageHeight + 100;
            nicesnowflakearray.push(nicesnowflake);
            stage.addChild(nicesnowflake);
            trace(nicesnowflakearray.length);
        }

【问题讨论】:

    标签: arrays actionscript-3 target


    【解决方案1】:

    为什么是两个,而不是一个?

    每当您扩展另一个类时,它都会隐式调用父类的构造函数。我们将其称为super(),并且非常方便。这就是为什么您在跟踪语句中得到双打的原因。从技术上讲,you can choose not to call super()

    .pop()

    It should 从该数组中删除最后一个元素,但是,我认为如果任意对象离开舞台,则不能保证它将是最后一个元素。所以,你想要splice()

    if (object.y == stage.stageHeight) {
        objectarray.splice(objectarray.indexOf(object), 1)
    }
    

    事件监听器

    我没有追随你的困惑,所以我会尝试重写我认为你正在尝试做的事情。

    package {
        import flash.display.MovieClip;
    
        public class Main extends MovieClip {
            private var objectarray:Array = []; // Note, I haven't populated it with anything, I'm assuming you have.
            private var theWall:MovieClip = new MovieClip(); // I haven't added this to the stage, or given it shape. You need to for hitTestObject to work.
    
            public function Main() {
                // This is your constructor.
                for (var i:Number = 0; i < objectarray.length; i++) {
                    objectarray[i].addEventListener(Event.ENTER_FRAME, collision);
                }
            }
    
            private function collision(e:Event):void {
                if (e.currentTarget.hitTestObject(theWall)) {
                    trace('hit');
                }
            }
        }
    }
    

    值得注意的是,如果有问题,您可能需要查看hitTestObject() 的指南。

    【讨论】:

    • 非常感谢您的回答,但我想我只是不明白我是否可以使用我从 Flash 中的绘图创建的类来使用 hittestobject()。如果它在屏幕上,它不是自动添加到舞台上的吗?还是我还必须将其添加到代码中才能正常工作?
    • 把你的类想象成一个容器(就像任何其他电影剪辑一样)。如果您向其中添加内容,然后将类添加到舞台,它是可见的。但是,即使您将子元素作为类的父元素,如果该类不在舞台上,它也不可见。我会看看你修改后的代码(接近午餐时间)。
    • 所有这些信息和建议让我忙了一阵子。不过不得不去上班,现在我ve come to some more precise questions. Hope you are still there. Firstly, putting the **super()** call into an impossible statement in my **child** class did not change a thing. Only code I have in it now is public class Head extends Main { public function Head(){ if (false){ super(); } this.stop(); } } }` 我需要它作为一个单独的类,因为它与角色分开动画。除非我对 FlashCS6 不了解,否则完全有可能。
    • 还有一件事是关于填充数组。 TWO 的问题仍然存在,因为我似乎无法摆脱 child 类中的隐式实例化,但是如果我摆脱函数中的实例化,那么它甚至不会在子类中复制任何内容。但是,当我 trace() 动态对象数组 nicesnowflakearray.length 它只执行 trace()两次,而不是 nicesnowflakearray.push(nicesnowflake) 如果构造函数重复代码,为什么它只添加到数组中一次,但跟踪两次?