- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我在为我的 C# XNA 游戏做出架构决策时遇到困难。
世界中的基本实体,例如树、僵尸或玩家,都表示为游戏对象。每个 GameObject 至少由一个 GameObjectController
、GameObjectModel
和 GameObjectView
组成。
这三个对于简单的实体来说已经足够了,比如无生命的树木或岩石。然而,当我尝试尽可能地保留功能时,继承开始变得笨拙。从语法上讲,我什至不确定如何最好地实现我的目标。
这是GameObjectController
:
public class GameObjectController
{
protected GameObjectModel model;
protected GameObjectView view;
public GameObjectController(GameObjectManager gameObjectManager)
{
this.gameObjectManager = gameObjectManager;
model = new GameObjectModel(this);
view = new GameObjectView(this);
}
public GameObjectManager GameObjectManager
{
get
{
return gameObjectManager;
}
}
public virtual GameObjectView View
{
get
{
return view;
}
}
public virtual GameObjectModel Model
{
get
{
return model;
}
}
public virtual void Update(long tick)
{
}
}
我想指定 GameObjectController
的每个子类至少可以访问 GameObjectView
和 GameObjectModel
。如果子类可以很好地使用这些类,但可能正在覆盖更复杂的 Update()
方法,我不希望它们必须复制代码来生成这些依赖项。因此,GameObjectController
构造函数会设置这些对象。
但是,有些对象确实想要覆盖模型和 View 。这就是问题所在。
一些对象需要战斗,所以它们是CombatantGameObjects
:
public class CombatantGameObject : GameObjectController
{
protected new readonly CombatantGameModel model;
public new virtual CombatantGameModel Model
{
get { return model; }
}
protected readonly CombatEngine combatEngine;
public CombatantGameObject(GameObjectManager gameObjectManager, CombatEngine combatEngine)
: base(gameObjectManager)
{
model = new CombatantGameModel(this);
this.combatEngine = combatEngine;
}
public override void Update(long tick)
{
if (model.Health <= 0)
{
gameObjectManager.RemoveFromWorld(this);
}
base.Update(tick);
}
}
还是很简单的。我使用 new
来隐藏实例变量是否正确?请注意,我在这里分配 CombatantObjectController.model
,即使 GameObjectController.Model
已经设置。而且,战斗人员不需要任何特殊的 View 功能,因此他们不用理会 GameObjectController.View
。
然后我开始研究 PlayerController
,在那里发现了一个错误。
public class PlayerController : CombatantGameObject
{
private readonly IInputReader inputReader;
private new readonly PlayerModel model;
public new PlayerModel Model
{
get { return model; }
}
private float lastInventoryIndexAt;
private float lastThrowAt;
public PlayerController(GameObjectManager gameObjectManager, IInputReader inputReader, CombatEngine combatEngine)
: base(gameObjectManager, combatEngine)
{
this.inputReader = inputReader;
model = new PlayerModel(this);
Model.Health = Constants.PLAYER_HEALTH;
}
public override void Update(long tick)
{
if (Model.Health <= 0)
{
gameObjectManager.RemoveFromWorld(this);
for (int i = 0; i < 10; i++)
{
Debug.WriteLine("YOU DEAD SON!!!");
}
return;
}
UpdateFromInput(tick);
// ....
}
}
第一次执行这一行时,我得到一个空引用异常:
model.Body.ApplyImpulse(movementImpulse, model.Position);
model.Position
看model.Body
,为null。
这是一个在游戏对象被部署到世界之前初始化游戏对象的函数:
public void Initialize(GameObjectController controller, IDictionary<string, string> data, WorldState worldState)
{
controller.View.read(data);
controller.View.createSpriteAnimations(data, _assets);
controller.Model.read(data);
SetUpPhysics(controller,
worldState,
controller.Model.BoundingCircleRadius,
Single.Parse(data["x"]),
Single.Parse(data["y"]), bool.Parse(data["isBullet"]));
}
每个对象都作为 GameObjectController
传递。这是否意味着如果对象真的是一个 PlayerController
,controller.Model
将引用基础的 GameObjectModel
而不是 PlayerController
的覆盖 PlayerObjectModel
?
回应rh:
This means that now for a PlayerModel p, p.Model is not equivalent to ((CombatantGameObject)p).Model, and also not equivalent to ((GameObjectController)p).Model.
这正是我不想要的。我要:
PlayerController p;
p.Model == ((CombatantGameObject)p).Model
p.Model == ((GameObjectController)p).Model
我该怎么做? 覆盖
?
最佳答案
关键在于你在这里使用了'new'关键字:
private new readonly PlayerModel model;
public new PlayerModel Model
{
get { return model; }
}
这里:
protected new readonly CombatantGameModel model;
public new virtual CombatantGameModel Model
{
get { return model; }
}
您的意思是:“我知道我的基类已经定义了这些,但我想定义不同的那些恰好具有相同名称的。”
这意味着现在对于 PlayerModel p,p.Model 不等同于 ((CombatantGameObject)p).Model,并且不等同于 ((GameObjectController) )p).模型。
您可以通过以下几种方式继续。
1) 不要提供强类型的子属性。我知道这起初听起来可能很糟糕,但它实际上是一个非常强大的概念。如果您的基础模型定义了适用于所有子类的适当抽象/虚拟方法,您可以在基类中定义一次属性并完成。然后子类可以提供自己的实现。
这是一种可能的实现方式。
public class GameObjectController /* ... */
{
/* ... */
public GameObjectController()
{
Model = new GameObjectModel(this);
}
public GameObjectModel Model { get; protected set; }
}
public class CombatantGameObject : GameObjectController
{
/* ... */
public CombatantGameObject()
{
Model = new CombatantModel(this);
}
}
/* ... */
2) 在通过子类访问时提供强类型属性,但将字段一次存储在基类中。
这可以工作,但要正确执行却很棘手。这不是我的第一选择。
public class GameObjectController /* ... */
{
/* ... */
public GameObjectController()
{
Model = new GameObjectModel(this);
}
public GameObjectModel Model { get; protected set; }
}
public class CombatantGameObject : GameObjectController
{
/* ... */
public CombatantGameObject()
{
Model = new CombatantModel(this);
}
public new CombatantModel Model
{
get
{
return (CombatantModel)base.Model;
}
protected set
{
base.Model = value;
}
}
}
/* ... */
另外,要警惕过早地过度致力于复杂的对象模型。有时,从简单开始并积极重构,是获得反射(reflect)代码最终实际工作方式的良好模型的最佳方式。
关于C#:继承、覆盖和隐藏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2597243/
代码如下: http://jsfiddle.net/t2nite/KCY8g/ 我正在使用 jquery 创建这些隐藏框。 每个框都有一些文本和一个“显示”和“隐藏”按钮。我正在尝试创建一个“显示/隐
我正在尝试做某事。如果单击一个添加 #add-conferance 然后菜单将显示.add-contact。当点击隐藏然后它显示隐藏。我也将 setTimeout 设置为 7sec,但我希望当我的鼠标
我有一个多步骤(多页?)表单,只要用户按下“下一步”或“上一步”按钮,表单字段就会通过 div 显示和隐藏。 我只想禁用第一个 div (div id="page1"class="pageform")
我有一个使用 IIS 6 和 7 的当前系统,用 ASP.NET 和 .NET 4 中的 C# 编写。 My purpose is to hide the url completely (as per
我正在建立一个网站,并有一个幻灯片。幻灯片有标题和索引,覆盖整个页面。当覆盖被激活时,标题需要消失。当覆盖层被停用时,通过单击退出按钮、缩略图链接或菜单链接,字幕必须返回。 这就是我目前所拥有的
我正在尝试为显示/隐藏功能制作简单的 jquery 代码。但我仍然做错了什么。 $(document).ready(function(){ $('.arrow').click(function
我有一个自定义对话框并使用它来代替 optionMenu。所以我希望 myDialog 表现得像菜单,即在按下菜单时显示/隐藏。我尝试了很多变体,但结果相同: 因为我为 myDialog 设置了一个
在我的项目中,我通过 ViewPager 创建我的 tabBar,如下所示: MainActivity.java mViewPager = (ViewPager) findViewById(R.id.
我目前正在使用一个 Excel 表,我将第 1-17 行分组并在单元格 B18 中写入了一个单元格值。我想知道当我在展开/折叠行时单击 +/- 符号时是否有办法更改 B18 中的值。 例如:我希望 B
我想创建一个按钮来使用 VBA 隐藏和取消隐藏特定组。我拥有的代码将隐藏或取消隐藏指定级别中的所有组: Sub Macro1() ActiveSheet.Outline.ShowLevels RowL
我是 VBA 新手。我想隐藏从任何行到工作表末尾的所有行。 我遇到的问题是我不知道如何编程以隐藏最后写入的行。 我使用下一个函数知道最后写入的单元格,但我不知道在哪里放置隐藏函数。 last = Ra
我想根据另一个字段的条件在 UI 上隐藏或更新一个字段。 例如,如果我有一个名为 Color 的字段: [PXUIField(DisplayName="Color")] [PXStringList("
这是我尝试开始收集通常不会遇到的 GCC 特殊功能。这是@jlebedev 在另一个问题中提到g++的“有效C++”选项之后, -Weffc++ This option warns about C++
我开发了一个 Flutter 应用程序,我使用了 ProgressDialog小部件 ( progress_dialog: ^1.2.0 )。首先,我展示了 ProgressDialog小部件和一些代
我需要在 API 17+ 的同一个 Activity(Fragment) 中显示/隐藏状态栏。假设一个按钮将隐藏它,另一个按钮将显示它: 节目: getActivity().getWindow().s
是否可以通过组件的 ts 代码以编程方式控制下拉列表的显示/隐藏(使用 Angular2 清楚)- https://vmware.github.io/clarity/documentation/dro
我想根据 if 函数的结果隐藏/显示 NiceScroll。 在我的html中有三个部分,从左到右逐一滚动。 我的脚本如下: var section2 = $('#section2').offset(
我有这个 jquery 代码: $(document).ready(function(){ //global vars var searchBoxes = $(".box"); var searchB
这个问题已经有答案了: Does something like jQuery.toggle(boolean) exist? (5 个回答) 已关闭 6 年前。 在 jQuery 中(我当前使用的是 1
我在这样的选择标签上使用 jQuery 的 selectMenu。 $('#ddlReport').selectmenu() 在某些情况下我想隐藏它,但我不知道如何隐藏。 这不起作用: $('#ddl
我是一名优秀的程序员,十分优秀!