2013-12-16 20 views
0

我正在从一个教程中制作一个小游戏,你可以用光标点击小豆腐,并收集点数和准确性 - 我已经实现了一个开始按钮,可以运行并进入框架(2),游戏开始。Flash AS3:游戏停止按钮时出错?

我想创建一个停止按钮,但是当我在场景中做一个按钮 - 按钮不起作用(无法点击它),当我打豆腐它得到1009错误? (无法访问空对象引用的属性或方法。)

当我没有停止按钮时,游戏有效,但我无法退出游戏。

如何在游戏中创建停止按钮或菜单,以便用户返回到上一个场景或停止游戏?

// define some global variables which let you track the player's statistics. 
var hits:int = 0; 
var misses:int = 0; 
var shots:int = 0; 
var cDepth:int = 100; 
var level:int = 1; 

// define some runtime variables which are used in calculations. 
var xSpeed:Number = 3; 
var stageWidth:Number = 480; 
var stageHeight:Number = 580; 

/* attach the crosshair_mc movie clip instance from the Library onto the Stage. 
    This clip is used as a custom mouse cursor. */ 
var crosshairClip:MovieClip = new crosshair_mc(); 
crosshairClip.mouseEnabled = false; 
addChild(crosshairClip); 

// hide the mouse cursor 
Mouse.hide(); 

/* every time the mouse cursor moves within the SWF file, 
    update the position of the crosshair movie clip instance on the Stage. */ 
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler); 
function mouseMoveHandler(event:MouseEvent):void { 
    crosshairClip.x = event.stageX; 
    crosshairClip.y = event.stageY; 
}; 
/* when the mouse button is clicked, check to see if the cursor is within the boundaries of the Stage. 
    If so, increment the number of shots taken. */ 
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler); 
function mouseDownHandler(event:MouseEvent):void { 
    if (bg_mc.hitTestPoint(event.stageX, event.stageY, false)) { 
     shots++; 
     updateStats(); 
    } 
}; 

// define a TextFormat which is used to format the stats_txt text field. 
var my_fmt:TextFormat = new TextFormat(); 
my_fmt.bold = true; 
my_fmt.font = "Arial"; 
my_fmt.size = 12; 
my_fmt.color = 0xFFFFFF; 
// create a text field to display the player's statistics. 
var stats_txt:TextField = new TextField(); 
stats_txt.x = 10; 
stats_txt.y = 0; 
stats_txt.width = 530; 
stats_txt.height = 22; 
addChild(stats_txt); 
// apply the TextFormat to the text field. 
stats_txt.defaultTextFormat = my_fmt; 
stats_txt.selectable = false; 
updateStats(); 

// add an onEnterFrame event to the main timeline so new tofu is constantly added to the game. 
stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler); 
function enterFrameHandler(event:Event):void { 
    // randomly add new target's to the Stage. 
    if (randRange(0, 20) == 0) { 
     var thisMC:MovieClip; 
     // attach a new instance of the tofu instance from the library onto the Stage, and give it a unique depth. 
     var randomTofu:Number = randRange(1, 3); 
     switch (randomTofu) { 
      case 1: 
       thisMC = new tofu1_mc(); 
       break; 
      case 2: 
       thisMC = new tofu2_mc(); 
       break; 
      case 3: 
       thisMC = new tofu3_mc(); 
       break; 
      default: 
       return; 
       break; 
     } 

     cDepth++; 
     // set the starting postition of the current target movie clip so it is just off to the left of the Stage. 
     thisMC.x = -thisMC.width; 
     /* create a random number between 80 and 100. 
      This is used to set the current movie clip's scale, 
      alpha and speed that it moves across the Stage. */ 
     var scale:int = randRange(80, 100); 
     /* set the _xscale and _yscale properties of the current movie clip. 
      This allows for some minor variations of the targets within the game. */ 
     thisMC.scaleX = scale/100; 
     thisMC.scaleY = scale/100; 
     thisMC.alpha = scale/100; 
     thisMC.speed = xSpeed + randRange(0, 3) + level; 
     /* set a random _y value for the target. 
      Now, instead of all targets flying along the same path, 
      they vary their vertical position slightly. */ 
     thisMC.y = Math.round(Math.random() * 350) + 65; 
     thisMC.name = "tofu" + cDepth; 
     /* create an onEnterFrame handler that executes a couple dozen times per second. 
      Update the target's position on the Stage. */ 
     thisMC.addEventListener(Event.ENTER_FRAME, tofuEnterFrameHandler); 
     thisMC.addEventListener(MouseEvent.CLICK, tofuClickHandler); 
     addChild(thisMC); 
     // swap the custom cursor to the higher depth 
     swapChildren(thisMC, crosshairClip); 
    } 
}; 
/* create a function to update the player's statistics on the Stage. 
    You're displaying number of shots taken, number of targets "hit", 
    number of targets "missed", the percentage of hits vs misses, 
    overall accuracy (number of shots taken vs number of hit targets). */ 
