Questions tagged «architecture»

代码的结构。有关游戏引擎内部设计的问题。

1
将物理和游戏逻辑与UI代码分开
我正在研究一个简单的基于块的益智游戏。 游戏过程由游戏区域中的许多移动块组成,因此这是一个简单的物理模拟。但是,我认为我的实现还远远不够理想,我想知道您是否可以为我提供任何有关如何更好地实现的建议。 我将代码分为两个区域:游戏逻辑和UI,就像我处理许多益智游戏一样: 游戏逻辑负责游戏的一般规则(例如国际象棋中的正式规则系统) UI显示游戏区域和棋子(例如棋盘和棋子),并负责动画(例如棋子的动画移动) 游戏逻辑将游戏状态表示为逻辑网格,其中每个单位是一个单元格在网格上的宽度/高度。因此,对于宽度为6的网格,可以将宽度为2的块移动四次,直到其与边界碰撞。 UI会获取此网格,然后通过将逻辑大小转换为像素大小(即,将其乘以一个常数)来绘制它。但是,由于游戏几乎没有任何游戏逻辑,因此我的游戏逻辑层[1]除了碰撞检测之外没有其他工作。运作方式如下: 玩家开始拖动一块 用户界面要求游戏逻辑确定该棋子的合法移动区域,并让玩家将其拖到该区域内 玩家放手 UI将样片捕捉到网格(以便它位于有效的逻辑位置) UI告诉游戏逻辑新的逻辑位置(通过mutator方法,我宁愿避免) 我对此不太满意: 我正在为我的游戏逻辑层而不是UI编写单元测试,结果所有棘手的代码都在UI中:阻止该部分与其他对象或边界碰撞并将其捕捉到网格中。 我不喜欢UI告诉游戏逻辑有关新状态的事实,我宁愿让它调用movePieceLeft()方法或类似的方法,就像我在其他游戏中一样,但是我对这种方法没有了解,因为游戏逻辑对用户界面中可能发生的拖动和捕捉一无所知。 我认为最好的办法是摆脱游戏逻辑层,改为实现物理层。我对此有一些疑问: 这样的物理层是常见的,还是让游戏逻辑层更典型地做到这一点? 捕捉到网格和片段拖动代码是属于UI还是物理层? 这样的物理层通常可以与像素大小或某种逻辑单位(例如我的游戏逻辑层)一起使用吗? 我曾经在游戏的代码库中看到过基于事件的碰撞检测,即玩家只需拖动棋子,UI就会顺从地渲染并通知物理系统,物理系统将调用onCollision()方法一旦检测到碰撞,就会在工件上撞上。更常见的是什么?这种方法还是先要求法律流通领域? [1] 层可能不是我所要表达的正确词,但是子系统听起来有些夸大其词,而类却是错误的,因为每一层都可以包含多个类。

2
小型游戏开发团队的有效策略是什么?[关闭]
按照目前的情况,这个问题并不适合我们的问答形式。我们希望答案得到事实,参考或专业知识的支持,但是这个问题可能会引起辩论,争论,民意调查或扩展讨论。如果您认为此问题可以解决并且可以重新提出,请访问帮助中心以获取指导。 8年前关闭。 对于由中级到高级开发人员组成的小型游戏开发团队,与语言/平台无关的最佳做法是什么? 欢迎使用高级策略(以及可能提供良好ROI的有关框架,引擎或IDE的建议)。

9
如何处理GUI元素?
注意:我计划制作自己的GUI系统。这对于学习,轻量级,只有我需要的部分,与游戏的联系等将非常有用。 我在考虑该怎么做。我的意思是: 单选按钮 在此处输入文本框 纽扣 滑杆 选框 我还没有考虑如何制作它们。但是更多的是他们将如何发展。 理念 我希望每个州都需要东西,所以几乎所有州都有一个元素容器。每个元素都是一个GUI件。 这些都有位置,图形等。 我更坚持的是他们的逻辑。 我的想法是,允许模块化和简单性是避免使用MainMenuStartButton。一个OptionsOneBackButton等等,而不是能够做Slider slide1; 或按钮启动; 取而代之的是,每个函数都将具有boost :: function到GUI名称空间中的函数,例如Gui :: StartButtonClick或GUI :: ColourSliderHover。 我只是想知道这是否会异常缓慢。 因此,有没有简单,简单的方法来制作游戏的GUI?没有Qt,wxWidgets或其他任何东西。
12 c++  architecture  gui 

