我是 AS3 的新手,并且制作了一个简单"asteroids"
的游戏,带有一个游戏结束屏幕和一个resetButton
让用户再次玩的游戏。当用户点击重置按钮时,游戏结束屏幕和重置按钮会从舞台上移除,并且游戏本身会与 eventListeners 一起添加到舞台上。其中之一是MouseEvent.CLICK
添加到的监听器stage
,它调用一个fireBullet
函数。此函数绘制一个子弹并将其添加到舞台(代码的其他部分然后使子弹在屏幕上移动)。
我遇到的问题是,当用户单击重置按钮时,游戏结束屏幕被正确删除,并且游戏本身(玩家、小行星、事件监听器)被正确添加到舞台,但同时也会bullet
触发即使用户在点击reset button
.
我的gameOver()
功能是这样的:
stage.removeChild() all objects
stage.removeEventListener() all listeners
null out all objects
draw and add to the stage the game over text and resetButton
addEventListener(MouseEvent.CLICK, onReset) to the resetButton
然后,onReset()
函数如下所示:
stage.removeChild() the gameover text and the resetButton
call gameStart();
该gameStart()
函数如下所示:
initialize variables
draw and add player and asteroids on the screen
add eventListeners including MouseEvent.Click, fireBullet
我在每个函数上添加了跟踪以查看发生了什么,这就是流程:
added fireBullet listener //this is gameStart() function being called from Main() and adding everything to the stage the first time
fired bullet //shooting at the asteroids
fired bullet
fired bullet
fireBullet listener should have been removed //this is gameOver() being called that removes everything from the stage and adds the resetButton
clicked on reset
added fireBullet listener //gameStart() being called again from onReset() function
fired bullet //I did not click a second time after clicking on reset
我在某处读到,无论是否有任何侦听器实际上在侦听它们,事件都会一直发送,所以我怀疑我的 MouseEvent.CLICK 侦听器从单击重置按钮时开始拾取鼠标按钮单击,甚至虽然这个听众后来被添加到舞台上。
我没有足够的 AS3 或编程经验来确定这是否真的是这种情况,我可以做些什么来确保MouseEvent.CLICK
听众不会响应在它被添加到舞台之前发生的任何点击,所以任何帮助对此将不胜感激。
====
编辑
我假设我有一个逻辑问题或者对 AS3 和闪存一无所知,所以我只是使用了上面的伪代码。下面是完整的 .as 文件的链接,包括生成的 .swf 下面是完整的相关功能 https://www.dropbox.com/sh/a4rlasq8o0taw82/wP3rB6KPKS
private function startGame():void
这是从 Main 调用的
{
//initialize variables
bulletArray = [];
cleanupBullets = [];
bulletSpeed = 10;
score = 0;
asteroid1Speed = 0;
asteroid2Speed = 0;
asteroid3Speed = 0;
asteroid4Speed = 0;
//draw player and asteroids
ship = drawPlayer();
asteroid1 = drawAsteroid();
asteroid2 = drawAsteroid();
asteroid3 = drawAsteroid();
asteroid4 = drawAsteroid();
//embarrasing and inefficient code to get random number between -5 and 5 without a 0
asteroid1Speed = Math.ceil(Math.random() * 10 -5);
if (asteroid1Speed == 0)
asteroid1Speed = returnNonZero(asteroid1Speed);
asteroid2Speed = Math.ceil(Math.random() * 10 -5);
if (asteroid2Speed == 0)
asteroid2Speed = returnNonZero(asteroid2Speed);
asteroid3Speed = Math.ceil(Math.random() * 10 -5);
if (asteroid3Speed == 0)
asteroid3Speed = returnNonZero(asteroid3Speed);
asteroid4Speed = Math.ceil(Math.random() * 10 -5);
if (asteroid4Speed == 0)
asteroid4Speed = returnNonZero(asteroid4Speed);
//trace(asteroid1Speed, asteroid2Speed, asteroid3Speed, asteroid4Speed);
//add asteroids to stage
stage.addChild(asteroid1);
stage.addChild(asteroid2);
stage.addChild(asteroid3);
stage.addChild(asteroid4);
//position player and add to stage
ship.x = 40;
ship.y = 40;
stage.addChild(ship);
//add event listeners
stage.addEventListener(Event.ENTER_FRAME, onFrame);
stage.addEventListener(MouseEvent.CLICK, fireBullet);
trace("added fireBullet listener");
}
private function gameOver():void
这是从onFrame
我不包括的(称为每一帧)函数中调用的(它太大并且不完全相关)。当所有小行星都被移除时调用它。
{
//remove any remaining bullets off the screen
for each (var item:Sprite in bulletArray)
{
stage.removeChild(item);
}
//null out objects and remove listeners
bulletArray = null;
stage.removeEventListener(Event.ENTER_FRAME, onFrame);
stage.removeEventListener(MouseEvent.CLICK, fireBullet);
//check if the listener has actually been removed
if (!(stage.hasEventListener(MouseEvent.CLICK))) {
trace("fireBullet listener should have been removed");
}
stage.removeChild(ship);
ship = null
//graphic for resetButton
resetButton = new Sprite();
resetButton.graphics.beginFill(0xFFFFFF);
resetButton.graphics.drawRect(0, 0, 100, 50);
resetButton.graphics.endFill();
//position for resetButton
resetButton.x = 250;
resetButton.y = 300;
//text for resetButton
resetTextField = new TextField();
var resetTextFormat:TextFormat = new TextFormat();
resetTextFormat.size = 30;
resetTextFormat.color = 0x000000;
resetTextField.defaultTextFormat = resetTextFormat;
resetTextField.selectable = false;
resetTextField.text = "RESET";
resetButton.addChild(resetTextField);
//add resetButton and listener
stage.addChild(resetButton);
resetButton.addEventListener(MouseEvent.CLICK, onReset);
//gameover text
gameOverTxtField = new TextField();
gameOverFormat = new TextFormat();
gameOverFormat.size = 50;
gameOverFormat.color = 0xFFFFFF;
gameOverFormat.align = "center";
gameOverTxtField.defaultTextFormat = gameOverFormat;
gameOverTxtField.selectable = false;
gameOverTxtField.text = "GAME OVER";
gameOverTxtField.width = 660;
gameOverTxtField.height = 200;
gameOverTxtField.x = -10;
gameOverTxtField.y = 20;
stage.addChild(gameOverTxtField);
}
private function onReset(e:MouseEvent):void
{
trace("clicked on reset");
//remove gameover objects and null them
resetButton.removeEventListener(MouseEvent.CLICK, onReset);
stage.removeChild(gameOverTxtField);
stage.removeChild(resetButton);
resetButton = null;
gameOverTxtField = null;
//restart the game
startGame();
}