【问题标题】:Enemy and Bullet movie clips freeze when Bullet movie clips enter on the stage - AS3 - CS6当子弹影片剪辑进入舞台时,敌人和子弹影片剪辑会冻结 - AS3 - CS6
【发布时间】:2014-01-07 08:01:54
【问题描述】:

我正在为大学作业制作一个自上而下的射击游戏。当我按下鼠标左键射击子弹时,当它们与跟随播放器影片剪辑的敌方影片剪辑碰撞时它们会冻结,当发生这种情况时,仍然可以使用箭头键移动播放器影片剪辑,因此 SWF 没有崩溃。

敌人和子弹影片剪辑被放置在一个数组中,并且都应该在相互碰撞时被移除。

当子弹影片剪辑进入舞台时,我在输出窗口中收到此错误消息

子弹击中坏人 0

TypeError:错误 #1034:类型强制失败:无法将 flash.display::Stage@2862e041 转换为 flash.display.MovieClip。

在 Bullet/removeSelf()

在 Bullet/loop() 处

在 Main/loop()

bullet hit baddie 0 之所以存在是因为它在代码中被跟踪。

Main.as

package
{
import flash.display.Stage;
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;

public class Main extends MovieClip
{
    public var player:Player;
    public var enemy:Enemy;

    public var bulletList:Array = [];

    public var mousePressed:Boolean = false; //keeps track of whether the mouse is currently pressed down
    public var delayCounter:int = 0; //this adds delay between the shots
    public var delayMax:int = 7; //change this number to shoot more or less rapidly
     
    var enemies:Array =  [];

    public function Main():void
    {
        player = new Player(stage, 320, 240);
        stage.addChild(player);

        //stage.addEventListener(MouseEvent.CLICK, shootBullet, false, 0, true); //remove this
        stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler, false, 0, true);
        stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler, false, 0, true);

        stage.addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
        for(var numBaddies=0; numBaddies<6;numBaddies++){
            var enemy:Enemy = new Enemy(null);
            enemy.x = numBaddies*50;
            enemy.y = numBaddies*50
            stage.addChild(enemy);
            enemies.push(enemy);
        }
    }

    public function loop(e:Event):void
    {
        if(mousePressed) // as long as the mouse is pressed...
        {
            delayCounter++; //increase the delayCounter by 1
            if(delayCounter == delayMax) //if it reaches the max...
            {
                shootBullet(); //shoot a bullet
                delayCounter = 0; //reset the delay counter so there is a pause between bullets
                
           }
        }

        if(bulletList.length > 0)
        {
            for(var i:int = bulletList.length-1; i >= 0; i--)
            {
                bulletList[i].loop();
            }
        }
        
        for(var h = 0; h<bulletList.length; ++h)
        {
            if(bulletList[h].hitTestObject(this)){
              trace("player hit by baddie " + h);
               }
        }
        
        for(var u:int=0; u<enemies.length; u++) {
        Enemy(enemies[u]).moveTowards(player.x, player.y);
        }
    }
    

    public function mouseDownHandler(e:MouseEvent):void //add this function
    {
        mousePressed = true; //set mousePressed to true
    }

    public function mouseUpHandler(e:MouseEvent):void //add this function
    {
        mousePressed = false; //reset this to false
    }

    public function shootBullet():void //delete the "e:MouseEvent" parameter
    {
        var bullet:Bullet = new Bullet(stage, player.x, player.y, player.rotation, enemies);
        bullet.addEventListener(Event.REMOVED_FROM_STAGE, bulletRemoved, false, 0, true);
        bulletList.push(bullet);
        stage.addChild(bullet);
    }

    public function bulletRemoved(e:Event):void
    {
        e.currentTarget.removeEventListener(Event.REMOVED_FROM_STAGE, bulletRemoved);
        bulletList.splice(bulletList.indexOf(e.currentTarget),1);
    }
}
}

Enemy.as

package  {

import flash.display.Stage;
import flash.display.MovieClip;
import flash.events.Event;

public class Enemy extends MovieClip {
    
    public var bullets:Array;
    public var stageRef:Stage;

    private var enemyPositionX, enemyPositionY,xDistance,yDistance,myRotation:int;
    public function Enemy(bulletList:Array) {
        // constructor code
        bullets = bulletList;
    }
    
    public function moveTowards(playerX:int, playerY:int){
        xDistance = this.x - playerX;
        yDistance = this.y - playerY;


        myRotation = Math.atan2(yDistance, xDistance);

        this.x -= 3 * Math.cos(myRotation);
        this.y -= 3 * Math.sin(myRotation);
        
        
    }

    public function loopE():void{
    
    for(var i=0; i<bullets.length; ++i)
        {
            if(bullets[i].hitTestObject(this)){
               trace("you killed enemy " + i);
               removeSelf();
               }
        }
    }
    
    private function removeSelf()
    {
        removeEventListener(Event.ENTER_FRAME, loopE);
        if (stageRef.contains(this))
        stageRef.removeChild(this);
    }
}

}

