实现接口的20个中只有2个类所需的方法

时间:2014-01-07 15:52:19

标签: android interface scene game-loop implements

背景

在我的应用程序(游戏)中 - 我有一个场景管理器来处理不同级别。所以我有:

接口代码

//Interface to allow switching scenes (works in conjunction with SceneManager class)
//Handles rendering, logic updating (on the GL rendering thread) and user input (on the main UI thread)

public interface Scene  {

void render();
void updateLogic();
boolean onTouchEvent(MotionEvent event);

}

SceneManager类

//Scene Manager class used in conjunction with the Scene interface.  This allows for querying of the current
//scene & changing the scene using the current instance of the manager.

public class SceneManager {

private static SceneManager Instance = new SceneManager();

private Scene currentScene;

public static SceneManager getInstance(){

    return Instance;

}

public Scene getCurrentScene(){

    return currentScene;

}

public void setCurrentScene(Scene scene){

    currentScene = scene;

}

}

所以,从我的游戏循环中我可以做到这样的事情:

SceneManager.getInstance().getCurrentScene().updateLogic();
SceneManager.getInstance().getCurrentScene().render();

我可以通过保存一个简单的int值并通过switch语句运行相应的代码来轻松更改我的级别。

switch (level){

case 1:{SceneManager.getInstance().setCurrentScene(r.level1);break


}

问题

这很好但是在我的一些级别(20个中的2个)中我需要运行一个特定的方法,但我不想在18个级别中实现它,在这个级别中它不是必需的(通过存根方法)。

我的另一个选择是在循环运行时在级别值上调用switch语句....

伪代码

If (level==5)

  callCode(5,0);

else if (level==10)

 {callCode (10,4);}

(等级5和10是需要这段代码的等级)

....但我宁愿把所需的方法放在它的相应级别类中,只是从当前场景中调用方法,因为我不确定在游戏循环中使用开关(或方法)本身正在运行 - (IE,我的大部分开关语句都来自于一个级别结束时的切割场景,而性能不是真正的问题)。像这样:

我更愿意做这样的事情:

SceneManager.getInstance().getCurrentScene().callCode();

其中callCode方法特定于级别中需要的任何值(或者实际上,然后可以简单地调用公共代码的主方法,但具有不同的值)。

希望我有意义。

任何指针都将不胜感激

修改

尝试创建第二个界面:

public interface Scene2 extends Scene {

    void callCode();

}

(场景仍然如上所述)

然后,在我的班级(例如说level10)

public class Level10 implements Scene2 {

    @Override
    public void render(){

        //Rendering code goes here
        mainGame.Drawsprites();  //As an example.  MainGame implements Scene and contains all my game code.  I can simply call the various methods from any of my level classes therefore I don't duplicate tons of code

    }

     @Override
    public void updateLogic(){

        //Game updates goes here (Similar to above)

    }

    @Override
    public void callCode(){

        //Level specific code here

    }

来自我的mainGame课程:

    public void doSomething(){

        SceneManager.getInstance().getCurrentScene().callCode;

    }

}

5 个答案:

答案 0 :(得分:0)

如果您有界面Scene

public interface Scene  {

void render();
void updateLogic();
boolean onTouchEvent(MotionEvent event);

}

您可以定义另一个界面,例如:

    public interface Scene2 extends Scene {

    void callCode();

}

然后在你的mainGame课中你可以做到:

public void doSomething(){

    Object currentScene = SceneManager.getInstance().getCurrentScene();
    if(currentScene instanceof Scene){
        ((Scene)currentScene).render();
        ((Scene)currentScene).updateLogic();
    }

    if(currentScene instanceof Scene2){
        ((Scene2)currentScene).allCode();

    }

}

答案 1 :(得分:0)

您应该定义一个扩展您的界面的额外图层。然后,您的2个独立场景可以实现此接口,并且仍然可以通过更通用的界面进行调用。

这是一个示例实现:

public class Main {
    public static void main(String[] args) {
        SomeInterface obj1 = new SomeClass2();
        obj1.method1();
        obj1.method2();
        SomeSubInterface obj2 = new SomeClass2();
        obj2.method1();
        obj2.method2();
        obj2.method3();
    }
}

interface SomeInterface {
    void method1();
    void method2();
}

interface SomeSubInterface extends SomeInterface {
    void method3();
}

class SomeClass1 implements SomeInterface {

    @Override
    public void method1() {
        // TODO Auto-generated method stub
    }

    @Override
    public void method2() {
        // TODO Auto-generated method stub
    }
}

class SomeClass2 implements SomeSubInterface {

    @Override
    public void method1() {
        // TODO Auto-generated method stub  
    }

    @Override
    public void method2() {
        // TODO Auto-generated method stub  
    }
    @Override
    public void method3() {
        // TODO Auto-generated method stub
    }
}

答案 2 :(得分:0)

仅举例说明我在上述评论中提出的解决方案。如上所述,它实现了对场景特定代码的本地化,并消除了一般游戏循环的复杂性。

public class Main {
    public static void main(String[] args) {
        Scene scene1 = new NormalScene();
        Scene scene2 = new SpecialScene();

        scene1.initialize();    //Does nothing
        scene2.initialize();    //Print hello world
    }
}
abstract class Scene {
    abstract void render();
    abstract void updateLogic();
    abstract boolean onTouchEvent();
    void initialize() {

    }
}
class NormalScene extends Scene {
    @Override
    void render() {
    }
    @Override
    void updateLogic() {
    }
    @Override
    boolean onTouchEvent() {
        return true;
    }
}
class SpecialScene extends Scene {
    @Override
    void render() {
    }
    @Override
    void updateLogic() {
    }
    @Override
    boolean onTouchEvent() {
        return true;
    }
    @Override
    void initialize() {
        System.out.println("Hello world");
    }
}

答案 3 :(得分:0)

正如我的评论中所述,我会喜欢以下方法,因为它非常适合Android的设计并为您提供最大的灵活性:

public interface Scene  {

void render();
void updateLogic();
boolean onTouchEvent(MotionEvent event);

/** additional lifecycle callbacks **/
void onBeforeRender();
void onAfterRender();
void onBeforeUpdateLogic();
void onAfterUpdateLogic();
/** though the naming updateLogic associated that it is not a typicall lifecycle related method **/
}

在您的课程中,当然还有事件监视器的setter和getter附加到生命周期事件。

答案 4 :(得分:0)

根据您的评论从其他答案中提取:我认为您最想尽量减少Scene界面的做法是将visitor pattern添加到您的代码中(它是一个双重调度设计模式)。基本上对你而言,这意味着(我假设第2级和第4级是你想要调用特殊方法的级别类):

interface LevelVisitor {
    void visit(Level2 level);

    void visit(Level4 level);
}

interface Scene {
    // Other methods stay the same as you have

    accept(LevelVisitor visitor);
}

您的不同级别现在有accept方法(在18/20课程中不需要它的课程中将其留空),上面我使LevelVisitor收到具体的{{1}您的classLevel2类(两个特定级别)的实现。

Level4类实现MainGame接口,这意味着MainGame类中现在有两个新方法,即接收具体LevelVisitorLevel2类实现的方法。所以现在从Level4拨打电话(MainGame会被调度到需要它的级别,MainGame/this是访问者):

MainGame

并且您在SceneManager.getInstance().getCurrentScene().accept(this);

中也有访问方法
MainGame

public void visit(Level2 level) { level.specificMethodInLevel2(); } public void visit(Level4 level) { level.specificMethodInLevel4(); } Level2类中,您使用非空实现的accept方法,例如Level4中的Level2 Level2/this将调度MainGame }}):

public void accept(LevelVisitor visitor) {
    visitor.visit(this);
}

现在您可以将特定方法(例如specificMethodInLevel2())添加到Level2Level4具体类中,这些类别是从其他级别看不到的,并从访问中调用它们你MainGame班的方法。此外,由于访问者模式的调度性质,您最终没有切换案例(所有“特殊”级别现在都采用不同的方法处理)。