2013-12-16 22 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()功能,你想要的任何幀...