我目前正在XNA中创建一款游戏(因为Monogame与我相处并不相同。),主要是为了锻炼和所有这些。
但是,我有一个玩家和敌人会继承的角色类,有这些成员:
protected Texture2D sprite_;
protected Point origin_;
protected Rectangle colBox_;
protected Weapon weapon_;
protected controlPair control_;
protected CharState state_;
protected Actions action_;
这基本上是一些枚举和东西,以控制角色正在做什么,同时仍然使它能够自己调用base.Update(),所以我可以保存一些代码。 Player类还有一个自定义Keyboard对象来处理来自用户的键盘输入。
现在问题来了,我显然需要处理环境和敌人的碰撞,并没有真正看到一个很好的解决方案。我试图让游戏Update()看起来干净,让所有类都由类本身处理,使它看起来像这样:
if (Keyboard.GetState().IsKeyDown(Keys.Escape))
this.Exit();
foreach (IUpdating i in entityList)
i.Update(gameTime);
base.Update(gameTime);
我希望保持这种处理方式,因为它使代码可读,我能看到的唯一真正的方法是收集所有必要的碰撞数据并将其放入容器(List?)中,我将其发送到所有这些,包括那些根本不需要它的人。
所以主要的问题是,如果有一种方法可以让两个不同的对象在没有成员的情况下与彼此进行通信,或者我应该在创建角色派生对象之前创建所有的hitbox,然后将它们推送到成员控件中同时地图的所有hitbox?但是我猜我必须要有命中箱的指针才能正确更新。
我是否采用某种解决方案,或者是否有一种我不知道的更简单的方法?
答案 0 :(得分:0)
建议的解决方案:
让所有需要检查碰撞的对象实现一个接口,比如ICollidable,它包含HitBox(作为属性)和HandleCollision(ICollidable other);
HitBox是自解释的,HandleCollision方法会相应地修改与其他碰撞时的对象。
然后将所有ICollidable对象放在容器中(可能是List<>)。
List<ICollidable> iCollidableList = new List<ICollidable>();
//you add and remove objects to/from list as they come and go
然后在每个步骤中,您可以在嵌套循环中运行列表并相互检查所有对象,无论是否发生碰撞并单独处理每个对象上的碰撞,例如。
foreach(ICollidable obj1 in iCollidableList)
{
foreach(ICollidable obj2 in iCollidableList)
{
if(obj1 != obj2 && HitBoxesIntersect(obj1, obj2))
{
obj1.HandleCollision(obj2);
obj2.HandleCollision(obj1);
}
}
}
方法HitBoxesIntersect(ICollidable,ICollidable)显然会检查hitbox的碰撞。
答案 1 :(得分:0)
就个人而言,我有一个游戏板,它有一个功能,允许一个物体检查每个附近的元素,看看它是否与“碰撞”。您可以使用空间哈希(tutorial)来避免测试每个项目与整个列表。
Public overrides sub Update(Gametime gametime)
foreach (IUpdating i in entityList)
i.CollideWith(testCollistion(i))
i.Update(gameTime);
base.Update(gameTime);
end sub
Function TestCollision(myentity as Entity) as Entity
//test collision as per the tutorial
//return nothing if it doesnt collide, or the colliding entity if is does
end function
在你的实体类中,你可以使用sub collideWith来处理当你与特定类型的实体(敌人,盟友,atc)发生碰撞时会发生什么
Overridable Sub CollideWith(entity as Entity)
if not IsNothing(entity) then
//set your FSM or any direct actions depending on the results
If typeof entity is EnemyEntity then ReceiveDamage(entity.attack)
If typeof entity is NPCEntity then TalkTo(entity)
end if
end sub