【发布时间】:2014-01-03 23:43:35
【问题描述】:
我正在根据教程制作一个小游戏,您可以用光标点击小豆腐并收集点数和准确性 - 我已经实现了一个开始按钮,该按钮可以工作并转到游戏开始的第 (2) 帧。
我想创建一个停止按钮,但是当我在场景中制作一个按钮时 - 该按钮不起作用(无法点击它)并且当我点击豆腐时它会收到 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);
}
}
【问题讨论】:
-
显然您需要学习如何正确清理正在运行的游戏。您有一组像样的向下飞的豆腐和一个点击监听器 - 您需要小心地将所有飞扬的豆腐从舞台上移开,将它们从监听器中剥离,移除所有其他监听器,然后使用开始按钮返回到第 1 帧。这是一个普遍的想法。
-
感谢维斯帕!我在 AS3 上有点菜鸟,但基本上我需要为舞台对象删除EventListener,我可以想象我还需要删除 Mouse.Hide 函数。我想也许可以改变舞台的宽度/高度并添加一个没有舞台的菜单..
-
改变舞台的宽度和高度并不是一件容易的事(这是可行的,但是通过外部调用),但是将菜单放在舞台可见区域之外的某个地方是处理菜单隐藏的常用方法之一/显示。确保禁用从其他地方跳转到菜单的选项卡,否则玩家可以通过选项卡访问菜单并导致不良游戏行为。
标签: actionscript-3 flash flash-cs5