星战游戏开发:如何在实例化LightSaber类时自动调用canWield方法?
问题分析
你遇到的核心问题是canWield方法没有被主动触发——它目前只是一个孤立的方法,不管是实例化LightSaber还是调用setItemCarried时,都没有任何代码逻辑去调用它。下面给你几个从快速修复到架构优化的解决方案:
方案1:直接在setItemCarried中触发检查
这是最直接的修复方式,因为setItemCarried是将物品交给演员的关键节点,正好是检查演员是否能使用该物品的最佳时机。修改你的setItemCarried方法:
public void setItemCarried(SWEntityInterface target) { this.itemCarried = target; // 检查携带物品是否为光剑,是的话立刻触发权限检查 if (target instanceof LightSaber) { ((LightSaber) target).canWield(this); } }
这样当你执行setItemCarried(bensweapon)时,就会自动调用光剑的canWield方法,传入当前的SWActor实例(也就是this),完成武器标记的逻辑。
方案2:用接口实现可扩展性(推荐)
如果你的游戏未来可能加入其他需要"使用权限检查"的武器(比如原力权杖、特制爆能枪),定义一个通用接口会让代码更整洁、更易维护:
首先创建一个Wieldable接口:
public interface Wieldable { // 统一定义检查物品是否可被actor使用的方法 void checkWieldCapability(SWActor actor); }
然后修改LightSaber实现这个接口(可以把原方法名重命名得更清晰):
public class LightSaber extends SWEntity implements Wieldable { // 记得补充定义minForcePoints变量,比如给个默认值 private int minForcePoints = 100; public LightSaber(MessageRenderer m) { super(m); this.shortDescription = "A Lightsaber"; this.longDescription = "A lightsaber. Bzzz-whoosh!"; this.hitpoints = 100000; this.addAffordance(new Take(this, m)); } @Override public void checkWieldCapability(SWActor actor) { if (actor.getForcepoints() >= minForcePoints) { this.capabilities.add(Capability.WEAPON); } else { // 可选:如果原力不够,移除武器标记(避免之前的标记残留) this.capabilities.remove(Capability.WEAPON); } } }
最后更新setItemCarried来支持所有Wieldable类型的物品:
public void setItemCarried(SWEntityInterface target) { this.itemCarried = target; // 对所有可使用的物品自动执行权限检查 if (target instanceof Wieldable) { ((Wieldable) target).checkWieldCapability(this); } }
这种方式的好处是,以后新增任何需要使用权限的物品,只要实现Wieldable接口,setItemCarried就能自动处理检查逻辑,不需要重复修改这个方法。
补充注意点
- 确保
minForcePoints变量在LightSaber中已定义(你的代码里没看到这个变量的声明,记得补上私有变量并设置默认值)。 - 如果光剑在多个演员之间传递,每次调用
setItemCarried都会重新检查权限,这正好符合逻辑——不同演员的原力值不同,权限自然会动态变化。
内容的提问来源于stack exchange,提问作者Sook Lim
相关产品推荐
相关产品推荐