function updateStats() { 
    var targetsHit:Number = Math.round(hits/(hits+misses)*100); 
    var accuracy:Number = Math.round((hits/shots)*100); 
    if (isNaN(targetsHit)) { 
     targetsHit = 0; 
    } 
    if (isNaN(accuracy)) { 
     accuracy = 0; 
    } 
    stats_txt.text = "shots:"+shots+"\t"+"hits: "+hits+"\t"+"misses: "+misses+"\t"+"targets hit: "+targetsHit+"%"+"\t"+"accuracy: "+accuracy+"%"+"\t"+"level:"+level; 
} 

/* create a function that returns a random integer between two specified numbers. 
    This allows you to add some subtle differences in size and speed for the movie clips on the Stage. */ 
function randRange(minNum:Number, maxNum:Number):Number { 
    return (Math.floor(Math.random() * (maxNum - minNum + 1)) + minNum); 
} 


function tofuEnterFrameHandler(event:Event):void { 
    var tofuMC:MovieClip = event.currentTarget as MovieClip; 
    /* move the target horizontally along the Stage. 
     Currently all targets will move from left to right. */ 
    tofuMC.x += tofuMC.speed; 
    /* slightly decrement the _y position of the current target movie clip. 
    This makes it appear like the targets are flying slightly higher as they move across the Stage. */ 
    tofuMC.y -= 0.4; 
    /* if the current position of the target is no longer on the Stage, 
     count the target as a "miss" and delete the instance. 
     If the instance wasn't deleted from the Stage, 
     the user's computer would eventually slow to a crawl. */ 
    if (tofuMC.x > stageWidth) { 
     misses++; 
     updateStats(); 
     removeChild(tofuMC); 
     tofuMC.removeEventListener(Event.ENTER_FRAME, tofuEnterFrameHandler); 
    } 
} 

// when the target movie clip instance is pressed, count it as a "hit". 
function tofuClickHandler(event:MouseEvent):void { 
    var tofuMC:MovieClip = event.currentTarget as MovieClip 
    // update the player's stats 
    hits++; 
    if ((hits%40) == 0) { 
     level++; 
    } 
    updateStats(); 
    /* go to the movie clip's label named "hit" 
     (which allows you to show a clever animation when the instance is hit.) */ 
    tofuMC.gotoAndPlay("hit"); 
    // create an onEnterFrame event for the current movie clip instance. 
    tofuMC.addEventListener(Event.ENTER_FRAME, tofuHitEnterFrameHandler); 
    /* delete the onPress event handler. 
     This makes it so the target cannot continually be clicked while it is falling from the sky. */ 
    tofuMC.removeEventListener(MouseEvent.CLICK, tofuClickHandler); 
    tofuMC.removeEventListener(Event.ENTER_FRAME, tofuEnterFrameHandler); 
} 

function tofuHitEnterFrameHandler(event:Event):void { 
    var tofuMC:MovieClip = event.currentTarget as MovieClip; 
    // set some local variables that you'll use to animate the target falling from the sky. 
    var gravity:int = 20; 
    var ymov:int = tofuMC.y + gravity; 
    // ***** xmov *= 0.5; 
    // increment the rotation of the current movie clip clock-wise by 5 degrees. 
    tofuMC.rotation += 5; 
    /* set the _x and _y properties of the movie clip on the Stage, 
     this allows us to make the target look like it is semi-realistically 
     falling from the sky instead of just dropping straight down. */ 
    tofuMC.x += xSpeed; 
    tofuMC.y = ymov; 
    /* after the _y position is off of the Stage, 
     remove the movie clip so that the coordinates aren't continually calculated */ 
    if (tofuMC.y > stageHeight) { 
     removeChild(tofuMC); 
     tofuMC.removeEventListener(Event.ENTER_FRAME, tofuHitEnterFrameHandler); 
    } 
} 
+0

显然你需要学习如何做一个正在运行的游戏适当的清理。你有一套体面的豆腐向下飞,还有一个咔哒咔哒的听众 - 你需要小心地把所有的飞豆腐从舞台上移开,将它们从听众身上剥离,除去所有其他听众,然后用开始按钮返回第1帧。这是一个普遍的想法。 – Vesper

+0

谢谢Vesper!我在AS3有点小气,但基本上我需要removeEventListener为舞台对象,我可以想象我也需要删除Mouse.Hide函数。我想也许人们可以改变舞台的宽度和高度,并添加一个舞台不存在的菜单.. – KevinDasman

+0

改变舞台的宽度和高度并不是一件容易的事(它是可行的,但通过外部呼叫),但将菜单放置在室外舞台的可见区域是处理菜单隐藏/显示的常用方式之一。确保禁用从其他地方跳转到菜单的选项卡,否则玩家可以通过选项卡访问菜单并导致不希望的游戏行为。 – Vesper

回答

0

舞台上感到困惑,因为当你改变帧不存在某些对象,所以你必须从stage删除所有事件:

stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler); 
stage.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler); 
stage.removeEventListener(Event.ENTER_FRAME, enterFrameHandler); 

然后你就可以调用gotoAndStop()功能,你想要的任何帧...