【问题标题】:Action Script 3. Delete object when mouse clicked动作脚本 3. 单击鼠标时删除对象
【发布时间】:2013-05-23 14:17:50
【问题描述】:

我正在创建Flash游戏,Idea是从天上掉下来的物体(在这种情况下是苹果),玩家需要点击苹果,点击苹果后必须删除它并更新分数10分。

这是我生成苹果的部分代码:

  public function startGame()
            {
                speed = C.PLAYER_SPEED;
                gravity = C.GRAVITY;
                score = C.PLAYER_START_SCORE;
                randomChance = C.APPLE_SPAWN_CHANCE;
                apples = new Array();

                mcGameStage.addEventListener(Event.ENTER_FRAME,update);

            }       

            private function update(evt:Event)
            {

                //Spawn new apples
                if (Math.random() < randomChance)
                {
                    var newApple = new Apple();
                    newApple.x = Math.random() * C.APPLE_SPAWN_END_X + C.APPLE_SPAWN_START_X;

                    newApple.y = C.APPLE_START_Y;
                    apples.push(newApple);

                    mcGameStage.addChildAt(newApple,0);
                }           
                //Move Apples
                for (var i = apples.length-1; i >= 0; i--)
                {
                    apples[i].y += gravity;

                    if (apples[i].y > C.APPLE_END_Y)
                    {
                        mcGameStage.removeChild(apples[i]);
                        apples.splice(i,1);
                    }
                }           


                //txtScore.text = String(score);
            }

        }

这里是通过鼠标点击删除苹果的代码。但它不起作用,我没有任何错误,只是没有删除苹果。请问你能帮帮我吗?

function onClick(evt:MouseEvent):void{
            var apples = evt.target;

                for (var iz = apples.length-1; iz >= 0; iz--)
                {
                        //Register hit
                        score += C.SCORE_PER_APPLE;                 
                        mcGameStage.removeChild(apples[iz]);                
                        apples.splice(iz,1);        
                }
            }

更新

所以我的代码现在看起来像:

        public function startGame()
        {
            speed = C.PLAYER_SPEED;
            gravity = C.GRAVITY;
            score = C.PLAYER_START_SCORE;
            randomChance = C.APPLE_SPAWN_CHANCE;
            apples = new Array();

            mcGameStage.addEventListener(Event.ENTER_FRAME,update);

        }       

        private function update(evt:Event)
        {

            //Spawn new apples
            if (Math.random() < randomChance)
            {
                var newApple = new Apple();
                newApple.x = Math.random() * C.APPLE_SPAWN_END_X + C.APPLE_SPAWN_START_X;

                newApple.y = C.APPLE_START_Y;
                apples.push(newApple);
                newApple.addEventListener(MouseEvent.CLICK, onClick);

                mcGameStage.addChildAt(newApple,0);
            }           
            //Move Apples
            for (var i = apples.length-1; i >= 0; i--)
            {
                apples[i].y += gravity;

                if (apples[i].y > C.APPLE_END_Y)
                {
                    mcGameStage.removeChild(apples[i]);

                    apples.splice(i,1);
                }
            }           


            txtScore.text = String(score);
        }
        function onClick(evt:MouseEvent):void{
            var apples = evt.target;
        apples.visible = false;
        //mcGameStage.removeChild(apples);      
        score += C.SCORE_PER_APPLE; 

        }
    }
}

我用这个apples.visible = false; 代替mcGameStage.removeChild(apples);,没关系。 只是我误解了为什么我的分数没有更新?始终显示 0。 有时我无法通过1单击将苹果设置为不可见如果单击苹果顶部没有任何反应,我需要单击苹果的中心来隐藏它,为什么会出现这个问题?

【问题讨论】:

  • 当您更改分数(即在 onClick 中)并在此之后立即检查值时,它仍然是零吗?你在哪里定义分数?
  • 感谢您的回答。我修复了它,这是因为在 textField 中输入了“0”,当我删除它时,现在计数正确。
  • 那么,你的问题解决了吗?

标签: actionscript-3 flash object actionscript


【解决方案1】:

如果您认真对待游戏开发,则应该考虑代码膨胀问题。在您的情况下,您不需要任何 apples 数组 - 您的显示列表(由 Flash Player 提供)已经能够将苹果包含在排序的链表结构中 - 对于您打算使用它的类型更有效 - 删除并添加苹果。如果您将容器精灵专门用于包含苹果,您将获得两个好处:1)您可以获得免费的苹果显示列表和 2)如果您为此精灵(仅包含苹果)注册鼠标单击事件侦听器,那么每次单击在苹果上,event.target 会反映出来。

仔细查看修改后的代码:

public function startGame()
{
    speed = C.PLAYER_SPEED;
    gravity = C.GRAVITY;
    score = C.PLAYER_START_SCORE;
    randomChance = C.APPLE_SPAWN_CHANCE;

    mcApples = new Sprite();
    mcApples.addEventListener(MouseEvent.CLICK, onClickApple);

    mcGameStage.addChild(mcApples);

    mcGameStage.addEventListener(Event.ENTER_FRAME, update);
}