6
我应该在策略游戏后面放一个配乐吗?哪些游戏需要音乐和声音
混洗卡和撞击声很酷(这是一款基于纸牌的游戏),但是我应该花时间/精力来连接背景音乐吗?我发现使用C#从流中播放音频,如果可以使用在线或类似代码来播放本地MP3,则可以用于挂钩到DI,但这值得吗?哪些游戏类型需要它,哪些游戏可以没有?放开它而不添加它,并将其添加为.5功能?

5
为什么要使用资产清单文件?
有时您会看到人们建议这样做,而不是使用图形/声音文件/等。像这样... // Game code Image myImage = new Image("path/to/image.png"); ...您应该使用清单文件作为间接级别: // Manifest file MY_IMAGE: path/to/image.png // Game code Manifest myManifest = new Manifest("path/to/manifest"); Image myImage = myManifest.getImage("MY_IMAGE"); 我采用这种方法会有什么原因?如果我不使用编译语言,还会有理由这样做吗?

1
创建健壮的物品系统
我的目标是创建一个模块化/尽可能通用的物料系统,该系统可以处理以下内容: 可升级物品(+6武士刀) Stat修饰符(+15敏捷) 物品修饰符(%X几率造成Y伤害,几率冻结) 充电物品(魔术师使用30次) 套装物品(装备4件X激活Y功能) 稀有度(常见,独特,传奇) 可分解的(分解成一些手工材料) 可制作(可以使用某些材料制作) 消耗(5分钟%X攻击强度,恢复+15 hp) *我能够解决以下设置中加粗的功能。 现在,我尝试添加许多选项以反映我的想法。我不打算添加所有必要的功能,但是我希望能够按照自己的意愿实施它们。这些也应该与库存系统和数据序列化兼容。 我计划完全不使用继承,而是使用实体组件/数据驱动的方法。最初,我想到的系统具有: BaseStat:通用类,可随时随地保存统计信息(也可用于项和字符统计信息) Item:包含数据的类,例如列表,名称,itemtype和与ui,actionName,description等相关的事物。 IWeapon:武器界面。每个武器都有实现IWeapon的自己的类。这将具有Attack(攻击)和对角色统计的引用。装备武器后,它的数据(物品类别的stat)将被注入角色stat(无论拥有什么BaseStat,它都会作为Stat奖励添加到角色类别中)因此,例如,我们想制作一把剑(想产生带有json的物品类),所以剑将对角色属性增加5点攻击。因此,我们有一个BaseStat为(“ Attack”,5)(我们也可以使用enum)。装备时,此属性将作为BonusStat(将是不同的类)添加到角色的“攻击”属性中。因此,名为Sword的类将实现IWeapon,项目类别已创建。因此,我们可以向这把剑注入角色统计数据,并且在攻击时,它可以从角色统计数据中检索总的攻击统计数据,并在Attack方法中造成伤害。 BonusStat:是一种将统计信息添加为奖励而无需触及BaseStat的方法。 IConsumable:与IWeapon相同的逻辑。添加直接属性相当容易(+15 hp),但是我不确定要使用此设置添加临时武器(%x攻击5分钟)。 IUpgradeable:可以使用此设置来实现。我正在考虑将UpgradeLevel作为基本属性,在升级武器时会增加它。升级后,我们可以重新计算武器的BaseStat以匹配其升级级别。 在此之前,我可以看到该系统相当不错。但是对于其他功能,我认为我们还需要其他东西,因为例如,我无法在其中实现Craftable功能,因为我的BaseStat无法处理该功能,这就是我遇到的问题。我可以将所有成分添加为统计信息,但这没有任何意义。 为了使您更轻松地进行此操作,以下一些问题可能会对您有所帮助: 我是否应该继续执行此设置以实现其他功能?没有继承就可能吗? 您有什么办法可以想到,在没有继承的情况下实现所有这些功能? 关于物品修饰符,如何实现?因为它的性质非常通用。 有什么建议可以做些什么来简化构建这种架构的过程? 有没有我可以挖掘的与此问题相关的来源? 我确实尽力避免继承,但是您认为在保持相当可维护性的同时,可以轻松地通过继承解决/实现这些继承吗? 由于我的问题范围很广,因此可以随意回答一个问题,这样我就可以从不同的方面/人那里获得知识。 编辑 遵循@ jjimenezg93的回答,我用C#创建了一个非常基本的系统进行测试,它可以正常工作!看看是否可以添加任何内容: public interface IItem { List<IAttribute> Components { get; set; } void ReceiveMessage<T>(T message); } public interface …

