theseal53
theseal53

Reputation: 189

Referencing functions defined by subclasses in Actionscript 3

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

Answers (1)

net.uk.sweet
net.uk.sweet

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

Related Questions