Bullet.as

package
{
import flash.display.Stage;
import flash.display.MovieClip;
import flash.events.Event;

public class Bullet extends MovieClip
{
    private var stageRef:Stage; //checks if the bullet leaves the screen borders
    private var speed:Number = 10; //speed that the bullet will travel at
    private var xVel:Number = 0; //current x velocity
    private var yVel:Number = 0; //current y velocity
    private var rotationInRadians = 0; //convenient to store our rotation in radians instead of degrees
    private var allBaddies:Array;
    //our constructor requires: the stage, the position of the bullet, and the direction the bullet should be facing
    public function Bullet(stageRef:Stage, X:int, Y:int, rotationInDegrees:Number, enemies:Array):void
    {
        this.stageRef = stageRef;
        this.x = X;
        this.y = Y;
        this.rotation = rotationInDegrees;
        this.rotationInRadians = rotationInDegrees * Math.PI / 180; //convert degrees to radians, for trigonometry
        allBaddies = enemies;
    }
    
    public function loop():void //we don't need to include the "e:Event" because we aren't using an EventListener
    {
        for(var b=0; b<allBaddies.length; ++b)
        {
            if(allBaddies[b].hitTestObject(this)){
               trace("bullet hit baddie " + b);
               removeSelf();
               }
        }
        
        xVel = Math.cos(rotationInRadians) * speed; //uses the cosine to get the xVel from the speed and rotation
        yVel = Math.sin(rotationInRadians) * speed; //uses the sine to get the yVel

        x += xVel; //updates the position
        y += yVel;

        //if the bullet goes off the edge of the screen...
        if(x > stageRef.stageWidth || x < 0 || y > stageRef.stageHeight || y < 0)
        {
            this.parent.removeChild(this); //remove the bullet
        }
    }
    
    private function removeSelf()
    {
        removeEventListener(Event.ENTER_FRAME, loop);
        if (MovieClip(root).stageRef.contains(this))
        MovieClip(root).stageRef.removeChild(this);
    }
}
}

感谢所有帮助,非常感谢。

【问题讨论】:

    标签: actionscript-3 flash movieclip flash-cs6


    【解决方案1】:

    您收到 TypeError 是因为将 root 转换为 MovieClip 失败。当您将变量括在括号中并在前面使用类型名称时,您就在断言该对象属于该类型(或扩展该类型)。在 Bullet.removeSelf() 函数中,您有:MovieClip(root) - 但在这种情况下,root 的类型为 Stage,它不会扩展 MovieClip,从而导致错误。*

    Stage 类型确实同时具有 containsremoveChild 方法,因此您可以删除强制转换。事实上,Bullet 类已经以stageRef 的形式引用了舞台,因此您可以重用它。尝试将removeSelf() 函数更改为:

    private function removeSelf():void
    {
        removeEventListener(Event.ENTER_FRAME, loop);
        if (stageRef.contains(this))
            stageRef.removeChild(this);
    }
    

    *(更多信息:root 属性的具体类型因上下文而异。有时它实际上是MovieClip;有时是Bitmap;在你的情况下,如错误所示,它是Stage - 但唯一保证的类型是 DisplayObject,这是最低公分母类型,上述类型都继承自该类型。这是关于 root 属性的 Adob​​e 文档:http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/DisplayObject.html#root)

    【讨论】:

    • 非常感谢它运行得很好,对不起我才回复,因为这个项目我前一天晚上没有睡觉所以昨天我真的很累。我现在对root 也有了更好的了解,非常感谢。我只剩下一件事要做,让敌人的动画剪辑从舞台上移除,并在与子弹动画剪辑的碰撞/碰撞时排列,我已经在 Enemy.as 中尝试过 loopE() 函数,但即使是跟踪语句'不向窗口输出任何内容。你能在这里给我一些关于我可能出错的地方吗?
    • 没问题 - 很高兴它解决了这个问题。如果不仔细研究它(这实际上是一个单独的问题/帖子),似乎根本没有调用 loopE 方法。您可能希望将调用添加到 Main.loop() 方法中,您已经在其中迭代了 enemies 数组。添加后可能会有一些后续问题需要解决,如果您对它们有特定问题,请发布一个新问题。
    • 谢谢,我会试试看会发生什么。非常感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 2014-01-28
    • 1970-01-01
    • 1970-01-01
    • 2012-05-24
    • 2017-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多