Reputation: 189
I am setting up a system to manage cutscenes in my game. However, I have run into a tricky problem, and I have a hard time trying to describe it to Google. I need to access a function that Flash tells me is "undefined".
Here's what I'm have;
Cutscene
is a base class that contains basic functions for all cutscenes
Cutscene1
extends Cutscene
, and contains the information about an individual cutscene. Such information includes functions and variables. Later will come Cutscene2,
Cutscene3
, all of which extend Cutscene
CutsceneHandler
takes a Cutscene
, determines the Cutscene
's next step, and tells the Cutscene
to execute the function defined by the step.
CutsceneHandler
only accepts a Cutscene
So we give this handler a newly instantiated Cutscene1
. Handler says "Hey, it's a Cutscene
, everything's cool.". But now, the handler tells Cutscene
to perform a function only defined in its subclass. Handler says "Whoa, the Cutscene
class has no function like this!" and throws an error. Call to possibly undefined function.
How can we get around this? Is it an issue with how we call the function? I've included some simplified code below.
public class CutsceneHandler extends Sprite {
var activeCutscene:Cutscene
public function CutsceneHandler() {
//empty constructor
}
public function beginCutscene(cutscene:Cutscene) {
activeCutscene = cutscene
executeStep(activeCutscene.steps[0])
}
public function executeStep(step:Object) {
if (step.action) {
activeCutscene.action()
}
}
}
__
public class Cutscene1 extends Cutscene {
public var steps = [
{action:someFunction,someImportantDetail:true},
{action:someOtherFunction,someImportantDetail:false}
]
public function Cutscene1() {
//empty constructor
}
public function someFunction() {
trace ("hello!")
}
public function someOtherFunction() {
trace ("goodbye!")
}
}
Upvotes: 3
Views: 46
Reputation: 12431
This sounds like a job for the command pattern!
In simple terms, the idea would be to encapsulate the specifics of each step in separate instances of classes which all implement an interface with a single execute
method. Your handler class can invoke the steps via that interface without any knowledge of the specific subclass of Cutscene
to which the steps belong.
Something like the following should get you moving in the right direction.
The ICommand interface:
public interface ICommand {
function execute():void
}
The concrete commands:
public class HelloCommand implements ICommand {
public function execute():void {
trace("hello");
}
}
public class GoodbyCommand implements ICommand {
public function execute():void {
trace("goodbye");
}
}
The subclass of Cutscene
public class Cutscene1 extends Cutscene {
// Declare steps variable in the base class since
// all subclasses will use it
public function Cutscene1() {
// Define the steps specific to this subclass
steps = [
new HelloCommand(),
new GoodbyeCommand()
];
}
}
The handler class
// Only extend Sprite if the class needs to be displayed
public class CutsceneHandler {
var activeCutscene:Cutscene
public function CutsceneHandler() {
//empty constructor
}
public function beginCutscene(cutscene:Cutscene) {
activeCutscene = cutscene;
// Cast the step as ICommand and execute it
(activeCutscene.steps[0] as ICommand).execute();
}
}
Upvotes: 3