Difference between revisions of "Programming Guide/zh"

From Space Engineers Wiki
Jump to: navigation, search
(Created page with "在太空工程师游戏内编程是通过可编程块完成的,可以使用C#(念做 C Sharp)语言来编写脚本。 它可用于制造自主式采矿无人机...")
 
m
 
(6 intermediate revisions by one other user not shown)
Line 1: Line 1:
 +
{{DISPLAYTITLE:'''编程块指南'''}}
 +
 
在太空工程师游戏内编程是通过[[可编程块]]完成的,可以使用C#(念做 C Sharp)语言来编写脚本。 它可用于制造自主式采矿无人机,远距离玩家捕杀鱼雷,船舶建造用自动焊接臂等等。
 
在太空工程师游戏内编程是通过[[可编程块]]完成的,可以使用C#(念做 C Sharp)语言来编写脚本。 它可用于制造自主式采矿无人机,远距离玩家捕杀鱼雷,船舶建造用自动焊接臂等等。
 
== 介绍 ==
 
== 介绍 ==
Line 4: Line 6:
 
同一时间只有一个玩家可以编辑同一个脚本。 如果已经有一个人在当前块打开编辑器,而此时其他人试图打开该块的编辑器时,会显示一条通知,表示编辑器已经打开。
 
同一时间只有一个玩家可以编辑同一个脚本。 如果已经有一个人在当前块打开编辑器,而此时其他人试图打开该块的编辑器时,会显示一条通知,表示编辑器已经打开。
  
=== Main method ===
+
=== Main 方法 ===
When the editor is opened for first time, void Main() method is present inside the code editor.
+
当编辑器第一次打开时,代码编辑器中会出现void Main() 方法。<br />
This is entry point that will be called when executing script. If Main method is removed / renamed, the script will not run and you will be notified in the programmable block details area.
+
这是执行脚本时程序调用的入口方法。 如果删除/重命名Main方法,脚本将不会运行,您将在可编程块详细信息区域中收到通知。<br />
Custom methods/variables can be defined and used, but only the Main method will be called without reference.
+
可以定义和使用自定义方法/变量,但只调用Main方法而不引用。<br />
  
=== Variables life ===
+
=== 变量的生命周期 ===
There are two types of variables for scripting:
+
脚本中有两种类型的变量:<br />
Local (inside the methods) – these variables will keep their value only during execution of a method.
+
局部变量(定义在方法内部) - 这些变量仅在方法被执行期间保持其值。方法结束时,变量值将“丢失”。<br />
Value will be “lost” when the method ends.
+
全局变量(定义在方法外部) - 这些变量将在整个脚本的生命周期内保持其值。 <br />
Global (outside the methods) - these variables will keep their values during the lifetime of script. E.g.
+
例如:如果变量需要在程序运行时保持值,则需要在方法之外定义它。<br />
If the variable needs to keep value between separate runs of program, it needs to be defined outside the methods.
+
按“保存并退出”或“保存”按钮后,之前的脚本将被覆盖,之前所有的全局变量都将丢失。<br />
After pressing “Remember & Exit” or “Remember” buttons, the previous script will be overwritten and all Global variables will be lost.
+
除了内置的保留变量之外的所有变量(局部和全局变量)将在重新编译代码时以及在已保存的游戏加载之间丢失其值或返回其默认值。<br />
All variables, local and global except for the built-in Storage variable will lose their value or return to their default value when recompiling the code and between saved game loads.
+
保留变量的独特之处在于它可以将在保存中和重新编译时的数据存储为字符串。<br />
The Storage variable is unique in that that it store data as string between saved seasons and recompile.
 
  
=== Compiling ===
+
=== 编译 ===
When the “Check code” button is pressed, the code will be compiled and the result of the compilation will be shown.
+
按下“检查代码”按钮时,将编译代码并显示编译结果。<br />
There are two steps of the compilation process:
+
编译过程分为两步:<br />
First the code inside editor is compiled by c# compiler for language errors.
+
首先,编辑器内部的代码由c#编译器编译,检查语言错误。<br />
If there are any errors during compilation the following dialog is shown:
+
如果在编译期间出现任何错误,则显示以下对话框:<br />
It this case “aaa” string is placed before Main method. This is the wrong language construction and the compilation failed.
+
It this case “aaa” string is placed before Main method. This is the wrong language construction and the compilation failed.<br />
In the error dialog the Line number error and description of the error is shown.
+
(大意为:“aaa”字符串不能放在了Main方法之前。 编译失败。)<br />
 +
