【问题标题】:Scrolling though objects then creating a new instace of this object创建此对象的新实例时滚动对象
【发布时间】:2012-09-26 22:46:03
【问题描述】:

在我的游戏中,当按下鼠标右键时,你会在地上放置一个物体。所有对象都具有相同的超类(GameObject)。 我有一个名为 selected 的字段,一次将等于一个特定的游戏对象。 单击鼠标右键时,它会检查所选实例是什么以及它如何确定将哪个对象放置在地面上。代码示例: t 是对象将要到达的“槽”。

if (selected instanceof MapleTree) {
    t = new MapleTree(game,highLight);
} else if (selected instanceof OakTree) {
        t = new OakTree(game,highLight);
}

现在它必须是对象的“新”实例。最终我的游戏将有数百个游戏对象,我不想有一个巨大的 if else 声明。我将如何制作它以便它滚动可能种类的对象,如果它的类型正确,然后创建它的一个新实例......?

当按下 E 时,它将切换选择的类型,并且也是一个 if else 语句。我该怎么做呢?这是一个代码示例:

if (selected instanceof MapleTree) {
        selected = new OakTree(game);
} else if (selected instanceof OakTree) {
    selected = new MapleTree(game);
}

【问题讨论】:

  • 我们正在尝试重制我的世界 :)
  • 我喜欢这里的每一篇与 java 和游戏有关的帖子都必须有人说确切的话,也许你可以帮忙而不是这样做。

标签: java object selection instanceof


【解决方案1】:

听起来你很适合使用Prototype

如果您想坚持使用显式路由,可以使用工厂方法的 HashMap。

如果你想隐式和自动化,你可以使用反射对实例类进行操作并检索随后调用的构造函数:http://docs.oracle.com/javase/tutorial/reflect/member/ctorInstance.html

上述一些方法的混合是确保每个类也实现一个静态(或非)工厂方法,如getInstance(),然后当你有你匹配的对象时,你可以调用那个工厂直接在该对象上的方法(或在它的类上保持静态静态)。这有点自动,但仍然更容易遵循。

【讨论】:

  • 但是当使用原型时,我将如何滚动可能的对象呢?
  • 您将克隆现有的选定一个,不需要条件。 selected 成为原型。
  • 似乎适用于第一个问题,但我不知道如何解决第二个问题。
  • 使用它时它不起作用,它不会给我一个“新”实例。
  • 只需遍历原型集合
【解决方案2】:

我对 Java 知之甚少,但建议您至少换掉很长的 if-else 树,以获得更好的可读性并且可能更快switch statement

【讨论】:

  • 您不能在 switch 语句中使用 instanceof。
【解决方案3】:

这是一个使用反射的示例。它假定按照惯例,您在所有 GameObject 子类中都有相同的构造函数签名。

如果您想“滚动浏览所有对象的列表”,您必须自己维护一组所有不同的类。然后,您可以使用与克隆和现有方法相同的方法来构建新的。

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class GameTest {

public static class Game {
    // TODO
}
public static abstract class GameObject {
    protected GameObject( Game game ) {
        // TODO
    }
}

public static class MapleTree extends GameObject {
    // Copy constructor
    public MapleTree( MapleTree tree, Game game ) {
        super( game );
        // TODO, copy
    }
}

public <T extends GameObject> T buildNew( Class<T> clazz, Game game ) {
    try {
        final Constructor<T> constructor = clazz.getConstructor( Game.class );
        return constructor.newInstance( game );
    }
    catch ( NoSuchMethodException | SecurityException
        | InstantiationException | IllegalAccessException
        | IllegalArgumentException | InvocationTargetException e ) {
        e.printStackTrace();
    }
    return null;
}

public GameObject cloneSelected( GameObject selected, Game game ) {
    return buildNew( selected.getClass(), game );
}
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-20
    • 2019-07-28
    • 2017-09-28
    • 1970-01-01
    • 2013-06-18
    • 1970-01-01
    相关资源
    最近更新 更多