首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在游戏中使用视觉主题

在游戏中使用视觉主题
EN

Code Review用户
提问于 2013-09-10 19:01:13
回答 4查看 258关注 0票数 2

在我的小应用程序中,我需要使用各种视觉主题。

这类的简化结构:

主题曲:.__菜单,.__,screenBackground,.__,itemsColor,getRandomItemAnimation,getRandomItemAnimation(),.__,getRandomItemAnimation,.__,getRandomItemAnimation,.__,.__,getRandomItemAnimation,.__,getRandomItemAnimation,.__,.__,getRandomItemAnimation,.__,getRandomItemAnimation,.__,.__,getRandomItemAnimation,.__,getRandomItemAnimation,.__,.__,getRandomItemAnimation,.__,.__,getRandomItemAnimation

我想写这样的代码:

代码语言:javascript
复制
setBackground(theme.game.screenBackground)

而不是

代码语言:javascript
复制
setBackground(theme.game().screenBackground())

但除此之外,我还想使用继承。但是,Java似乎不允许覆盖子类中父类的公共字段。

因此,我决定使用以下实现:

基类:

代码语言:javascript
复制
// All constructors (in the next 3 classes) used to set final class-members by descendants

public abstract class Theme {
    public final MenuTheme menu;
    public final GameTheme game;

    public abstract Image getRandomStartScreenImage();

    public Theme(MenuTheme menuTheme, GameTheme gameTheme) {
        this.menuTheme = menuTheme;
        this.gameTheme = gameTheme;
    }
}

public abstract class MenuTheme {
    public final Image screenBackground;
    public final Color itemsColor;

    public abstract Animation getRandomItemAnimation();

    public MenuTheme(Image screenBackground, Color itemsColor) {
        this.screenBackground = screenBackground;
        this.itemsColor = itemsColor;
    }
}

public abstract class GameTheme {
    public final Image screenBackground;
    public final Image gameBoardBackground;

    public abstract Sound getRandomMoveSound();

    public GameTheme(Image screenBackground, Image gameBoardBackground) {
        this.screenBackground = screenBackground;
        this.gameBoardBackground = gameBoardBackground;
    }
}

使用:

代码语言:javascript
复制
public class Menu {
    public void setUp() {
        Theme theme = GameContext.getCurrentTheme();
        setBackground(theme.menu.screenBackground);
        setItemsColor(theme.menu.itemsColor);
    }

    public void onClickItem(Item clickedItem) {
        Theme theme = GameContext.getCurrentTheme();
        clickedItem.startAnimation(theme.menu.getRandomItemAnimation());
        // Action action = getActionByItem(clickedItem);
        // action.start();
    }
}

如何添加主题:

代码语言:javascript
复制
public class DarkTheme extends Theme {
    private Image[] startScreenImages = getStartScreenImages();

    public Image getRandomStartScreenImage() {
        return startScreenImages[getRandomIndex()];
    }

    public DarkTheme() {
        super(new DarkMenuTheme(), new DarkGameTheme());
    }
}

public class DarkMenuTheme extends MenuTheme {
    private Animation[] itemAnimations = getItemAnimations();

    public Animation getRandomItemAnimation() {
        return itemAnimations[getRandomIndex()];
    }

    public DarkMenuTheme() {
        super(getDarkMenuScreenBackground(), getDarkMenuItemsColor());
    }
}

public class DarkGameTheme {
    private Sound[] moveSounds = getMoveSounds();

    public Sound getRandomMoveSound() {
        return moveSounds[randomIndex()];
    }

    public DarkGameTheme() {
        super(getDarkGameScreenBackground(), getDarkGameBoardBackground());
    }
}

你对Theme的结构有什么看法?它看起来像一个很好的实现吗?

Theme的结构不会改变。只会增加新的主题。考虑到这一点,该代码的缺点和好处是什么?您可以推荐哪些改进或其他实现?

EN

回答 4

Code Review用户

回答已采纳

发布于 2013-09-10 20:30:07

我想编写这样的代码: setBackground(theme.game.screenBackground)而不是setBackground

读这个:http://c2.com/cgi/wiki?AccessorsAreEvil

网址有误导性,它是一篇“平衡”的文章,我想让你特别注意的部分是:

示例... --它们实际上是结构(数据),而不是完全的对象。

您的主题类应该是一个结构,并且太简单,不应该有getter。

响应@bowmore,主题不应该负责加载资源,主题应该真正返回资源标识符。

顺便说一句,如果是我,我可能会

game.drawBackground()

其中,游戏知道主题是什么,并从主题获取资源名称的背景,然后加载类加载,然后显示UI类。

票数 5
EN

Code Review用户

发布于 2013-09-10 19:44:56

我想编写这样的代码:setBackground(theme.game.screenBackground)而不是setBackground(theme.game().screenBackground())

为什么你要牺牲封装(面向对象设计的第一原则)来减少输入括号的小方便呢?

坦率地说,我看不到任何真正的好处,但我可以看到几个缺点:

  • 主题必须在施工时完全初始化。
  • 延迟加载或初始化是困难的,如果不是不可能的话,字段的嵌套暴露甚至使代理实现成为一个困难的选择。对于引用可能必须从文件中读取的重量级对象(图像、声音)的字段来说,这尤其痛苦。
  • API并不表示这些字段是不可变的。

我相信这些观点在Java以外的其他语言中也是有效的。

票数 4
EN

Code Review用户

发布于 2013-09-11 09:50:30

一言为定的建议

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/31065

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档