GML语言概述(一)
声明:半吊子水平的自学程序策划,如有翻译不尽详细有错漏的地方,请以官方文档为主。
- GML语言概述内容:
- 1.1.基础编程结构(BASIC CODE STRUCTURE)
- 1.2.函数FUNCTIONS
- 1.3.脚本SCRIPTS
- 1.4.注释COMMENTS IN CODE
- 1.5.保留关键字RESERVED KEYWORDS
- 1.6.变量和变量范围VARIABLES AND VARIABLE SCOPE
- 1.7.处理实例变量(ADDRESSING VARIABLES IN OTHER INSTANCES)
- 1.8.赋值/求值顺序(EVALUATION ORDER)
- 1.9.数据类型(DATA TYPES)
- 1.10.数组(ARRAYS)
- 1.11.赋值(ASSIGNMENTS)
- 1.12.运算(EXPRESSIONS)
- 1.13.访问器(ACCESSORS)
- 1.14.语言特性(LANGUAGE FEATURES)
1.1.基础编程结构(BASIC CODE STRUCTURE)
一个语法模块是由几个单句组成的,每个单句之间需要适用“;”做分割。
单句的数量可多可少,取决于模块的功能作用大小,或者说取决于在游戏里面产生的效果大小。
1.2.函数FUNCTIONS
Define: A function has an input and an output, and the output is related somehow to the input.
函数调用方式;
<function>(<arg0>, <arg1> ,... <arg15>);
two types of functions:
- 大量的Gamemaker内置函数
- 任何在Gamemaker用户自建的脚本
一些函数可以用表达式来获取返回值。
- instance_destroy();
- // Destroy the calling instance - this requires no arguments and returns nothing
- dist = point_distance(x, y, mouse_x, mouse_y;
- // Get the distance from the current instance position to the mouse position - takes four arguments and returns a real
使用函数的内部变量来赋值是不被允许的,会被报错
- instance_nearest(x, y, obj).speed = 0;
The return value for the expression in that code example is a real number (the unique ID value for the nearest instance) and so it must be enclosed in brackets to be used in this way and properly address the instance required (see Addressing Variables In Other Instances for more information). [以便以这种方式使用,并正确地处理所需的实例(参见其他实例中的寻址变量以获得更多信息)]The above code would be correctly written as:
- (instance_nearest(x, y, obj)).speed = 0;
- //or
- var inst = instance_nearest(x, y, obj);
- inst.speed = 0;
1.3.脚本SCRIPTS
Scripts are essentially【实质上】 functions that you write yourself as short snippets of code that can resolve[解析] expressions, return values or anything else that the language permits. Basically if you have a block of code that you use in more than one place or object, then it's probably better off in a script, as it means that you can change it once when required and the change will be "picked up" by every object that has a call to the script. They can also be very handy from an organisational point of view, even if the code they hold is called only once by a single object, since it permits you to break large code blocks into more easily managed "chunks" at logical points.
脚本本质上是把自己编写成代码片段的函数,这些代码可以解析表达式、返回值或语言允许的任何其他内容。基本上,如果您有一个代码块,您在多个地方或对象中使用,那么它可能在脚本中更好,因为这意味着您可以在需要时更改一次,每个调用对象的调用都会“更改”。从组织的角度来看,它们也非常方便,即使它们所持有的代码只被一个对象调用一次,因为它允许您将大型代码块分解为更易于管理的逻辑块。
脚本可以返回任何值,以及任何被语法允许的结构,并且它可以用在不仅仅一个对象和代码片段内,它可以在任何一处调用它,
脚本参数是在脚本被调用时,需要传入的值,它在脚本以变量的形式储存,在脚本调用时,you must ensure that the script uses all the supplied arguments.,如果传入的参数不够,将会报错。
脚本一次能接受的单独参数,最多为15个,还有一个是它自己,但是可以用数组的形式传入单个参数,这样就不限于传16个参数了。
argument[0 ... max_num]
argument_count常常配合使用,它可以计算出数组一共传入了多少个参数。
但是在脚本被调用时,不用混合使用两种类型的参数,argument[0,1,argument[2,3]]是错误的,要是使用argument0,argument1 ...,要么使用一个数组argument[0 ... max_num]
函数可以返回值:
return <expression>
需要注意的是,脚本在return语句处结束,任何在其之后的语句都不会运行,下面的语句就会报错,返回的值不是一个正确的值:
- {
- if !is_real(argument0)
- {
- return 0;
- }
- else
- {
- return (argument0 * argument0);
- }
- }
在创建脚本时,会自动添加类似JSON格式的注释
@description:
1.4.注释COMMENTS IN CODE
在多人协作,解决大项目时,给代码和脚本留下注释是很重要的,在GamemakerStudio2中有几种写注释的方式
- 用双斜杠进行单行注释
- //initialize variables
- sr = 10;
- hp = 100;
- 用/* */进行多行注释,
- /*
- usage:
- diff = angle_difference(angle1,angle2);
- angle1 first direction in degrees, real
- angle2 second direction in degrees, real
- returns: difference of the given angles in degrees, -180 to 180
- GMLscripts.com
- */
- {
- return ((((argument0 - argument1) mod 360) + 540) mod 360) - 180;
- }
- 如果想要在调用脚本时,得到内置函数一样的提示,需要以JsonDoc风格的注释在脚本开头注明。
- /// @description Compare an instance object index with that of another.
- /// @param {real} instance_id The unique instance ID value of the instance to check.
- /// @param {real} object_index The object index to be checked against.
- if argument0.object_index == argument1
- {
- return true;
- }else return false;
1.5.保留关键字RESERVED KEYWORDS
These keywords are used primarily to identify instances and each one is explained in the text below. Note that all keywords are represented by a negative integer value internally, so care must be taken when assigning values to variables, as you may get unexpected results later as GameMaker Studio 2 interprets the value you have used as something else. You should also note that using the values instead of the keywords in your code is not at all recommended and could cause issues later on.
因为保留关键字在GMS2内部以负整数的形式储存,因此不推荐使用关键字进行赋值和变量储存操作,这会带来不可见的影响。例如self和other关键字
Self(-1): The instance which is executing the current block of code.指代当前正在执行的代码所归属的实例
Other(-2): The other instance involved in a collision event, or the other instance from a with function.使用with函数返回,或者碰撞函数返回的实例。
碰撞事件:仅仅发生在两个实例中,在多个碰撞中实现多个碰撞,在GMS2中必须以1对1的方式来实现,想象一个玩家,和多个怪物对象以及对应多个子弹对象,可以分配给每个敌人的子弹对象,造成随机的伤害,在子弹碰到玩家时。
- var nnn;
- nnn = instance_create(x, y, obj_Bullet);
- nnn.damage = 5 + irandom(5);
- nnn.speed = 8;
- nnn.direction = point_direction(x, y, obj_Player.x, obj_Player.y);
See how we[看看我们如何] set its variables using the point method outlined[后置过去分词定语:上文概述过的] in the section on Addressing Variables[看看我们在Addressing Variable部分讲过的指针方法来给变量赋值]? This will give the bullet objects a different damage value[这会给子弹对象赋值不同的伤害数值]. But what about the player object? How will it detect the damage that it has to take[如何侦测到它自己的受到伤害]? By using other in the collision event[那就是在碰撞事件中使用other变量]:
- hp -= other.damage;
- if hp <= 0 instance_destroy();
The above code will deduct the amount stored in the other instance in the collisions "damage" variable from the player "hp" variable, then it will check to see if the "hp" is lower than or equal to 0. If it is then it will destroy the player object. Please note that other used in this way only works in the collision event and that the other instance must have the variable being checked or else an error will be thrown. However you can assign values to variables, or even create new ones, using other in the collision event too, like this:
上面的代码将从当前实例的“HP”变量中减去一个数值,而这个数值是存储在另一个碰撞实例中的“Damege”变量中的值,然后检查当前实例“HP”是否低于或等于0。如果是的话,它会摧毁玩家对象。请注意,这种方式使用的其他程序只能在碰撞事件中工作,而另一个碰撞实例必须检查变量,否则将引发错误。但是,您可以在碰撞事件中使用变量,甚至创建新的变量,就像这样:
- other.mana += 10; //add ten to the other instance "mana" variable
- other.hit = true; //set the other instance variable "hit" to true, creating it if the variable doesn't already exist
all(-3): All instances currently active in the room.指代所有在场景中(room)中活动着的实例
This keyword is used to tell GameMaker Studio 2 that a function is to be applied, or to check, all active instances within a room (deactivated instances will not be checked or accessed). You cannot use all to access or set variables in other instances using the point method (see here), but you can use it when calling with(), for example:
此关键字用于在应用某个功能或检查时,告诉GameMaker Studio 2房间中的所有活动实例(禁用的实例将不被检查或访问)。 您不能使用all来访问或使用指针方法在其他实例中设置变量(请参阅此处),但是可以在调用with()时使用它,例如:
- with (all)
- {
- speed = 0;
- }
The above code will set the speed of all instances in the room to 0. You can also use all within functions to target or check all instances in the room for example:
上述代码将把房间中所有实例的速度设置为0(静止不动).您还可以使用函数内的所有内容来定位或检查房间中的所有实例,例如:
- inst = instance_position(mouse_x, mouse_y, all);
- //Check a point for any active instance in the room 访问房间中任何活动实例的位置
- if collision_line(x, y, mouse_x, mouse_y, all, false, true)
- {
- }
- //Check all instances for a collision along a line
- 访问沿一条线的碰撞上的所有实例
- mp_grid_add_instances(grid, all, false);
- //Add all instances in the room into a motion planning grid 将房间中的所有实例添加到动态的规划网格
all is a very useful keyword and can be used in numerous situations within your code and actions, often cutting down on the amount of code you need to write to achieve a desired effect.[以达预期的效果]
noone: No instance at all.没有任何实例
It may seem odd, but many times while programming your games will you find the need to check if there are no instances found at a location, or in a collision etc... In those cases you would use this keyword to check for nothing, something like this:
这可能看起来很奇怪,但是很多时候编程游戏时,您会发现需要检查在某个位置或碰撞中是否找不到任何实例,在这种情况下,您将使用此关键字来确认这件事情
- if instance_nearest(x, y, obj_enemy) != noone
- {
- //do something as there is an enemy instance near
- }
In this example, the function instance_nearest() will return either noone or the unique ID of the nearest found instance. Basically, any time that you need to check for an instance, you can expect to get either noone or a unique instance ID returned
在这个例子中,函数instance_nearest()将返回没有实例或找到的最近实例的唯一ID。 基本上,任何时候您来确认实例是否存在,您都可以预计获得结果:要么返回不存在“noone”或返回找到唯一的实例ID。
有一种终于有人并肩作战的感觉哈哈哈~