3
将相同组件集的实体分组到线性内存中
我们从基本的系统-组件-实体方法开始。 让我们创建组合(源自长期本文章)仅仅是出于对信息类型的组件。它是在运行时动态完成的,就像我们将组件一个接一个地添加/删除到实体中一样,但是让我们更精确地命名它是因为它仅涉及类型信息。 然后,我们构造为每个实体指定集合的实体。创建实体后,它的组合是不可变的,这意味着我们无法直接对其进行修改,但是仍然可以获得现有实体对本地副本的签名(以及内容),对其进行适当的更改,然后创建一个新实体它的。 现在是关键概念:每创建一个实体,就会将其分配给一个名为assemblage bucket的对象,这意味着具有相同签名的所有实体都将位于同一容器中(例如,在std :: vector中)。 现在,系统只是遍历他们感兴趣的每个环节并完成工作。 这种方法有一些优点: 组件存储在几个(精确地:存储桶数)连续的内存块中-这提高了内存友好性,并且更容易转储整个游戏状态 系统以线性方式处理组件,这意味着改进了缓存一致性-再见字典和随机存储器跳转 创建新实体就像将组合映射到存储桶并将所需组件推回其向量一样容易 删除一个实体就像调用std :: move一样容易,将最后一个元素与删除的元素交换,因为此时顺序并不重要 如果我们有很多具有完全不同的签名的实体,那么缓存一致性的好处就会减少,但是我认为大多数应用程序都不会发生这种情况。 重新分配向量后,指针失效也存在问题-可以通过引入以下结构来解决: struct assemblage_bucket { struct entity_watcher { assemblage_bucket* owner; entity_id real_index_in_vector; }; std::unordered_map<entity_id, std::vector<entity_watcher*>> subscribers; //... }; 因此,只要出于游戏逻辑中的某种原因,我们想要跟踪一个新创建的实体,就在存储桶中注册一个entity_watcher,并且一旦在删除期间必须将该实体std :: move移开,我们便会查找其观察者并进行更新他们real_index_in_vector的新价值。在大多数情况下,这对每个实体删除都仅施加了一个字典查找。 这种方法还有其他缺点吗? 尽管很明显,为什么没有提到解决方案? 编辑:我正在编辑问题以“回答答案”,因为评论不足。 您将失去可插拔组件的动态特性,该特性是为摆脱静态类构造而专门创建的。 我不。也许我没有足够清楚地解释它: auto signature = world.get_signature(entity_id); // this would just return …

5
如何在基于组件的游戏中正确处理碰撞?
在围绕组件设计的游戏中,尝试绕过正确处理碰撞的方法。 我看到许多示例PhysicsComponent在实体的组件列表中添加了某种示例,但实际的实现使我感到困惑。 为了PhysicsComponent使它起作用,需要访问周围的环境。这对我来说没有直觉。组件不应该不仅意识到其容器(实体),还没有意识到其容器的容器(世界)吗? 对我来说,听起来好像关卡或场景应该维护这些实体的列表,并且每次游戏更新都会遍历这些实体以确定哪个碰撞。 我的问题是,首先,这是否是好的设计,其次,如何确定哪些实体会发生冲突。我想实体实体可以实现一个空的IRigidBody接口,以便该级别可以确定列表中的哪些实体支持冲突。但这会破坏组件设计吗? 相反,它们应该包含一个空的RigidBody成分吗?实际上,这可能会更好,因为它可能并不总是空的,而且这种方法更适合未来。唯一的问题是复杂性。场景不仅必须遍历每个实体,还必须遍历每个实体的组件,以确定它是否具有此RigidBody组件。 第三,当它们确实发生碰撞时,应该以某种方式告知两个实体,我也不确定如何做到这一点。 假设两个实体都包含一个HealthComponent,并且当它们碰撞时,两个实体的健康状况都会降低一些任意值5。我想当场景中检测到两个实体之间发生碰撞时,要负责处理此问题? 但是,现场是否要承担太多责任?当场景负责实体不应该访问的许多事物时,我可以看到这种情况可能会变得一发不可收拾并且变得笨拙。 编辑:问题已更新,具有更多详细信息。

3
我想摆脱我的“制作一切静态和全局”设计模式,但是如何做呢?
我正在太空中制作一个小地牢爬行者,我想听听一些有关如何使引擎后端更好的建议。基本上,当前所有内容都是基于管理人员的: BackgroundManager:具有AddBackground(image, parallax)制作炫酷背景效果的方法。 ConfigManager:读取/制作配置文件,还保存从该配置文件读取的数据。 DrawManager:有Draw(sprite)方法来绘制的东西到屏幕上,事情就是这样SetView(view),GetView()等等。 EntityManager:包含所有活动实体,并具有添加,删除和查找实体的方法。 DungeonManager(实际上称为GridManager,但这是为了简单):有方法,如GenerateDungeon(),PlaceEnemies(),PlaceFinish()等。 现在我什至没有列出所有我的经理,所以我认为这必须改变。我的游戏也基于屏幕,这使它更令人讨厌,因为我不需要经理管理的一半内容,例如主菜单(我的主菜单中不需要物理/实体/地下城) !) 现在,我考虑使管理器不是静态的,并为我的ScreenMainGame提供所有特定于游戏的管理器的实例。但这使打电话给/获取与管理人员有关的任何东西变得一团糟...例如,如果我想从不在的任何地方绘制地牢ScreenMainGame.Draw(),我就必须这样做... ((ScreenMainGame)ScreenManager.CurrentScreen).GridManager.Draw() 真丑。 那么,游戏开发者们,你们有谁知道如何解决这个混乱局面吗?我将不胜感激!

