【问题标题】:Perform Hit Test on anonymous object对匿名对象执行命中测试
【发布时间】:2012-04-24 22:05:39
【问题描述】:

我有一个用 AS3 制作的基本太空射击游戏。

游戏目前由一个敌人和玩家组成 - 一个可移动的炮塔。

游戏的前提是,当敌人被击中时,它会重生,玩家得分上升一分。

现在我想通过在比赛场地上拥有多个敌人来扩展游戏。每一波敌人的数量可能不同,所以我真的不想单独跟踪它们。

当我想创建一个敌人时,我会调用(在我的主类中)

this.addChild(createNewEnemy());

使用 createNewEnemy() 函数创建并返回匿名 Enemy 对象。

我的问题是,如何在玩家发射子弹的情况下对这些匿名敌人进行命中测试?当敌人与子弹相撞时,应将其移除并增加分数。

【问题讨论】:

    标签: actionscript-3 hittest


    【解决方案1】:

    我不太清楚您所说的“匿名对象”是什么意思。您真的应该以可以跟踪它们的方式创建这些东西。一种方法可能是覆盖容器精灵的 addChild 方法并将新敌人推送到向量。示例:

    var enemies:Vector.<Enemy> = new Vector.<Enemy>();
    
    override public function addChild(child:DisplayObject):DisplayObject
    {
        if(child is Enemy) {
           enemies.push(child);
        }
        super.addChild(child);
    }
    

    现在您可以简单地针对敌人向量进行测试,或者在您的子弹碰撞中使用相同的“is”关键字来检查碰撞显示对象是否为基于类型的Enemy

    至于实际做碰撞检测的代码,请看下面的回答:https://stackoverflow.com/a/7083965/562566

    【讨论】:

    • 我想看看我是否可以在不追踪所有敌人的情况下逃脱。似乎这是不可能的。至少现在矢量使它更容易!请注意语法中的一些错误:它应该是 Vector. 并且 addChild 方法需要返回一个 DisplayObject。所以我简单地返回了 super.addChild(child) 方法,它就不再抱怨了。
    • 对,对不起!我只是在脑海中输入它,并没有费心检查任何东西。我会编辑答案。
    • 我不知道为什么 Adob​​e 在他们的模板参数括号前加上一个句点……太傻了。习惯于在 C++ 中执行此操作,因此我的代码中出现错误。很高兴它对你有用。
    • 我认为这与 AS3 没有任何泛型有关。 Vector 是一种特殊情况。
    【解决方案2】:

    你好!

    我不太明白您所说的“匿名”是什么意思,但其中一种解决方案是创建所谓的 hitboxes

    假设你有一个 Enemy 类:

    public class Enemy {
        public var hitBox:Sprite = new Sprite() ;
    
        public function Enemy() {
            hitBox.graphics.clear() ; /* Not filled by a color, as needs to be invisible */
            hitBox.graphics.drawRect(x,y,width,height) ; /* Adjust the parameters manually */
            this.addChild(hitBox) ;
        }
    }
    

    有很多敌人,所以只需创建enemyArray 并将敌人推入其中。 这是玩家的子弹:

    public class PlayerBullet extends Sprite {
        private var stageReference:Stage ;
        public function PlayerBullet(coord:Point, stageReference:Stage){
            this.x = coord.x ;
            this.y = coord.y ;
            this.stageReference = stageReference ;
            this.stageReference.addChild(this) ;
            this.addEventListener(Event.ENTER_FRAME, loop) ;
        }
    
        private function loop(e:Event){
    
            /*Provide some movement for bullet by changing or incrementing
              this.x and this.y as you wish */
    
            for (var i:Number = 0 ; i < enemyArray.length ; i++){
              if (this.hitTestObject(enemyArray[i].hitBox)) {
                  enemyArray.splice(i,1) ; /* Remove the enemy from enemy array on collision */
                  this.stageReference.removeChild(this) ; /* Do not display bullet anymore on collision with enemy */
              }
           }
        }
    }
    

    注意:hitboxes 只提供一些正方形区域。如果您需要碰撞的一些确切细节,请创建几个碰撞箱。

    我希望这会有所帮助! :)

    【讨论】:

    • hitTest 本身对我来说没有问题。我对匿名的意思是我在创建对象时没有给它提供变量名。我只是简单地制作,并添加到主容器中。不过还是谢谢! :)
    • 好吧,你只需执行:enemyArray.push(new Enemy()) 所以,你的敌人不会被命名,但会在数组中有自己的索引,所以你可以追踪他们及其属性:) 欢迎您!
    • 我做了类似于你建议的事情。我使用了一个向量,并且每个都使用一个简单的向量来遍历该向量。当屏幕上的敌人数量变得很多(> 1000)时,它会变得疯狂,但这只是为了演示目的,所以没关系。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多