在错误对话框中,将显示错误行号和错误描述。<br />
  
After compilation, the code is checked for usage of disallowed namespaces and types. In case that check fails,
+
编译后,将检查代码是否使用不允许的命名空间和类型。 如果检查失败,<br />
the following dialog is shown:
+
显示以下对话框:<br />
In this case System.IO.Directory was used to delete some directory. This is forbidden and error is shown that “Not allowed type was used in script”.
+
In this case System.IO.Directory was used to delete some directory. This is forbidden and error is shown that “Not allowed type was used in script”.<br />
 +
(大意为:禁止使用System.IO.Directory删除某个目录。 错误“脚本中使用了不允许的类型”。)<br />
  
If compilation and checks pass, a dialog is shown, confirming the checks passed, and the code is saved.
+
如果编译和检查通过,则会显示一个对话框,确认已通过检查,并保存代码。<br />
  
=== Script execution ===
+
=== 脚本执行 ===
When “Run” button is pressed or “Run” is assigned as terminal action, script is executed. Currently “Run” needs to be called manually e.g. user need to click on “Run” button or attach it as terminal action.
+
按下“运行”按钮或将“运行”指定为终端操作时,将执行脚本。 目前需要手动调用“运行”,例如 用户需要单击“运行”按钮或将其作为终端操作附加。<br />
Script is executed only on server even if it’s triggered from client. If there is any exception during script execution, all clients will be notified in programmable block details area about failure.
+
脚本仅在服务器上执行,即使它是从客户端触发的。 如果在脚本执行期间出现任何异常,将在可编程块详细信息区域中通知所有客户端有关失败的信息。<br />
In case of exception during script execution, script will not run again unless User opens editor and change script.
+
如果在脚本执行期间发生异常,除非用户打开编辑器并更改脚本,否则脚本将不会再次运行。<br />
A timer can also continuesly run the script by having a run action (you may be prompt to input an argument) and then starting/triggering itself or being started/triggered via script code (if going by the letter the timer will stop if the script crash).
+
计时器还可以通过运行操作(可能会提示您输入参数)继续运行脚本,然后启动/触发自身或通过脚本代码启动/触发(如果脚本崩溃,计时器将停止)。<br />
  
=== Counting of instructions ===
+
=== 指令计数 ===
Every time script is executed, every instruction of script is counted. If script executes more instruction than limit, execution is stopped and user is notified that script is too complex for execution. This prevents scripts to “freeze” game.
+
每次执行脚本时,都会计算脚本的每条指令。 如果脚本执行的指令多于限制,则停止执行并通知用户脚本太复杂而无法执行。 这可以防止脚本“冻结”游戏。
  
=== Whitelist ===
+
=== 白名单 ===
The types and classes allowed in scripts are restricted. Refer to the [[Scripting Whitelist]] to see what you are allowed to use.
+
脚本中允许的类型和类受到限制。 请参阅[[脚本白名单]]以查看允许使用的内容。
  
== Available interfaces ==
+
== 可用的接口 ==
  
=== Possible Actions ===
+
=== 可用的操作 ===
Currently only terminal actions can be triggered inside scripts. User can access terminal system for grid on which programmable block is located and trigger any terminal action on any block at grid.
+
目前,只能在脚本内触发终端操作。 用户可以访问可编程块所在的网格的终端系统,并触发网格上任何块的任何终端动作。
 
:* [[Programming_Guide/API_List|API List]]
 
:* [[Programming_Guide/API_List|API List]]
  
=== Block Classes (Action List) ===
+
=== 方块类 (操作对象列表) ===
 
:* [[Programming_Guide/Action_List|Block Action List]]
 
:* [[Programming_Guide/Action_List|Block Action List]]
  
=== Same block class for different SubTypeID ===
+
=== 同一方块类的不同SubTypeID ===
Some blocks have same parent (e.g. <TypeId> in cubeblocks.sbc) and differs only by subtype (e.g. <SubtypeId>). This means there is no distinction between these block in code. <br />
+
一些块具有相同的父类 (例如: 在 cubeblocks.sbc中的<TypeId> ) 只有子类不同 (例如:其中的<SubtypeId>). 这意味着代码中的这些块之间没有区别。 <br />
Example of these blocks is the Cargo Container: there are 3 types of cargo containers in the game: small, medium and large. These three types differ only by subtype and Type is same for them e.g. large cargo container id is: <br />
+
一个例子是货物储存箱:在游戏中有三种货物储存箱:小型、中型和大型。这三种类型的区别仅在于子类型不同。<br />
 +
