Actionscript 3 addChild未在舞台上显示任何内容
所以我想让飞船在按下空格键的时候发射激光。我以前在一个纯flex项目中做过这件事,但最近得到了CreativeCloud,我正在尝试使用FlashProfessional/FlashBuilder重新创建相同的效果 不幸的是,当我创建我的“Laser”类的新实例并尝试使用addChild()将其放到舞台上时,似乎什么都没有发生 这是主文件/文档类Actionscript 3 addChild未在舞台上显示任何内容,actionscript-3,flash,actionscript,Actionscript 3,Flash,Actionscript,所以我想让飞船在按下空格键的时候发射激光。我以前在一个纯flex项目中做过这件事,但最近得到了CreativeCloud,我正在尝试使用FlashProfessional/FlashBuilder重新创建相同的效果 不幸的是,当我创建我的“Laser”类的新实例并尝试使用addChild()将其放到舞台上时,似乎什么都没有发生 这是主文件/文档类 public class PlayerShip extends Sprite { private var laser
public class PlayerShip extends Sprite
{
private var laserTimer:Timer;
private var shipTime:Timer;
private var upKey:Boolean;
private var downKey:Boolean;
private var leftKey:Boolean;
private var rightKey:Boolean;
private var spacebar:Boolean;
private var utils:Utils = new Utils();
//tuning variables
private var MOVE_SPEED:int = 5;
private var REVERSE_SPEED:int = 3;
private var TURN_SPEED:int = 5;
private var laserEmitter:shipLasers = new shipLasers(stage);
public function PlayerShip():void
{
super();
addEventListener(Event.ENTER_FRAME, fly);
stage.addEventListener(KeyboardEvent.KEY_DOWN, movementKeysDown);
stage.addEventListener(KeyboardEvent.KEY_UP, movementKeysUp);
laserTimer = new Timer(1000/1000);
laserTimer.addEventListener(TimerEvent.TIMER, fireLasers);
laserTimer.start();
addChild(laserEmitter);
}
public function fly(e:Event):void {
if(downKey) {
SpaceShip.x -= Math.sin(utils.degreesToRadians(SpaceShip.rotation)) * REVERSE_SPEED;
SpaceShip.y += Math.cos(utils.degreesToRadians(SpaceShip.rotation)) * REVERSE_SPEED;
}
if(upKey) {
SpaceShip.x += Math.sin(utils.degreesToRadians(SpaceShip.rotation)) * MOVE_SPEED;
SpaceShip.y -= Math.cos(utils.degreesToRadians(SpaceShip.rotation)) * MOVE_SPEED;
}
if(leftKey) {
SpaceShip.rotation -= TURN_SPEED;
}
if(rightKey) {
SpaceShip.rotation += TURN_SPEED;
}
}
public function movementKeysUp(e:KeyboardEvent):void { //rotators is key_up :P
switch(e.keyCode) {
case 83:
downKey = false;
break;
case 65:
leftKey = false; // on "a" key_up sets left turn to false. Simple enough.
break;
case 68:
rightKey = false; // K. "d" released makes me not turn right.
break;
case 87:
upKey = false; // I guess case 87 is "w"
break;
case 32:
spacebar = false;
break;
}
}
public function movementKeysDown(e:KeyboardEvent):void { // key_down for movers
switch(e.keyCode) {
case 83:
downKey = true;
break;
case 65:
leftKey = true; //so now on key_down for the "a" key it makes me go left! :D
break;
case 68:
rightKey = true; //same as lft...
break;
case 87:
upKey = true;
break;
case 32:
spacebar = true;
break;
}
}
public function fireLasers(e:TimerEvent) {
if(spacebar) {
laserEmitter.Emit(SpaceShip.x, SpaceShip.y, SpaceShip.rotation);
addChild(laserEmitter);
}
}
public function getShip():MovieClip {
return SpaceShip;
}
}
}
这是一个单独的类,应该创建Laser类的新实例,并将它们放到舞台上
public class shipLasers extends Sprite implements Emittable
{
var tempLaserRight:MovieClip;
var tempLaserLeft:MovieClip;
var laserArray:Array = [];
public function shipLasers(stage:Stage):void
{
}
public function Emit(x:int, y:int, rotation:Number):void {
tempLaserRight = new Laser();
tempLaserLeft = new Laser();
tempLaserRight.rotation = tempLaserLeft.rotation = rotation;
tempLaserRight.x = 200;
tempLaserLeft.x = 210;
tempLaserRight.y = 200;
tempLaserLeft.y = 200;
laserArray.push(tempLaserRight);
laserArray.push(tempLaserLeft);
stage.addChild(tempLaserRight);
stage.addChild(tempLaserLeft);
trace("Oh come on!");
}
}
}
谢谢 您从未将传递的stage引用存储在
shipllass
类中,因此您试图引用它自己的内置stage ref,这可能是空的,因为您的shipllass
实例本身没有添加到显示列表中。您需要存储在构造函数中传递的stage ref,并使用它来添加子级
public class shipLasers ... {
var theStage:Stage;
public function shipLasers(aStage:Stage){
theStage = aStage;
}
public function Emit(...) {
...
theStage.addChild(tempLaserRight);
thestage.addChild(tempLaserLeft);
}
}
更新:首先检查阶段可用性,然后使用阶段参考也是一个好的实践。要做到这一点,您需要收听事件。在ship类中添加了“STAGE To_STAGE
事件”,因为它使用STAGE left right and center。实现这一目标的共同准则如下:
public function PlayerShip() {
....
// leave here only code that does not require stage
if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE,init);
}
private function init(e:Event=null):void {
removeEventListener(Event.ADDED_TO_STAGE,init);
// here place all code that's left from your initialization process
laserEmitter=new shipLasers(stage);
stage.addEventListener(KeyboardEvent.KEY_DOWN, movementKeysDown);
stage.addEventListener(KeyboardEvent.KEY_UP, movementKeysUp);
// etc.
}
您从未将传递的stage引用存储在
shipllass
类中,因此您试图引用它自己的内置stage ref,这可能是空的,因为您的shipllass
实例本身没有添加到显示列表中。您需要存储在构造函数中传递的stage ref,并使用它来添加子级
public class shipLasers ... {
var theStage:Stage;
public function shipLasers(aStage:Stage){
theStage = aStage;
}
public function Emit(...) {
...
theStage.addChild(tempLaserRight);
thestage.addChild(tempLaserLeft);
}
}
更新:首先检查阶段可用性,然后使用阶段参考也是一个好的实践。要做到这一点,您需要收听事件。在ship类中添加了“STAGE To_STAGE
事件”,因为它使用STAGE left right and center。实现这一目标的共同准则如下:
public function PlayerShip() {
....
// leave here only code that does not require stage
if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE,init);
}
private function init(e:Event=null):void {
removeEventListener(Event.ADDED_TO_STAGE,init);
// here place all code that's left from your initialization process
laserEmitter=new shipLasers(stage);
stage.addEventListener(KeyboardEvent.KEY_DOWN, movementKeysDown);
stage.addEventListener(KeyboardEvent.KEY_UP, movementKeysUp);
// etc.
}
我现在有了一个stage变量,它接受了从构造函数传入的stage对象,并从新的stage对象调用addChild,正如您所示,但出于某种原因,我仍然只能得到一个trace语句。您必须跟踪的不仅仅是“来吧”,比如它们的X和Y位置,它们的旋转,此外,添加后,您还可以获得激光器目标点的
localToGlobal()
转换。有可能你的激光离开了舞台的可见部分,另一个可能导致游戏无法正常运行的错误,请参阅更新的答案。我在PlayerShip的构造函数中加入了init函数,并跟踪了激光的坐标和旋转,使用了localToGlobal,它们实际上显示在我预期的位置(我检查了关于正确使用localToGlobal的另一个SO主题,因此我认为我使用的是正确的)。我不知道这是否真的是一个问题,但我已经尝试将背景从舞台上移开,以确保它们不会以某种方式隐藏在它后面,这也不是问题。使用localToGlobal()
应该像tempLaserRight.localToGlobal(new Point())
,调用localToGlobal()的对象
应该是您需要确定的位置。不要使用此
或shipLasers
类中的空限定符,如果这样做,您将收到虚假值,因为您的激光发射器
不是包含这些激光的显示列表的一部分。我现在有了一个stage变量,它包含stage对象从构造函数传入,我从新的stage对象调用addChild,如您所示,但出于某种原因,我仍然只能得到一个trace语句。您必须跟踪的不仅仅是“来吧”,比如它们的X和Y位置,它们的旋转,在添加之后,您还可以得到localToGlobal()
激光目标点的转换。可能是你的激光超出了舞台的可见部分。另外,另一个可能导致游戏无法正常运行的错误,请参阅更新的答案。我在PlayerShip的构造函数中输入了init函数,跟踪了激光的坐标和旋转,并使用了localToGlobal事实上,它们出现在我期望的地方(我检查了另一个关于正确使用localToGlobal的SO主题,所以我认为我正确地使用了它)。我不知道这是否真的是一个问题,但我已尝试将背景从舞台上移开,以确保它们不在后台,这也不是问题。使用localToGlobal()
应该像tempLaserRight.localToGlobal(new Point())
,调用localToGlobal()的对象
应该是您需要确定的位置。不要使用此
或ShipLaser
类中的空限定符,如果这样做,您将收到虚假值,因为您的激光发射器
不是包含这些激光的显示列表的一部分。