Actionscript 3 使用命令模式切换帧
我试图为我的flash游戏创建一个介绍动画,但是当它应该转到动画的第二帧时,事情就出了问题 这是菜单中的“开始游戏”按钮应该执行的代码(位于文档类中):Actionscript 3 使用命令模式切换帧,actionscript-3,flash,null,frame,command-pattern,Actionscript 3,Flash,Null,Frame,Command Pattern,我试图为我的flash游戏创建一个介绍动画,但是当它应该转到动画的第二帧时,事情就出了问题 这是菜单中的“开始游戏”按钮应该执行的代码(位于文档类中): gotoAndStop(3); animationHero1.addEventListener(Event.ENTER_FRAME, resetWalkAnimation); var command1:Command = new SerialCommand(0, //start animation new Tween
gotoAndStop(3);
animationHero1.addEventListener(Event.ENTER_FRAME, resetWalkAnimation);
var command1:Command =
new SerialCommand(0, //start animation
new TweenLiteToCommand(0, animationHero1, 6, { x: 1300, ease:Linear.easeNone } ), //move hero to door
new ChangeFrameCommand(0, animationHero1, 1), //stop hero animation
new ParallelCommand(0,
new PlaySoundCommand(0, new OpenDoorSound), //open the door
new TweenLiteToCommand(0, animationHero1, 1, { alpha: 0 } ) //fade out hero
),
new ChangeFrameCommand(0.5, this, 4), //next frame
new TraceCommand(1, this.currentFrame.toString()) //trace current frame
//new TweenLiteToCommand(0.5, this.animationHero2, 3, { x: 1100, ease:Linear.easeNone } ) //Walk hero across the room
);
command1.start();
如您所见,我正在使用命令模式。changeFrameCommand将“this”设置为第4帧。但是,当我在下一个命令中跟踪currentFrame时,输出为“3”。这没有任何意义,因为当我运行程序时,帧确实更改为第4帧。下面的命令(现在已注释掉)随后抛出“无法访问空对象引用的属性或方法”,因为animationHero2位于第4帧中
我假设最可能出现问题的地方是changeFrameCommand,下面是该类的代码:
package commands
{
import commands.Command;
import flash.display.MovieClip;
import flash.display.Stage;
/**
* ...
* @author Berry Hermans
*/
public class ChangeFrameCommand extends Command
{
private var mc:MovieClip;
private var frame:int;
public function ChangeFrameCommand(delay:Number, movieclip:MovieClip, frameNumber:int)
{
super(delay);
mc = movieclip;
frame = frameNumber;
}
override protected function execute():void
{
mc.gotoAndStop(frame);
complete();
}
}
}
如果有人能对这种情况有所了解,我将永远感激,因为我的最后期限还有两天
根据要求,添加代码
SerialCommand类:
package commands {
import flash.events.Event;
public class SerialCommand extends Command {
private var _commands:Array;
public function SerialCommand(delay:Number, ...commands) {
super(delay);
_commands = commands;
}
private var _completeCommandCount:int;
override final protected function execute():void {
//set the complete command count to zero
_completeCommandCount = 0;
//listen for the complete event of the first subcommand...
_commands[0].addEventListener(Event.COMPLETE, onSubcommandComplete);
//...and start the subcommand
_commands[0].start();
}
private function onSubcommandComplete(e:Event):void {
//stop listening for the complete event
Command(e.target).removeEventListener(Event.COMPLETE, onSubcommandComplete);
//increment the complete command count
_completeCommandCount++;
//if all the commands are complete...
if (_completeCommandCount == _commands.length) {
//...then this serial command is complete
complete();
} else {
//...otherwise listen for the complete event of the next subcommand...
_commands[_completeCommandCount].addEventListener(Event.COMPLETE, onSubcommandComplete);
//...and start the subcommand
_commands[_completeCommandCount].start();
}
}
}
}
package commands {
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.TimerEvent;
import flash.utils.Timer;
public class Command extends EventDispatcher {
private var _timer:Timer;
public function Command(delay:Number = 0) {
_timer = new Timer(int(1000 * delay), 1);
_timer.addEventListener(TimerEvent.TIMER_COMPLETE, onTimerComplete);
}
private function onTimerComplete(e:TimerEvent):void {
execute();
}
/**
* Starts the command.
* Waits for the timer to complete and calls the execute() method.
* This method can be used directly as an event listener.
*/
public final function start(e:Event = null):void {
_timer.start();
}
/**
* The abstract method for you to override to create your own command.
*/
protected function execute():void {
}
/**
* Completes the command.
* Dispatches a complete event.
* This method can be used directly as an event listener.
*/
protected final function complete(e:Event = null):void {
dispatchEvent(new Event(Event.COMPLETE));
}
}
}
命令类:
package commands {
import flash.events.Event;
public class SerialCommand extends Command {
private var _commands:Array;
public function SerialCommand(delay:Number, ...commands) {
super(delay);
_commands = commands;
}
private var _completeCommandCount:int;
override final protected function execute():void {
//set the complete command count to zero
_completeCommandCount = 0;
//listen for the complete event of the first subcommand...
_commands[0].addEventListener(Event.COMPLETE, onSubcommandComplete);
//...and start the subcommand
_commands[0].start();
}
private function onSubcommandComplete(e:Event):void {
//stop listening for the complete event
Command(e.target).removeEventListener(Event.COMPLETE, onSubcommandComplete);
//increment the complete command count
_completeCommandCount++;
//if all the commands are complete...
if (_completeCommandCount == _commands.length) {
//...then this serial command is complete
complete();
} else {
//...otherwise listen for the complete event of the next subcommand...
_commands[_completeCommandCount].addEventListener(Event.COMPLETE, onSubcommandComplete);
//...and start the subcommand
_commands[_completeCommandCount].start();
}
}
}
}
package commands {
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.TimerEvent;
import flash.utils.Timer;
public class Command extends EventDispatcher {
private var _timer:Timer;
public function Command(delay:Number = 0) {
_timer = new Timer(int(1000 * delay), 1);
_timer.addEventListener(TimerEvent.TIMER_COMPLETE, onTimerComplete);
}
private function onTimerComplete(e:TimerEvent):void {
execute();
}
/**
* Starts the command.
* Waits for the timer to complete and calls the execute() method.
* This method can be used directly as an event listener.
*/
public final function start(e:Event = null):void {
_timer.start();
}
/**
* The abstract method for you to override to create your own command.
*/
protected function execute():void {
}
/**
* Completes the command.
* Dispatches a complete event.
* This method can be used directly as an event listener.
*/
protected final function complete(e:Event = null):void {
dispatchEvent(new Event(Event.COMPLETE));
}
}
}
resetWalkAnimation做什么?公共函数resetWalkAnimation(e:Event){if(e.target.currentFrame==8){e.target.gotoAndPlay(2);}}}是在执行新的TraceCommand(1,this.currentFrame.toString()之前执行的ChangeFrameCommand.execute方法?您可以发布SerialCommand.start方法吗?您收到的是3而不是4,因为您将3作为参数“this.currentFrame.toString()”传递。ChangeFrameCommand在执行TraceCommand之前执行并完成。添加了附加代码。因此,在您的第一个代码中:gotoAndStop(3);-步骤到第3帧,然后使用new new TraceCommand创建新的SerialCommand(在trace command中,第二个参数是this.currentFrame.toString(),然后将其计算为3,因此如果将断点设置为TraceCommand的c-tor,您将看到该命令将使用参数new TraceCommand(1,3)创建.I,我不确定TraceCommand的execute方法是做什么的,但我几乎可以肯定它将类似于trace(3)。通常,当您传递时,使用此.currentFrame.toString()将计算为当前帧,而不是执行命令后的帧。