例如:大型货物储存箱的id是: <br />
 
<Id><br />
 
<Id><br />
 
<TypeId>CargoContainer</TypeId><br />
 
<TypeId>CargoContainer</TypeId><br />
 
<SubtypeId>LargeBlockLargeContainer</SubtypeId><br />
 
<SubtypeId>LargeBlockLargeContainer</SubtypeId><br />
 
</Id><br />
 
</Id><br />
Medium is:<br />
+
中型的是:<br />
 
<Id><br />
 
<Id><br />
 
<TypeId>CargoContainer</TypeId><br />
 
<TypeId>CargoContainer</TypeId><br />
 
<SubtypeId>SmallBlockMediumContainer</SubtypeId><br />
 
<SubtypeId>SmallBlockMediumContainer</SubtypeId><br />
 
</Id><br />
 
</Id><br />
And small is:<br />
+
小型的是:<br />
 
<Id><br />
 
<Id><br />
 
<TypeId>CargoContainer</TypeId><br />
 
<TypeId>CargoContainer</TypeId><br />
Line 72: Line 76:
 
</Id><br />
 
</Id><br />
  
In this case there is only one class IMyCargoContainer for all types of cargo containers.
+
在这种情况下,所有类型的货物储存箱都只有一个类IMyCargoContainer。
  
== Example programs ==
+
== 示例程序 ==
  
 
=== Hello world ===
 
=== Hello world ===
The standard Hello World program in Space Engineers can be written as such:
+
Space Engineers中的标准Hello World程序可以这样编写:
  
 
  public void Main()
 
  public void Main()
Line 84: Line 88:
 
  }
 
  }
  
If this program is entered into a programmable block and run, it will result in "Hello, world!" being displayed in the programmable block's interface on the lower right hand side of the screen.
+
如果将该程序输入可编程块并运行,将导致“Hello,world!” 显示在屏幕右下方的可编程块界面中。
  
=== Getting your position ===
+
=== 获得你的位置 ===
This program will show the current GPS coordinates of your programming block's position in the world.
+
该程序将显示编程块在世界中的位置的当前GPS坐标。
  
 
  public void Main()
 
  public void Main()
Line 96: Line 100:
  
  
=== Checking a sensor ===
+
=== 检查传感器 ===
It's easy to get a sensor to open a door or trigger some other action even without any programming if you just place that action in the sensor's "Setup actions" list. However, triggering an action when a sensor does ''not'' detect something is more difficult, and cannot be done with timer blocks. This program will automatically check a sensor every 10 ticks (working out to about 6 times per second) and close a door if the sensor does not detect anything. This can easily be applied to other purposes, like turning off drills when asteroids are not in sensor range.
+
如果您只是将该操作放在传感器的“设置操作”列表中,即使没有任何编程,也很容易让传感器打开门或触发其他操作。 但是,当传感器“没有”检测到某些东西时触发动作将变得困难,并且无法通过定时器块完成。 该程序将每10个游戏周期自动检查一个传感器(每秒工作约6次),如果传感器没有检测到任何东西,则关闭一个门。 这可以很容易地应用于其他目的,例如当小行星不在传感器范围内时关闭钻头。
  
 
  List<MyDetectedEntityInfo> entity_list = new List<MyDetectedEntityInfo>();  
 
  List<MyDetectedEntityInfo> entity_list = new List<MyDetectedEntityInfo>();  
Line 116: Line 120:
 
  }
 
  }
  
For this script to work, the sensor must be named "Door Sensor 1" and the door must be named "Door 1". If you configure the sensor to open the door, the door will automatically open when the player enters the sensor range and close when the player leaves the sensor range.
+
要使此脚本起作用,传感器必须命名为“Door Sensor 1”,门必须命名为“Door 1”。 如果您将传感器配置为打开门,则当玩家进入传感器范围时门将自动打开,当玩家离开传感器范围时门将关闭。
  
== Compilation errors ==
+
== 编译错误 ==
This is a list (in progress) of known compilation errors and what causes them.
+
这是已知编译错误的列表(正在进行中)以及导致它们的原因。
  
* Method name expected: The compiler found parentheses when it wasn't expecting them. You could be missing a method name before the parentheses, or you might be inappropriately using parentheses instead of square or curly brackets, depending on what you're trying to do.
+
* Method name expected: 编译器在不期望它们时找到括号。 您可能在括号前缺少方法名称,或者您可能不恰当地使用括号而不是方括号或大括号,具体取决于您要执行的操作。
  