4
如何在基于回合,基于距离的策略游戏中确定可能的运动范围?
我正在使用c ++和SFML-2.0创建一个二维的,基于回合的策略游戏。运动是基于距离的,而不是基于网格的,具有几个不同的三角形块,这些三角形块在给定的转弯中可以就位旋转或向前移动。 移动将以这样的方式进行:玩家选择棋子要移动到的位置,从而为棋子生成一条可能的路径。玩家确认自己的决定后,棋子将沿着该路径移动到所需位置。路径受到两个因素的限制:距离,一块东西可以走多远,考虑任何转弯(因此,如果有一条曲线,它将是沿着曲线的长度,而不是直接从一点到另一点);和转向角,即在移动(例如,从-30度到30度)时,该零件在任何(以及每个点)可以旋转多远。 我的问题是,我应该如何确定玩家可以选择将棋子移动到的潜在位置范围? 我不确定要在这里使用什么方程式和/或算法。我最初的计划过于复杂,以至于几乎无法实施,更不用说解释了,在这一点上,我因项目停滞而完全迷失了。 考虑到其转弯半径,如何确定设备可以移动的范围? 例如,在下图中。红线,蓝线和绿线的长度都相同。紫色圆圈表示单位可以移动的移动范围。(形状可能不准确,线条的长度实际上可能不相同,但您会明白的)

