我有一些.as文件。它们是:MainClass.as,FrontEnd.as,Levels.as和Hero.as.我的问题(据我所知)在我的Hero.as文件中。让我说明我是如何完成这一切的,因为我有点担心在AS3中有更好的办法。
MainClass.as创建一个FrontEnd变量(菜单,即主菜单)并调用它(addChild)。 FrontEnd.as是我的菜单。按钮等等...... Levels.as现在只是在主菜单上按下开始新游戏按钮时调出级别1。曾经有一段时间弄清楚如何使用来自不同.as文件的函数。 Hero.as我将添加我的代码。我发布了整件事,因为我不知道我的问题在哪里。
public class Hero extends MovieClip
{
public var roger:player = new player();
private var animationState:String = "down";
public var facing:String = "down";
private var isLeft:Boolean = false;
private var isRight:Boolean = false;
private var isUp:Boolean = false;
private var isDown:Boolean = false;
public var currentPlayer:MovieClip = roger;
public function Hero()
{
addEventListener(Event.ENTER_FRAME, loop);
addEventListener(Event.ADDED_TO_STAGE, onStage);
trace(currentPlayer);
}
public function onStage( event:Event ):void
{
removeEventListener( Event.ADDED_TO_STAGE, onStage );
}
public function addCurrentPlayer():void
{
roger.x = stage.stageWidth * .5;
roger.y = stage.stageHeight * .5;
addChild(roger);
currentPlayer = roger;
setBoundaries();
}
public function keyDownHandler(event:KeyboardEvent)
{
if (event.keyCode == 39)//right press
{
isRight = true;
}
if (event.keyCode == 37)//left pressed
{
isLeft = true;
}
if (event.keyCode == 38)//up pressed
{
isUp = true;
}
if (event.keyCode == 40)//down pressed
{
isDown = true;
}
}
public function keyUpHandler(event:KeyboardEvent)
{
if (event.keyCode == 39)//right released
{
isRight = false;
}
if (event.keyCode == 37)//left released
{
isLeft = false;
}
if (event.keyCode == 38)//up released
{
isUp = false;
}
if (event.keyCode == 40)//down released
{
isDown = false;
}
}
public function loop(Event):void
{
if (currentPlayer == null)
{
addCurrentPlayer();//make sure at least roger is on the screen
}
currentPlayer.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
currentPlayer.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
//----------------------------------0
//Animation States
//----------------------------------0
if (isDown == true)
{
currentPlayer.y += 5;
animationState = "walk_down";
facing = "down";
currentPlayer.gotoAndStop(animationState);
}
else if (isUp == true)
{
currentPlayer.y -= 5;
animationState = "walk_up";
facing = "up";
currentPlayer.gotoAndStop(animationState);
}
else if (isRight == true)
{
currentPlayer.x += 5;
animationState = "walk_right";
facing = "right";
currentPlayer.gotoAndStop(animationState);
}
else if (isLeft == true)
{
currentPlayer.x -= 5;
animationState = "walk_left";
facing = "left";
currentPlayer.gotoAndStop(animationState);
}
//----------------------------------0;
//IDLE STATES
//----------------------------------0
else if (isDown == false)
{
currentPlayer.gotoAndStop(facing);
}
else if (isUp == false)
{
currentPlayer.gotoAndStop(facing);
}
else if (isRight == false)
{
currentPlayer.gotoAndStop(facing);
}
else if (isLeft == false)
{
currentPlayer.gotoAndStop(facing);
}
}
public function setBoundaries():void
{
var halfHeight:int = currentPlayer.height * .5;
var halfWidth:int = currentPlayer.width * .5;
if(currentPlayer.y <= 1)
{
currentPlayer.y += halfHeight;
}
else if(currentPlayer.y > stage.stageHeight)
{
currentPlayer.y -= halfHeight;
}
else if(currentPlayer.x <= 1)
{
currentPlayer.x += halfWidth;
}
else if(currentPlayer.x > stage.stageWidth)
{
currentPlayer.x -= halfWidth;
}
}
}
}
迹(currentPlayer);给我[对象播放器]而不是实例名称“roger”。 (后来我想要更多可玩的角色。)我不确定问题是存在还是在我的关卡文件中,我将在此处发布。 (不像Hero.as那么长)
public class Levels extends MovieClip
{
var currentLevel:MovieClip;
public function Levels()
{
addEventListener(Event.ADDED_TO_STAGE, onStage);
}
private function onStage(event:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, gotoLevelOne);
}
public function gotoLevelOne():void
{
var levelOne:LevelOne = new LevelOne();
var hero:Hero = new Hero();
addChild(hero);
levelOne.x = stage.stageWidth * .5;
levelOne.y = stage.stageHeight * .5;
addChild(levelOne);
currentLevel = levelOne;
hero.currentPlayer.x = 100;
hero.currentPlayer.y = 100;
addChild(hero.currentPlayer);
}
}
}
如果我删除= roger;来自var currentPlayer:MovieClip = roger;它给了我#1009 null对象,即使我在addCurrentPlayer()中告诉它将currentPlayer更改为roger。在第1级,一切都显示出来但我无法移动我的角色。我知道它在我制作动画时有用,我会把他叫到主菜单。一切都在他身上发挥作用。现在有什么问题?
答案 0 :(得分:0)
首先,你的代码有很多问题:
在你的英雄课程中,&#39; onStage&#39;事件处理程序除了删除触发它的事件侦听器之外,实际上并没有做任何其他事情。虽然删除事件侦听器是一个好习惯,但事件处理程序应该有其他目的。如果没有,您可以将其删除而不用费心去听ADDED_TO_STAGE事件。
同样,在你的Levels Class&#39; onStage&#39;您尝试删除事件的事件处理程序,但命名错误的处理程序。我假设您要删除事件处理程序,然后运行&#39; gotoLevelOne&#39;方法。如果是这样,只需让Event.ADDED_TO_STAGE监听器调用&#39; gotoLevelOne&#39;然后删除那里的事件监听器:
public function Levels()
{
addEventListener(Event.ADDED_TO_STAGE, gotoLevelOne);
}
public function gotoLevelOne():void
{
removeEventListener(Event.ADDED_TO_STAGE, gotoLevelOne);
// class continues....
好的,那么你的问题:
您将获得null错误,因为您在调用addCurrentPlayer(设置它之前)之前从Hero类外部引用currentPlayer。
如果您暂时将currentPlayer定义为私有变量,编译器应该为您提供一个行号,您首先从OUTSIDE Hero Class引用currentPlayer(错误将类似于&#39; Class X正在尝试访问私有(或者Y类&#39;)的不存在的财产。
然后,您可以在调用addCurrentPlayer之前解决为什么要访问currentPlayer。您可能还想考虑currentPlayer NEEDS是否公开(如果是,那么&#39; addCurrentPlayer&#39; for?该函数有效地用作currentPlayer的setter。)
修改强>
目前,您正在为游戏循环的每个帧添加新的KEY_DOWN和KEY_UP事件侦听器。这是不必要的。在游戏初始化中添加它们(可能在你的Hero的onStage处理程序中),并指望它们触发相应的处理程序。
您需要将KEY_DOWN和KEY_UP监听器添加到&#39; stage&#39;而不是currentPlayer,所以:
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
您需要在将Hero实例添加到舞台后添加侦听器,以便它可以访问“阶段”。这就是为什么在Hero的舞台处理程序中添加听众是有意义的。