我在点击检测方面遇到问题

时间:2016-01-11 14:36:25

标签: actionscript-3 flash

我无法让我的命中检测功能在as3中运行。我正在制作像游戏一样的飞鸟,当玩家死亡并回到第2帧时,我们得到错误#1009。我是新手,所以如果你能尽可能简单,那就非常感激。谢谢!这是我的代码。

import flash.events.Event;

stage.addEventListener(MouseEvent.CLICK, fl_MouseClickHandler);

function fl_MouseClickHandler(event:MouseEvent):void
{
    player.y += -100;
}

var randomX:Number = Math.random() * 550;
player.x = 50;
player.y = 50;

var speed:Number = 5;

player.addEventListener(Event.ENTER_FRAME, moveDown);

function moveDown(e:Event):void {
    e.target.y += speed; 

    if(e.target.y >= 400) {

        {
            gotoAndStop(2);
            player.removeEventListener(Event.ENTER_FRAME, moveDown);

        }
    }
}
var gravity = 8;

    stage.addEventListener(Event.ENTER_FRAME, movewt);
function movewt(e:Event):void 
{
    wt.x = wt.x - 5;
}

stage.addEventListener( Event.ENTER_FRAME, handleCollision)

function handleCollision( e:Event ):void
{
    if(player.hitTestObject(wt))
       {
         gotoAndStop(2);
         stage.removeEventListener(MouseEvent.CLICK, fl_MouseClickHandler);
         player.removeEventListener(Event.ENTER_FRAME, moveDown);
         stage.removeEventListener(Event.ENTER_FRAME, movewt);
         stage.removeEventListener( Event.ENTER_FRAME, handleCollision);


       }
}

1 个答案:

答案 0 :(得分:0)

问题

当此代码转到第2帧时

if(e.target.y >= 400) 
{
    {
        gotoAndStop(2);
        player.removeEventListener(Event.ENTER_FRAME, moveDown);

    }
}

它只从ENTER_FRAME中删除player事件侦听器,所有其他处理程序仍然存在,即:

  1. fl_MouseClickHandler
  2. movewt
  3. handleCollision
  4. 后两者是自己执行的,这使得它们成为问题,因为它们访问的对象不一定存在于第2帧。

    movewt访问wthandleCollision访问playerwt。如果第2帧中不存在playerwt,则它们为null

    解决方案

    不要使用框架!虽然基于框架构建导航似乎非常容易,但很快就会遇到类似问题的问题。框架是为动画而制作的,他们非常擅长这样做,因此请使用它们。如何不使用框架超出了本答案的范围,网上有很多关于如何做到这一点的资源。大多数游戏框架甚至没有框架并且为此目的使用状态机。强烈建议您了解游戏框架如何处理此问题。

    另一个问题是您在帧之间切换的方式不一致。有时你删除一个事件监听器,有时你删除其他一些...你只是忘了删除所有这些吗? 为什么你首先要有这种重复的逻辑?如果你有不同的游戏状态(例如,游戏本身,目前在第1帧(或者您发布的代码所在的任何帧)以及第2帧的游戏屏幕),那么您应该有一个明确定义的方式在两个状态之间转换。

    如果您想进入游戏结束状态,请使用一个执行此操作的功能并执行该功能中的所有清理工作:

    function gameOver():void
    {
        gotoAndStop(2);
        stage.removeEventListener(MouseEvent.CLICK, fl_MouseClickHandler);
        player.removeEventListener(Event.ENTER_FRAME, moveDown);
        stage.removeEventListener(Event.ENTER_FRAME, movewt);
        stage.removeEventListener( Event.ENTER_FRAME, handleCollision);
    }
    

    现在,每当你想要改变到那个状态时,无论是因为等级的结束还是因为碰撞,都要调用那个函数:

    import flash.events.Event;
    
    var speed:Number = 5;
    var gravity = 8;
    var randomX:Number = Math.random() * 550;
    
    player.x = 50;
    player.y = 50;
    
    stage.addEventListener(Event.ENTER_FRAME, movewt);
    stage.addEventListener( Event.ENTER_FRAME, handleCollision);
    player.addEventListener(Event.ENTER_FRAME, moveDown);
    stage.addEventListener(MouseEvent.CLICK, fl_MouseClickHandler);
    
    function fl_MouseClickHandler(event:MouseEvent):void
    {
        player.y += -100;
    }
    
    function moveDown(e:Event):void 
    {
        e.target.y += speed; 
    
        if(e.target.y >= 400) 
        {
            gameOver();
        }
    }
    
    function movewt(e:Event):void 
    {
        wt.x = wt.x - 5;
    }
    
    function handleCollision(e:Event):void
    {
        if(player.hitTestObject(wt))
        {
            gameOver();
        }
    }
    
    function gameOver():void
    {
        gotoAndStop(2);
        stage.removeEventListener(MouseEvent.CLICK, fl_MouseClickHandler);
        player.removeEventListener(Event.ENTER_FRAME, moveDown);
        stage.removeEventListener(Event.ENTER_FRAME, movewt);
        stage.removeEventListener( Event.ENTER_FRAME, handleCollision);
    }
    

    同样,理想情况下,您将使用一个提供代表游戏状态的类的框架。这允许在状态之间明确定义的转换: 正如代码现在所示,您必须记住,应该调用gameOver()以便正确转换到游戏结束状态,您仍然可以通过其他方式执行此操作。有了图书馆,没有“其他方式”,只有一个。但就目前而言,gameOver()将会解决您的问题。