2
我该如何使好人攻击只击中坏人,反之亦然?
我的游戏有许多不同类型的好人和许多不同类型的坏人。他们都将向对方发射弹丸,但我不希望任何对准都会发生意外附带损害。因此,坏人不应该打/伤害其他坏人,好人不应该打/伤害其他好人。 我想解决此问题的方法是通过使其Unit实例(这是javascript,btw)具有alignment可以为goodor 的属性bad。而且我只会让碰撞发生 class Attack boolean didAttackCollideWithTarget(target) return attack.source.alignment != target.alignment and collisionDetected(attack.source, target) 当然,这是伪代码。 但是我之所以问这个问题,是因为我觉得除了在Unit类中添加另一个属性之外,还有一种更优雅的方法来设计它。

2
将角色的技能和能力作为命令,很好的做法?
我正在设计一款包含具有独特进攻技能和其他能力(例如建造,修理等)的角色的游戏。玩家可以控制多个这样的角色。 我正在考虑将所有这些技能和能力放到单独的命令中。静态控制器会将所有这些命令注册到静态命令列表中。静态列表将包含游戏中所有角色的所有可用技能和能力。因此,当玩家选择一个角色并单击UI上的按钮以投射咒语或执行一项功能时,View会调用静态控制器从列表中获取所需命令并执行该命令。 但是,鉴于我要在Unity中构建游戏,因此我不确定这是否是一个好的设计。我想我可以将所有技能和能力作为独立的组件,然后将其附加到代表游戏角色的GameObjects上。然后,UI将需要保留角色的GameObject,然后执行命令。 对于我正在设计的游戏,什么是更好的设计和实践?

4
如何在不破坏每个实体单一类型的一个组件的情况下,为每个实体使用多个网格?
我们只是从基于层次的游戏引擎切换到基于组件的游戏引擎。我的问题是,当我加载具有网格层次结构的模型时,我的理解是,基于组件的系统中的实体不能具有相同类型的多个组件,但是每个组件都需要一个“ meshComponent”在模型中进行网格划分。那么我该如何解决这个问题。 他们在此站点上实现了基于组件的游戏引擎:http : //cowboyprogramming.com/2007/01/05/evolve-your-heirachy/

6
游戏状态管理(游戏,菜单,标题屏幕等)
基本上,到目前为止,在我制作的每个游戏中,我总是有一个变量,例如“ current_state”,可以是“ game”,“ titlescreen”,“ gameoverscreen”等。 然后在我的Update函数上,我有一个庞大的功能: if current_state == "game" game stuf ... else if current_state == "titlescreen" ... 但是,我觉得这不是处理状态的专业/干净方法。关于如何更好地执行此操作的任何想法?还是这是标准方式?

2
在简单的冒险游戏中实现行为
我最近一直在通过编写一个简单的基于文本的冒险游戏来娱乐自己,而我一直停留在看似非常简单的设计问题上。 简要概述一下:游戏分为Room对象。每个对象都有该房间Room中的Entity对象的列表。每个对象Entity都有一个事件状态,它是一个简单的string-> boolean映射,以及一个动作列表,它是一个string-> function映射。 用户输入采用形式[action] [entity]。在Room使用实体名称返回合适的Entity对象,然后使用操作名称来找到正确的功能,并执行它。 为了生成房间描述,每个Room对象显示其自己的描述字符串,然后附加每个的描述字符串Entity。该Entity描述可基于其状态(“门被打开”,“门关闭”,“门被锁定”,等等)。 问题出在这里:使用这种方法,我需要快速实现的描述和动作函数的数量就一发不可收拾。我的起居室仅在5个实体之间就具有约20种功能。 我可以将所有动作组合为一个函数,并通过if-else /进行切换,但是每个实体仍然是两个函数。我还可Entity以为常见/通用对象(例如门和钥匙)创建特定的子类,但是到目前为止,这还不多。 编辑1:根据要求,这些动作函数的伪代码示例。 string outsideDungeonBushesSearch(currentRoom, thisEntity, player) if thisEntity["is_searched"] then return "There was nothing more in the bushes." else thisEntity["is_searched"] := true currentRoom.setEntity("dungeonDoorKey") return "You found a key in the bushes." end if string dungeonDoorKeyUse(currentRoom, thisEntity, player) if getEntity("outsideDungeonDoor")["is_locked"] then getEntity("outsideDungeonDoor")["is_locked"] := …

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.