== See also ==
+
== 另请参见 ==
 
* [[API:Sandbox.ModAPI.Ingame.MyGridTerminalSystem|MyGridTerminalSystem]] - Methods for getting object references to your various ship components.
 
* [[API:Sandbox.ModAPI.Ingame.MyGridTerminalSystem|MyGridTerminalSystem]] - Methods for getting object references to your various ship components.
 
* [[Programming Guide/Action List]] - Actions you can apply to objects via the Object.ApplyAction method. Also includes some of the object properties. Data appears incomplete as of March 19th, 2018.
 
* [[Programming Guide/Action List]] - Actions you can apply to objects via the Object.ApplyAction method. Also includes some of the object properties. Data appears incomplete as of March 19th, 2018.
  
== External links ==
+
== 外部链接 ==
 
* [https://forums.keenswh.com/threads/guide-programmable-block-c-101-for-space-engineers.7225150/ <nowiki>[Guide]</nowiki> Programmable Block - C# 101 For Space Engineers] - Basic intro to C# programming for Space Engineers.
 
* [https://forums.keenswh.com/threads/guide-programmable-block-c-101-for-space-engineers.7225150/ <nowiki>[Guide]</nowiki> Programmable Block - C# 101 For Space Engineers] - Basic intro to C# programming for Space Engineers.
 
* [https://forum.keenswh.com/threads/guide-programmable-block-c-102-for-space-engineers-loops-strings-and-other-things.7229828/ <nowiki>[Guide]</nowiki> Programmable Block - C# 102 for Space Engineers: Loops, Strings, and Other Things] - Basic intro to using loops and strings in C#
 
* [https://forum.keenswh.com/threads/guide-programmable-block-c-102-for-space-engineers-loops-strings-and-other-things.7229828/ <nowiki>[Guide]</nowiki> Programmable Block - C# 102 for Space Engineers: Loops, Strings, and Other Things] - Basic intro to using loops and strings in C#

Latest revision as of 12:44, 19 August 2021


在太空工程师游戏内编程是通过可编程块完成的,可以使用C#(念做 C Sharp)语言来编写脚本。 它可用于制造自主式采矿无人机,远距离玩家捕杀鱼雷,船舶建造用自动焊接臂等等。

介绍

编辑权限

同一时间只有一个玩家可以编辑同一个脚本。 如果已经有一个人在当前块打开编辑器,而此时其他人试图打开该块的编辑器时,会显示一条通知,表示编辑器已经打开。

Main 方法

当编辑器第一次打开时,代码编辑器中会出现void Main() 方法。
这是执行脚本时程序调用的入口方法。 如果删除/重命名Main方法,脚本将不会运行,您将在可编程块详细信息区域中收到通知。
可以定义和使用自定义方法/变量,但只调用Main方法而不引用。

变量的生命周期

脚本中有两种类型的变量:
局部变量(定义在方法内部) - 这些变量仅在方法被执行期间保持其值。方法结束时,变量值将“丢失”。
全局变量(定义在方法外部) - 这些变量将在整个脚本的生命周期内保持其值。
例如:如果变量需要在程序运行时保持值,则需要在方法之外定义它。
按“保存并退出”或“保存”按钮后,之前的脚本将被覆盖,之前所有的全局变量都将丢失。
除了内置的保留变量之外的所有变量(局部和全局变量)将在重新编译代码时以及在已保存的游戏加载之间丢失其值或返回其默认值。
保留变量的独特之处在于它可以将在保存中和重新编译时的数据存储为字符串。

编译

按下“检查代码”按钮时,将编译代码并显示编译结果。
编译过程分为两步:
首先,编辑器内部的代码由c#编译器编译,检查语言错误。
如果在编译期间出现任何错误,则显示以下对话框:
It this case “aaa” string is placed before Main method. This is the wrong language construction and the compilation failed.
(大意为:“aaa”字符串不能放在了Main方法之前。 编译失败。)
在错误对话框中,将显示错误行号和错误描述。

编译后,将检查代码是否使用不允许的命名空间和类型。 如果检查失败,
显示以下对话框:
In this case System.IO.Directory was used to delete some directory. This is forbidden and error is shown that “Not allowed type was used in script”.
(大意为:禁止使用System.IO.Directory删除某个目录。 错误“脚本中使用了不允许的类型”。)

如果编译和检查通过,则会显示一个对话框,确认已通过检查,并保存代码。

脚本执行

按下“运行”按钮或将“运行”指定为终端操作时,将执行脚本。 目前需要手动调用“运行”,例如 用户需要单击“运行”按钮或将其作为终端操作附加。
脚本仅在服务器上执行,即使它是从客户端触发的。 如果在脚本执行期间出现任何异常,将在可编程块详细信息区域中通知所有客户端有关失败的信息。
如果在脚本执行期间发生异常,除非用户打开编辑器并更改脚本,否则脚本将不会再次运行。
计时器还可以通过运行操作(可能会提示您输入参数)继续运行脚本,然后启动/触发自身或通过脚本代码启动/触发(如果脚本崩溃,计时器将停止)。

指令计数

每次执行脚本时,都会计算脚本的每条指令。 如果脚本执行的指令多于限制,则停止执行并通知用户脚本太复杂而无法执行。 这可以防止脚本“冻结”游戏。

白名单

脚本中允许的类型和类受到限制。 请参阅脚本白名单以查看允许使用的内容。

可用的接口

可用的操作

目前,只能在脚本内触发终端操作。 用户可以访问可编程块所在的网格的终端系统,并触发网格上任何块的任何终端动作。

方块类 (操作对象列表)

同一方块类的不同SubTypeID

一些块具有相同的父类 (例如: 在 cubeblocks.sbc中的<TypeId> ) 只有子类不同 (例如:其中的<SubtypeId>). 这意味着代码中的这些块之间没有区别。
一个例子是货物储存箱:在游戏中有三种货物储存箱:小型、中型和大型。这三种类型的区别仅在于子类型不同。
例如:大型货物储存箱的id是:
<Id>
<TypeId>CargoContainer</TypeId>
<SubtypeId>LargeBlockLargeContainer</SubtypeId>
</Id>
中型的是:
<Id>
<TypeId>CargoContainer</TypeId>
<SubtypeId>SmallBlockMediumContainer</SubtypeId>
</Id>
小型的是:
<Id>
<TypeId>CargoContainer</TypeId>
<SubtypeId>LargeBlockSmallContainer</SubtypeId>
</Id>

在这种情况下,所有类型的货物储存箱都只有一个类IMyCargoContainer。

示例程序

Hello world

Space Engineers中的标准Hello World程序可以这样编写:

public void Main()
{
   Echo ("Hello, world!");
}

如果将该程序输入可编程块并运行,将导致“Hello,world!” 显示在屏幕右下方的可编程块界面中。

获得你的位置

该程序将显示编程块在世界中的位置的当前GPS坐标。

public void Main()
{
    var pos = Me.GetPosition();
    Echo (pos.ToString());
}


检查传感器

如果您只是将该操作放在传感器的“设置操作”列表中,即使没有任何编程,也很容易让传感器打开门或触发其他操作。 但是,当传感器“没有”检测到某些东西时触发动作将变得困难,并且无法通过定时器块完成。 该程序将每10个游戏周期自动检查一个传感器(每秒工作约6次),如果传感器没有检测到任何东西,则关闭一个门。 这可以很容易地应用于其他目的,例如当小行星不在传感器范围内时关闭钻头。

List<MyDetectedEntityInfo> entity_list = new List<MyDetectedEntityInfo>(); 
public Program()
{
    Runtime.UpdateFrequency = UpdateFrequency.Update10;
    //This makes the program automatically run every 10 ticks.
}
public void Main()
{
    var door_sensor = GridTerminalSystem.GetBlockWithName("Door Sensor 1") as IMySensorBlock;
    door_sensor.DetectedEntities (entity_list);
    if (entity_list.Count == 0)
    {
        var door = GridTerminalSystem.GetBlockWithName("Door 1") as IMyDoor;
        door.ApplyAction ("Open_Off");
    }
}

要使此脚本起作用,传感器必须命名为“Door Sensor 1”,门必须命名为“Door 1”。 如果您将传感器配置为打开门,则当玩家进入传感器范围时门将自动打开,当玩家离开传感器范围时门将关闭。

编译错误

这是已知编译错误的列表(正在进行中)以及导致它们的原因。

  • Method name expected: 编译器在不期望它们时找到括号。 您可能在括号前缺少方法名称,或者您可能不恰当地使用括号而不是方括号或大括号,具体取决于您要执行的操作。

另请参见

  • MyGridTerminalSystem - Methods for getting object references to your various ship components.
  • Programming Guide/Action List - Actions you can apply to objects via the Object.ApplyAction method. Also includes some of the object properties. Data appears incomplete as of March 19th, 2018.

外部链接