AS3 更新变量报告 Null.. 在一个模式中
AS3 Update Variable Reports Null.. in a pattern
我正在 AS3 中制作 space 游戏 - 我有一个名为 EnemyShip 的敌人 class。
我已经注册了 Event.ENTER_FRAME 并且它工作正常 - 问题是我的变量,Array 类型的 rowXY,在一个模式中报告空值和非空值。
我怎样才能避免这种情况发生(或者在 Flash Professional 中是否有更简单的方法来设置船舶动画?)。
模式如下:
敌舰:
package
{
import flash.display.Sprite;
import flash.events.Event;
public class EnemyShip extends Sprite
{
internal var id:int;
internal var rowOrder:int;
internal var rowXY:Array;
private var dirUp:Boolean = false;
public function EnemyShip()
{
// add event listeners
addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
addEventListener(Event.ENTER_FRAME, update);
}
private function update(e:Event):void
{
moveUpAndDown();
trace(rowXY);
function moveUpAndDown():void
{
if (dirUp)
y -= C.ENEMY_SPEED;
else
y += C.ENEMY_SPEED;
}
}
private function onAddedToStage(e:Event):void
{
// get row XY
if (rowOrder == 1)
rowXY = C.ENEMY_ROW_1;
if (rowOrder == 2)
rowXY = C.ENEMY_ROW_2;
if (rowOrder == 3)
rowXY = C.ENEMY_ROW_3;
// set XY position
x = rowXY[0];
y = rowXY[1];
removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
internal function destroy():void
{
rowOrder = null;
rowXY = null;
// remove event listeners
removeEventListener(Event.ENTER_FRAME, update);
// remove from display list
parent.removeChild(this);
}
}
}
C.as(常量):
package
{
// C stands for constants
public class C
{
// ship constants
public static const FIRE_DELAY:int = 500; // milliseconds
// laser constants
public static const LASER_SPEED:int = 30;
public static const POINTS_KILL:int = 10;
// mcScore constants
public static const SCORE_LOC_X:Number = 345;
public static const SCORE_LOC_Y:Number = -120;
// enemy ship constants
public static const ENEMY_ROW_1:Array = [485, -45];
public static const ENEMY_ROW_2:Array = [485, 25];
public static const ENEMY_ROW_3:Array = [485, 95];
public static const ENEMY_SPEED:int = 5; // 5 pixels
public static const ENEMY_Y_MIN:int = -10;
public static const ENEMY_Y_MAX:int = 10;
}
}
如果您尝试使用 Flash Professional 制作动画,我会利用其内置 Motion Tween feature. You could also animate the ship in your code by taking advantage of the Tween class.
我重现了你使用这个 for
循环的行为(你可以通过实例化 3 个对象并将另外 3 个对象直接插入舞台来获得相同的结果):
for(var i:int = 1; i < 7; i++){
var enemy:EnemyShip = new EnemyShip();
enemy.rowOrder = i;
addChild(enemy);
}
在这里我们可以很清楚地看到 i
是 4、5 或 6,rowOrder
将是 null
,这也会为所有实例触发一些 #1009 错误此行中的 rowOrder
大于 3 :
x = rowXY[0];
因此,为了避免这种情况,您可以将 rowOrder
的值限制在 1 到 3 之间,例如:
enemy.rowOrder = 1 + int(Math.random()*3);
您还可以在 EnemyShip
class 本身中设置该值。
...
希望能帮到你。
解决方案
据我所知,事件 Event.ENTER_FRAME 仅传递给舞台上的对象,但事实并非如此。
问题出在我的 EnemyShip class' 构造方法中 - ENTER_FRAME 事件正在被舞台上和舞台下的实例侦听 - 舞台下的实例尚未分配一个 rowXY(这发生在 ADDED_TO_STAGE 事件中)。
旧代码:
新代码:
那么这里有什么教训呢?
Event.ENTER_FRAME 无论对象是否显示都会发生。
在您发布的屏幕截图中,您有以下代码:
if(rowOrder > 3)
rowOrder = 0;
但是当您在 onAddedToStage()
中检查 rowOrder
时,您没有 0 的情况 - 只有 1、2 或 3。因此 rowXY
永远不会在 rowOrder
是 0.
要么更改该代码以将 rowOrder
设置为 1 而不是 0,或者将您的其他代码更改为零索引。
我正在 AS3 中制作 space 游戏 - 我有一个名为 EnemyShip 的敌人 class。
我已经注册了 Event.ENTER_FRAME 并且它工作正常 - 问题是我的变量,Array 类型的 rowXY,在一个模式中报告空值和非空值。
我怎样才能避免这种情况发生(或者在 Flash Professional 中是否有更简单的方法来设置船舶动画?)。
模式如下:
敌舰:
package
{
import flash.display.Sprite;
import flash.events.Event;
public class EnemyShip extends Sprite
{
internal var id:int;
internal var rowOrder:int;
internal var rowXY:Array;
private var dirUp:Boolean = false;
public function EnemyShip()
{
// add event listeners
addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
addEventListener(Event.ENTER_FRAME, update);
}
private function update(e:Event):void
{
moveUpAndDown();
trace(rowXY);
function moveUpAndDown():void
{
if (dirUp)
y -= C.ENEMY_SPEED;
else
y += C.ENEMY_SPEED;
}
}
private function onAddedToStage(e:Event):void
{
// get row XY
if (rowOrder == 1)
rowXY = C.ENEMY_ROW_1;
if (rowOrder == 2)
rowXY = C.ENEMY_ROW_2;
if (rowOrder == 3)
rowXY = C.ENEMY_ROW_3;
// set XY position
x = rowXY[0];
y = rowXY[1];
removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
internal function destroy():void
{
rowOrder = null;
rowXY = null;
// remove event listeners
removeEventListener(Event.ENTER_FRAME, update);
// remove from display list
parent.removeChild(this);
}
}
}
C.as(常量):
package
{
// C stands for constants
public class C
{
// ship constants
public static const FIRE_DELAY:int = 500; // milliseconds
// laser constants
public static const LASER_SPEED:int = 30;
public static const POINTS_KILL:int = 10;
// mcScore constants
public static const SCORE_LOC_X:Number = 345;
public static const SCORE_LOC_Y:Number = -120;
// enemy ship constants
public static const ENEMY_ROW_1:Array = [485, -45];
public static const ENEMY_ROW_2:Array = [485, 25];
public static const ENEMY_ROW_3:Array = [485, 95];
public static const ENEMY_SPEED:int = 5; // 5 pixels
public static const ENEMY_Y_MIN:int = -10;
public static const ENEMY_Y_MAX:int = 10;
}
}
如果您尝试使用 Flash Professional 制作动画,我会利用其内置 Motion Tween feature. You could also animate the ship in your code by taking advantage of the Tween class.
我重现了你使用这个 for
循环的行为(你可以通过实例化 3 个对象并将另外 3 个对象直接插入舞台来获得相同的结果):
for(var i:int = 1; i < 7; i++){
var enemy:EnemyShip = new EnemyShip();
enemy.rowOrder = i;
addChild(enemy);
}
在这里我们可以很清楚地看到 i
是 4、5 或 6,rowOrder
将是 null
,这也会为所有实例触发一些 #1009 错误此行中的 rowOrder
大于 3 :
x = rowXY[0];
因此,为了避免这种情况,您可以将 rowOrder
的值限制在 1 到 3 之间,例如:
enemy.rowOrder = 1 + int(Math.random()*3);
您还可以在 EnemyShip
class 本身中设置该值。
...
希望能帮到你。
解决方案
据我所知,事件 Event.ENTER_FRAME 仅传递给舞台上的对象,但事实并非如此。
问题出在我的 EnemyShip class' 构造方法中 - ENTER_FRAME 事件正在被舞台上和舞台下的实例侦听 - 舞台下的实例尚未分配一个 rowXY(这发生在 ADDED_TO_STAGE 事件中)。
旧代码:
新代码:
那么这里有什么教训呢?
Event.ENTER_FRAME 无论对象是否显示都会发生。
在您发布的屏幕截图中,您有以下代码:
if(rowOrder > 3)
rowOrder = 0;
但是当您在 onAddedToStage()
中检查 rowOrder
时,您没有 0 的情况 - 只有 1、2 或 3。因此 rowXY
永远不会在 rowOrder
是 0.
要么更改该代码以将 rowOrder
设置为 1 而不是 0,或者将您的其他代码更改为零索引。