private function update(evt:Event)
{
    //Spawn new apple
    if(Math.random() < randomChance)
    {
        var newApple = new Apple();

        newApple.x = Math.random() * C.APPLE_SPAWN_END_X + C.APPLE_SPAWN_START_X;
        newApple.y = C.APPLE_START_Y;

        mcApples.addChild(newApple);
    }

    //Move Apples
    for (var i = 0; i < mcApples.numChildren;)
    {
        var apple = mcApples.getChildAt(i);

        apple.y += gravity;

        if(apple.y > C.APPLE_END_Y)
        {
            apple.parent.removeChild(apple);
            continue;
        }

        i++;
    }
}

function onClickApple(event: MouseEvent):void
{
    var apple : Apple = event.target;

    apple.parent.removeChild(apple);

    score += C.SCORE_PER_APPLE;
}

因此,重要的变化及其影响如下:

  1. 添加和删除苹果的专用精灵mcApples
  2. 不需要苹果数组,Flash Player 会跟踪 mcApples 容器中的苹果。
  3. 鼠标点击监听器设置保证任何点击都是在苹果上。

因此,不需要拼接数组,也不需要在Apple 类中显式引用函数或为每个新苹果添加事件监听器。

作为额外的建议,您应该小心地将您的逻辑绑定到enter frame 事件 - 帧速率越快,调用频率越快 - 通常没问题,但有时不是您想要的。我会将update 调用绑定到计时器事件;-)

【讨论】:

  • 谢谢,但我在使用这个时遇到了一些错误:img40.imageshack.us/img40/1463/qqqzi.png
  • 也许我需要添加private var mcApples:....,但我不知道该使用哪种类型:Object:ContainerController,但这些不起作用。
  • 嗯,显示对象可能包含其他对象,其中Sprite是一个例子,都是DisplayObjectContainer的子类,但是由于它是一个抽象类,我们使用Sprite .所以,var mcApples: Sprite。另外,我在脑海中写下了这个例子,从来没有编译过。我相信你知道如何修复编译错误,把它当作一个练习 ;-)
【解决方案2】:
        private function update(evt:Event)
        {

            //Spawn new apples
            if (Math.random() < randomChance)
            {
                var newApple = new Apple(appleClick);
                newApple.x = Math.random() * C.APPLE_SPAWN_END_X + C.APPLE_SPAWN_START_X;

                newApple.y = C.APPLE_START_Y;
                apples.push(newApple);
                mcGameStage.addChildAt(newApple,0);
            }           
            //Move Apples
            for (var i = apples.length-1; i >= 0; i--)
            {
                apples[i].y += gravity;

                if (apples[i].y > C.APPLE_END_Y)
                {
                    mcGameStage.removeChild(apples[i]);
                    apples[iz].destruct();
                    apples.splice(i,1);
                }
            }           


            //txtScore.text = String(score);
        }

        function appleClick(pApple:Apple):void{
            for (var iz = apples.length-1; iz >= 0; iz--)
            {
                    if (apples[iz] == pApple)
                    {
                        //Register hit
                        score += C.SCORE_PER_APPLE;                 
                        mcGameStage.removeChild(apples[iz]);
                        apples[iz].destruct();
                        apples.splice(iz,1);
                        break;
                    }
            }
        }

....

public class Apple extends Group or something
{
    private var m_fCallback:Function;

    public function Apple(pCallback:Function):void
    {
        addEventListener(MouseEvent.CLICK, onClick);
        m_fCallback = pCallback;
    }

    private function destruct():void
    {
        removeEventListener(MouseEvent.CLICK, onClick);
    }

    private function onClick(pEvent:MouseEvent):void
    {
        m_fCallback(this);
    }
}

【讨论】:

  • 谢谢你的回答,现在当我使用trace onClick函数trace("test");它写正确,只是没有删除苹果
  • 因其他原因再次编辑。抱歉,我一直被办公室里发生的事情分心,现在校对答案并不轻松。抱歉,我有点急于赶时间并发布答案,但我会尝试再次检查它。主要问题是苹果没有添加事件监听器。
  • 感谢您的回答,但我误解了您为什么要创建新课程?这种情况更好吗?我更新了我的问题,我的代码现在的样子。
  • 在内存和(可能)运行时速度方面效率很低。
  • 好吧,这段代码现在应该没问题了。从您的代码来看,Apple 已经是一个单独的类,而且我个人不习惯使用 Event.target (尽管我可能应该这样做),所以我不能指望给你一个使用它的答案。您似乎在编辑中提到单击堆叠的苹果一次只能处理其中一个; click 事件只会去到任何 UIComponent 的最上面的一切,所以你必须添加特殊的逻辑来处理它。
【解决方案3】:

我没有看到为 onClick() 添加了任何事件侦听器。请务必检查您的事件侦听器是否已添加,并在您的 onClick() 函数中添加跟踪或警报,以便您确认代码已实际到达。

【讨论】:

  • 谢谢你的回答,现在当我使用 trace onClick 函数 trace("test");它写入正确,只是不删除苹果
  • 您可以尝试将苹果的可见性设置为 false 以查看是否有所不同。否则它一定是试图移除错误的苹果。
  • 谢谢,将可见设置为 false。也许你知道我点击苹果顶部没有隐藏是什么问题,我必须点击苹果中心才能隐藏它。
  • 也许你知道为什么我的分数没有变化,总是显示 0
  • 如果不知道您将事件侦听器的确切放置位置,这很难说。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-10
  • 1970-01-01
  • 1970-01-01
  • 2013-06-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多