火星任务(5):燃料化学(译文)
By robot-v1.0
本文链接 https://www.kyfws.com/games/mars-mission-5-the-chemistry-of-fuel-zh/
版权声明 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
- 44 分钟阅读 - 21906 个词 阅读量 0火星任务(5):燃料化学(译文)
原文地址:https://www.codeproject.com/Articles/221234/Mars-Mission-5-the-Chemistry-of-Fuel
原文作者:Christ Kennedy
译文由本站 robot-v1.0 翻译
前言
adding chemical elements the ships can use as fuel, and a new auto-pilot feature
添加船舶可以用作燃料的化学元素,以及新的自动驾驶功能
- 下载MarsMission_-__Article_V_-_source_code_20110706.zip-1.42 MB(*Download MarsMission_-_Article_V_-_source_code_20110706.zip - 1.42 MB*)
- 下载MarsMission_-__Article_V_-_Help_Menu.zip-5.49 MB(*Download MarsMission_-_Article_V_-_Help_Menu.zip - 5.49 MB*)
- 下载MarsMission_-__Article_V_-__images.zip-5.64 MB(*Download MarsMission_-_Article_V_-_images.zip - 5.64 MB*)
- 下载MarsMission_-__Article_V_-__Sprites_A.zip-5.36 MB(*Download MarsMission_-_Article_V_-_Sprites_A.zip - 5.36 MB*)
- 下载MarsMission_-__Article_V_-__Sprites_B.zip-5.27 MB(*Download MarsMission_-_Article_V_-_Sprites_B.zip - 5.27 MB*)
- 下载MarsMission_-__Article_V_-__Sprites_C.zip-5.62 MB(*Download MarsMission_-_Article_V_-_Sprites_C.zip - 5.62 MB*)
- 下载MarsMission_-__Article_V_-__Sprites_D.zip-5.4 MB(*Download MarsMission_-_Article_V_-_Sprites_D.zip - 5.4 MB*)
- 下载MarsMission_-__Article_V_-__Sprites_E.zip-5.41 MB(*Download MarsMission_-_Article_V_-_Sprites_E.zip - 5.41 MB*)
- 下载MarsMission_-__Article_V_-__Sprites_F.zip-5.66 MB(*Download MarsMission_-_Article_V_-_Sprites_F.zip - 5.66 MB*)
- 下载MarsMission_-__Article_V_-__Sprites_G.zip-4.58 MB(*Download MarsMission_-_Article_V_-_Sprites_G.zip - 4.58 MB*)
- 下载MarsMission_-__Article_V_-__Sprites_H.zip-4.54 MB(*Download MarsMission_-_Article_V_-_Sprites_H.zip - 4.54 MB*)
- 下载MarsMission_-__Article_V_-_Sprites_I.zip-5.25 MB(*Download MarsMission_-_Article_V_-_Sprites_I.zip - 5.25 MB*)
- 下载MarsMission_-__Article_V_-__Sprites_J.zip-4.68 MB(*Download MarsMission_-_Article_V_-_Sprites_J.zip - 4.68 MB*)
- 下载MarsMission_-__Article_V_-__Sprites_K.zip-4.9 MB(*Download MarsMission_-_Article_V_-_Sprites_K.zip - 4.9 MB*)
对技术人员的警告(Warning for Technocrats)
阅读了我在<火星任务>系列文章中的最后一篇文章后,我注意到在解释如何玩游戏时已经用了大量的文字和图像.由于该网站致力于推广开源软件,并且他们继续认为该项目值得发布,我惊讶地发现没有人提及我的过失,无法更充分地解释参与此复杂项目的代码.因此,我决定警告读者,以免他们不必要地阅读整个文本段,而这些文本段不包含对该编码企业内部运作的任何引用.因此,我在此向所有不愿意浪费时间阅读无聊的研究的人提供警告,这些研究涉及沉闷的题外话,琐碎的段落和漫无目的的论点,内容涉及玩愚蠢的计算机游戏所涉及的琐碎事情: “如何玩火星任务”.(After reading the last entry in my series of Mars Mission articles I noticed that an exorbitant amount of text and images had been used up in explaining how to play the game. Since this website is dedicated to promoting open-source software and they continue to deem this project worth posting I was surprised to discover that noone had made any mention of my negligence to explain more adequately the code involved in making this elaborate project. Therefore I decided to warn my readers in order to spare them having to needlessly read through entire segments of text which do not contain any references whatsoever to the inner workings of this coding enterprise. And so I hereby provide this caveat for any of you not interested in wasting time reading a senseless study full of dull digressions, petty passages, and aimless arguments in a mindless manuscript concerning the frivolities involved in playing a silly computer game : skip the following section “How to Play Mars Mission”.)
如何玩火星任务(How to play Mars Mission)
按F1进入帮助菜单.(Press F1 for help menu.)
化学品库存(Chemical Inventory)
与现实生活相比,“火星任务"中涉及的化学物质相对简单,但是其背后的代码有一些有趣的地方.您可能从高中时代起就回想起这些被称为"原子"的事物,它们配对并结合成分子,我们称其为各种状态的气体,液体或固体,您可能已经意识到化学世界比它复杂得多.你的高中老师告诉你.在这件事上进行了一些粗略的研究,我发现化学家每天都在开发数十亿个已知分子,因此我得出结论,试图保持所有已知化学物质的最新记录(The chemistry involved in Mars Mission is relatively simple compared to real life but the code behind it has a few points you could find interesting. You may recall from your high school days these things called “atoms” that pair up and combine into molecules which we call matter in its various states of gas, liquid or solid, you probably realize that the world of chemistry is somewhat more complicated than what your high-school teacher told you. Doing some cursory research in the matter I discovered that there are billions of known molecules with chemists inventing new ones every day, and so, I came to the conclusion that trying to keep an up-to-date record of all known chemical)分子(molecules)是不现实的.尽管有这个障碍,但是已知化学物质的清单(is unrealistic. Despite this obstacle, however, the list of known chemical)元素(elements)现在已经固定了很长一段时间,您可以在任何周期表中查看它们.(has remained fixed for quite some time now and you can view these in any periodic table.)
我的目标是创建一个界面,该界面允许用户以所需的顺序或数字将输入资源组合在一起,并对输出资源进行相同操作,以创建不需要预先编程到计算机中的平衡方程.换句话说,我不想将化学组绑定到已知化学反应的预定义列表中,而是让玩家自由决定如何分解输入分子并将其成分重组为不同的输出分子.因此,列出一个化学元素列表和另一个化学分子列表意味着将水(一个分子)分解成两个元素(氧气和氢气)的组合,我需要的是可以同时定义它们的一类,这就是什么(My objective here was to create an interface that would allow the user to combine input resources together in whatever order or number they wanted and do the same with the output resources to create balanced equations that didn’t need to be preprogrammed into the computer. In other words, I didn’t want to bound the chemistry set within a predefined list of known chemical reactions but keep the player free to decide how to break down input molecules and recombine their components into different output molecules. So making one list of chemical-elements and another list of chemical-molecules meant that water(a molecule) would be broken into a combination of two elements(oxygen and hydrogen), what I needed was one class that could define them both and that’s what the) classChemical
是,还有更多.(is, and more.)
自从(Since the) classChemical
该类具有将三元树合并为便于检索的所有要求,该类具有指向三元树根的静态指针,该指针用于快速获取程序所需的任何化学物质.只有一个实例(has all the requirements to be combined into a ternary tree for easy retrievability the class has a static pointer to the root of a ternary tree which it uses to quickly fetch whatever chemical the program requires. There is only one instance of) classChemical
已知化学物质列表(即火星任务所知)中的每种化学物质以及代码其余部分中的指针在确定其各种算法的流程时均引用这些实例.(per chemical in the list of known chemicals (known to Mars Mission, that is) and pointers throughout the rest of the code make reference to these instances when deciding the flow of their various algorithms.)
但是我仍然需要保留一份单独的化学品清单,告诉我哪些是元素.所以我整理了一个单独的元素列表…我知道,我知道我刚才说过的关于将它们放在一起在同一个类中的内容,但是我最后要做的是在一个称为(But I still needed to keep a separate list of chemicals telling me which ones were elements. So I wound up making a separate list of elements… I know, I know what I just said about keeping them together in the same class but what I wound up doing is having a list of elements in a class called) classChemical_Element
(我确定是恰当地命名),然后将每个元素都包含到的静态三叉树中((aptly named, I’m sure) and then included every element into the static ternary tree of) classChemical
因此,当用户编写将食盐分解成元素的化学反应时,实际上发生的事情是我们将一个分子(化学氯化钠)分解成两个组成的"分子”(化学物质Na和Cl),尽管Na和Cl是在技术上根本不是分子,而是化学元素.大多数人不会注意到或关心的细微差别,但那里的铁杆化学家已经摇了摇头,对此已经t不休,所以让我简化模拟这次太空冒险中的化学反应所涉及的下一个急剧简化. .(so that when the user writes a chemical reaction decomposing table salt into its elements what actually happens is we have one molecule (chemical NaCl) breaking down into its two component “molecules” (chemicals Na & Cl) despite the fact that Na and Cl are not technically molecules at all but really chemical elements. A subtle difference most people wouldn’t notice or care about but the hardcore chemists out there are all shaking their heads and tut-tutting about it already so let me ease the next drastic simplification involved in simulating a chemistry set in this space adventure…)
对某些人来说,冷可能是没有热量的情况,但对化学家而言,吸热和放热类型的反应之间的区别就像是在热桶中冷融合(您见过那些Coors Light商业广告!),因为已知化学反应物的清单是不断增长的您可以确定已知化学反应的列表也无谓地庞大并且永远在增长,这就是为了跟踪哪些反应是吸热的(需要热量才能引起反应之间的反应)输入反应物)或放热(由于将输入反应物聚集在一起而产生热量),并且由于缺少一系列已知化学反应而无法跟踪哪些化学组合物需要热量以及哪些组合散发出热量,此版本的"火星任务"未考虑热量.放热/吸热,巴特尔/塔特尔,都一样.我之所以做出此设计决定,是因为我想让玩家在编写自己的化学反应时拥有更大的灵活性,并尽可能使化学反应和平衡方程式变得"有趣".(Cold may be the absence of heat to some people but to chemists the difference between endothermic and exothermic types of reactions is like cold-fusion in a hot-tub(have you seen those Coors Light commercials!) Since the list of known chemical reactants is constantly growing you can be certain that the list of known chemical reactions is also unreasonably huge and forever growing as well, and that is what would be required in order to keep track of which reactions are endothermic(require heat in order to cause a reaction between input reactants) or exothermic(produce heat as a result of bringing input reactants together) and so as a consequence of a lack of a list of known chemical reactions that would keep track of which combinations of chemicals require heat and which combinations give off heat, heat is not being considered in this version of Mars Mission. Exothermic/endothermic, Buttle/Tuttle, its all the same. I chose to make this design decision because I wanted to allow the player to have greater flexibility in writing their own chemical reactions and make chemistry and balancing equations “fun”, if at all possible.)
化学和元素定义存储在Xml文件中(The chemical and element definitions are stored in Xml files) chemicals.xml
和(&) Chemical_Elements.xml
.尽管元素列表可能不应该更改,但是您可以轻松地从xml文件中添加/删除节点以修改现有列表并在那里创建自己的"已知"化学分子.(. Although the list of elements should probably not be changed you can easily add/remove nodes from the xml file to modify the existing list and create your own “known” chemical molecules there.)
化学品库存(Chemical Inventory)
尽管资源对象需要是容纳化学品的容器才能利用其化学品清单,但是每个资源对象,船舶和基地都有自己的化学品清单.这可以通过创建一个以类似但非静态的方式完成工作的类来轻松完成(Although resource objects need to be containers which hold chemicals in order to make use of their chemical inventories, each resource object, ship and base has its own chemical inventory. This is easily done by creating a class that does the job in a similar but non-static way that) classChemical
跟踪所有已知化学物质.(keeps track of all known chemicals.) classChemicalInventory
持有一个(holds a)清单(list)的(of) classChemicalInvetory_Item
它被解析成可以快速搜索的三元树.如果不是由于需要而不是每个时钟周期更新图形显示所涉及的复杂性,则该类没有什么特别的.播放器的船舶/结构控制台中有几个仪表,可用于指示结构(船舶/建筑物)清单中可用的化学品水平.燃油表监控燃油和氧化剂的水平,这是船上库存中的两种化学物质,用户可以提示化学物质库存以进行显示.这两个显示并不总是可见的,不需要在每个时钟周期进行不断的更新,因为这会不必要地增加程序的流畅度.(which is parsed out into a ternary tree which can be quickly searched. This class would not be anything special if it were not for the complications involved in updating a graphic display when required as opposed to every clock cycle. There are several gauges available in the player’s ship/structure consoles that indicate the level of chemicals available in the structure(ship/building) inventory. The fuel gauge monitors the level of fuel & oxidizer which are two chemicals in the ship’s inventory and the chemical inventory can be prompted by the user for display. These two displays are not always visible and don’t require constant updating at every clock cycle, as that would cause needless strain on the smooth flow of the program.)
因此,(For this reason then the) classChemicalInventory_Item
有一个用于更改其值的事件,只要清单的内容发生更改,就会调用此事件,但是据我所知,C#不允许程序在创建事件处理程序后立即中止该事件处理程序.因此,我们为每艘船都有一个清单,并且在屏幕上有一个显示面板和表格,当我们从一艘船上切换时,事件处理程序告诉显示器更改其清单的值,然后用户控制另一艘船,该船的库存开始在同一显示器上引发事件,我们开始遇到问题,因为两艘船的化学物质库存都在增加,并向显示面板下达了订单,这无济于事.不仅如此,当第一艘飞船在第二,第三次及以后由用户控制时,该第一艘飞船每次都会重新初始化其事件处理程序,不久我们就会发生数十个事件,内容发生相同的变化每艘船.结果是一场灾难.(has an event for changes in its value, this event is called whenever the contents of the inventory is altered but C# does not(to my knowledge) allow a program to discontinue an event-handler once it has been created. So we have an inventory for every ship and one display panel & form on the screen and when we switch from one ship which has event handlers to tell the display to change the value of its inventory and the user then takes control of a different ship and that ship’s inventory starts to throw events at the same display we start to have a problem because both ships have chemical inventories that are acting up and giving orders to the display panel which can’t make the difference. Not only that but when the first ship is taken control of by the user a second, third and subsequent time, that first ship re-initializes its event-handlers every time and pretty soon we have dozens of events for the same change in content happening for every ship. The result is a disaster.)
一种解决方案是通过重建每个项目的清单来复制清单中的化学品清单.(A solution to this was to make a copy of the list of chemicals in the inventory by rebuilding each item of) classChemicalInventory_Item
在里面(in the) classChemicalInventory
的列表,从而摆脱了所有旧的事件处理程序.然后使三叉树为零,以便下次请求该新树时需要从新列表中进行重建.该界面允许用户通过以下操作来弹出化学库存:将鼠标移到标签上,然后在鼠标移开时丢弃库存显示,以便在召唤显示时创建新的库存项目事件,然后在销毁显示事件时销毁它们.鼠标移开了"化学品清单"标签,但是即使玩家没有将鼠标光标移到该标签上以查看清单中剩余的特定量的燃料/氧化剂,燃油表仍需要显示剩余的燃油百分比,因此,如果涉及的战舰是在游戏的战舰导航控制台中显示的战舰,则一旦旧战舰被销毁,就会重新创建燃料的事件处理程序.(’s list and in that way getting rid of all the old event handlers. Then nulling the ternary tree so that it requires rebuilding from the new list the next time a request is made of it. The interface allows the user to pop-up the chemical inventory by moving the mouse over a label and then discarding the inventory display when the mouse moves away so that new inventory item events are created when the display is summoned and then they are destroyed when the mouse moves away from the “chemical inventory” label but the fuel gauge still needs to show the percentage of fuel remaining even if the player has not moved the mouse cursor over that label to see the specific amount of fuel/oxidizer left in the inventory, so the event handlers for the fuel are recreated as soon as the old ones are destroyed if the ship involved is the one being displayed in the game’s ship-navigation-console.)
public void killEvents()
{
for (int intItemCounter = 0; intItemCounter < lcInventory.Count; intItemCounter++)
{
lcInventory[intItemCounter] = lcInventory[intItemCounter].Copy();
}
rebuildChemTree();
if (SI != null)
{
if (SI.cShip != null)
{
if (SI.cShip.grbShipData != null)
{
SI.cShip.grbShipData.grbResources.lblwFuelGuage_Value.Ship = SI.cShip;
}
}
}
}
动态生成的动作(Dynamically Generated Actions)
动态生成的动作是未在使用以下命令设置的动作列表中预定义的动作(Dynamically generated actions are actions that are not predefined in the list of actions which are set-up using the) resourceEditor
的选项(option of the) program.cs
文件.这些动作清楚地说明了输入,中断和输出资源,以及特定的技能要求,工作时间和其他一些细节,这些细节定义了宇航员在与环境互动时可以做和不能做的一切.动态生成的动作是由玩家在运行时发明的,他们在游戏中做出决策时就可以做什么和不能做什么做出更大的灵活性.显然,让玩家发明自己想要的任何动作都会使事情变得太容易了,并破坏了游戏,但是在发生化学反应的情况下,输入和输出可以通过一个界面进行管理,该界面不允许没有资格的化学家产生任何不平衡的化学方程式.必要的输入资源,例如化学处理站.(file. Those actions are clearly spelled out with input, interrupt, and output resources, as well as specific skill requirements, hours of labor and a few other details that define everything the astronauts can and cannot do when they interact with their environment. Dynamically generated actions are invented during run-time by the players as they make decisions in the game to create more flexibility in what can and cannot be done. Clearly allowing the players to invent any action they want would make things far too easy and ruin the game but in the case of chemical reactions inputs and outputs can be managed with an interface that does not allow any unbalanced chemical equations produced by unqualified chemists without the necessary input resources such as a chemistry processing station.)
如上所述,我希望允许用户编写自己的化学反应.由于游戏已经有一个(As I mentioned above I wanted to allow the users to write their own chemical reactions. Since the game already has a) classAction
接受输入并产生输出的最简单的操作是允许将化学品用作这些操作的输入和输出,在列举清单中具有一种称为"化学反应"的通用操作类型(which takes in inputs and produces outputs the simplest thing to do was to allow chemicals to be used as inputs and outputs in these actions, have a generic type of action called “chemical reaction” in the enumerated list) enuActions
以便在行动计划完成时更容易识别化学反应,然后像对待其他任何非动态生成的行动一样对待所有输入和输出.(to make it easier to identify chemical reactions when they are completed in the actions schedule, and then treat all the inputs and output as they would be treated were it any other kind of non-dynamically generated action.)
这就是我所做的.(And that’s what I did.)
在这方面没有太多改变(There weren’t many things to change in the) classAction
为了适应这一新功能,除了能够处理化学资源的清单外.唯一需要更改的重要事项是将循环操作(当前操作完成后的操作)存储在xml文件中的方式以及(in order to accomodate this new feature aside from being able to handle the inventories for the chemical resources. The only important thing that needed to change was the way a loop-action(the action that follows the completion of a current action) was stored in the xml file and the) classAction
.旧方法使用(. The old method used the) enuActions
枚举类型列表,但这样做不能识别玩家可以自己定义的无数可能的化学反应中的任何一种,因此必须更改为更灵活的字符串定义,以允许动态生成或以其他方式生成任何动作名称.这样,可以将化学反应的循环作用识别为在功能中指向自身(enumerated type list but doing that does not identify any one of the countless possible chemical reactions which the players can define on their own so that had to be changed to a more flexible string definition which allows any action name, dynamically generated or otherwise. This way the loop-action of a chemical reaction can be identified as pointing to itself in the function)
public static classAction fromXmlNode(ref XmlNode xNode)
从已保存的游戏加载动作事件(which loads an action event from the saved game) GameInfo.xml
文件在构建动作事件时间表并包含以下行时(file when it builds the schedule of action events and includes the line)
if (cRetVal.cRequirements.strLoopActionName == cRetVal.Name)
cRetVal.cRequirements.cLoopAction = cRetVal;
允许动态生成的动作在其内部循环,直到输入资源或变化的条件中断了该循环动作为止.可以实现相同目的的替代解决方案很容易实现,但是由于该解决方案没有产生任何新问题,而且我马上就解决了这一问题,因此再次证明,“第一个可行的解决方案是正确的解决方案” .我对的时候会喜欢的!(allowing a dynamically generated action to loop within itself until the input resources or changing conditions discontinue the looping action. Alternate solutions to achieve the same thing could have been just as easily implemented but since this one didn’t create any new issues and I got it working right away it turns out once again that, “the first solution that works is the right one”. I love it when I’m right!)
这意味着尽管您可以有五个化学家,每个化学家都将二氧化碳转化为二氧化碳和二氧化碳的组成部分,但每个化学家都动态创建了自己的(This means that although you can have five chemists each converting carbon dioxide into its component parts of carbon and dioxide each chemist has dynamically created her own instance of a) classAction
它具有相同的功能,并具有与其他名称完全相同的名称,因为这些动作均未保存在任何列表或数组中,可供其他化学家复制.可能值得考虑列出这样的清单,但是由于易于推导和应用关于化学反应有效性的法律,因此动态地为所有化学反应创建动作不需要太多的MIP处理,因此可以选择负担已经很沉重的游戏负担图形缓存所需的内存以及以前动态生成的化学反应的列表似乎是不必要的.(which does the same thing and has the exact same name as the others because none of these actions are kept in any list or array for other chemists to copy from. It may be worth considering making such a list but since the laws governing the validity of a chemical reaction is easily derived and applied, dynamically creating actions for all chemical reactions does not require much MIPs processing and therefore the option of burdening the game’s already heavily ladened memory, which the graphics caching requires, with a list of previously dynamically generated chemical reactions seemed unnecessary.)
化学处理站(Chemical Processing Station)
为了创建自己的化学反应,用户可以在化学处理站进行操作.的(To create their own chemical reactions the user interfaces at a chemical processing station. The) formChemicalReactionInterface
允许玩家与游戏对接,以编程他们希望化学家进行的化学反应.角色的化学技能水平决定了帮助的力度,例如化学智能,根据名称或公式选择化学分子的选项以及反应的剩余不平衡度,以帮助玩家发明所需的化学反应.为此,它严重依赖于(allows the players to interface with the game to program the chemical reactions they want their chemists to perform. The character’s level of chemistry skill determines the amount of help, such as a chemistry intellisense, option to choose chemical molecules by name or formula, and the remaining imbalance of the reaction, to help the player invent the chemical reactions they need. To do this it relies heavily on the) textbox_Chemical
与玩家互动以帮助选择化学分子.此处可用选项的限制取决于化学家的技能.熟练的化学家可以选择编写化合物的化学式或名称,而非熟练的化学家只能按名称选择(当在屏幕上看不到其组成元素时,很难平衡方程式).(which interfaces with the player to help choose a chemical molecule. The limit of options available here depends on the chemist’s skill. A very skilled chemist has the option to write the formula or name of a compound while an unskilled chemist can only choose one by name (making it difficult to balance equations when their component elements are not visible on the screen).)
写(Writing the) textbox_Chemical
涉及一些我以前没有想到的细节.由于必须满足几种不同类型的界面的需求,因此两个文本框的组合似乎是合适的,一个文本框用于用户选择的化学药品名称,另一个文本框用于选择化学药品的配方.我编写了该类使其在这两个文本框都可见的情况下起作用,然后根据化学家进行接口的技能水平拒绝了一个文本框或另一个文本框.这两个文本框都需要智能感知,以使玩家知道他们正在编写的内容是否有效.这些文本框不仅会根据结果显示是否以黄色或红色背景显示的拼写检查,而且只要化学家的技能水平足以证明给玩家额外的帮助,就会出现智能提示选项.(involved a few details which I hadn’t thought of before. Since the need to have several different types of interfaces had to be met the combination of two textboxes seemed appropriate, one for the name of the chemical being selected by the user and the other for the formula of the chemical being selected. I wrote the class to function with both these textboxes visible and then denied the one textbox or the other depending on the skill level of the chemist doing the interfacing. Both of these textboxes needed an intellisense to let the player know if what they are writing is valid or if it isn’t. Not only do these textboxes do a spell-check which is reflected in a yellow or red background depending on the result but the option of an intellisense appears whenever the chemist’s skill level is high enough to justify giving the player that extra bit of help.)
因此,需要在(So a sub-tree search needed to be written in the) classChemical
它会返回给定任何"根"叶作为开始搜索位置的静态三元化学树中所有条目的列表.三叉树的构建和搜索方式使从每个叶子分支出来的树的每个分支都具有与其分支所在的叶子相同的前几个搜索字符,因为只有一条搜索路径会引导您从根到该叶子的树.这意味着如果我们扫描一棵树,直到找到与玩家所写内容完全一致的分支,那么分支上从该叶子延伸出来的所有叶子将具有与整个叶子相同的第一个字符叶子的入口.这意味着,如果玩家写下" carbo",智商就可以搜索包含火星任务的所有"已知"分子的三叉树,从该树上下来直到到达最后一个由玩家使用" carbo"一词,然后遍历该分支以获取具有以" carbo"开头的名称的分子的完整列表,例如" carbon",“二氧化碳”,“一氧化碳"等等.一旦获得此列表,它就会以无边界形式打印在列表框上,并悬停在(which returns a list of all entries in the static ternary tree of chemicals given any “root” leaf to start the search at. The way a ternary tree is built and searched makes every branch of the tree branching off each leaf have the same first few search characters as the leaf off which it branches since there is only one search path that will lead you to that leaf from the root of the tree. What this means is that if we do a scan of a tree until we find the branch that meets with the exact spelling of what the player has written then all the leaves on the branch extending off that leaf will have the same first characters as the entire entry of the leaf. This means that if the player writes “carbo” the intellisense can search through the ternary tree containing all of Mars Mission’s “known” molecules find the leaf with the search key “o” after going down the tree until it reaches the last character written by the player in the word “carbo” and then traverses that branch in-order to get a complete list of molecules which have names that start with the letters “carbo”, such as “carbon”, “carbon dioxide”, “carbon monoxide” and so on. Once we have this list its printed up on a listbox in a borderless form that hovers near the) textbox_Chemical
玩家可以自由选择该列表中的任何选项,以设置玩家选择的化学品.(and the player is free to choose any of the options on that list which sets the chemical the player has selected.)
由于出于美学原因需要以化学方式显示化学式,因此,每当鼠标光标从屏幕上移开时,都会在图片框的前面绘制一个图片框.(Because the chemical formula needs to be displayed graphically for esthetic reasons a picture box is drawn and positioned in front of the textboxes whenever the mouse cursor moves away from the) textbox_chemical
班级和化学家的技能水平允许看到配方.(class and the chemist’s skill level permits the formula to be seen.)
单击右侧或左侧的表单可添加输入或输出(Clicking the form on either the right side or left side adds an input or output) textbox_Chemical
根据您单击的一侧,然后在其中之一的文本框中按Enter键,而没有文本会丢弃(depending on the side you clicked and pressing enter in the textbox of one of these while there is no text discards that) <code><code>textbox_Chem
表格中的ical.只要对以下任何一个列表进行更改(ical from the form. Whenever a change is made to any of the list of) textbox_Chemicals
然后通过对等式两边的元素(而非分子)计数来比较它们,然后告诉用户哪些不平衡项可以帮助那些精通技术的化学家,并且每当编写了一个等式时,就会显示"确定"按钮.(then they are compared by counting the elements (not molecules) on either side of the equation and then telling the user what is imbalanced to help those savvy skilled chemist’s and showing the “ok” button whenever a balanced equation is written.)
排气(Venting Gas)
排气是动态产生动作的另一个示例.该界面允许用户通过将船舶或建筑物的化学物品的内容绘制到位图上来选择排放的气体,该位图可以单击以进行选择.一旦选择了要排放的气体,就会动态生成一个新动作,该动作将吸收Gas_Exhaust_Controls资源对象,并根据进行排放的角色的化学技能水平确定所选的气体量,然后仅返回Gas_Exhaust_Controls资源对象,并只要排出的气体和其他条件允许,或者角色退出任务,循环就会自行循环.(Venting gas is another example of a dynamically generated action. The interface allowing the user to select which gas to vent is made by drawing the contents of the ship or building’s chemical inventory onto a bitmap which can be clicked to make the selection. Once the gas to be vented has been selected then a new action is dynamically generated that takes in a Gas_Exhaust_Controls resource object and an amount of gas selected determined by the chemistry skill level of the character doing the venting and then returns only the Gas_Exhaust_Controls resource object and loops on itself so long as the gas being vented and other conditions allow, or the character quits the task.)
自动驾驶(Auto-Pilot)
我上一次编写此游戏时(在VB 6.1中燃烧了很多绿色的洞察力),自动驾驶的概念超出了我的头脑,但这次我决定自动驾驶功能是必不可少的,因此我决定在解决问题之前,请先提出解决方案.因此,我花了一个星期的时间来尝试控制船舶的发动机,使其在运行时改变航向,以期在飞行过程中抓住太阳体并进入圆形轨道,但效果并不理想.(The last time I wrote this game (in VB 6.1 while burning many little green bags of insight) the notion of an auto-pilot was beyond my befuddled brain, but this time around I decided that an auto-pilot feature was essential and I determined to plug away at a solution until I had something working. So I spent a week trying to control the ship’s engines to redirect its course during runtime in the hopes of catching a solar body in its flight and entering into a circular orbit but the result was unsatisfactory.)
我想我应该让导航控件通过确定太阳物体在给定时间点的位置来实际绘制路线,并让飞船在准备进入轨道的确切时间出现在那儿,因此,我决定编写一个界面来进行自动驾驶测试,您可能想通过在其中更改一行来了解一下(I figured I should have the navigation controls actually plot out a course by figuring out where the solar body would be at a given point in time and have the ship appear there at the exact moment ready to enter into orbit so, with that in mind, I decided to write an interface to do the auto-pilot testing and you may want to have a look at this by changing a line in) program.cs
public static enuPrograms eProgram = enuPrograms.MarsMission;
读书(to read)
public static enuPrograms eProgram = enuPrograms.testAutoPilot;
它相当用户友好,因此您应该能够加载它并环顾四周.一旦我进行了不错的测试工作,每天都要花几个星期解决这个问题,才能取得真正的进展.无论我试图通过这种路线图悖论来打破令人费解的脑筋的方法,无论是仓库和出发地的角度和大小,停靠点和起跑速度都在那儿迅速进行,并且在适当的情况下加快了最艰巨的因素这个困难的功能.(Its fairly user friendly so you should be able to load it up and have a look around. Once I had a decent testing-ground working it took a couple of weeks of daily plugging away at this problem to make any real progress. No matter how many ways I tried to break down the brain business of puzzling through this course-plot paradox, the angles and magnitudes of the depot and depart, the stop and start velocities made proceeding there promptly and at the right expedite the most formidable factor of this difficult function.) 当我决定将问题分为两个独立的轴X和Y时,我就开始取得一些进步.这本来应该很容易,但实际上我花了几天的时间才决定这样做.然后,分别处理每个轴,我们有两个简单得多的线性问题,它们涉及开始和停止速度(Vi&Vf)以及开始和停止位置(Xi&Xf,即使实际上是在处理Y -轴,我正在使用相同的功能).(I started making some progress when I decided to divide the problem in two separate axes X & Y. That should have been a no-brainer but it actually took me a couple of days to decide to do this. Then, dealing with each axis separately, we have two much simpler linear problems that involve the start and stop velocities (Vi & Vf) as well as the start and stop positions (Xi & Xf, even if we’re actually dealing with the Y-axis, I’m using the same function).) 这是问题所在:(Here’s the problem :)
-
我们有N个时间段可以到达目的地.(we have N time segments in which to reach our destination.)
-
我们必须在N段中移动Xf和Xi之间的距离.(we have to travel the distance between Xf & Xi in N segments.)
-
起始段与Vi的差值不得大于MaxDeltaV(最大加速度)(the start segment must not vary from Vi by a value greater than MaxDeltaV (max acceleration))
-
末段不得与Vf相差大于MaxDeltaV的值(the end segment must not vary from Vf by a value greater than MaxDeltaV) 因此,首先,我将所有Xi到Xi左边的问题的输入值取反,然后将这些取反的值运回到函数中并取反,以便实际计算始终处理正X.运动(同样,无论该函数实际在哪个轴上求解).这意味着每次计算都涉及从左到右的运动,但是仍然存在不同的情况(So, at first, I started by reversing the input values of all problems that had the Xf to the left of Xi then I ran those reversed values back into the function and reversed the results so that the actual calculations were always dealing with a positive X motion(again, regardless of which axis the function was actually solving). Meaning that every calculation involved a motion from left to right but then there were still different cases)
- 一种. Vi> 0&Vf> 0(*a. Vi > 0 & Vf > 0*) - b. Vi> 0&Vf <0(*b. Vi > 0 & Vf < 0*) - C. Vi <0&Vf> 0(*c. Vi < 0 & Vf > 0*) - d. Vi <0&Vf <0(*d. Vi < 0 & Vf < 0*)
这些情况中的每一种都涉及几个单独的计算,以反转初始速度,向目的地增加速度,降低向目的地速度,经过目的地后反向速度以及增加速度以达到正确速度.(each one of these cases involved several separate calculations to either reverse initial velocity, gain speed towards destination, reduce speed towards destination, reverse speed after passing destination and gain speed to arrive at the correct velocity.) 如果还不够…(and if that wasn’t enough…) 我一直遇到上述实际1.2.3和4.标准的问题.甚至在(a)中,Vi> 0,Vf> 0和deltaX> 0都无法找到问题的解决方案,因为我还没有找到一种方法来解决累加一整段的数学问题(vel at每个时间段),其步长变化受到常数(最大加速度)的限制,因此在给定第一个和最后一个段大小(起始和终止速度)的固定标准的情况下,所有段的总和等于另一个输入变量(总距离)旅行).(I kept running into problems with the actual 1.2.3 & 4. criterias mentioned above. Even in (a) where Vi>0, Vf>0 and deltaX>0 finding a solution to the problem remained an obstacle as I hadn’t yet found a way to resolve the mathematics involved in adding up a bunch of segments(vel at each time segment) whose step-to-step variance was limited by a constant (max acceleration) such that given a fixed criteria of first and last segment size(start and stop velocities) the sum of all segments equalled another input variable (total distance travelled).) 我花了一些时间才得出结论,如果不首先解决满足四个数学问题标准所涉及的数学问题,就无法轻松解决四种不同情况(a,b,c或d).当我开始拼命地尝试匹配两个半段,它们合计正确的行进距离,但是它们之间速度的变化却不允许他们通过在他们的邻居之间重新分配过多的段部分来将它们组合在一起时,我终于取得了突破.(It took some time before I reasoned out that none of the four different cases (a,b,c or d) could be easily resolved without first solving the mathematics involved in meeting the four mathematical problem criterias. And when I began to desperately try to match two half segments that totalled in the correct distance travelled but whose changes in velocities between them disallowed their combining together by redistributing the excessive segment portions among their neaghbours did I finally make a breakthrough.) 那时,我将(a)问题分为以下三个部分:(At that point I was separating the (a) problem into three segments of)
-
I.从初始速度加速到稳定速度(I. Accelerate to steady velocity from initial velocity)
-
二.保持稳定的速度(II. Maintain steady velocity)
-
三,从稳定速度加速到最终速度(III. Accelerate to final velocity from steady velocity) 在设法使零件I和零件II一起在指定的时间内达到最终速度,同时又保持了总行驶距离并满足这四个标准后,就出现了问题.我对这三部分解决方案的第三部分所做的工作是将剩余距离取为剩余距离,并将其除以剩下的步数.为此,我将剩余距离分为剩余时间段数量的一半,并计算出最后一段与第一段的总和应等于该常数,这使得问题类似于高斯对1到100的总和的求解.(After managing to get parts I & II together reaching the final velocity in the alotted time while keeping the total distance travelled and meeting the four criteria was problematic. What I was doing for part III of this three segmented solution was taking the remaining distance and dividing it up into the number of steps left in which to make the distance. To do that I divided the remaining distance into half the number of time segments remaining and calculated that the sum of the last segment with the first segment should equal this constant making the problem similar to Gauss’s solution to the sum of numbers from 1 to 100.)
- 1 + 100 =101(*1 + 100 = 101*) - 2 + 99 =101(*2 + 99 = 101*) - 3 + 98 =101(*3 + 98 = 101*) - ...(*...*) - 49 + 52 =101(*49 + 52 = 101*) - 总和=49 * 101 + 50(*sum = 49 * 101 + 50*)
除了现在,本课程第III节的"开始"必须与稳定速度的结束(第II节)相匹配,并且不允许加速度(或速度变化,紧身段的大小)超过最大加速度的标准.(except now the “start” of section III of this course had to match with the end of the steady velocity(section II) and the criteria of not allowing the acceleration (or change in velocity, size of neaghbouring segments) exceed the max acceleration.) 因此,在这里,我进行了计算机测试,将稳态速度的组合与估计的加速度和随机计算的步数相吻合.它一直在寻找可能的解决方案很长时间,并且通常从未找到有效的匹配项.(So this is where I was having the computer test which combinations of divined steady velocities fit in with the estimated acceleration and randomly reckoned number of steps. It was looping through the possible solutions for a long time and usually never found a valid match.) 最终我想到了简单的想法(Eventually I alighted on the idea of simply)通过重新分配值来强制段匹配(forcing segments to match by redistributing the values)在不遵守maxAcceleration规则的相邻步骤之间.(between adjacent steps that did not abide by the maxAcceleration rule.) 从而取得突破…(and thus the breakthrough…) 在短短的几个小时内,我就以一种奇怪的困惑的方式蜿蜒曲折地走着船,以正确的航向和速度到达了准确的时间和地点,而没有一次打破最大加速度神的伟大规则.(In only a few hours I had a ship meandering in a bizarre confused fashion to arrive at the exact time and place with the correct course and speed and without once breaking that great rule of the god of maximum acceleration.) 凌晨2点,我散步去祝贺自己.(It was 2am and I went for a walk to congratulate myself.) 第二天,我启动计算机,在做早餐并剃光后做了一些拉丁语操作,然后又重新上了自动驾驶仪,直到中午我都解决了.(The next day I sparked up my computer, did a bit of latin after cooking breakfast and shaved then I got to work on my auto-pilot again and by noon I had it all solved.) 无需反转输入并处理特定类型的问题,然后使用我将要描述的算法将它们进一步细分为上述四种情况.正如我在之前的文章中所解释的那样,我在NO RESEARCH旁边做,因此很有可能该算法是由十四世纪的某人发明的,并且已经有一个名称,但是我为能够独立解决而感到自豪(我非常喜欢这个探索!)(There is no need to reverse the inputs and work with a specific type of problem and then further subdividing these into the four situations mentioned above using the algorithm I am about to describe. As I’ve explained in previous articles I do next to NO RESEARCH so its very likely that this algorithm was invented by someone in the fourteenth century and already has a name but I take pride in having solved it independently(and I thoroughly enjoyed the quest!))
- 初始化一个具有相等段大小的数组,该数组的大小等于行进的总距离,这将是恒定速度,其中不需要改变速度,并且船舶将滑行至目的地.(initialize an array with equal segment sizes that sum up to the total distance travelled, this will be the steady velocity where no change in velocity will be required and the ship will coast towards its destination.)
- 跟踪开始和停止标记,这些标记记录了我们当前正在使用的段的索引(keep track of start and stop markers that record the index of the segments we are currently working with)
- 初始化无起始一段大小和终止加一段大小变量(initialize start-less-one segment size and stop-plus-one segment size variables)
- 在不超过maxAcceleration的情况下,将片段的值从无开始的1逐渐减小到稳定速度,并保持每个片段的更改量之和.(taper the values of the segments from start-less-one down to the steady velocity without exceeding maxAcceleration and keeping a sum of the amounts by which each segment was altered.)
- 将” less-start-one"指示器向右移动,直到它仍保持稳定速度的第一段上方(move the start-less-one indicator to the right until it is over the first segment that is still at steady velocity)
- 在不超过maxAcceleration的情况下,将段的值从停止加一减小到稳定速度(向后工作),并将这些变化与上面第4部分中保持的总和相加.(taper the values of the segments from stop-plus-one down to the steady velocity(working backwards) without exceeding maxAcceleration and summing these changes with the sum kept in part 4 above.)
- 向左移动"停止加一"指示器以指示剩余的最后一个稳定速度段(move the stop-plus-one indicator to the left to indicate the last steady velocity segment remaining)
- 分配两个开始/停止指标之间所有差异的总和,并将平均值添加到尚未更改的细分中(distribute the sum of all differences between the two start/stop indicators and add the average to the segments that have not yet been altered)
- 如果新的稳定速度与起步一开始速度之间的差值超过maxAcceleration,或者新的稳定速度与停止加一发生时速度之间的差值超过maxAcceleration,则返回到上面的#3(if the difference between the new steady velocity and the start-less-one velocity exceeds maxAcceleration or if the difference between the new steady velocity and the stop-plus-one velocity exceeds maxAcceleration then loop back to #3 above)
进入轨道(Entering Orbit)
但这还没有结束.下一个问题是选择进近点,因为仅选择相对于飞船起始位置的太阳体最终位置上的最近点,并说"以正确的速度在N圈内绕到那里"并不能保证绘制的航向在最终进近过程中改变速度时,不会使您的飞船直飞整个星球.在某些情况下,根据飞船到达时相对于行星的速度所需要的最终速度,碰巧该船需要飞越最终位置,然后返回以达到正确的航向和速度,这常常导致其坠毁和飞溅和烧伤,并且乘员在燃烧的碎片爆炸中死亡.当然,这是一个问题.(But that wasn’t the end of it. The next issue was selecting a point of approach because simply picking the nearest point on the solar-body’s final position relative to the ship’s starting position and saying “wind up there at the right speed in N turns” doesn’t guarantee that the plotted course won’t make your ship fly right through the planet when it alters its speed during final approach. In certain cases, depending on the final velocity required relative to the planet’s velocty when the ship gets there, it happens that the ship needs to fly beyond the final position and then return to arrive at the correct course and speed which often leads it to crash and splatter and burn and the crew dies in a flaming blast of debris. And that, of course, is a problem.) 为了解决这个问题,我们需要做的是在行星附近某个地方找到一个点,我们可以确定该船永远不会意外坠入它试图运行的行星.经过几次尝试,我将问题分为两种不同的情况:从左边(相对于太阳体的最终路径)或从右边来,相对容易地解决了问题.然后,我进一步将它们划分为顺时针或逆时针方向,很容易找到解决方案.(To resolve this then what we need to do is find a point somewhere near the planet where we are certain that the ship will never accidentally crash into the planet its trying to orbit. After several attempts to fumble with the trig involved I resolved the problem relatively easily by dividing the issue into two different situations : coming from the left (relative to the final path of the solar body) or coming from the right. And then I further divided those into clockwise or counter-wise orbit the solution was fairly easy to find.) 为了弄清楚我们是在向太阳体最终速度的左侧飞行还是向右飞行,该算法找到了两条线之间的交点:一条线以等于太阳体最终角度的角度穿过太阳体最终位置速度和另一个垂直于第一个,并贯穿船的原始位置.然后,在相交点和船的初始位置之间绘制一个矢量,并将该矢量的角度与行星或月球的最终速度角度进行比较.如果矢量的角度等于太阳体的最终速度角加Pi/2,则我们位于太阳体的右侧(我应该解释一下,下图中的角度是顺时针增加的,以与图形屏幕的负数一致y轴)和一个等于太阳体最终速度角减去Pi/2的角度的矢量表示我们正在飞向太阳体的左侧.(To figure out whether we’re flying to the left of or to the right of the solar body’s final velocity the algorithm finds a point of intersection between two lines : one goes through the solar body’s final position at an angle equal to the solar body’s final velocity and the other is perpendicular to the first and runs through the ship’s original position. Then a vector is drawn between the point of intersection and the ship’s initial position and this vector’s angle is compared with the planet or moon’s angle of final velocity. If the angle of the vector is equal to the solar body’s final velocity angle plus Pi/2 then we are to the right of the solar-body(I should explain that the angles in the following diagrams increase clockwise to agree with the graphic screen’s negative y-axis) and a vector with an angle equal to the solar-body’s final velocity angle minus Pi/2 indicates that we are flying to the left of the solar body.) 现在,将世界沿太阳体在其最终位置的最终速度一分为二,我们知道该放置哪一点.(Now, dividing the world in half along the solar body’s final velocity at its final position, we know which half to place our point of approach.) 接下来,我们需要考虑是否要进入顺时针或逆时针轨道,并根据左/右和顺时针/逆时针的组合将接近点定位在太阳物体的前面或后面.(Next we need to consider whether we want to enter into a clockwise or counter-clockwise orbit and we position the point of approach either in front or in back of the solar object depending on the combination of left/right and clockwise/counter-clockwise.)
选择了逼近点后,将航迹分为两个部分绘制.第一部分以给定的开始速度和等于太阳体最终速度的最终速度使我们从起始位置到达逼近点,这样我们就可以到达安全距离,并在最终逼近之前跟踪太阳体.第二部分将我们从进场点移到将船只放入轨道的轨道进入点.(Once the approach point has been selected, the course is plotted in two segments. The first segment gets us from our start position to the approach point with a given start velocity and a final velocity equal to the solar body’s final velocity and in that way we can arrive a safe distance away and track the solar body before final approach. The second segment moves us from the approach point to the point of orbital entry where the ship will be placed into orbit.)
启用自动驾驶仪后,船舶将沿着这些预定义的"航迹"行驶,并且船舶的引擎或任何太阳体的重力都不会对其产生影响(除非玩家控制并取消了自动驾驶仪),直到航迹已经行驶并且通过改变(When the auto-pilot is engaged the ship travels along these predefined “tracks” and neither the ship’s engines nor any solar body’s gravitational forces affect it(unless the player takes control and cancels the auto-pilot) until the course has been travelled and the ship is set into orbit by changing the) enuLocation
的价值(value in the) classCollisionDetectionObject
从"空间"到"轨道",这意味着它的轨道角在每个时钟周期都会改变,并且会根据其高度重新定位到确切的位置.这样重力就不会对其产生影响,它只会不断旋转,直到玩家做出其他决定为止.(from “Space” to “Orbit” which means that its angle of orbit is altered every clock cycle and it is repositioned to the exact location given its altitude. This way gravity has no effect on it and it just keeps flying round and round until the player decides otherwise.)
我意识到,在现实世界中,事情要复杂得多,没有哪位NASA工程师会愚蠢地提出如此简单的解决方案,但这只是一个简单的模拟,因此必须这样做.就目前而言,进入较快卫星的轨道是一个现实的问题,但我将让自动驾驶轨道成为主要轨道并尽快接近主要轨道.(I realize that in the real world things are much more complicated and no NASA engineer would be foolish enough to propose so simple a solution but this is just a simple simulation so it’ll just have to do. For the moment entering orbit around the speedier moons is a real problem but I’ll have the Auto-Pilot orbit the primary and approach the primary soon enough.)
制作帮助菜单(Making the Help Menu)
使用我最初为先前项目制作的类制作了帮助菜单,该类以图形方式显示了文本的多色文本.(The help menu was made using a class I originally made for a previous project that graphically displays multi-colored text for a) GCIDE:完整的英语词典(GCIDE : A Complete English Dictionary) 字典(dictionary) classGraphicOutputPanel
.虽然我被迫使用(. Although I was forced to use) RichTextBoxes
来构建编辑器,这些都是很不理想的(我经历了"处理RichTextBoxes"的四个阶段,包括(to build the editor and these leave much to be desired (I went through the four stages of “Dealing with RichTextBoxes” including)愤怒(anger),(,)否认(denial),(,)**讨价还价(bargaining)**最终(and eventually)**验收(acceptance)**在最终与我的计算机保持稳定的关系之前,我们经过了很多挫折后现在进行了对帐)编辑器运行良好,并且大多数情况下都很稳定,但是如果您打算自己使用它,我建议您耐心和多"节省数据"在此游戏中投影或编辑帮助菜单.(before finally reattaining a stable relationship with my computer, we’re reconciled now after much bruising) the editor is functioning well enough and is mostly stable though I would suggest patience and much “saving of data” if you plan on using it in your own projects or editing the help-menu in this game.)
它主要依靠第二类,我在制作<火星任务>中的各种图形显示面板时会用到它,(It relies mostly on a second class which I use in making the various graphic display panels in Mars Mission,) classGraphicText
.要在位图上显示文本,(. To display text on a bitmap the) classGraphicText
使用一组较小的位图,这些位图组成单词并将它们拼贴在一起以构成一页文本.由于生成这些字图像可能会使速度变慢,因此将它们存储在动态生成的二叉树中(uses a collection of smaller bitmaps which make up the words and collages them together to make a page of text. Since generating these word-images may slow things down they are stored in a dynamically generated binary tree) WordImage_BinTree
可以轻松地附加或搜索.因为一个单词可以以脚本,字体,大小或颜色的任意组合出现在页面上,所以该信息也与单词的图像一起存储,并且二叉树中的每个叶子都可以有任意数量的相似的叶子显示相同的单词以略微不同的方式存储为树的叶子指向的链接列表.尽管此设计要求每个运行时至少在屏幕上显示每个单词至少要绘制一次图像,并且每个新单词的每个新变体都会增加二叉树,但此方案实现的速度和内存要求适用于帮助菜单或任何其他封闭环境,这些环境没有无休止的词汇或大小/字体/颜色变化,最终将导致程序的内存故障.(which can easily be appended or searched. Because a word can appear on the page in any combination of script, font, size or color this information is also kept stored with the word’s image and each leaf in the binary-tree may have any number of similar leaves that have the same word displayed slightly differently stored as a linked-list pointed to by the tree’s leaf. Although this design requires each word displayed onto the screen to have it’s image drawn at least once every run-time, and the binary tree grows with every new variation of every new word, the speed achieved with this scheme and the memory requirements are suitable for a help-menu or any other closed environment that does not have an endless vocabulary or size/font/color variations which would eventually cause the program’s memory to fail.)
如上所述,为了制作编辑器,我不得不使用(In order to make the editor, however, as mentioned above, I had to make use of the) RichTextBoxes
任何曾经乐于与这些技术打交道的人都会知道,他们无法充分满足提议的规格.从理论上讲,他们应该容易相处,并且应该以理性的方式做出回应,但有时似乎要处理(and anyone who has ever had the pleasure of dealing with these would know that they are woefully inadequate in meeting their proposed specs. They, in theory, should be easy to get along with and they should respond in a rational manner but sometimes it seems like dealing with a) RichTextBox
就像面对一个在窃取您的钱包时欺骗他的美沙酮计划的傻瓜一样.这些东西都是垃圾.(is like dealing with a crack-head who’s cheating on his methadone program while stealing your wallet. These things are trash.)
不过,我设法通过使用Code-Project文章中的RTF解析器来获得(Nevertheless, I managed to get by using an RTF parser from the Code-Project article) 编写自己的RTF转换器(Writing your own RTF Converter) 使我困惑.如果不是该文章及其源代码,您将读到如何发射推进器以及压缩星球大气以制造燃料的需求,而不是沮丧的程序员徒劳无益的尝试的详细细节. MS BS过时的物件,应尽快处理.因此,感谢在我仍然等待Bill回复我有关原因的同时编写RTF解析器的人(to muddle me through. If it weren’t for that article and its source-code you would be reading about how to fire your thrusters and the need to compress the planet’s atmosphere to make fuel rather than the finer details of a frustrated programmer’s vain attempts to make sense of an antiquated piece of MS BS that should soon be disposed of. So thanks go out to the guy who wrote the RTF parser while I still wait for Bill to get back to me about why) RichTextBoxes
与Microsoft向那些只喜欢编写代码的人赠送的Visual Suite礼物相比,这还不算什么.(aren’t up to snuff compared with the rest of the Visual Suite gifts Microsoft has made to those of us who just love to write code.)
的重要方面(An important aspect of the) classGraphicText
其产生化学式图像的能力,否则将很难在屏幕上充分显示化学式.任何必须在屏幕上显示化学式的人都可能会证明上标和下标所涉及的麻烦,但是只需调用以下命令即可轻松实现(is its ability to generate images of chemical formulae which would otherwise be difficult to display adequately on the screen. Anyone who has had to display a chemical formula on the screen would probably attest to the trouble involved in super-scripting and sub-scripting but this is easily achieved with a single call to)
static public Bitmap getImageChemicalFormula(string strFormula, classMyFont cFnt)
{
classWordImage[] udrWordImage = new classWordImage[0];
appendWordImage_ChemicalFormula(ref udrWordImage, strFormula, cFnt);
return udrWordImage[0].bmp;
}
这会向您吐出图像,以所需的颜色,大小和字体显示化学式.的(Which spits an image back at you displaying your chemical formula in the desired color, size and font. The) appendWordImage_ChemicalFormula
通过将字符串分解成不同的元素来完成所有工作.它通过扫描文本中的开括号和闭括号以及有时在数学中用来表示乘法或在布尔逻辑中用来表示"与"的小点状圆,然后从主公式中分离出不同的子公式,从而完成此操作通过将它们进一步分解为数字来遍历它们,并确定字母以识别一个字符元素(C,N或O)中的两个字符元素(例如Co,Mn或Al),然后在元素后面加上数字下标或子公式的括号,并以常规大小显示公式前面的数字.在为公式的每个组成部分创建位图之后,这些位图被单独组装成一个图像,然后存储到上述的二叉树中,因此,如果再次需要精确的公式,则不再需要重建它,而只需将其拔掉即可RAM.(does all the work by breaking the string down into its different elements. It does this by scanning the text for open and close brackets as well as those little dot-like circles sometimes used in mathematics to mean multiply or in boolean logic to mean “and”, then separates the different sub-formulae from the main formula and iterates through them all by breaking them down further into numbers and letters being certain to recognize two-character elements(e.g. Co, Mn or Al) from one-character elements(C, N, or O) then sub-scripting numbers that follow elements or brackets of a sub-formula and displaying in regular size those numbers that precede the formula. After creating bitmaps for each component of a formula, these bitmaps are individually assembled into a single image which is then stored into the binary-tree mentioned above so that should that exact formula be required again it no longer needs to be rebuilt but simply pulled off of RAM.)
帮助菜单可以显示常规文本,链接,弹出文本,Flash弹出文本和图像.要管理这个(The Help-Menu can display regular text, link, pop-up text, flash pop-up text and images. To manage this the) classGraphicText
跟踪每个单词的位置,并在二进制树中具有指向图像的指针,以调出每个单词的图像的大小,因此可以根据给定鼠标光标相对于顶部光标的位置,找出鼠标光标下方的单词图像.文本输出图像的左上角.它在功能中做到这一点(keeps track of where each word is and has a pointer to the image in the binary tree to recall the size of each word’s image and can therefore figure out what word image is under the mouse cursor given where the mouse cursor is relative to the top-left corner of the text’s output image. It does this in the function)
public classWordImage getWordUnderMouse(Point ptMouse, classWordImage[] cWordArray)
然后,调用函数(给出结果)可以查看(Then the calling function, given the result, can look at the) classWordImage
它回来了,看看是什么样的词是(或图像)和(it got back and sees what kind of word that is(or image) and the) classGraphicOutputPanel
做出相应的回应.例如,每当鼠标移动到链接上时,光标就会变为弯曲的箭头,这表示如果单击该单词,查看者将链接到其他文本.(responds accordingly. For example, whenever the mouse moves over a link the cursor changes to a crooked arrow which indicates that the viewer will link to a different text if that word is clicked.)
此类也由(This class is also used by the) formReport
类,它还在屏幕上显示信息的图形文本.(class which also displays a graphic text of information on the screen.)
以下行位于(The following line located in the) formHelpMenu()
该功能可防止玩家编辑帮助菜单,除非他们以调试模式运行游戏.(function prevents the player from editing the help-menu unless they are running the game in debug-mode.)
pnlOutput.bolEdit = (System.IO.Directory.GetCurrentDirectory().ToUpper().Contains("DEBUG"));
要编辑链接,图像和闪烁,您必须将光标放在可见的文本上(对于图像为标题),然后按Ctrl-E召唤一个"链接编辑器".链接编辑器有几个选项,包括确定是否要处理链接,图像或闪光灯,但是要向页面添加链接,必须首先搜索要链接的页面,然后从中选择它.结果列表框,或单击"新"链接按钮,这将为您生成一个新的链接.然后,要控制指向此链接的可见文本,请删除"可见文本"文本框中的文本,然后按"保存".链接编辑器将消失,您的新链接将包含在您当前正在编辑的页面中(仍需要保存!).如果您添加了新链接,请不要立即添加另一个链接,因为尚未真正创建刚刚创建的链接(您已经添加了指向该文件中不存在的文件的指针) (目前正在编辑中),因此请保存您正在编辑的文件,然后在查看器中显示刚保存的文件时单击"新建链接"链接.在查看器中单击"新建链接"链接将迫使编辑器再次出现,但是这次可以编辑您要用于先前文件的链接.如果将"可见文本"文本框留为空白,则您在此处标题中输入的任何文本都会显示在先前文件的链接参考中.请记住也要保存此文件.(To edit the links, images and flashes you have to place the cursor on the visible text(the caption in the case of images) and then press Ctrl-E to summon a “link-editor”. The link editor has several options including deciding whether or not you’re dealing with a link, an image or a flash but in order to add a link to your page you must first search the page you want to link to and then select it from the list box of results or click the “new” link button which will generate a new one for you. Then, to control the visible text to this link, delete the text in the “visible text” textbox and press “save”. The link-editor will disappear and your new link will be included in the page you’re currently editing(which still needs to be saved!). If you’ve added a new link, do not add another one right away as the one you just ‘created’ hasn’t actually be created yet(you’ve added a pointer to a file that doesn’t exist in the file you’re currently editing), so save the file you’re editing and then click the “New Link” link in the viewer when it appears displaying the file you just saved. clicking the “New Link” link while in the viewer will force the editor to appear again but this time ready to edit the link you intended for the previous file. If you left the “visible text” textbox blank, then whatever text you write in your heading here will appear in your previous file’s link reference. Just remember to save this file too.)
尽管班级相对稳定,但我不得不经历的所有麻烦绝对不值得.的问题太多了(Although the class is relatively stable all the trouble I had to go through to get it that way was definitely not worth it. There are so many issues with the) RichTextBoxes
以及建立具有链接和其他形式的不可见文本(如图像和"闪光灯")的编辑器的一般概念,这些不可见文本显示通常不可见的文本弹出窗口,这使得构建稳定的编辑器很困难,因为所有这些都可以使用HTML来完成和专业的HTML编辑器,如果您有心去做和我一样的事情,我建议您走这条路,因为尽管它可以工作,但可以认真改进.(and the general concept of building an editor that has links and other forms of non-visible-text like images and “flash” that display popup’s of text not normally seen make building a stable editor difficult and since all this could probably be done using HTML and a professional HTML editor, I would suggest you go that route if you ever have a mind to do something like what I did because although it works it could seriously be improved.)
配置(Setting Up)
您可能已经注意到了十几个可供下载的文件.这些zip文件的许多内容都包含在以前的文章的下载文件中,但是由于对游戏的设置和首次启动进行初始化的方式进行了一些重大更改,所以最好还是从头开始.好了,我们在这里,再次下载文件.对于您来说,代码世界的新手和C#的创新使我一步步地指导您完成将自己置入Raptor并进入星际空隙的过程.(You’ve probably already noticed the dozen-odd files ready for you to download. Many of the contents of these zip files are included in the download files of previous articles but since some major changes have been made to the way the game sets up and initializes on first launch you’re better off just starting from scratch. Well, here we are, downloading files again. For you newbies in the Code world and the C# novitiates let me step you through what you’ll have to do to get yourself inside a Raptor and fly your way into the interplanetary void.)
-
首先,您需要在计算机上启动并运行的C#2010副本. Microsoft免费提供该软件,任何人都可以从以下位置下载(first you’ll need a copy of C#2010 up and running on your computer. Microsoft provides this software free for anyone to download at) Microsoft C#2010(Microsoft C# 2010) .(.)
-
那么您将必须获取此页面顶部列出的所有文件.从开始(then you’ll have to grab all the files listed at the top of this page. Starting with the) 源代码(source code) .这是实际的程序,它还包含所有其他文件都包含在其中的子目录.解压缩此文件后,下载所有剩余文件,并将其解压缩到最后一个MarsMission子目录中,在该子目录中还将找到应用程序的带红色图标.(. This is the actual program and it also contains the subdirectories in which all the other files are to be included. When you’ve extracted this file download all the remaining files and extract them into the last MarsMission subdirectory where you’ll also find the application’s reddish icon.)
-
将所有文件提取到正确的目录中后,您必须启动C#2010 IDE(上面提到的MS软件)并加载项目的解决方案文件,无论它是在计算机上提取的.(when you’ve got all the files extracted into the correct directory you’ll have to spark-up your C#2010 IDE (the MS software mentioned above) and load the project’s solution file wherever it was that you extracted it on your computer.)
-
因为此项目需要运行的文件非常大(比您下载的文件大100倍),所以它们无法发布在此站点上,而需要在您第一次运行该应用程序时生成.这需要时间.因此,我建议您做的是,不要像大多数人从新CodeProject文章中下载代码那样在调试器中运行应用程序,而是编译应用程序,然后找到可执行文件并运行它.对于新手来说,这可能有点粗糙,但还算不错.加载项目,然后按F6.当C#IDE完成编译后,将不会有任何夸张的声音,灯光,蜂鸣器或其他任何东西,但是您会注意到,“开始构建”,“构建进度”(带有进度条)和"构建完成"这两个词屏幕的左下角.完成后,您可以退出C#程序并转到Windows资源管理器以查找可执行文件,该可执行文件将位于项目的新创建的子目录\ bin \ release \中.您可以通过其图标识别它,但这次您要查找的文件不会是(because the files this project needs to run are so big (100s of times bigger than what you’ve downloaded) they cannot be posted on this site but need to be generated the first time you run the application. this takes time. So what I suggest you do is, instead of running the application in the debugger like most people would do when downloading the code from a new CodeProject article, compile the application and then find the executable and run it. For a newbie this may a bit rough but its not too bad. Load the project and press F6. When the C# IDE has finished compiling there won’t be any fanfare or lights or buzzers or anything but you’ll notice the words “Build start”, “Build Progress”(with a progress bar) and “Build Complete” written at the very bottom left of the screen. When that’s done you can exit the C# program and go to your Windows Explorer a-huntin' for the executable which will be located in the project’s newly created sub-directory \bin\release. You can recognize it by its icon, except the file you’re looking for this time will not be an)**图标(icon)**文件但(file but an)应用(application).(.)
-
接下来,双击文件名后,将开始发生很多事情,但是如果您坐在电梯里突然感到失重,可能会遇到问题,我无法为您解决.首先,您应该期望的是:应用程序将开始生成所需的所有文件,并且正如我在上一篇文章中所承诺的那样,将需要一些时间.一堆(next, after you’ve double-clicked the file’s name, a lot of things will start to happen but if you’re in an elevator and you suddenly feel weightless you might have a problem and that I can’t help you with. Primarily what you should expect is this: the application will start to generate all the files it needs and, as i promised in a previous article, will take some time. There’ll be a bunch of)**快取(caching)**参与但希望没有真实(involved but hopefully no real)**崩溃(crashing)**当它为各种资源构建文件流时,您可能会发现它围绕任何不整洁的太空飞船铺设,然后屏幕上将显示星空,不久您将看到一个文本框,询问您每四分之一圈需要多少个图像.如果您已尝试过该项目的前几期,则该内容与以前几乎相同,但我会再次解释.每四分之一圈旋转的图像数是指行星每四分之一圈绕其自身轴可见的角度数.数值越高,行星看起来旋转的流体就越多,数值越小,整个机器发出的响声就越响(不过,如果可能的话,会保持沉默).无论哪种方式,轨道都保持不变,如果您选择90之类的数字,它看起来会更凉爽,但是如果您急于选择,则可以选择4.本质上:更好的平滑图形需要花费一些时间进行初始化,并且您会坐在在屏幕前观看它工作约九十分钟(也许更多,取决于…只需确保运行可执行文件,否则将需要8到16个小时!).(while it builds file-streams for the different resources you might find laying around any untidy space-ship and then the screen will show a star-scape and soon you’ll get a text-box asking you how many images you want per quarter rotation. If you’ve tried the previous installments of this project this is pretty much the same as before but I’ll explain again. The number of images per quarter rotation refers to the number of angles the planets will be visible per quarter turn about their own axes. The higher the number the more fluid the planets will appear to rotate and the smaller the number the clunkier the whole machine will clang about(silently though, if that’s possible). Either way, the orbits remain the same and it just looks cooler if you pick a number like 90 but if you’re in a hurry you can go with 4. Essentially : better smoother graphics take time to initialize and you’ll be sitting in front of that screen watching it work for ninety minutes or so (maybe more, depends… just be sure to run the executable or this will take 8-16 hours!).)
下一步是什么 ?(what’s next ?)
由于自动驾驶处于创始阶段,因此我将寻找方法让舰队互相跟踪,并可能跟踪目标点,时间和速度,而不是"进入轨道",但现在我要希望将一些矿物质包括在土壤中进行开采,并开始让工程师实际建造和固定东西,这意味着东西必须分解.我不确定太阳耀斑可能很酷.沟通需要工作.因为您可以随时随地到达任何地点,但是现在您可以在轨道上捕获卫星了,所以我必须限制对卫星和无线电的通信需求.我得再咀嚼一下…(since the auto-pilot’s in its genesis phase I’ll find ways to allow a fleet of ships to track each other and possibly a target point, time and speed, as opposed to “enter orbit”, eventually, but for now I’d like to include some minerals on the soil for mining and start the engineers actually building and fixing things, which means stuff has to break down. maybe solar flares might be cool, i’m not sure. communications needs work. as it is you can reach any one any time but now that you can capture satellites in orbit I’ll have to limit communications with the need for satellites and radios. I’ll have to chew on that for a bit…) 向宇航员发出诸如"工程报告"之类的命令会很酷,但这是迈出的重要一步,我不确定我该如何解决,因此我必须花一会儿时间再思考.(giving astronauts orders like “report to Engineering” will be cool but that’s a major step I’m not sure how I want to tackle yet so I’ll have to ponder on it for a while before I do.)
更新(updates)
- 毫不奇怪,尽管花费了我的时间并进行了最后十天的调试和测试,但那天我还是发现了很多崩溃的错误(no surprise that despite taking my time and debugging and testing for the last ten days I discover a bunch of crashing-bugs the day)**后(after)**我发布了…修复了这些问题和一些细节.(I publish… fixed those and a few details.)
- 2011年7月18日-由于无法访问,再次上传了所有其他文件(july 18, 2011 - uploaded all the extra files again because they were not accessible)
许可
本文以及所有相关的源代码和文件均已获得The Code Project Open License (CPOL)的许可。
C# Windows 新闻 翻译