From d7cd470a1b7b935d53f4d9de1416e69384d2d16c Mon Sep 17 00:00:00 2001 From: COCO Date: Mon, 4 Jan 2021 13:45:18 +0800 Subject: [PATCH 001/134] update physics --- docs/zh/manuals/physics-groups.md | 18 + docs/zh/manuals/physics-joints.md | 56 +++ docs/zh/manuals/physics-messages.md | 110 +++++ docs/zh/manuals/physics-objects.md | 110 +++++ docs/zh/manuals/physics-ray-casts.md | 30 ++ .../manuals/physics-resolving-collisions.md | 87 ++++ docs/zh/manuals/physics-shapes.md | 76 ++++ docs/zh/manuals/physics.md | 412 +----------------- docs/zh/shared/html5-faq.md | 5 + 9 files changed, 506 insertions(+), 398 deletions(-) create mode 100644 docs/zh/manuals/physics-groups.md create mode 100644 docs/zh/manuals/physics-joints.md create mode 100644 docs/zh/manuals/physics-messages.md create mode 100644 docs/zh/manuals/physics-objects.md create mode 100644 docs/zh/manuals/physics-ray-casts.md create mode 100644 docs/zh/manuals/physics-resolving-collisions.md create mode 100644 docs/zh/manuals/physics-shapes.md diff --git a/docs/zh/manuals/physics-groups.md b/docs/zh/manuals/physics-groups.md new file mode 100644 index 00000000..9b7c311b --- /dev/null +++ b/docs/zh/manuals/physics-groups.md @@ -0,0 +1,18 @@ +--- +title: Defold 中的碰撞组 +brief: 物理引擎使用组来划分物理对象碰撞双方. +--- + +# 碰撞组与碰撞掩码 + +物理引擎通过组与掩码处理碰撞. 这个组就是 _碰撞组_. 每个碰撞对象都有2个属性用以控制其与其他物体的碰撞, *Group* 和 *Mask*. + +碰撞只发生在两个物体所处的组分别被包含在对方的 *碰撞掩码* 之中的情况下. + +![Physics collision group](images/physics/collision_group.png){srcset="images/physics/collision_group@2x.png 2x"} + +*掩码* 可包含多个组名, 以实现复杂的碰撞控制. + + +## 碰撞检测 +当组码掩码都相匹配两个碰撞对象接触时, 游戏引擎就会发出 [碰撞消息](/manuals/physics-messages) 作为响应. diff --git a/docs/zh/manuals/physics-joints.md b/docs/zh/manuals/physics-joints.md new file mode 100644 index 00000000..9ca1ea33 --- /dev/null +++ b/docs/zh/manuals/physics-joints.md @@ -0,0 +1,56 @@ +--- +title: Defold 中的物理关节 +brief: Defold 支持 2D 物理关节约束. 本教程介绍了其用法. +--- + +# 關節約束 + +Defold 支持物理关节. 一个关键基于某种限制连接两个物体. 支持的关节类型如下: + +* Fixed (physics.JOINT_TYPE_FIXED) - 限制两物体最大距离的固定关节. 在 Box2D 被称为绳子关节. +* Hinge (physics.JOINT_TYPE_HINGE) - 把两个物体通过一个锚点钉在一起的钉子关节. 两物体相对位置固定而相对旋转没有限制. 这种关节可以开启马达给一个最大扭力与速度. 在 Box2D 被称为旋转关节. +* Spring (physics.JOINT_TYPE_SPRING) - 限制两个物体之间距离范围的弹簧关节. 弹簧关节通过设定其频率和阻尼比可以让物体像是被软弹簧连接. 在 Box2D 被称为距离关节. +* Slider (physics.JOINT_TYPE_SLIDER) - 限制两物体只能在某个指定轴上相对移动而不允许相对转动的滑动关节. 在 Box2D 被称为活塞关节. + +## 建立关节 + +目前只能使用 [`physics.create_joint()`](/ref/physics/#physics.create_joint:joint_type-collisionobject_a-joint_id-position_a-collisionobject_b-position_b-[properties]) 函数手动建立关节: + +::: 注意 +编辑器可视环境下创建关节的功能在开发计划中但发布时间未知. +::: + +```lua +-- 将两个碰撞物体用固定关节连接 (绳子) +physics.create_joint(physics.JOINT_TYPE_FIXED, "obj_a#collisionobject", "my_test_joint", vmath.vector3(10, 0, 0), "obj_b#collisionobject", vmath.vector3(0, 20, 0), { max_length = 20 }) +``` + +上述代码创建了一个固定关节, 其id为 `my_test_joint`, 连接了两个物体 `obj_a#collisionobject` 与 `obj_b#collisionobject`. 关节位于 `obj_a#collisionobject` 偏左10像素, `obj_b#collisionobject` 偏上20像素的位置上. 设定的最大距离是20像素. + +## 删除关节 + +可以使用 [`physics.destroy_joint()`](/ref/physics/#physics.destroy_joint:collisionobject-joint_id) 函数删除关节: + +```lua +-- 删除上面提到的第一个物体上的关节 +physics.destroy_joint("obj_a#collisionobject", "my_test_joint") +``` + +## 关节属性及修改 + +可以使用 [`physics.get_joint_properties()`](/ref/physics/#physics.get_joint_properties:collisionobject-joint_id) 读取关节属性, 使用 [`physics.set_joint_properties()`](/ref/physics/#physics.set_joint_properties:collisionobject-joint_id-properties) 修改关节属性: + +```lua +function update(self, dt) + if self.accelerating then + local hinge_props = physics.get_joint_properties("obj_a#collisionobject", "my_hinge") + -- 马达速度提升每秒100转 + hinge_props.motor_speed = hinge_props.motor_speed + 100 * 2 * math.pi * dt + physics.set_joint_properties("obj_a#collisionobject", "my_hinge", hinge_props) + end +end +``` + +## 关节反作用力和扭矩 + +可以使用 [`physics.get_joint_reaction_force()`](/ref/physics/#physics.get_joint_reaction_force:collisionobject-joint_id) 读取关节反作用力, 使用 [`physics.get_joint_reaction_torque()`](/ref/physics/#physics.get_joint_reaction_torque:collisionobject-joint_id) 读取关节扭力. diff --git a/docs/zh/manuals/physics-messages.md b/docs/zh/manuals/physics-messages.md new file mode 100644 index 00000000..e7ea843e --- /dev/null +++ b/docs/zh/manuals/physics-messages.md @@ -0,0 +1,110 @@ +--- +title: Defold 中的碰撞消息 +brief: 当两个碰撞对象接触, 引擎会向这两个对象上的所有组件广播碰撞消息. +--- + +# 碰撞消息 + +当两个碰撞对象接触, 引擎会向这两个对象上的所有组件广播碰撞消息: + +## 碰撞响应 + +所有碰撞物体都会收到 `"collision_response"` 消息. 消息包含如下内容: + +`other_id` +: 另一个碰撞物的id (`hash`过的) + +`other_position` +: 另一个碰撞物的世界坐标 (`vector3`类型) + +`other_group` +: 另一个碰撞物所在的碰撞组 (`hash`过的) + +如果不需要很详细的信息, 碰撞响应消息就足够了, 比如检测子弹是否碰撞了敌人. 每帧每对碰撞物只有一个能收到此消息. + +```Lua +function on_message(self, message_id, message, sender) + -- 辨识消息 + if message_id == hash("collision_response") then + -- 做出响应 + print("I collided with", message.other_id) + end +end +``` + +## 碰撞点响应 + +如果碰撞一方是 dynamic 或 kinematic 对象, 那么它会收到 `"contact_point_response"` 消息. 消息包含如下内容: + +`position` +: 接触点世界坐标 (`vector3`类型). + +`normal` +: 接触点世界坐标系法向量, 方向是从另一物体指向当前物体 (`vector3`类型). + +`relative_velocity` +: 两个接触物体之间的相对速度, 方向是从另一物体指向当前物体 (`vector3`类型). + +`distance` +: 两个接触物体之间穿透距离 -- 非负数 (`number`类型). + +`applied_impulse` +: 两个接触物体间的冲量大小 (`number`类型). + +`life_time` +: (*目前未使用*) 接触时长 (`number`类型). + +`mass` +: 当前物体质量, 单位千克 (`number`类型). + +`other_mass` +: 另一个物体质量, 单位千克 (`number`类型). + +`other_id` +: 另一个物体的id (`hash`过的). + +`other_position` +: 另一个物体的世界坐标 (`vector3`类型). + +`group` +: 另一个物体所处的碰撞组 (`hash`过的). + +要让相碰撞的物体好好分离, 用 `"contact_point_response"` 消息里的数据就够了. 注意每帧每对碰撞物可能不止收到一个 `"contact_point_response"` 消息, 这取决于接触的情况, 详见 [碰撞处理教程](/manuals/physics-resolving-collisions). + +```Lua +function on_message(self, message_id, message, sender) + -- check for the message + if message_id == hash("contact_point_response") then + -- take action + if message.other_mass > 10 then + print("I collided with something weighing more than 10 kilos!") + end + end +end +``` + +## 触发器响应 + +作为 "trigger" 类型的碰撞对象会收到 `"trigger_response"` 消息. +触发器与碰撞对象接触时会收到 `"collision_response"` 消息. 而且, 接触开始和结束时都会收到 `"trigger_response"` 消息. 消息包含如下信息: + +`other_id` +: 另一个物体的id (`hash`过的). + +`enter` +: 如果另一个物体进入触发器为 `true`, 离开为 `false`. (`boolean`类型). + +```Lua +function on_message(self, message_id, message, sender) + -- check for the message + if message_id == hash("trigger_response") then + if message.enter then + -- take action for entry + print("I am now inside", message.other_id) + else + -- take action for exit + print("I am now outside", message.other_id) + end + end +end +``` diff --git a/docs/zh/manuals/physics-objects.md b/docs/zh/manuals/physics-objects.md new file mode 100644 index 00000000..b7c0d9ce --- /dev/null +++ b/docs/zh/manuals/physics-objects.md @@ -0,0 +1,110 @@ +--- +title: Defold 中的碰撞对象 +brief: 碰撞对象是能给与游戏对象物理行为的组件. 碰撞对象包含许多物理属性和空间形状. +--- + +# 碰撞对象 + +碰撞对象是能给与游戏对象物理行为的组件. 碰撞对象包含许多物理属性比如重量, 弹性, 阻力等等. 组件上定义的一个或多个 _形状_ 决定了它在物理空间中的样子. Defold 支持以下的碰撞对象: + +Static objects +: 静态对象不会移动但是能和移动物体进行碰撞. 静态对象很适合制作游戏固定场景元素 (比如地板和墙). 它们比动态对象性能消耗少. 静态对象不能被移动和修改. + +Dynamic objects +: 动态对象由物理引擎负责计算位移. 处理碰撞然后给予力. 动态对象看起来很有真实感但是你 *不能* 直接控制它的位置与方向. 要想对其施加影响, 只能向它[施加力的作用](/ref/physics/#apply_force). + +Kinematic objects +: 动画对象可以和其他对象产生碰撞, 但是物理引擎并不处理它们. 忽略碰撞, 或者交给你来处理. 动画对象很适合用作由脚本控制的又能对物理做出反应的物体, 比如游戏角色. + +Triggers +: 触发器是记录碰撞的物体. 很适合用作碰撞检测 (比如子弹碰撞) 或者接触后触发时间的场景. 触发器比动画对象节省性能所以可以多用一些. + + +## 加入碰撞對象组件 + +碰撞对象组件包含一系列 *属性* 用以设定其类型和物理特性. 还包含一个或多个 *形状* 用以定义这个物体的物理形态. + +在游戏对象上添加碰撞对象组件: + +1. 在 *大綱* 視圖中, 右鍵點擊 游戲對象然後在上下文菜單中選擇 Add Component ▸ Collision Object. 新添加的組件沒有形狀. +2. 在組件上 右鍵點擊 然後選擇 Add Shape ▸ Box / Capsule / Sphere. 來為組件添加形狀. 一個組件可以有多個形狀. 還可以使用瓷磚地圖或者凸多邊形頂點文件定義物理對象的形狀. +3. 可以使用移動, 旋轉, 縮放工具修改形狀. +4. 點選組件后可在 *大綱* 視圖中編輯其 *屬性*. + +![Physics collision object](images/physics/collision_object.png){srcset="images/physics/collision_object@2x.png 2x"} + + +## 加入碰撞形状 + +碰撞组件可包含多个简单形状或者一个复杂形状. 详见 [碰撞形状教程](/manuals/physics-shapes). + + +## 碰撞對象屬性 + +Id +: 组件名. + +Collision Shape +: 这个是针对瓷砖地图的几何形状设置. 详见 [碰撞形状教程](/manuals/physics-shapes). + +Type +: 碰撞对象的类型有: `Dynamic`, `Kinematic`, `Static` 和 `Trigger`. 如果设为动态就 _必须_ 设置其 *Mass* 属性为非0的值. 动态静态碰撞对象都需要为其设置适当的 *Friction* 和 *Restitution* 值. + +Friction +: 摩擦可以做出一个物体在另一个物体上滑动的效果. 一般摩擦系数取值范围从 `0` (无摩擦---超级光滑) 到 `1` (强摩擦---超级粗糙) 之间. 但其实任何正数值都有效. + +摩擦力于法方向上的力成正比 (称为库伦摩擦). 计算两个物体 (`A` 和 `B`) 间的摩擦力时, 摩擦系数取两个物体的几何平均值: + +$$ +F_{combined} = \sqrt{ F_A \times F_B } +$$ + +也就是说只要有一个物体是0摩擦的, 两个物体之间就不会有摩擦力. + +Restitution +: 弹性是物体的 "反弹性能". 一般取值范围从 0 (非弹性碰撞—一点也不反弹) 到 1 (完全弹性碰撞---物体速度在碰撞后完全反向) + +两个物体 (`A` 和 `B`) 之间的弹性计算基于以下公式: + +$$ +R = \max{ \left( R_A, R_B \right) } +$$ + +当一个形状发生多处碰撞时, 弹性模拟并不精确因为 Box2D 使用的是迭代解算器. Box2D 在碰撞相对速度很小时也使用非弹性碰撞代替, 以防止反弹抖动. + +Linear damping +: 线性阻尼会减小刚体的线性速度. 不像摩擦只在物体接触时产生, 线性阻尼始终应用与线性移动的物体上, 给人一种物体飘进比空气密度大的环境中的感觉. 取值范围 0 到 1. + +Box2D 并不精确计算阻尼. 值很小时阻尼与时间无关, 值很大时阻尼随时间变化. 如果时间步固定, 这不会造成问题. + +Angular damping +: 角阻尼与线性阻尼类似, 不同的是它减小的是刚体角速度. 取值范围 0 到 1. + +Locked rotation +: 关闭碰撞对象的旋转, 无论力如何施加都不会旋转. + +Group +: 此碰撞对象所归属的碰撞组. 可以自由定义16个组. 比如 "players", "bullets", "enemies" 或 "world". 如果瓷砖地图上设置了 *Collision Shape*, 则使用的是瓷砖图源里的组名而不是该属性定义的组名. + +Mask +: 可以与此对象进行碰撞的 _组_. 如果指定多个, 组名以逗号分割. 如果值为空, 则此对象不与任何物体进行碰撞. + + +## 運行時屬性 + +可以使用 `go.get()` 和 `go.set()` 來存取物理對象的一系列屬性: + +`angular_damping` +: 碰撞對象的旋轉阻尼 (`number`). [API reference](/ref/physics/#angular_damping). + +`angular_velocity` +: 碰撞對象的旋轉速度 (`vector3`). [API reference](/ref/physics/#angular_velocity). + +`linear_damping` +: 碰撞對象的綫性阻尼 (`number`). [API reference](/ref/physics/#linear_damping). + +`linear_velocity` +: 碰撞對象的綫性速度 (`vector3`). [API reference](/ref/physics/#linear_velocity). + +`mass` +: 碰撞對象的物理質量 (`number`). [API reference](/ref/physics/#mass). diff --git a/docs/zh/manuals/physics-ray-casts.md b/docs/zh/manuals/physics-ray-casts.md new file mode 100644 index 00000000..f13e8782 --- /dev/null +++ b/docs/zh/manuals/physics-ray-casts.md @@ -0,0 +1,30 @@ +--- +title: Defold 中的物理投射 +brief: 投射用于收集延一条投射射线所遇到的物理世界的物体. 本教程介绍了其用法. +--- + +## 投射 + +投射用于收集延一条投射射线所遇到的物理世界的物体. 只要提供起止点和 [碰撞组](/manuals/physics-groups) , 就可以投射射线了. + +射线碰到的物体数据都会被记录下来. 包括动态, 静态和动画碰撞对象. 不包括触发器对象. + + +```lua +function update(self, dt) + -- 投射射线 + local my_start = vmath.vector3(0, 0, 0) + local my_end = vmath.vector3(100, 1000, 1000) + local my_groups = { hash("my_group1"), hash("my_group2") } + + local result = physics.raycast(my_start, my_end, my_groups) + if result then + -- 处理射线碰撞结果 (所有数据参见 'ray_cast_response' 消息) + print(result.id) + end +end +``` + +::: 注意 +结果不包括射线起始点位置的碰撞物体. 这是 Box2D 做的限制. +::: diff --git a/docs/zh/manuals/physics-resolving-collisions.md b/docs/zh/manuals/physics-resolving-collisions.md new file mode 100644 index 00000000..0dd8e2c0 --- /dev/null +++ b/docs/zh/manuals/physics-resolving-collisions.md @@ -0,0 +1,87 @@ +--- +title: Defold 中的碰撞处理 +brief: 本教程介绍了动画物理对象的碰撞处理方法. +--- + +# 處理动画碰撞 + +对于动画碰撞对象的碰撞必须手动处理. 一个想当然的处理方法如下: + +```lua +function on_message(self, message_id, message, sender) + -- 处理碰撞 + if message_id == hash("contact_point_response") then + local newpos = go.get_position() + message.normal * message.distance + go.set_position(newpos) + end +end +``` + +动画碰撞对象的确离开了碰撞穿透, 但是分离之后经常会过冲, 这在许多情况下会产生抖动. 为了便于理解, 想象游戏主角碰到了两个物体, *A* 和 *B*: + +![Physics collision](images/physics/collision_multi.png){srcset="images/physics/collision_multi@2x.png 2x"} + +碰撞发生的那一帧里, 物理引擎发出多个 `"contact_point_response"` 消息, 一个给 *A* 一个给 *B*. 如果按上面那样移动角色, 结果会是这样: + +- 根据 *A* 的穿透距离把角色向上移 (黑色箭头) +- 根据 *B* 的穿透距离把角色向左上移 (黑色箭头) + +顺序无所谓结果是一样的: 最终位移是 *每个穿透向量的矢量和*: + +![Physics separation naive](images/physics/separation_naive.png){srcset="images/physics/separation_naive@2x.png 2x"} + +要想正确地将角色移出 *A* 和 *B*, 需要处理碰撞点的穿透距离并检测上一个位移是否, 完全或部分, 分离了它们. + +假设第一次碰撞从 *A* 开始, 然后针对 *A* 做位移: + +![Physics separation step 1](images/physics/separation_step1.png){srcset="images/physics/separation_step1@2x.png 2x"} + +这样一来角色也部分离开了 *B*. 最后只剩下 *B* 黑色箭头那点穿透. 这段位移应该是 *A* 向量映射到 *B* 剩余的补偿: + +![Projection](images/physics/projection.png){srcset="images/physics/projection@2x.png 2x"} + +$$l = vmath.project(A, B) \times vmath.length(B)$$ + +补偿向量等于 *B* 向量减去 *l* 向量. 所以计算位移的时候, 对于每个碰撞点, 可以引入矫正向量按以下步骤进行矫正: + +1. 把当前矫正向量映射到碰撞穿透向量上. +2. 计算穿透向量的补偿 (按照上述公式). +3. 依照补偿向量移动对象. +4. 把补偿向量累加到矫正向量中. + +完整的代码实现如下: + +```lua +function init(self) + -- 校正向量 + self.correction = vmath.vector3() +end + +function update(self, dt) + -- 重置矫正向量 + self.correction = vmath.vector3() +end + +function on_message(self, message_id, message, sender) + -- 处理碰撞 + if message_id == hash("contact_point_response") then + -- 获取位移计算所需数据. + -- 当前帧可能有多个碰撞点需要处理, + -- 通过累积矫正向量, + -- 达到正确计算位移的目的: + if message.distance > 0 then + -- 第一步, 把矫正向量投射到 + -- 穿透向量上. + local proj = vmath.project(self.correction, message.normal * message.distance) + if proj < 1 then + -- 没有过冲的才需要补偿. + local comp = (message.distance - message.distance * proj) * message.normal + -- 应用补偿向量. + go.set_position(go.get_position() + comp) + -- 积累矫正向量. + self.correction = self.correction + comp + end + end + end +end +``` diff --git a/docs/zh/manuals/physics-shapes.md b/docs/zh/manuals/physics-shapes.md new file mode 100644 index 00000000..384ea05d --- /dev/null +++ b/docs/zh/manuals/physics-shapes.md @@ -0,0 +1,76 @@ +--- +title: 碰撞形状 +brief: 碰撞对象的形状可以包含多个简单形状组成也可以由一个复杂形状代替. +--- + +# 碰撞對象形狀 + +碰撞对象的形状可以包含多个简单形状组成也可以由一个复杂形状代替. + +### 简单形状 +简单形状有 *box*, *sphere* 和 *capsule*. 要加入简单形状可以在碰撞对象上 右键单击 选择 Add Shape: + +![Add a primitive shape](images/physics/add_shape.png) + +## 方形 +方形设定由位置, 旋转和尺寸 (宽度, 高度和深度) 组成: + +![Box shape](images/physics/box.png) + +## 圓形 +圆形设定由位置, 旋转和直径组成: + +![Sphere shape](images/physics/sphere.png) + +## 膠囊形 +胶囊形设定由位置, 旋转, 直径和高度组成: + +![Sphere shape](images/physics/capsule.png) + +::: 注意 +胶囊形仅用于 3D 物理 (在 *game.project* 文件的物理部分进行设置). +::: + + +### 复杂形状 +复杂形状可以由瓷砖地图生成或者使用凸多边形. + +## 瓷砖地图碰撞形状 +Defold 包含一个功能就是从瓷砖地图中自动生成物理碰撞形状. [瓷砖地图教程](/manuals/tilemap/) 介绍了新建瓷砖图源的碰撞组与把瓷砖分配给碰撞组的 ([例子](/examples/tilemap/collisions/)). + +在瓷砖地图上添加碰撞: + +1. 右键点击 游戏对象, 选择 Add Component File. 来选取瓷砖地图文件. +2. 右键点击 游戏对象, 选择 Add Component ▸ Collision Object 加入碰撞对象组件. +3. 不加入形状, 而是配置 *Collision Shape* 属性为 *瓷砖地图* 文件. +4. 设置碰撞对象的其他 *属性*. + +![Tilesource collision](images/physics/collision_tilemap.png){srcset="images/physics/collision_tilemap@2x.png 2x"} + +::: 注意 +这里的 *Group* 属性 **不会** 生效, 因为碰撞组已在瓷砖图源中定义好了. +::: + +## 凸多边形 +Defold 有一个功能就是让你用3个或多个点建立凸多边形. 可以使用资源 [Defold 多边形编辑器](/assets/defoldpolygoneditor/) 或者 [物理刚体编辑器](/assets/physicsbodyeditor/) 来创建凸多边形. + +1. 新建凸多边形文件 (扩展名 `.convexshape`). +2. 不在碰撞对象上加入形状, 而是设置 *Collision Shape* 属性为 *凸多边形文件*. + +::: 注意 +编辑器里不显示形状. 只有 [开启物理调试](/manuals/debugging-game-logic/#物理引擎调试) 才能在运行时看到形状. +::: + + +# 缩放碰撞形状 + +可以让碰撞形状继承游戏对象的缩放. 在 *game.project* 里的物理部分勾选 [Allow Dynamic Transforms](/manuals/project-settings/#Allow Dynamic Transforms) 即可. 注意缩放继承只支持等比缩放, 如果不等比, 去三周最小值. + + +# 旋转碰撞形状 + +## 在3D物理世界中旋转碰撞形状 +在3D物理中物体在各个轴上都可以进行旋转. + +## 在2D物理世界中旋转碰撞形状 +在3D物理中物体只能在z轴上旋转. 其他轴旋转会造成错误结果, 即使旋转180度用于翻转形状也不行. 要翻转物理形状推荐使用 [`physics.set_hlip(url, flip)`](/ref/stable/physics/?#physics.set_hflip:url-flip) 和 [`physics.set_vlip(url, flip)`](/ref/stable/physics/?#physics.set_vflip:url-flip) 函数. diff --git a/docs/zh/manuals/physics.md b/docs/zh/manuals/physics.md index 13bb01b9..7a6831f1 100644 --- a/docs/zh/manuals/physics.md +++ b/docs/zh/manuals/physics.md @@ -1,418 +1,30 @@ --- title: Defold 中的物理系统 -brief: Defold 包含的物理引擎可以基于牛顿物理定律模拟物体运动碰撞时的物理效果. 本教程介绍了物理引擎的使用方法. +brief: Defold 包含 2D 和 3D 的物理引擎. 它们可以基于牛顿物理定律模拟各种物体运动碰撞时的物理效果. --- # 物理 Defold 包含一个修改版的 [Box2D](http://www.box2d.org) 物理引擎 (版本 2.1) 用于模拟2D物理效果和一个 Bullet physics 引擎 (版本 2.77) 用来模拟3D物理效果. 物理引擎可以基于牛顿物理定律模拟各种 _碰撞物体_ 运动碰撞时的物理效果. 本教程介绍了物理引擎的使用方法. -## 碰撞对象 +Defold 中的物理相关教程如下: -碰撞对象是能给与游戏对象物理行为的组件. 碰撞对象包含许多物理属性比如重量, 弹性, 阻力等等. 组件上定义的一个或多个 _形状_ 决定了它在物理空间中的样子. Defold 支持以下的碰撞对象: +* **碰撞对象** - 碰撞对象是用于使游戏物体产生物理效果的组件. 碰撞对象组件含有一系列物理属性比如重量, 摩擦和形状. 详见 [碰撞对象教程](/manuals/physics-objects). +* **碰撞形状** - 碰撞对象可由多个简单形状或者一个复杂形状构成. 详见 [物理形状教程](/manuals/physics-shapes). +* **碰撞组** - 碰撞对象用组划分一遍确定碰撞关系. 详见 [碰撞组教程](/manuals/physics-groups). +* **碰撞消息** - 两个碰撞对象接触时引擎会自动向二者的游戏对象发送物理碰撞消息. 详见 [碰撞消息教程](/manuals/physics-messages) -Static objects -: 静态对象不会移动但是能和移动物体进行碰撞. 静态对象很适合制作游戏固定场景元素 (比如地板和墙). 它们比动态对象性能消耗少. 静态对象不能被移动和修改. +另外还可以向物理碰撞对象施加 **约束**, 称为 **关节**, 用以向碰撞对象进行物理约束或者力的施加. 详见 [物理关节教程](/manuals/physics-joints). -Dynamic objects -: 动态对象由物理引擎负责计算位移. 处理碰撞然后给予力. 动态对象看起来很有真实感但是你 *不能* 直接控制它的位置与方向. 要想对其施加影响, 只能向它[施加力的作用](/ref/physics/#apply_force). +还可以通过向物理世界发出射线以便了解各个物体的位置情况, 称为 **投射**. 详见 [物理投射教程](/manuals/physics-ray-casts). -Kinematic objects -: 动画对象可以和其他对象产生碰撞, 但是物理引擎并不处理它们. 忽略碰撞, 或者交给你来处理. 动画对象很适合用作由脚本控制的又能对物理做出反应的物体, 比如游戏角色. -Triggers -: 触发器是记录碰撞的物体. 很适合用作碰撞检测 (比如子弹碰撞) 或者接触后触发时间的场景. 触发器比动画对象节省性能所以可以多用一些. +## 物理模拟数量单位 -## 加入碰撞對象组件 - -碰撞对象组件包含一系列 *属性* 用以设定其类型和物理特性. 还包含一个或多个 *形状* 用以定义这个物体的物理形态. - -在游戏对象上添加碰撞对象组件: - -1. 在 *大綱* 視圖中, 右鍵點擊 游戲對象然後在上下文菜單中選擇 Add Component ▸ Collision Object. 新添加的組件沒有形狀. -2. 在組件上 右鍵點擊 然後選擇 Add Shape ▸ Box / Capsule / Sphere. 來為組件添加形狀. 一個組件可以有多個形狀. 還可以使用瓷磚地圖或者凸多邊形頂點文件定義物理對象的形狀. -3. 可以使用移動, 旋轉, 縮放工具修改形狀. -4. 點選組件后可在 *大綱* 視圖中編輯其 *屬性*. - -![Physics collision object](images/physics/collision_object.png){srcset="images/physics/collision_object@2x.png 2x"} - - -## 碰撞對象屬性 - -Id -: 组件名. - -Collision Shape -: 这个是针对瓷砖地图的几何形状设置. 详见下文. - -Type -: 碰撞对象的类型有: `Dynamic`, `Kinematic`, `Static` 和 `Trigger`. 如果设为动态就 _必须_ 设置其 *Mass* 属性为非0的值. 动态静态碰撞对象都需要为其设置适当的 *Friction* 和 *Restitution* 值. - -Friction -: 摩擦可以做出一个物体在另一个物体上滑动的效果. 一般摩擦系数取值范围从 `0` (无摩擦---超级光滑) 到 `1` (强摩擦---超级粗糙) 之间. 但其实任何正数值都有效. - - 摩擦力于法方向上的力成正比 (称为库伦摩擦). 计算两个物体 (`A` 和 `B`) 间的摩擦力时, 摩擦系数取两个物体的几何平均值: - - $$ - F_{combined} = \sqrt{ F_A \times F_B } - $$ - - 也就是说只要有一个物体是0摩擦的, 两个物体之间就不会有摩擦力. - -Restitution -: 弹性是物体的 "反弹性能". 一般取值范围从 0 (非弹性碰撞—一点也不反弹) 到 1 (完全弹性碰撞---物体速度在碰撞后完全反向) - - 两个物体 (`A` 和 `B`) 之间的弹性计算基于以下公式: - - $$ - R = \max{ \left( R_A, R_B \right) } - $$ - - 当一个形状发生多处碰撞时, 弹性模拟并不精确因为 Box2D 使用的是迭代解算器. Box2D 在碰撞相对速度很小时也使用非弹性碰撞代替, 以防止反弹抖动. - -Linear damping -: 线性阻尼会减小刚体的线性速度. 不像摩擦只在物体接触时产生, 线性阻尼始终应用与线性移动的物体上, 给人一种物体飘进比空气密度大的环境中的感觉. 取值范围 0 到 1. - - Box2D 并不精确计算阻尼. 值很小时阻尼与时间无关, 值很大时阻尼随时间变化. 如果时间步固定, 这不会造成问题. - -Angular damping -: 角阻尼与线性阻尼类似, 不同的是它减小的是刚体角速度. 取值范围 0 到 1. - -Locked rotation -: 关闭碰撞对象的旋转, 无论力如何施加都不会旋转. - -Group -: 此碰撞对象所归属的碰撞组. 可以自由定义16个组. 比如 "players", "bullets", "enemies" 或 "world". 如果瓷砖地图上设置了 *Collision Shape*, 则使用的是瓷砖图源里的组名而不是该属性定义的组名. - -Mask -: 可以与此对象进行碰撞的 _组_. 如果指定多个, 组名以逗号分割. 如果值为空, 则此对象不与任何物体进行碰撞. - -## 碰撞對象形狀 - -碰撞对象的形状可以由多个简单形状组成也可以由一个复杂形状代替. 简单形状有 *box*, *sphere* 和 *capsule*. 复杂形状可以由瓷砖地图生成或者使用凸多边形. - -### 方形 -方形设定由位置, 旋转和尺寸 (宽度, 高度和深度) 组成: - -![Box shape](images/physics/box.png) - -### 圓形 -圆形设定由位置, 旋转和直径组成: - -![Sphere shape](images/physics/sphere.png) - -### 膠囊形 -胶囊形设定由位置, 旋转, 直径和高度组成: - -![Sphere shape](images/physics/capsule.png) - -### 瓷砖地图碰撞形状 -Defold 包含一个功能就是从瓷砖地图中自动生成物理碰撞形状. [瓷砖地图教程](/manuals/tilemap/) 介绍了新建瓷砖图源的碰撞组与把瓷砖分配给碰撞组的 ([例子](/examples/tilemap/collisions/)). - -在瓷砖地图上添加碰撞: - -1. 右键点击 游戏对象, 选择 Add Component File. 来选取瓷砖地图文件. -2. 右键点击 游戏对象, 选择 Add Component ▸ Collision Object 加入碰撞对象组件. -3. 不加入形状, 而是配置 *Collision Shape* 属性为 *瓷砖地图* 文件. -4. 设置碰撞对象的其他 *属性*. - -![Tilesource collision](images/physics/collision_tilemap.png){srcset="images/physics/collision_tilemap@2x.png 2x"} - -::: 注意 -这里的 *Group* 属性 **不** 生效, 因为碰撞组已在瓷砖图源中定义好了. -::: - -### 凸多边形 -Defold 有一个功能就是让你用3个或多个点建立凸多边形. 可以使用资源 [Defold 多边形编辑器](/assets/defoldpolygoneditor/) 或者 [物理刚体编辑器](/assets/physicsbodyeditor/) 来创建凸多边形. - -1. 新建凸多边形文件 (扩展名 `.convexshape`). -2. 不在碰撞对象上加入形状, 而是设置 *Collision Shape* 属性为 *凸多边形文件*. - -::: 注意 -编辑器里不显示形状. 只有 [开启物理调试](/manuals/debugging-game-logic/#物理引擎调试) 才能在运行时看到形状. -::: - - -### 缩放碰撞形状 - -可以让碰撞形状继承游戏对象的缩放. 在 *game.project* 里的物理部分勾选 [Allow Dynamic Transforms](/manuals/project-settings/#Allow Dynamic Transforms) 即可. 注意缩放继承只支持等比缩放, 如果不等比, 去三周最小值. - - -### 旋转碰撞形状 - -#### 在3D物理世界中旋转碰撞形状 -在3D物理中物体在各个轴上都可以进行旋转. - -#### 在2D物理世界中旋转碰撞形状 -在3D物理中物体只能在z轴上旋转. 其他轴旋转会造成错误结果, 即使旋转180度用于翻转形状也不行. 要翻转物理形状推荐使用 [`physics.set_hlip(url, flip)`](/ref/stable/physics/?#physics.set_hflip:url-flip) 和 [`physics.set_vlip(url, flip)`](/ref/stable/physics/?#physics.set_vflip:url-flip) 函数. - - -### 物理引擎单位 - -设计上按照牛顿物理学单位米, 千克和秒 (MKS) 的标准单位. 模拟物尺寸 0.1 到 10 米范围 (静态对象可以更大) 效果较好, 默认一像素 (pixel) 当作 1 米. 这种转换是物理模拟器层次上的, 对游戏来说并不适用. +设计上按照牛顿物理学单位米, 千克和秒 (MKS) 的标准单位. 模拟物尺寸 0.1 到 10 米范围 (静态对象可以更大) 效果较好, 默认一像素 (pixel) 当作 1 米. 这种转换比例是物理模拟器层次上的, 对游戏来说并不适用. 默认一个200像素的物体在物理世界相当于200米超过了最佳模拟范围. 一般需要对游戏里的物体进行物理上的缩放. 可以在 `game.project` 里的 [物理缩放设置](/manuals/project-settings/#Physics) 处指定缩放值. 比如设置为 0.02 意味着 1:50, 那么200像素就是 4 米. 注意重力 (也在 `game.project` 里进行设定) 也需要基于缩放值进行调整. -## 碰撞组与碰撞掩码 - -物理引擎通过组与掩码处理碰撞. 这个组就是 _碰撞组_. 每个碰撞对象都有2个属性用以控制其与其他物体的碰撞, *Group* 和 *Mask*. - -碰撞只发生在两个物体所处的组分别被包含在对方的 *碰撞掩码* 之中的情况下. - -![Physics collision group](images/physics/collision_group.png){srcset="images/physics/collision_group@2x.png 2x"} - -*掩码* 可包含多个组名, 以实现复杂的碰撞控制. - -## 運行時屬性 - -可以使用 `go.get()` 和 `go.set()` 來存取物理對象的一系列屬性: - -`angular_damping` -: 碰撞對象的旋轉阻尼 (`number`). [API reference](/ref/physics/#angular_damping). - -`angular_velocity` -: 碰撞對象的旋轉速度 (`vector3`). [API reference](/ref/physics/#angular_velocity). - -`linear_damping` -: 碰撞對象的綫性阻尼 (`number`). [API reference](/ref/physics/#linear_damping). - -`linear_velocity` -: 碰撞對象的綫性速度 (`vector3`). [API reference](/ref/physics/#linear_velocity). - -`mass` -: 碰撞對象的物理質量 (`number`). [API reference](/ref/physics/#mass). - - -## 碰撞消息 - -两个物体发生碰撞时, 消息会广播到两个物体上的所有组件中: - -**`"collision_response"`** - -碰撞对象会收到此消息. 其包含以下数据内容: - -`other_id` -: 另一个碰撞物的id (`hash`过的) - -`other_position` -: 另一个碰撞物的世界坐标 (`vector3`类型) - -`other_group` -: 另一个碰撞物所在的碰撞组 (`hash`过的) - -如果不需要很详细的信息, 碰撞响应消息就足够了, 比如检测子弹是否碰撞了敌人. 每帧每对碰撞物只有一个能收到此消息. - -**`"contact_point_response"`** - -这个消息由 dynamic 或 kinematic 碰撞对物体其中之一接收. 附带如下数据: - -`position` -: 接触点世界坐标 (`vector3`类型). - -`normal` -: 接触点世界坐标系法向量, 方向是从另一物体指向当前物体 (`vector3`类型). - -`relative_velocity` -: 两个接触物体之间的相对速度, 方向是从另一物体指向当前物体 (`vector3`类型). - -`distance` -: 两个接触物体之间穿透距离 -- 非负数 (`number`类型). - -`applied_impulse` -: 两个接触物体间的冲量大小 (`number`类型). - -`life_time` -: (*目前未使用*) 接触时长 (`number`类型). - -`mass` -: 当前物体质量, 单位千克 (`number`类型). - -`other_mass` -: 另一个物体质量, 单位千克 (`number`类型). - -`other_id` -: 另一个物体的id (`hash`过的). - -`other_position` -: 另一个物体的世界坐标 (`vector3`类型). - -`group` -: 另一个物体所处的碰撞组 (`hash`过的). - -要让相碰撞的物体好好分离, 用 `"contact_point_response"` 消息里的数据就够了. 注意每帧每对碰撞物可能不止收到一个 `"contact_point_response"` 消息, 取决于接触的多少. 详情请见下文. - -## 触发器消息 - -触发器是精简版的碰撞物体. 根投射射线类似, 它们迭代物理世界物品但不与之进行交互. - -触发器碰撞时发出 `"collision_response"` 消息. 而且在碰撞开始和结束时都会发送 `"trigger_response"` 消息. 消息包含如下信息: - -`other_id` -: 另一个物体的id (`hash`过的). - -`enter` -: 如果另一个物体进入触发器为 `true`, 离开为 `false`. (`boolean`类型). - -## 處理动画碰撞 - -对于动画碰撞对象的碰撞必须手动处理. 一个想当然的处理方法如下: - -```lua -function on_message(self, message_id, message, sender) - -- 处理碰撞 - if message_id == hash("contact_point_response") then - local newpos = go.get_position() + message.normal * message.distance - go.set_position(newpos) - end -end -``` - -动画碰撞对象的确离开了碰撞穿透, 但是分离之后经常会过冲, 这在许多情况下会产生抖动. 为了便于理解, 想象游戏主角碰到了两个物体, *A* 和 *B*: - -![Physics collision](images/physics/collision_multi.png){srcset="images/physics/collision_multi@2x.png 2x"} - -碰撞发生的那一帧里, 物理引擎发出多个 `"contact_point_response"` 消息, 一个给 *A* 一个给 *B*. 如果按上面那样移动角色, 结果会是这样: - -- 根据 *A* 的穿透距离把角色向上移 (黑色箭头) -- 根据 *B* 的穿透距离把角色向左上移 (黑色箭头) - -顺序无所谓结果是一样的: 最终位移是 *每个穿透向量的矢量和*: - -![Physics separation naive](images/physics/separation_naive.png){srcset="images/physics/separation_naive@2x.png 2x"} - -要想正确地将角色移出 *A* 和 *B*, 需要处理碰撞点的穿透距离并检测上一个位移是否, 完全或部分, 分离了它们. - -假设第一次碰撞从 *A* 开始, 然后针对 *A* 做位移: - -![Physics separation step 1](images/physics/separation_step1.png){srcset="images/physics/separation_step1@2x.png 2x"} - -这样一来角色也部分离开了 *B*. 最后只剩下 *B* 黑色箭头那点穿透. 这段位移应该是 *A* 向量映射到 *B* 剩余的补偿: - -![Projection](images/physics/projection.png){srcset="images/physics/projection@2x.png 2x"} - -$$l = vmath.project(A, B) \times vmath.length(B)$$ - -补偿向量等于 *B* 向量减去 *l* 向量. 所以计算位移的时候, 对于每个碰撞点, 可以引入矫正向量按以下步骤进行矫正: - -1. 把当前矫正向量映射到碰撞穿透向量上. -2. 计算穿透向量的补偿 (按照上述公式). -3. 依照补偿向量移动对象. -4. 把补偿向量累加到矫正向量中. - -完整的代码实现如下: - -```lua -function init(self) - -- 校正向量 - self.correction = vmath.vector3() -end - -function update(self, dt) - -- 重置矫正向量 - self.correction = vmath.vector3() -end - -function on_message(self, message_id, message, sender) - -- 处理碰撞 - if message_id == hash("contact_point_response") then - -- 获取位移计算所需数据. - -- 当前帧可能有多个碰撞点需要处理, - -- 通过累积矫正向量, - -- 达到正确计算位移的目的: - if message.distance > 0 then - -- 第一步, 把矫正向量投射到 - -- 穿透向量上. - local proj = vmath.project(self.correction, message.normal * message.distance) - if proj < 1 then - -- 没有过冲的才需要补偿. - local comp = (message.distance - message.distance * proj) * message.normal - -- 应用补偿向量. - go.set_position(go.get_position() + comp) - -- 积累矫正向量. - self.correction = self.correction + comp - end - end - end -end -``` - -## 投射 - -射线用于收集延一条投射射线所遇到的物理世界的物体. 只要提供起止点和碰撞组, 就可以投射射线了. - -射线碰到的物体数据都会被记录下来. 包括动态, 静态和动画碰撞对象. 不包括触发器对象. - -```lua -function update(self, dt) - -- 投射射线 - local my_start = vmath.vector3(0, 0, 0) - local my_end = vmath.vector3(100, 1000, 1000) - local my_groups = { hash("my_group1"), hash("my_group2") } - - local result = physics.raycast(my_start, my_end, my_groups) - if result then - -- 处理射线碰撞结果 (所有数据参见 'ray_cast_response' 消息) - print(result.id) - end -end -``` - -::: 注意 -结果不包括射线起始点位置的碰撞物体. 这是 Box2D 做的限制. -::: - -## 關節約束 - -Defold 支持物理关节. 一个关键基于某种限制连接两个物体. 支持的关节类型如下: - -* Fixed (physics.JOINT_TYPE_FIXED) - 限制两物体最大距离的固定关节. 在 Box2D 被称为绳子关节. -* Hinge (physics.JOINT_TYPE_HINGE) - 把两个物体通过一个锚点钉在一起的钉子关节. 两物体相对位置固定而相对旋转没有限制. 这种关节可以开启马达给一个最大扭力与速度. 在 Box2D 被称为旋转关节. -* Spring (physics.JOINT_TYPE_SPRING) - 限制两个物体之间距离范围的弹簧关节. 弹簧关节通过设定其频率和阻尼比可以让物体像是被软弹簧连接. 在 Box2D 被称为距离关节. -* Slider (physics.JOINT_TYPE_SLIDER) - 限制两物体只能在某个指定轴上相对移动而不允许相对转动的滑动关节. 在 Box2D 被称为活塞关节. - -### 建立关节 - -目前只能使用 [`physics.create_joint()`](/ref/physics/#physics.create_joint:joint_type-collisionobject_a-joint_id-position_a-collisionobject_b-position_b-[properties]) 函数手动建立关节: - -::: 注意 -编辑器可是环境新建关节在支持计划中但发布时间未知. -::: - -```lua --- 将两个碰撞物体用固定关节连接 (绳子) -physics.create_joint(physics.JOINT_TYPE_FIXED, "obj_a#collisionobject", "my_test_joint", vmath.vector3(10, 0, 0), "obj_b#collisionobject", vmath.vector3(0, 20, 0), { max_length = 20 }) -``` - -上述代码创建了一个固定关节, 其id为 `my_test_joint`, 连接了两个物体 `obj_a#collisionobject` 与 `obj_b#collisionobject`. 关节位于 `obj_a#collisionobject` 偏左10像素, `obj_b#collisionobject` 偏上20像素的位置上. 设定的最大距离是20像素. - -### 删除关节 - -可以使用 [`physics.destroy_joint()`](/ref/physics/#physics.destroy_joint:collisionobject-joint_id) 函数删除关节: - -```lua --- 删除上面提到的第一个物体上的关节 -physics.destroy_joint("obj_a#collisionobject", "my_test_joint") -``` - -### 关节属性及修改 - -可以使用 [`physics.get_joint_properties()`](/ref/physics/#physics.get_joint_properties:collisionobject-joint_id) 读取关节属性, 使用 [`physics.set_joint_properties()`](/ref/physics/#physics.set_joint_properties:collisionobject-joint_id-properties) 修改关节属性: - -```lua -function update(self, dt) - if self.accelerating then - local hinge_props = physics.get_joint_properties("obj_a#collisionobject", "my_hinge") - -- 马达速度提升每秒100转 - hinge_props.motor_speed = hinge_props.motor_speed + 100 * 2 * math.pi * dt - physics.set_joint_properties("obj_a#collisionobject", "my_hinge", hinge_props) - end -end -``` - -### 关节反作用力和扭矩 - -可以使用 [`physics.get_joint_reaction_force()`](/ref/physics/#physics.get_joint_reaction_force:collisionobject-joint_id) 读取关节反作用力, 使用 [`physics.get_joint_reaction_torque()`](/ref/physics/#physics.get_joint_reaction_torque:collisionobject-joint_id) 读取关节扭力. - ## 注意事项 @@ -421,3 +33,7 @@ end 碰撞漏检 : 如果发现碰撞未检测或未处理请先阅读 [调试教程的物理调试部分](/manuals/debugging-game-logic/#物理引擎调试). + + + + diff --git a/docs/zh/shared/html5-faq.md b/docs/zh/shared/html5-faq.md index 90ca92f9..25636c46 100644 --- a/docs/zh/shared/html5-faq.md +++ b/docs/zh/shared/html5-faq.md @@ -5,3 +5,8 @@ A: 很多浏览器不允许从本地磁盘文件来启动程序. 从编辑器里 ```sh $ python -m SimpleHTTPServer [port] ``` + + +#### Q: 游戏加载时报 "Unexpected data size" 错误然后崩溃? + +A: 这种情况可能发生在使用 Windows 编译并且提交到 Git 上的时候. 如果 Git 配置文件里含有不正确的行尾符上传的时候就会被自动改正造成数据大小变化. 解决方案详见: https://docs.github.com/en/free-pro-team@latest/github/using-git/configuring-git-to-handle-line-endings From 1ea7aa9be7d526cc0f50886b3ee58bb685662d8e Mon Sep 17 00:00:00 2001 From: COCO Date: Tue, 5 Jan 2021 10:53:46 +0800 Subject: [PATCH 002/134] update input --- docs/zh/manuals/editor.md | 4 ++-- docs/zh/manuals/input.md | 32 ++++++++++++++++++++------------ 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/docs/zh/manuals/editor.md b/docs/zh/manuals/editor.md index 74ded820..27527952 100644 --- a/docs/zh/manuals/editor.md +++ b/docs/zh/manuals/editor.md @@ -61,7 +61,7 @@ Defold 编辑器被划分为许多面板, 或称视图, 以展示和编辑数据 : 这个视图分为几个组. *Console* 组显示游戏输出和报错信息. 旁边是显示 *编译错误*, *查找结果* 和编辑粒子曲线数据时用到的 *曲线编辑器*. 同时工具面板也负责与调试器进行交互. *Changed Files* 面板 -: 如果项目使用 Git 做版本控制, 这个视图会列出项目中被修改, 添加或者删除的文件. 同步机制会把你的本地项目文件与 Git 托管项目进行同步, 这种机制方便团队合作开发, 而且云端备份可以保证项目不易损坏丢失. 相关操作: +: 如果你的项目使用 Git 做版本控制, 这个视图会列出项目中被修改, 添加或者删除的文件. 同步机制会把你的本地项目文件与 Git 托管项目进行同步, 这种机制方便团队合作开发, 而且云端备份可以保证项目不易损坏丢失. 关于 Git 详见 [版本控制教程](/manuals/version-control/). 相关操作: - 双击 文件显示版本区别窗口. 同样, 编辑器会根据文件类型选择合适的显示窗口. - 右键点击 文件弹出的上下文菜单中, 可以进行显示版本区别窗口, 回退文件的更改, 打开文件系统浏览器显示文件位置等操作. @@ -257,4 +257,4 @@ $ > ./path/to/Defold.app/Contents/MacOS/Defold ## 常見問題 -:[Editor FAQ](../shared/editor-faq.md) \ No newline at end of file +:[Editor FAQ](../shared/editor-faq.md) diff --git a/docs/zh/manuals/input.md b/docs/zh/manuals/input.md index 0afe9fb8..a986139f 100644 --- a/docs/zh/manuals/input.md +++ b/docs/zh/manuals/input.md @@ -151,16 +151,8 @@ msg.post(".", "acquire_input_focus") ![Input stack](images/input/input_stack.png){srcset="images/input/input_stack@2x.png 2x"} -由集合代理加载的每个游戏世界都有自己的输入栈. 被加载的游戏世界获得输入, 前提是主游戏世界输入栈里包含了这个游戏世界的集合代理. +如果已获得输入焦点的游戏对象再次请求输入焦点, 那么其组件会被移至输入栈顶端. -已获得输入焦点的游戏对象再次请求焦点的话, 它上面的所有组件都会被推到输入栈顶. - -要取消动作监听, 发送 `release_input_focus` 消息给游戏对象即可. 这样该游戏对象的所有组件都会从输入栈中移除: - -```lua --- 告诉当前游戏对象 (".") 释放输入焦点. -msg.post(".", "release_input_focus") -``` ## 输入调度和 on_input() 函数 @@ -195,13 +187,29 @@ function on_input(self, action_id, action) end ``` -集合代理必须位于主世界输入栈中才能把输入传递到其代理的游戏世界中去. 代理入栈的组件优先与主世界组件获得输入事件触发动作: + +### 输入焦点与集合代理组件 + +由集合代理动态载入的游戏世界都有自己的输入栈. 为了让被载入的游戏世界获得输入信息, 集合代理组件必须位于主游戏世界的输入栈里. 被加载的游戏世界优先于主游戏世界获得输入信息: ![Action dispatch to proxies](images/input/proxy.png){srcset="images/input/proxy@2x.png 2x"} -使用集合代理组件时经常会忘记让其游戏对象 `acquire_input_focus`. 没有这一步其加载的游戏世界将得不到任何输入信息. +::: 注意 +开发者经常会忘记发送 `acquire_input_focus` 来使集合代理所在的游戏对象获得输入焦点. 不这么做的话此集合代理加载的所有游戏世界都无法获得输入消息. +::: + + +### 释放输入焦点 + +要取消动作监听, 发送 `release_input_focus` 消息给游戏对象即可. 这样该游戏对象的所有组件都会从输入栈中移除: + +```lua +-- 告诉当前游戏对象 (".") 释放输入焦点. +msg.post(".", "release_input_focus") +``` + -## Consuming input +## 输入传播 每个 `on_input()` 函数都能决定当前动作是否要阻止其继续传播下去: From a8076bf8adc96be600b8c0c1042752bca923e06b Mon Sep 17 00:00:00 2001 From: COCO Date: Tue, 12 Jan 2021 20:08:45 +0800 Subject: [PATCH 003/134] update --- docs/zh/manuals/libraries.md | 18 +++++++++++++++++- docs/zh/shared/linux-faq.md | 10 ++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/docs/zh/manuals/libraries.md b/docs/zh/manuals/libraries.md index 145d9f28..af3db793 100644 --- a/docs/zh/manuals/libraries.md +++ b/docs/zh/manuals/libraries.md @@ -31,10 +31,26 @@ brief: 项目间可以使用库共享资源. 本教程解释了其工作方式. 最好使用库项目的发布地址而不是主分支来引用库. 作为开发者你要决定什么时候该合并更新而不是时刻保持主分支最新代码 (使用主分支最新版可能引入潜在的不稳定性). ::: + +### 基本訪問驗證 + +對於不公開的庫可以通過在 URL 上加入用戶名密碼 / 訪問權標記的方法來訪問: + +``` +https://username:password@github.com/defold/private/archive/main.zip +``` + +這裏 `username` 和 `password` 項會被提取並轉化爲 `Authorization` 請求頭. 這種方法一般服務器都適用. 包括從 GitHub 上獲取私有庫. GitHub 還支持使用 [生成訪問權標記](https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/creating-a-personal-access-token) 的方法來代替密碼. + +``` +https://github-username:personal-access-token@github.com/defold/private/archive/main.zip +``` + ::: 注意 -你要有库 URL 的访问权限. 对于 GitHub 托管项目来说, 这意味着要么项目是公开的要么你已经获取了权限. 对于 Defold 托管项目来说, 这意味着你必须是项目开发组成员. +不要共享或者不小心泄露你的密碼或訪問權標記, 否則可能會落入他人之手造成不良後果. ::: + ## 设置库依赖 打开需要引入库的项目. 在项目设置里, 把 URL 加入到 *dependencies* 属性下. 如果需要可以加入多个. 使用 `+` 按钮一个一个加入, 使用 `-` 按钮移除: diff --git a/docs/zh/shared/linux-faq.md b/docs/zh/shared/linux-faq.md index eb3a4e91..bc1e4515 100644 --- a/docs/zh/shared/linux-faq.md +++ b/docs/zh/shared/linux-faq.md @@ -40,6 +40,16 @@ $ ./Defold ``` +#### Q: 在 Ubuntu 20.04 上運行 Defold 報錯 "com.jogamp.opengl.GLException: Graphics configuration failed" ? + +A: 這個版本在運行 Defold 時會出現新驅動程序 (Iris) 問題. 可以嘗試使用舊版本驅動程序: + +```bash +$ export MESA_LOADER_DRIVER_OVERRIDE=i965 +$ ./Defold +``` + + #### Q: 在 Linux 上启动 Defold 游戏无效? A: 看看 Defold 编辑器控制台. 如果有下面这样的输出: From e0a4d20c13f850d12bb887deac40d38353ac5d70 Mon Sep 17 00:00:00 2001 From: COCO Date: Sat, 16 Jan 2021 13:09:37 +0800 Subject: [PATCH 004/134] update code sharing in getting-help.md --- docs/zh/manuals/getting-help.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/zh/manuals/getting-help.md b/docs/zh/manuals/getting-help.md index 2aa1b177..ec26648a 100644 --- a/docs/zh/manuals/getting-help.md +++ b/docs/zh/manuals/getting-help.md @@ -50,6 +50,22 @@ brief: 本教程介绍了使用 Defold 遇到麻烦时该如何寻求帮助. * **其他 (可选)** - 还可以加入其他问题相关上下文信息. +### 提交代码 +提交代码最好用文本, 别用截图. 文本代码便于查找, 分析错误并提出修改意见. 代码使用 \`\`\` 符号包裹或者行首加4个空格. + +举例: + +\`\`\` +print("Hello code!") +\`\`\` + +效果: + +``` +print("Hello code!") +``` + + ## 从编辑器里汇报问题 编辑器提供了一个汇报错误的方便的方法. 选择 Help->Report Issue 菜单项来汇报错误. From e74d03e98533b1a79ef71876ed35d2a43f088260 Mon Sep 17 00:00:00 2001 From: COCO Date: Tue, 19 Jan 2021 19:47:21 +0800 Subject: [PATCH 005/134] Export Compliance --- docs/zh/manuals/ios.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/zh/manuals/ios.md b/docs/zh/manuals/ios.md index 8c0f1ff6..7d27178a 100644 --- a/docs/zh/manuals/ios.md +++ b/docs/zh/manuals/ios.md @@ -219,5 +219,22 @@ open /Applications/Xcode.app/Contents/Developer/Applications/Simulator.app ``` +## 出口合规信息 + +将游戏上传到 App Store 时要提供加密部分的出口合规信息. [Apple 在此解释了这个需求的原因](https://developer.apple.com/documentation/security/complying_with_encryption_export_regulations): + +"把应用往 TestFlight 或者 App Store 上传的时候, 你是把应用上传到了美国的服务器上. 一旦要把应用分发到美国或者加拿大之外的国家, 无论你的法人实体在哪里, 都必须遵守美国出口法案. 如果你的应用使用, 访问, 包含, 实现, 或者汇入了加密内容, 就会被视作加密软件出口, 这意味着你的应用必须符合美国出口法案的要求, 同时也要符合你的出口目的国家的法律需求." + +相关文档: + +* 出口合规概要 - https://help.apple.com/app-store-connect/#/dev88f5c7bf9 +* 查看游戏是否符合出口规范 - https://help.apple.com/app-store-connect/#/dev63c95e436 + +Defold 引擎会对以下内容实施加密: + +* 加密信道调用 (如 HTTPS 和 SSL) +* Lua 代码版权保护 + + ## 常見問題 :[iOS FAQ](../shared/ios-faq.md) From e357675ee1f4733c8549c07d516ee81722c0336f Mon Sep 17 00:00:00 2001 From: COCO Date: Tue, 26 Jan 2021 20:52:48 +0800 Subject: [PATCH 006/134] update on file i/o --- docs/zh/manuals/file-access.md | 22 ++++++++++++++++------ docs/zh/manuals/project-settings.md | 7 +++++-- docs/zh/shared/ios-faq.md | 10 ++++++++++ 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/docs/zh/manuals/file-access.md b/docs/zh/manuals/file-access.md index 6751fe5b..b8ef75cb 100644 --- a/docs/zh/manuals/file-access.md +++ b/docs/zh/manuals/file-access.md @@ -26,18 +26,28 @@ Defold 提供如下函数用以存取文件/文件夹: [Check the example showing how to use sys.save() and sys.load()](/examples/file/sys_save_load/). ### 游戏应用打包进去的文件处理 -游戏打包有两种方法: +把文件打包进游戏应用有两种方法: -1. 在 *game.project* 配置文件中的 [*Custom Resources* 项](https://defold.com/manuals/project-settings/#Project) 设置自定义资源. 然后就可以使用 [`sys.load_resource()`](https://defold.com/ref/sys/#sys.load_resource) 函数进行加载. 其实这不是在加载磁盘上的文件. 打包进游戏的资源文件作为游戏的一部分保存为二进制数据, 只能使用 `sys.load_resource()` 载入. +1. **用户资源文件** - 在 *game.project* 配置文件的 [*Custom Resources* 项](https://defold.com/manuals/project-settings/#project) 进行设置. 然后可以使用 [`sys.load_resource()`](https://defold.com/ref/sys/#sys.load_resource) 函数进行访问. 注意这些文件实际上并不存在于用户的操作系统之中. 这样打包的文件作为游戏包的一部分只可以使用 `sys.load_resource()` 进行访问. +2. **打包资源文件** - 在 *game.project* 配置文件的 [*Bundle Resources* 项](https://defold.com/manuals/project-settings/#project) 进行设置. 然后可以使用 [`sys.get_application_path()`](https://defold.com/ref/stable/sys/#sys.get_application_path:) 得到应用的实际路径. 再基于应用路径得到资源文件的完整路径. 之后就可以使用 `io.*` 和 `os.*` 的功能函数进行访问 (参见上文). + + ::: 注意 + 基于安全考虑浏览器 (及浏览器里运行的 JavaScript 插件) 不允许访问本地文件. 虽然 HTML5 游戏也能运行, 但是只能用浏览器提供的 IndexedDB API 在 "虚拟文件系统" 中存取数据. 也就是说不允许使用 `io.*` 和 `os.*` 下的函数. 但是可以用 `http.request()` 请求在线资源文件. + ::: + +#### 用户资源与打包资源对比 + +| 特点 | 用户资源 | 打包资源 | +|-----------------------------|-------------------------------------------|------------------------------------------------| +| 加载速度 | 快 - 从应用二进制包内加载 | 慢 - 从文件系统中加载 | +| 加载单个文件的功能 | 无 - 只能加载全部资源 | 有 - 基于文件的字节读取 | +| 应用打包后修改资源文件 | 无 - 所有资源保存为一个二进制资源包 | 有 - 文件存储基于文件操作系统 | +| HTML5 支持 | 有 | 有 - 但是这里的访问基于 http 而不是文件 I/O | -2. 在 *game.project* 配置文件中的 [*Bundle Resources* 项](https://defold.com/manuals/project-settings/#Project) 设置额外打包文件. 然后就可以使用 [`sys.get_application_path()`](https://defold.com/ref/stable/sys/#sys.get_application_path:) 取得游戏所在位置. 进而取得文件的绝对路径. 然后用 `sys.*`, `io.*` 和 `os.*` 函数处理文件/文件夹 (见上文). ### 操作系统文件处理 基于安全考虑操作系统所管理的文件存取被严格限制. 可以使用 [`extension-directiories`](https://defold.com/assets/extensiondirectories/) 原生扩展来存取某些地方的绝对路径 (例如 documents, resource, temp). 然后用 `sys.*`, `io.*` 和 `os.*` 函数处理文件/文件夹 (见上文). -::: 注意 -基于安全考虑浏览器 (及浏览器里运行的 JavaScript 插件) 不允许访问本地文件. 虽然 HTML5 游戏也能运行, 但是只能用浏览器提供的 IndexedDB API 在 "虚拟文件系统" 中存取数据. 也就是说不允许使用 `io.*` 和 `os.*` 下的函数. 但是可以用 `http.request()` 请求在线资源文件. -::: ## 相关原生扩展 在 [资源中心](https://defold.com/assets/) 里有些原生扩展能简化文件存取的工作. 例如: diff --git a/docs/zh/manuals/project-settings.md b/docs/zh/manuals/project-settings.md index c811b135..e37b2682 100644 --- a/docs/zh/manuals/project-settings.md +++ b/docs/zh/manuals/project-settings.md @@ -321,8 +321,11 @@ Storyboard 文件 (.storyboard). 其创建方法详情请见 [iOS 教程](/manua #### Info.plist 如果设置了, 则打包应用时使用此 info.plist 文件. -#### Entitlements -如果设置了, 则覆盖引用档文件 (.entitlements, .xcent, .plist) 中定义的通用权限. +#### Custom Entitlements +如果设置了, 则打包应用会把这里的配置与档案文件 (.entitlements, .xcent, .plist) 里面设置的权限相混合. + +#### Override Entitlements +如果设置了, 则会覆盖档案文件 (.entitlements, .xcent, .plist) 里面设置的权限. 必须与上面的 Custom Entitlements 配置项一起使用. #### Default Language 如果用户没有指定 `Localizations` 列表里的语言, 则使用此处设置的语言 (见 [CFBundleDevelopmentRegion](https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/20001431-130430)). diff --git a/docs/zh/shared/ios-faq.md b/docs/zh/shared/ios-faq.md index f9257362..d1a179cd 100644 --- a/docs/zh/shared/ios-faq.md +++ b/docs/zh/shared/ios-faq.md @@ -1,2 +1,12 @@ #### Q: 使用免費 Apple Developer 賬戶無法安裝 Defold 游戲. A: 請確保游戲包 id 與 Defold 導出的 Xcode 項目檔案裏設置的 id 是一致的. + +#### Q: 如何查看应用包的权限? +A: 参见 [应用的权限检查](https://developer.apple.com/library/archive/technotes/tn2415/_index.html#//apple_ref/doc/uid/DTS40016427-CH1-APPENTITLEMENTS): + +> $ codesign -d --ent :- /path/to/the.app + +#### Q: 如何查看配置档案的权限? +A: 参见 [档案设置的权限检查](https://developer.apple.com/library/archive/technotes/tn2415/_index.html#//apple_ref/doc/uid/DTS40016427-CH1-PROFILESENTITLEMENTS): + +> $ security cms -D -i /path/to/iOSTeamProfile.mobileprovision From 0fcdc163c61277ee035510cf596c49bcbedc53b7 Mon Sep 17 00:00:00 2001 From: COCO Date: Wed, 3 Feb 2021 12:46:39 +0800 Subject: [PATCH 007/134] pi / 4 --- docs/zh/manuals/camera.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh/manuals/camera.md b/docs/zh/manuals/camera.md index ee8d1dd4..47e27260 100644 --- a/docs/zh/manuals/camera.md +++ b/docs/zh/manuals/camera.md @@ -24,7 +24,7 @@ Aspect Ratio : (**透视摄像机可用**) - 视锥宽高比. 1.0 代表正方形视口. 4:3 显示器 1024x768 这样的分辨率用 1.33. 16:9 的显示器用 1.78. 如果设置了 *Auto Aspect Ratio* 则此属性无效. Fov -: (**透视摄像机可用**) - 以 _弧度_ 表示的摄像机 *垂直* 视域. 视域越宽, 摄像机看到的内容越多. 注意目前默认值 (45) 有点误导. 要 45 度的视域, 要设置值为 0.785 ($\pi / 4$). +: (**透视摄像机可用**) - 以 _弧度_ 表示的摄像机 *垂直* 视域. 视域越宽, 摄像机看到的内容越多. 注意目前默认值 (45) 有点误导. 要 45 度的视域, 要设置值为 0.785 (`π / 4`). Near Z : (**透视摄像机可用**) - 近端裁剪平面z值. From 9f4dfe2ccfe0b450c3959fb3801bf1afe0367a83 Mon Sep 17 00:00:00 2001 From: COCO Date: Sun, 7 Feb 2021 20:37:20 +0800 Subject: [PATCH 008/134] inputs --- docs/zh/manuals/input-gamepads.md | 111 +++++++++++++++++++ docs/zh/manuals/input-key-and-text.md | 51 +++++++++ docs/zh/manuals/input-mouse-and-touch.md | 121 +++++++++++++++++++++ docs/zh/manuals/input.md | 132 +++-------------------- 4 files changed, 299 insertions(+), 116 deletions(-) create mode 100644 docs/zh/manuals/input-gamepads.md create mode 100644 docs/zh/manuals/input-key-and-text.md create mode 100644 docs/zh/manuals/input-mouse-and-touch.md diff --git a/docs/zh/manuals/input-gamepads.md b/docs/zh/manuals/input-gamepads.md new file mode 100644 index 00000000..2af40140 --- /dev/null +++ b/docs/zh/manuals/input-gamepads.md @@ -0,0 +1,111 @@ +--- +title: Defold 游戏手柄输入教程 +brief: 本教程介绍了游戏手柄输入的功能. +--- + +::: 注意 +建议首先熟练掌握 Defold 中常规输入的消息处理方式, 例如输入消息获取以及脚本间输入消息广播顺序等. 关于输入系统详情请见 [输入系统教程](/manuals/input). +::: + +# Gamepads +游戏手柄触发器可以绑定标准手柄输入到游戏功能的映射. 游戏手柄可以绑定: + +- 左右摇杆 (方向和按下) +- 手柄按钮. 通常右手柄 Xbox 为 "A", "B", "X" 和 "Y", Playstation 为 "方块", "圆圈", "三角" 和 "十叉". +- 方向按钮. +- 左右肩按钮. +- 开始, 后退, 暂停按钮 + +![](images/input/gamepad_bindings.png) + +::: 注意 +下面的例子中使用了上图的映射绑定配置. 映射与命名可以根据项目需要自由设置. +::: + +## 十字键 +十字键可以生成按下, 抬起和连按消息. 获取十字键消息的方法如下 (按下和抬起): + +```lua +function on_input(self, action_id, action) + if action_id == hash("gamepad_lpad_left") then + if action.pressed then + -- 向左移动 + elseif action.released then + -- 停止移动 + end + end +end +``` + +## 摇杆 +摇杆拨动到阈值以外就可以持续生成输入消息 (阈值配置见下文). 获取摇杆消息的方法如下: + +```lua +function on_input(self, action_id, action) + if action_id == hash("gamepad_lstick_down") then + -- 左摇杆向下拨动 + print(action.value) -- 取值范围 0.0 到 -1.0 + end +end +``` + +摇杆处于某方向极值的时候还会生成按下和抬起消息. 这样类似十字键的消息很适合用作方向导航: + +```lua +function on_input(self, action_id, action) + if action_id == hash("gamepad_lstick_down") and action.pressed then + -- 左摇杆向下拨动到头 + end +end +``` + +## 多手柄 +Defold 基于其宿主操作系统支持多个手柄, 事件里 `gamepad` 项对应手柄输入来源: + +```lua +function on_input(self, action_id, action) + if action_id == hash("gamepad_start") then + if action.gamepad == 0 then + -- 手柄0号玩家申请加入游戏 + end + end +end +``` + +## Connect and Disconnect +游戏手柄还有 `Connected` 和 `Disconnected` 两种事件用以通知手柄连接和断开. + +```lua +function on_input(self, action_id, action) + if action_id == hash("gamepad_connected") then + if action.gamepad == 0 then + -- 手柄0号已连接 + end + elseif action_id == hash("gamepad_dicconnected") then + if action.gamepad == 0 then + -- 手柄0号已断开 + end + end +end +``` + +## 手柄配置文件 +在 Windows 上, 只支持 XBox 360 兼容手柄. 安装方法请见 http://www.wikihow.com/Use-Your-Xbox-360-Controller-for-Windows + +每种手柄分别对应一份映射文件, 可以在 *gamepads* 配置文件中设置. Defold 自带一个通用的手柄映射配置文件: + +![Gamepad settings](images/input/gamepads.png){srcset="images/input/gamepads@2x.png 2x"} + +如需自定义文件, 可以配合使用这个工具: + +[Click to download gdc.zip](https://forum.defold.com/t/big-thread-of-gamepad-testing/56032). + +这个工具包含 Windows, Linux 和 macOS 的可运行文件. 命令行启动方法: + +```sh +./gdc +``` + +这个工具通过收集连接控制器的输入自动生成映射文件. 新的映射文件可以在 "game.project" 里进行指定或者混合使用: + +![Gamepad settings](images/input/gamepad_setting.png){srcset="images/input/gamepad_setting@2x.png 2x"} diff --git a/docs/zh/manuals/input-key-and-text.md b/docs/zh/manuals/input-key-and-text.md new file mode 100644 index 00000000..00814f77 --- /dev/null +++ b/docs/zh/manuals/input-key-and-text.md @@ -0,0 +1,51 @@ +--- +title: Defold 键盘按键和文本输入教程 +brief: 本教程介绍了键盘按键和文本输入的功能. +--- + +::: 注意 +建议首先熟练掌握 Defold 中常规输入的消息处理方式, 例如输入消息获取以及脚本间输入消息广播顺序等. 关于输入系统详情请见 [输入系统教程](/manuals/input). +::: + +# Key Triggers +键盘输入触发器用以把键盘按键输入映射为游戏需要的动作. 每个按键分别与动作一一对应, 比如箭头键和WASD键映射为角色移动. 如果需要文字输入, 要使用 text triggers (见下文). + +![](images/input/key_bindings.png) + +```lua +function on_input(self, action_id, action) + if action_id == hash("left") then + if action.pressed then + -- start moving left + elseif action.released then + -- stop moving left + end + end +end +``` + +# Text Triggers +文本触发器用来读取输入的文字. 分为两种: text 和 marked text. + +![](images/input/text_bindings.png) + +## Text +`text` 捕获一般字符输入. 事件 `text` 项保存了输入的字符. 动作由按下按钮时触发, 不存在 `release` 和 `repeated` 事件. + + ```lua + if action_id == hash("text") then + -- 收集输入字符填充 "user" 节点... + local node = gui.get_node("user") + local name = gui.get_text(node) + name = name .. action.text + gui.set_text(node, name) + end + ``` + +## Marked text +`marked-text` 一般用于亚洲键盘可把多个按键事件合为一个输入事件. 比如说, iOS 里的 "Japanese-Kana" 键盘, 用户输入多个键时键盘上方就会显示出可供输入的文字或字符串. + +![Input marked text](images/input/marked_text.png){srcset="images/input/marked_text@2x.png 2x"} + +- 每个键被按下时触发事件, 动作 `text` 为目前已经输入了的字符串 (星号标记文本). +- 用户选择了要提交的文字时, 一个 `text` 类型动作被触发 (证明当前触发器配置正确). 而这个动作的 `text` 项保存了用户最终提交的文字. diff --git a/docs/zh/manuals/input-mouse-and-touch.md b/docs/zh/manuals/input-mouse-and-touch.md new file mode 100644 index 00000000..c501ada1 --- /dev/null +++ b/docs/zh/manuals/input-mouse-and-touch.md @@ -0,0 +1,121 @@ +--- +title: Defold 鼠标和触摸输入教程 +brief: 本教程介绍了鼠标和触摸输入的功能. +--- + +::: 注意 +建议首先熟练掌握 Defold 中常规输入的消息处理方式, 例如输入消息获取以及脚本间输入消息广播顺序等. 关于输入系统详情请见 [输入系统教程](/manuals/input). +::: + +# Mouse Triggers +鼠标触发器可以绑定鼠标按键和滚轮输入到游戏功能的映射. + +![](images/input/mouse_bindings.png) + +::: 注意 +鼠标按键输入 `MOUSE_BUTTON_LEFT`, `MOUSE_BUTTON_RIGHT` 和 `MOUSE_BUTTON_MIDDLE` 等同于 `MOUSE_BUTTON_1`, `MOUSE_BUTTON_2` 和 `MOUSE_BUTTON_3`. +::: + +::: 注意 +下面的例子中使用了上图的映射绑定配置. 映射与命名可以根据项目需要自由设置. +::: + +## 鼠标键 +鼠标键可以生成按下, 抬起和连按消息. 获取鼠标键消息的方法如下 (按下和抬起): + +```lua +function on_input(self, action_id, action) + if action_id == hash("mouse_button_left") then + if action.pressed then + -- 鼠标左键按下 + elseif action.released then + -- 鼠标左键抬起 + end + end +end +``` + +::: 注意 +单点触摸也会触发 `MOUSE_BUTTON_LEFT` (或 `MOUSE_BUTTON_1`) 事件. +::: + +## 鼠标滚轮 +鼠标滚轮可以生成滚动消息. 如果 `action.value` 为 `1` 代表转动, 为 `0` 代表不转动. (滚轮转动被当作一种按钮消息来处理. Defold 目前不支持触摸板上的滚轮输入.) + +```lua +function on_input(self, action_id, action) + if action_id == hash("mouse_wheel_up") then + if action.value == 1 then + -- 鼠标滚轮向上滚动 + end + end +end +``` + +## 鼠标移动 +鼠标移动消息有点特别. 如果输入绑定表里没有鼠标的话, 鼠标移动事件也会被丢弃. + +但是不用特地为了鼠标移动配置绑定, 因为鼠标移动时会自动生成事件, 其中 `action_id` 为 `nil` 并且 `action` 表保存了鼠标位置与移动距离. + +```lua +function on_input(self, action_id, action) + if action.x and action.y then + -- 游戏对象跟随鼠标/触摸 + local pos = vmath.vector3(action.x, action.y, 0) + go.set_position(pos) + end +end +``` + +# 触摸触发器 +iOS 和 Android 设备上运行的原生应用与HTML5应用都支持单点和多点触摸输入. + +![](images/input/touch_bindings.png) + +## Single-touch +单点触摸不用在触摸映射部分进行设置. 而在 **鼠标映射设置了 `MOUSE_BUTTON_LEFT` 或称 `MOUSE_BUTTON_1`** 之后自行配置. + +## Multi-touch +多点触摸在输入映射表里叫做 `touch`. 其元素索引为数字 `1`--`N`, 这里 `N` 是触摸点的编号. 其元素值为触摸点数据: + +```lua +function on_input(self, action_id, action) + if action_id == hash("touch_multi") then + -- 在触摸点的位置生成游戏对象 + for i, touchdata in ipairs(action.touch) do + local pos = vmath.vector3(touchdata.x, touchdata.y, 0) + factory.create("#factory", pos) + end + end +end +``` + +::: 注意 +多点触摸动作名不能与 `MOUSE_BUTTON_LEFT` 或 `MOUSE_BUTTON_1` 的动作名重名. 否则的话将导致事件覆盖, 就监听不到单点触摸事件了. +::: + +::: 注意 +公共资源 [Defold 输入手柄](https://defold.com/assets/defoldinput/) 可以用来在多点触摸屏上模拟手柄输入. +::: + + +## 拾取检测 +游戏里经常可见拾取操作. 可能是玩家点击界面按钮或者战略游戏里玩家选取一个作战单位, RPG 游戏点取宝箱等等. 不同组件有不同解决方法. + +### 界面点击检测 +界面有一个 `gui.pick_node(node, x, y)` 函数来判断点击输入是否处在某个节点范围之内. 详见 [API 文档](/ref/gui/#gui.pick_node:node-x-y), [指针悬停示例](https://www.defold.com/examples/pointer_over/) 或者 [按钮示例](https://www.defold.com/examples/button/). + +### 游戏对象点击检测 +游戏对象检测有点复杂, 因为摄像机移动和渲染脚本映射都会影响位置计算. 方法主要分为两种: + + 1. 追踪游戏对象的位置和大小然后检测点选位置是否包含在内. + 2. 给游戏对象加入碰撞组件再在点选位置生成一个碰撞对象检查二者碰撞情况. + +::: 注意 +公共资源 [Defold 输入库](https://github.com/britzl/defold-input) 是一个开箱即用的输入检测库. +::: + +无论哪种方案都必须将鼠标手点选的屏幕坐标转换成游戏对象的世界坐标. 实现思路如下: + + * 手动跟踪渲染脚本使用的视口和投射用以进行坐标转换. 详见 [摄像机教程的这个示例](/manuals/camera/#鼠标位置转换为世界坐标). + * 使用 [第三方摄像机解决方案](/manuals/camera/#第三方摄像机解决方案) 里面的屏幕到世界坐标转换函数. diff --git a/docs/zh/manuals/input.md b/docs/zh/manuals/input.md index a986139f..e5fb0e1e 100644 --- a/docs/zh/manuals/input.md +++ b/docs/zh/manuals/input.md @@ -57,86 +57,31 @@ Consuming input 触发器有五种类型: Key Triggers -: 键盘单键输入. 每个键分别映射为动作. 一个键一个功能, 比如箭头键或者 WASD 键对应上左下右. 如果需要获得输入字符, 要使用 text triggers (见下文). +: 键盘单键输入. 每个键分别映射为指定的动作. 一一对应. 详情请见 [键盘按键输入教程](/manuals/input-key-and-text). -Mouse Triggers -: 鼠标按键或者滚轮输入. 鼠标移动输入事件不在这里设定. 但是如果没设定鼠标触发器, 也不会捕获鼠标移动事件. - - - 鼠标按键输入 `MOUSE_BUTTON_LEFT`, `MOUSE_BUTTON_RIGHT` 和 `MOUSE_BUTTON_MIDDLE` 等同于 `MOUSE_BUTTON_1`, `MOUSE_BUTTON_2` 和 `MOUSE_BUTTON_3`. - - - **单点触摸也会触发 `MOUSE_BUTTON_LEFT` (或 `MOUSE_BUTTON_1`) 事件**. - - - 鼠标滚轮转动输入. 如果 `action.value` 为 `1` 代表转动, 为 `0` 代表不转动. (滚轮转动被当作按钮按下处理. Defold 目前不支持触摸板上的滚轮输入.) - - - 鼠标移动不在此做设定, 但是鼠标移动时会自动发出事件, 其中 `action_id` 为 `nil` 并且 `action` 表保存了鼠标位置与移动距离. - -Gamepad Triggers -: 游戏手柄触发器绑定标准手柄输入到游戏功能的映射. Defold 通过操作系统支持多种游戏手柄, 事件里 `gamepad` 项对应手柄输入来源: - - ```lua - if action_id == hash("gamepad_start") then - if action.gamepad == 0 then - -- gamepad 0 申请加入游戏 - end - end - ``` - - 游戏手柄可以绑定: - - - 左右摇杆 (方向和按下) - - 手柄按钮. 通常右手柄 Xbox 为 "A", "B", "X" 和 "Y", Playstation 为 "方块", "圆圈", "三角" 和 "十叉". - - 方向按钮. - - 左右肩按钮. - - 开始, 后退, 暂停按钮 - - 在 Windows 上, 只支持 XBox 360 兼容手柄. 安装方法请见 http://www.wikihow.com/Use-Your-Xbox-360-Controller-for-Windows +Text Triggers +: 文本触发器用来读取输入的文字. 详情请见 [键盘按键输入教程](/manuals/input-key-and-text). - 每种手柄分别对应一份映射文件. 详情请见下文. - - 游戏手柄还有 `Connected` 和 `Disconnected` 两种事件用以通知手柄连接和断开. +Mouse Triggers +: 来自鼠标按键和滚轮的输入. 详情请见 [鼠标和触摸输入教程](/manuals/input-mouse-and-touch). Touch Triggers -: iOS 和 Android 设备支持单点触摸. 单点触摸不用在触摸映射部分进行设置. 而在 **鼠标映射设置 `MOUSE_BUTTON_LEFT` 或 `MOUSE_BUTTON_1`** 之后自动触发. - -: iOS 和 Android 设备支持 APP 和 HTML5 应用的多点触摸. 触发时 `touch` 表即是记录触摸点的数组. 其中数组键 `1`--`N` 的 `N` 是触摸点的排号. 对应的值为触摸点数据: - - ```lua - -- 捕获到接触事件时触发 - for i, touchdata in ipairs(action.touch) do - local pos = vmath.vector3(touchdata.x, touchdata.y, 0) - factory.create("#factory", pos) - end - ``` - -::: 注意 -多点触摸动作名不能与 `MOUSE_BUTTON_LEFT` 或 `MOUSE_BUTTON_1` 的动作名重名. 否则的话将导致事件覆盖, 就监听不到单点触摸事件了. -::: +: iOS 和 Android 设备上运行的原生应用与HTML5应用都支持单点和多点触摸输入. 详情请见 [鼠标和触摸输入教程](/manuals/input-mouse-and-touch). -::: 注意 -公共资源 [Defold 输入手柄](https://defold.com/assets/defoldinput/) 可以用来在多点触摸屏上模拟手柄输入. -::: +Gamepad Triggers +: 这种触发器可以绑定标准手柄输入到游戏功能的映射. 详情请见 [游戏手柄输入教程](/manuals/input-gamepads). -Text Triggers -: 文本触发器用来读取输入的文字. 分为以下两种: +### 加速度计输入 - - `text` 捕获一般字符输入. 事件 `text` 项保存了输入的字符. 动作由按下按钮时触发, 不存在 `release` 和 `repeated` 事件. +除了上述五种输入触发器, Defold 还支持 Android 和 iOS 原生系统加速度计输入. 需要勾选 *game.project* 配置文件中输入部分里的 Use Accelerometer. - ```lua - if action_id == hash("text") then - -- 收集输入字符填充 "user" 节点... - local node = gui.get_node("user") - local name = gui.get_text(node) - name = name .. action.text - gui.set_text(node, name) +```lua +function on_input(self, action_id, action) + if action.acc_x and action.acc_y and action.acc_z then + -- 读取加速度计数据 end - ``` - - - `marked-text` 一般用于亚洲键盘可把多个按键事件合为一个输入事件. 比如说, iOS 里的 "Japanese-Kana" 键盘, 用户输入多个键时键盘上方就会显示出可供输入的文字或字符串. - - ![Input marked text](images/input/marked_text.png){srcset="images/input/marked_text@2x.png 2x"} - - - 每个键被按下时触发事件, 动作 `text` 为目前已经输入了的字符串 (星号标记文本). - - 用户选择了要提交的文字时, 一个 `text` 类型动作被触发 (证明当前触发器配置正确). 而这个动作的 `text` 项保存了用户最终提交的文字. +end +``` ## 输入焦点 @@ -274,48 +219,3 @@ function on_input(self, action_id, action) return true end ``` - - -## 拾取检测 - -游戏里经常可见拾取操作. 可能是玩家点击界面按钮或者战略游戏里玩家选取一个作战单位, RPG 游戏点取宝箱等等. 不同组件有不同解决方法. - -### 界面点击检测 - -界面有一个 `gui.pick_node(node, x, y)` 函数来判断点击输入是否处在某个节点范围之内. 详见 [API 文档](/ref/gui/#gui.pick_node:node-x-y), [指针悬停示例](https://www.defold.com/examples/pointer_over/) 或者 [按钮示例](https://www.defold.com/examples/button/). - -### 游戏对象点击检测 -游戏对象检测有点复杂, 因为摄像机移动和渲染脚本映射都会影响位置计算. 方法主要分为两种: - - 1. 追踪游戏对象的位置和大小然后检测点选位置是否包含在内. - 2. 给游戏对象加入碰撞组件再在点选位置生成一个碰撞对象检查二者碰撞情况. - -::: 注意 -公共资源 [Defold 输入库](https://github.com/britzl/defold-input) 是一个开箱即用的输入检测库. -::: - -无论哪种方案都必须将鼠标手点选的屏幕坐标转换成游戏对象的世界坐标. 实现思路如下: - - * 手动跟踪渲染脚本使用的视口和投射用以进行坐标转换. 详见 [摄像机教程的这个示例](/manuals/camera/#鼠标位置转换为世界坐标). - * 使用 [第三方摄像机解决方案](/manuals/camera/#第三方摄像机解决方案) 里面的屏幕到世界坐标转换函数. - - -## 游戏手柄配置文件 - -游戏手柄配置保存在 *gamepads* 文件里. Defold 自带一个通用手柄配置文件: - -![Gamepad settings](images/input/gamepads.png){srcset="images/input/gamepads@2x.png 2x"} - -如需自定义手柄配置, 这里有个工具可供使用: - -[gdc.zip](https://forum.defold.com/t/big-thread-of-gamepad-testing/56032). - -其中包含可运行于 Windows, Linux 和 macOS 上的可执行文件. 从命令行打开: - -```sh -./gdc -``` - -工具提示你按下手柄某个按键. 然后输出配置文件. 保存这个文件, 并在 "game.project" 里引用它: - -![Gamepad settings](images/input/gamepad_setting.png){srcset="images/input/gamepad_setting@2x.png 2x"} From d9d0a07fd45949d4724bcaab0ac01edf71d45b5c Mon Sep 17 00:00:00 2001 From: COCO Date: Mon, 8 Feb 2021 10:04:06 +0800 Subject: [PATCH 009/134] forum url --- docs/zh/manuals/android.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh/manuals/android.md b/docs/zh/manuals/android.md index 16bb42eb..380e7a80 100644 --- a/docs/zh/manuals/android.md +++ b/docs/zh/manuals/android.md @@ -20,7 +20,7 @@ Android 要求每个 APK 文件在被安装到设备上或者在设备上更新 ## 制作 keystore ::: 注意 -Defold 应对安卓应用包签名的改变是从 1.2.173 版开始的, 就是使用单独的证书和密码来合成 keystore. +Defold 应对安卓应用包签名的改变是从 1.2.173 版开始的, 就是使用单独的证书和密码来合成 keystore. [详见论坛帖子](https://forum.defold.com/t/upcoming-change-to-the-android-build-pipeline/66084). ::: 也可以 [使用 Android Studio](https://developer.android.com/studio/publish/app-signing#generate-key) 或者通过使用控制台命令来生成签名: From 13846752aa20b784c1c98ae0323b324b3bd35d63 Mon Sep 17 00:00:00 2001 From: COCO Date: Tue, 9 Feb 2021 11:38:50 +0800 Subject: [PATCH 010/134] read only user --- docs/zh/manuals/libraries.md | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/docs/zh/manuals/libraries.md b/docs/zh/manuals/libraries.md index af3db793..a4ebfb68 100644 --- a/docs/zh/manuals/libraries.md +++ b/docs/zh/manuals/libraries.md @@ -34,22 +34,41 @@ brief: 项目间可以使用库共享资源. 本教程解释了其工作方式. ### 基本訪問驗證 -對於不公開的庫可以通過在 URL 上加入用戶名密碼 / 訪問權標記的方法來訪問: +對於不公開的庫可以通過在 URL 上加入用戶名密碼 / 訪問權token的方法來訪問: ``` https://username:password@github.com/defold/private/archive/main.zip ``` -這裏 `username` 和 `password` 項會被提取並轉化爲 `Authorization` 請求頭. 這種方法一般服務器都適用. 包括從 GitHub 上獲取私有庫. GitHub 還支持使用 [生成訪問權標記](https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/creating-a-personal-access-token) 的方法來代替密碼. +這裏 `username` 和 `password` 項會被提取並轉化爲 `Authorization` 請求頭. 這種方法一般服務器都適用. 包括從 GitHub 上獲取私有庫. GitHub 還支持使用 [生成訪問權token](https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/creating-a-personal-access-token) 的方法來代替密碼. ``` https://github-username:personal-access-token@github.com/defold/private/archive/main.zip ``` ::: 注意 -不要共享或者不小心泄露你的密碼或訪問權標記, 否則可能會落入他人之手造成不良後果. +不要共享或者不小心泄露你的密碼或訪問權token, 否則可能會落入他人之手造成不良後果. ::: +### 严格访问权限 + +基本訪問权限下token和用户名都在项目依赖库上公开. 这对于多人开发团队来说可能会造成麻烦. 解决办法是给库引入一个 "只读" 用户, 在 GitHub 上可以设置一个机构, 一个团队以及一个不需要编辑代码的用户 (也就是只读用户). + +GitHub 具体步骤: +* [创建机构](https://docs.github.com/en/github/setting-up-and-managing-organizations-and-teams/creating-a-new-organization-from-scratch) +* [机构之下的团队](https://docs.github.com/en/github/setting-up-and-managing-organizations-and-teams/creating-a-team) +* [把需要的私有库存放到机构之下](https://docs.github.com/en/github/administering-a-repository/transferring-a-repository) +* [将开发团队设置为对库 "只读"](https://docs.github.com/en/github/setting-up-and-managing-organizations-and-teams/managing-team-access-to-an-organization-repository) +* [创建只读团队的只读用户成员](https://docs.github.com/en/github/setting-up-and-managing-organizations-and-teams/organizing-members-into-teams) +* 给只读用户发放 "基本访问权限" token + +此时这个只读用户的信息就可以放心公开在依赖库上. 这样就可以将私有库公开化而不用担心被恶意篡改. + +::: 注意 +使用这种只读用户的 token 可以访问所有依赖私有库的游戏. +::: + +上述解决方案于 Defold 论坛提出并 [于此帖子上进行谈论](https://forum.defold.com/t/private-github-for-library-solved/67240). ## 设置库依赖 From 3f3abaaf2f00a929c34dd1a96894a1090c0f043c Mon Sep 17 00:00:00 2001 From: COCO Date: Fri, 12 Feb 2021 13:00:35 +0800 Subject: [PATCH 011/134] html5 gamepad --- docs/zh/manuals/html5.md | 1 + docs/zh/manuals/input-gamepads.md | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/docs/zh/manuals/html5.md b/docs/zh/manuals/html5.md index f3405a18..ce6e21a9 100644 --- a/docs/zh/manuals/html5.md +++ b/docs/zh/manuals/html5.md @@ -59,6 +59,7 @@ Defold 打包 HTML5 游戏很简单, 跟其他平台一样: 从菜单栏选择 < * Full screen - 全屏模式在浏览器中不可靠. * Chrome * Slow debug builds - 为了在 HTML5 平台更好地调试我们开启了校验所有 WebGL 图像调用来检测错误. 但是这样做在 Chrome 上会运行缓慢. 可以把 *game.project* 里的 *Engine Arguments* 部分设置为 `–-verify-graphics-calls=false` 来关闭图像调用校验. +* 游戏手柄支持 - 对于 HTML5 平台的游戏手柄支持与配置参见[这篇教程](/manuals/input-gamepads/#gamepads-in-html5). ## 自定义HTML5打包 diff --git a/docs/zh/manuals/input-gamepads.md b/docs/zh/manuals/input-gamepads.md index 2af40140..e5f1d00b 100644 --- a/docs/zh/manuals/input-gamepads.md +++ b/docs/zh/manuals/input-gamepads.md @@ -109,3 +109,21 @@ end 这个工具通过收集连接控制器的输入自动生成映射文件. 新的映射文件可以在 "game.project" 里进行指定或者混合使用: ![Gamepad settings](images/input/gamepad_setting.png){srcset="images/input/gamepad_setting@2x.png 2x"} + +## HTML5上的游戏手柄 +HTML5平台同样支持游戏手柄, 效果和原生应用一样. 游戏手柄的支持基于 [标准游戏手柄API](https://www.w3.org/TR/gamepad/), 并且受绝大多数浏览器支持 ([详见此图表](https://caniuse.com/?search=gamepad)). 万一遇到不支持的浏览器 Defold 会忽略所有游戏手柄的操作. 可以通过检查浏览器的`navigator`对象中是否存在`getGamepads`函数来判断其是否支持游戏手柄: + +```lua +local function supports_gamepads() + return not html5 or (html5.run('typeof navigator.getGamepads === "function"') == "true") +end +if supports_gamepads() then + print("Platform supports gamepads") +end +``` + +运行在 `iframe` 上的游戏要确保 `iframe` 的 `gamepad` 权限已被开启: + +```html + +``` From bab01d9b6df948fd5ab0329a225dd31cc36f76b7 Mon Sep 17 00:00:00 2001 From: COCO Date: Mon, 15 Feb 2021 11:31:22 +0800 Subject: [PATCH 012/134] sdk api update --- docs/zh/manuals/extensions-defold-sdk.md | 31 ++++++++++++++++++------ 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/docs/zh/manuals/extensions-defold-sdk.md b/docs/zh/manuals/extensions-defold-sdk.md index e12af208..3bf02ed4 100644 --- a/docs/zh/manuals/extensions-defold-sdk.md +++ b/docs/zh/manuals/extensions-defold-sdk.md @@ -20,12 +20,29 @@ Defold SDK 包含了应用运行的原生平台底层接口与高层Lua逻辑接 * [Buffer](/ref/dmBuffer/) - 数据缓存功能是不同平台互相交流的主要途径. [Lua API](/ref/buffer/) 同样具有缓存功能. * [Condition Variable](/ref/dmConditionVariable/) - 条件变量. * [ConfigFile](/ref/dmConfigFile/) - 配置文件的存取功能. 配置文件是 game.project 文件的编译后版本. -* [Extension](/ref/dmExtension/) - 创建和控制引擎扩展的功能. -* [Graphics](/ref/dmGraphics/) - 特定原生平台的图像功能. +* [Connection Pool](/ref/dmConnectionPool/) - Socket连接池功能. +* [Crypt](/ref/dmCrypt/) - 加密功能. +* [DNS](/ref/dmDNS/) - DNS功能. +* [Engine](/ref/dmEngine/) - 引擎用于处理配置文件, 内部web服务器, 游戏对象等核心功能. +* [Extension](/ref/dmExtension/) - 创建和控制引擎原生扩展库功能. +* [Game Object](/ref/dmGameObject/) - 游戏对象管理功能. +* [Graphics](/ref/dmGraphics/) - 平台相关的原生图像功能. * [Hash](/ref/dmHash/) - 哈希功能. -* [Json](/ref/dmJson/) - 平台与关的json解析器. +* [HID](/ref/dmHid/) - 通用程序化输入功能. +* [HTTP Client](/ref/dmHttpClient/) - HTTP客户端交互功能. +* [Json](/ref/dmJson/) - 平台无关的json文件解析器. * [Log](/ref/dmLog/) - 日志功能. -* [Mutex](/ref/dmMutex/) - 平台无关的互斥同步基础功能 -* [Script](/ref/dmScript/) - 内建脚本运行环境. -* [Shared Library](/ref/sharedlibrary/) - 共享库导入导出功能 -* [Sony vector Math Library](/manuals/assets/Vector_Math_Library-Overview.pdf) - Sony 矢量计算库 主要为了3D图像和3D, 4D矢量运算, 矩阵运算和四元运算. +* [Math](/ref/dmMath/) - 数学库. +* [Mutex](/ref/dmMutex/) - 平台无关的互斥锁同步基础功能. +* [SSL Socket](/ref/dmSSLSocket/) - 加密socket功能. +* [Script](/ref/dmScript/) - 内置脚本运行环境. +* [Socket](/ref/dmSocket/) - 非加密socket功能. +* [String Functions](/ref/dmStringFunc/) - 字符串管理功能. +* [Thread](/ref/dmThread/) - 线程创建功能. +* [Time](/ref/dmTime/) - 时间与计时功能. +* [URI](/ref/dmURI/) - URI管理功能. +* [Web Server](/ref/dmWebServer/) - 基于dmHttpServer的高级单线程web服务器. +* [Shared Library](/ref/sharedlibrary/) - 共享库导入导出功能. +* [Sony vector Math Library](../assets/Vector_Math_Library-Overview.pdf) - Sony 矢量计算库 主要为了3D图像和3D, 4D矢量运算, 矩阵运算和四元运算. + + From 1cb14e76b659166f1e977e0b5a756273162fcaa9 Mon Sep 17 00:00:00 2001 From: COCO Date: Wed, 3 Mar 2021 10:46:48 +0800 Subject: [PATCH 013/134] update --- docs/zh/shared/linux-faq.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/zh/shared/linux-faq.md b/docs/zh/shared/linux-faq.md index bc1e4515..5bb2ffee 100644 --- a/docs/zh/shared/linux-faq.md +++ b/docs/zh/shared/linux-faq.md @@ -49,6 +49,12 @@ $ export MESA_LOADER_DRIVER_OVERRIDE=i965 $ ./Defold ``` +可能还需要指定载入 libffi 版本 6 才能启动 Defold: + +```bash +$ export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libffi.so.6 +``` + #### Q: 在 Linux 上启动 Defold 游戏无效? From 3830962ddd1a878ec064f89220787c0319987d44 Mon Sep 17 00:00:00 2001 From: COCO Date: Fri, 5 Mar 2021 21:30:24 +0800 Subject: [PATCH 014/134] image properties --- docs/zh/manuals/atlas.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/docs/zh/manuals/atlas.md b/docs/zh/manuals/atlas.md index 41a13290..5071f472 100644 --- a/docs/zh/manuals/atlas.md +++ b/docs/zh/manuals/atlas.md @@ -70,6 +70,24 @@ Extrude Borders ![Atlas properties](images/atlas/atlas_properties.png){srcset="images/atlas/atlas_properties@2x.png 2x"} +## 图片属性 + +图集中的每个图片都有一系列属性: + +Id +: 图片名称 (只读). + +Size +: 图片宽高 (只读). + +Sprite Trim Mode +: 决定sprite如何渲染. 默认以矩形渲染 (Sprite Trim Mode 为 Off). 如果图片由许多透明的地方最好用4个或8个顶点设定非矩形渲染. + +Image +: 图片路径. + +![Image properties](images/atlas/image_properties.png){srcset="images/atlas/image_properties@2x.png 2x"} + ## 动画属性 动画组除了组成动画的图片, 还提供了一些属性: From c61bc38dfcc23ef2219ffeff31cfa6388d8adde3 Mon Sep 17 00:00:00 2001 From: COCO Date: Tue, 9 Mar 2021 10:09:23 +0800 Subject: [PATCH 015/134] update editor --- docs/zh/manuals/editor.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/zh/manuals/editor.md b/docs/zh/manuals/editor.md index 27527952..dbf6df2f 100644 --- a/docs/zh/manuals/editor.md +++ b/docs/zh/manuals/editor.md @@ -132,6 +132,14 @@ Defold 编辑器被划分为许多面板, 或称视图, 以展示和编辑数据 ![Import files](images/editor/import.png){srcset="images/editor/import@2x.png 2x"} +## 编辑器更新 + +编辑器自动检查更新. 检测到新版本的话就会在编辑器右下角或者项目选择视图里显示出来. 点击即可自动更新. + +![Update from project selection](images/editor/update-project-selection.png){srcset="images/editor/update-project-selection@2x.png 2x"} + +![Update from editor](images/editor/update-main.png){srcset="images/editor/update-main@2x.png 2x"} + ## 快捷键 ### 默認快捷鍵 From 6c4897e3eac13201a0f78e12509c9f5277af7962 Mon Sep 17 00:00:00 2001 From: COCO Date: Sun, 14 Mar 2021 15:45:07 +0800 Subject: [PATCH 016/134] defold sdk update --- docs/zh/manuals/extensions-defold-sdk.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/zh/manuals/extensions-defold-sdk.md b/docs/zh/manuals/extensions-defold-sdk.md index 3bf02ed4..0426807f 100644 --- a/docs/zh/manuals/extensions-defold-sdk.md +++ b/docs/zh/manuals/extensions-defold-sdk.md @@ -13,7 +13,7 @@ Defold SDK 包含了应用运行的原生平台底层接口与高层Lua逻辑接 #include -这个头文件并不公开发布但是SDK的所有功能都在 [API](/ref/dmExtension/) 里写明了. SDK包含以下命名空间和功能: +可用的SDK功能都在 [API文档](/ref/dmExtension/) 里写明了. SDK包含以下命名空间和功能: * [Align](/ref/dmAlign/) - 公共宏. 用来保证编译器兼容 * [Array](/ref/dmArray/) - 具有边界检测的模板化数组. @@ -45,4 +45,5 @@ Defold SDK 包含了应用运行的原生平台底层接口与高层Lua逻辑接 * [Shared Library](/ref/sharedlibrary/) - 共享库导入导出功能. * [Sony vector Math Library](../assets/Vector_Math_Library-Overview.pdf) - Sony 矢量计算库 主要为了3D图像和3D, 4D矢量运算, 矩阵运算和四元运算. +如果需要 `dmsdk/sdk.h` 头文件请到 [Defold 官方 Github 库](https://github.com/defold/defold/blob/dev/engine/sdk/src/dmsdk/sdk.h) 查询, 这里有 [各种命名空间的头文件](https://github.com/defold/defold/tree/dev/engine/dlib/src/dmsdk/dlib). From 7533c9cca544f4cb751059bbcf9e2f3ce6790232 Mon Sep 17 00:00:00 2001 From: COCO Date: Tue, 16 Mar 2021 18:41:34 +0800 Subject: [PATCH 017/134] animation updates --- docs/zh/manuals/animation.md | 476 +------------------------- docs/zh/manuals/collection-proxy.md | 15 +- docs/zh/manuals/flipbook-animation.md | 111 ++++++ docs/zh/manuals/model-animation.md | 86 +++++ docs/zh/manuals/property-animation.md | 181 ++++++++++ docs/zh/manuals/spine.md | 143 +++++++- docs/zh/manuals/spinemodel.md | 18 +- 7 files changed, 540 insertions(+), 490 deletions(-) create mode 100644 docs/zh/manuals/flipbook-animation.md create mode 100644 docs/zh/manuals/model-animation.md create mode 100644 docs/zh/manuals/property-animation.md diff --git a/docs/zh/manuals/animation.md b/docs/zh/manuals/animation.md index 9662cd45..2aa9002a 100644 --- a/docs/zh/manuals/animation.md +++ b/docs/zh/manuals/animation.md @@ -5,475 +5,9 @@ brief: 本教程介绍了 Defold 的动画支持. # 动画 -Defold 内置支持多种动画: +Defold 内置组件支持多种动画: -* 逐帧动画 -* Spine 动画 -* 3D 蒙皮动画 -* 属性动画 - -## 逐帧动画 - -逐帧动画就是由一些列静态图片轮流显示生成的动画. 这种技术类似于老式翻页动画 (详见 http://en.wikipedia.org/wiki/Traditional_animation). 由于每帧的独立性使得这种技术很自由. 但是每帧一张图片会很耗费内存. 相似图片越多动画过渡越平滑同时也带来了巨大的工作量. Defold 逐帧动画使用来自于 [图集](/manuals/atlas), 或者 [瓷砖图源](/manuals/tilesource) 里水平排列的图片. - - ![Animation sheet](images/animation/animsheet.png){.inline} - ![Run loop](images/animation/runloop.gif){.inline} - -## Spine 动画 - -Spine 动画提供 2D _骨骼动画_ 支持 (详见 http://en.wikipedia.org/wiki/Skeletal_animation). 这是一种类似于剪裁动画的技术. 剪裁动画把对象分成各部分 (比如身体, 眼睛, 嘴巴之类的) 在每帧上独立运动. Spine 动画可以建立隐藏的, 树形关联的虚拟 _骨骼_. 骨架, 或称 _绑定_, 来为骨骼上添加的图片单独做动画. Defold 支持以 [Spine JSON 格式](http://esotericsoftware.com/spine-json-format) 输出的动画. Skeletal 动画都很平滑因为骨骼动画关键帧之间可以自动进行插值. - - 关于导入 Spine 数据作为 Spine 模型和动画, 详见 [Spine 教程](/manuals/spine). - - ![Spine animation](images/animation/spine_animation.png){.inline} - ![Run loop](images/animation/frog_runloop.gif){.inline} - -## 3D 蒙皮动画 - -3D 模型的骨骼动画和 Spine 动画类似但是是针对于 3D 空间的. 3D 模型不是像剪裁动画那样先分成各个部分然后用骨骼连起来做动画. 而是使用骨骼精细控制模型上各个三角形如何移动. - - 关于如何导入 3D 模型动画, 详情请见 [模型教程](/manuals/model). - - ![Blender animation](images/animation/blender_animation.png){.inline srcset="images/animation/blender_animation@2x.png 2x"} - ![Wiggle loop](images/animation/suzanne.gif){.inline} - -## 属性动画 - -数值类的属性 (numbers, vector3, vector4 和 quaterions) 以及着色器常量都可以由内置的属性动画系统制作属性动画, 即使用 `go.animate()` 函数. 引擎会在属性值之间进行 "补间" 依照指定的播放和缓动模式进行播放. 你也可以自定义缓动函数. - - ![Property animation](images/animation/property_animation.png){.inline srcset="images/animation/property_animation@2x.png 2x"} - ![Bounce loop](images/animation/bounce.gif){.inline} - -## 播放逐帧动画 - -Sprite 和 GUI 方块节点可以用来播放逐帧动画而且可以在运行时进行控制. - -Sprites -: 通过调用 [`sprite.play_flipbook()`](/ref/sprite/?q=play_flipbook#sprite.play_flipbook:url-id-[complete_function]-[play_properties]) 函数播放逐帧动画. 示例见下文. - -GUI 方块节点 -: 通过调用 [`gui.play_flipbook()`](/ref/gui/?q=play_flipbook#gui.play_flipbook:node-animation-[complete_function]-[play_properties]) 函数播放逐帧动画. 示例见下文. - -::: 注意 -ping-pong 播放模式把动画从第一帧播放到最后一帧再反向播放到 **第二帧** , 而不是第一帧. 这样便于连续播放的衔接. -::: - -### Sprite 示例 - -假设你的游戏有个 "dodge" 功能, 按下指定的键主角就进行闪避动作. 为此你建立了四组动画: - -"idle" -: 主角待机的循环动画. - -"dodge_idle" -: 主角闪避动作的循环动画. - -"start_dodge" -: 主角从站立姿态到闪避动作的一次性动画. - -"stop_dodge" -: 主角从闪避动作到站立姿态的一次性动画. - -逻辑代码如下: - -```lua - -local function play_idle_animation(self) - if self.dodge then - sprite.play_flipbook("#sprite", hash("dodge_idle")) - else - sprite.play_flipbook("#sprite", hash("idle")) - end -end - -function on_input(self, action_id, action) - -- "dodge" 就是输入动作 - if action_id == hash("dodge") then - if action.pressed then - sprite.play_flipbook("#sprite", hash("start_dodge"), play_idle_animation) - -- 记录闪避动作已开始 - self.dodge = true - elseif action.released then - sprite.play_flipbook("#sprite", hash("stop_dodge"), play_idle_animation) - -- 记录闪避动作完成 - self.dodge = false - end - end -end -``` - -### GUI 方块节点示例 - -给节点选择图片或者动画时, 实际上也同时指定了图片来源 (图集或者瓷砖图源) 以及默认动画. 节点图源是静态的, 但是当前播放的动画是可以在运行时指定的. 静态图片被视作单帧动画, 所以运行时切换图片相当于播放另一个动画: - -```lua -local function flipbook_done(self) - msg.post("#", "jump_completed") -end - -function init(self) - local character_node = gui.get_node("character") - -- 新动画/图片播放时 - -- 节点图源要存在默认动画. - gui.play_flipbook(character_node, "jump_left", flipbook_done) -end -``` - -动画播放完成时可以提供一个回调函数. 如果动画是以 `ONCE_*` 模式播放, 播放完成后会调用这个回调函数. - -## Spine model 动画 - -在 Spine 模型上播放动画, 只需调用 [`spine.play_anim()`](/ref/spine#spine.play_anim) 函数: - -```lua -local function anim_done(self) - -- 动画播放完成, 做其他事情... -end - -function init(self) - -- 在 "spinemodel" 组件上播放 "walk" 动画同时与上一个动画 - -- 在前 0.1 内混合, 然后进行回调. - local anim_props = { blend_duration = 0.1 } - spine.play_anim("#spinemodel", "run", go.PLAYBACK_LOOP_FORWARD, anim_props, anim_done) -end -``` - -![Spine model in game](images/animation/spine_ingame.png){srcset="images/animation/spine_ingame@2x.png 2x"} - -如果动画是以 `go.PLAYBACK_ONCE_*` 模式播放, 然后在 `spine.play_anim()` 里指定回调函数, 则动画播放完成后会调用回调函数. 关于回调函数详见下文. - -### Spine model - 播放头 - -除了 `spine.play_anim()` 还有更高级的方法, *Spine Model* 组件暴露了一个 "cursor" 属性可以通过 `go.animate()` 进行控制: - -```lua --- 设置 spine model 动画但是不播放. -spine.play_anim("#spinemodel", "run_right", go.PLAYBACK_NONE) - --- 设置播放头为 0 -go.set("#spinemodel", "cursor", 0) - --- 基于 in-out quad 缓动慢慢对播放头进行从 0 到 1 的 pingpong 补间. -go.animate("#spinemodel", "cursor", go.PLAYBACK_LOOP_PINGPONG, 1, go.EASING_INOUTQUAD, 6) -``` - -::: 注意 -补间和设置播放头时, 时间轴事件不会被触发. -::: - -### Spine model - 骨骼层级 - -Spine 骨架的各个骨骼实例在游戏对象内展示出来. 在 Spine model 组件的 *Outline* 视图内, 可以看到完整的嵌套关系. 在此层级嵌套关系中你可以看到骨骼的名称和其所在的位置. - -![Spine model hierarchy](images/animation/spine_bones.png){srcset="images/animation/spine_bones@2x.png 2x"} - -通过骨骼名称, 就可以在运行时得到骨骼实例. 函数 [`spine.get_go()`](/ref/spine#spine.get_go) 返回指定骨骼的 id, 然后就可以用来进行设置父级之类的操作: - -```lua --- 把手枪绑定到英雄手上 -local hand = spine.get_go("heroine#spinemodel", "front_hand") -msg.post("pistol", "set_parent", { parent_id = hand }) -``` - -### Spine model - 时间轴事件 - -Spine 动画可以基于精确的时间触发事件. 对于需要做同步行为的功能非常有帮助, 例如播放走路声音, 场景粒子效果, 在骨骼层级上进行绑定和解绑或者实现你需要的其他功能. - -在 Spine 软件里可以使用时间轴设置事件: - -![Spine events](images/animation/spine_events.png) - -各种事件由事件 id 表示 (上例中是 "bump") 而且时间轴上的事件可以包含一些数据: - -Integer -: 整数值. - -Float -: 浮点数值. - -String -: 字符串值. - -动画播放遇到事件时, `spine_event` 消息会被发回到调用 `spine.play()` 函数的脚本上. 消息数据参数就是事件附带的数据, 连同其他一些有用的数据: - -`t` -: 自动画播放第一帧开始经过的时间. - -`animation_id` -: 动画名, 哈希值. - -`string` -: 事件附带字符串值, 哈希值. - -`float` -: 事件附带浮点数值. - -`integer` -: 事件附带整数值. - -`event_id` -: 事件 id, 哈希值. - -`blend_weight` -: 此时动画混合情况. 0 表示动画还没有被混合, 1 当前动画混合 100%. - -```lua --- Spine 动画包含与动画同步的音效. --- 作为消息传到这里. -function on_message(self, message_id, message, sender) - if message_id == hash("spine_event") and message.event_id == hash("play_sound") then - -- 播放动画音效. 事件数据包括声音组件和声音增益. - local url = msg.url("sounds") - url.fragment = message.string - sound.play(url, { gain = message.float }) - end -end -``` - -## 3D Model 动画 - -通过调用 [`model.play_anim()`](/ref/model#model.play_anim) 函数播放模型动画: - -```lua -function init(self) - -- 在 #model 上来回播放 "wiggle" 动画 - model.play_anim("#model", "wiggle", go.PLAYBACK_LOOP_PINGPONG) -end -``` - -::: 注意 -Defold 目前只支持烘焙动画. 动画每个骨骼每一帧都要有矩阵数据, 而不是单独的位置, 旋转和缩放数据. - -动画是线性插值的. 如果需要曲线插值动画要在输出时烘焙. - -不支持 Collada 中的动画剪辑. 想要一个模型多个动画, 就要分别导出为 *.dae* 文件然后在 Defold 里组成 *.animationset* 文件. -::: - -### 3D Model - 骨骼层级 - -模型骨骼作为游戏对象展示出来. - -通过骨骼名称, 就可以在运行时得到骨骼实例. 函数 [`model.get_go()`](/ref/model#model.get_go) 返回指定骨骼的 id. - -```lua --- 得到 wiggler 模型的中央骨骼 -local bone_go = model.get_go("#wiggler", "Bone_002") - --- 然后可以任意操作该游戏对象... -``` - -### 3D Model - 播放头 - -像 Spine 模型一样, 3D 模型也可以通过控制 `cursor` 属性播放动画: - -```lua --- 设置 #model 上的动画但不播放 -model.play_anim("#model", "wiggle", go.PLAYBACK_NONE) --- 把播放头设置为动画起始位置 -go.set("#model", "cursor", 0) --- 基于 in-out quad 缓动对播放头进行从 0 到 1 的 pingpong 补间. -go.animate("#model", "cursor", go.PLAYBACK_LOOP_PINGPONG, 1, go.EASING_INOUTQUAD, 3) -``` - -## 属性动画 - -制作游戏对象或者组件的属性动画, 可以使用函数 `go.animate()`. 对于 GUI 节点属性, 可以使用函数 `gui.animate()`. - -```lua --- 设置 y 轴位置为 200 -go.set(".", "position.y", 200) --- 制作动画 -go.animate(".", "position.y", go.PLAYBACK_LOOP_PINGPONG, 100, go.EASING_OUTBOUNCE, 2) -``` - -停止某个属性的所有动画, 调用 `go.cancel_animations()`, 对于 GUI 节点, 调用 `gui.cancel_animation()`: - -```lua --- 停止当前游戏对象欧拉 z 轴旋转动画 -go.cancel_animation(".", "euler.z") -``` - -如果取消组合属性的动画, 例如 `position`, 其所有子属性 (`position.x`, `position.y` 和 `position.z`) 动画也会一同取消. - -[属性教程](/manuals/properties) 涵盖游戏对象, 组件和 GUI 节点的所有属性. - -## GUI 节点属性动画 - -几乎所有 GUI 节点属性都可以制作动画. 比如说, 把一个节点的 `color` 设置成透明看不见然后制作属性动画到全白使其可见 (也就是没有染色). - -```lua -local node = gui.get_node("button") -local color = gui.get_color(node) --- 节点白色动画 -gui.animate(node, gui.PROP_COLOR, vmath.vector4(1, 1, 1, 1), gui.EASING_INOUTQUAD, 0.5) --- 边框红色动画 -gui.animate(node, "outline.x", 1, gui.EASING_INOUTQUAD, 0.5) --- 位置延 x 轴移动 100 像素动画 -gui.animate(node, hash("position.x"), 100, gui.EASING_INOUTQUAD, 0.5) -``` - -## 播放模式 - -动画可以单次播放也可以循环播放. 取决于播放模式: - -* go.PLAYBACK_NONE -* go.PLAYBACK_ONCE_FORWARD -* go.PLAYBACK_ONCE_BACKWARD -* go.PLAYBACK_ONCE_PINGPONG -* go.PLAYBACK_LOOP_FORWARD -* go.PLAYBACK_LOOP_BACKWARD -* go.PLAYBACK_LOOP_PINGPONG - -pingpong 模式先正向播放, 再反向播放. GUI 属性动画也有这些播放模式: - -* gui.PLAYBACK_NONE -* gui.PLAYBACK_ONCE_FORWARD -* gui.PLAYBACK_ONCE_BACKWARD -* gui.PLAYBACK_ONCE_PINGPONG -* gui.PLAYBACK_LOOP_FORWARD -* gui.PLAYBACK_LOOP_BACKWARD -* gui.PLAYBACK_LOOP_PINGPONG - -## 缓动 - -缓动决定动画基于时间的变化. 下面列出了内置的缓动函数. - -以下可用于 `go.animate()` 函数: - -|---|---| -| go.EASING_LINEAR | | -| go.EASING_INBACK | go.EASING_OUTBACK | -| go.EASING_INOUTBACK | go.EASING_OUTINBACK | -| go.EASING_INBOUNCE | go.EASING_OUTBOUNCE | -| go.EASING_INOUTBOUNCE | go.EASING_OUTINBOUNCE | -| go.EASING_INELASTIC | go.EASING_OUTELASTIC | -| go.EASING_INOUTELASTIC | go.EASING_OUTINELASTIC | -| go.EASING_INSINE | go.EASING_OUTSINE | -| go.EASING_INOUTSINE | go.EASING_OUTINSINE | -| go.EASING_INEXPO | go.EASING_OUTEXPO | -| go.EASING_INOUTEXPO | go.EASING_OUTINEXPO | -| go.EASING_INCIRC | go.EASING_OUTCIRC | -| go.EASING_INOUTCIRC | go.EASING_OUTINCIRC | -| go.EASING_INQUAD | go.EASING_OUTQUAD | -| go.EASING_INOUTQUAD | go.EASING_OUTINQUAD | -| go.EASING_INCUBIC | go.EASING_OUTCUBIC | -| go.EASING_INOUTCUBIC | go.EASING_OUTINCUBIC | -| go.EASING_INQUART | go.EASING_OUTQUART | -| go.EASING_INOUTQUART | go.EASING_OUTINQUART | -| go.EASING_INQUINT | go.EASING_OUTQUINT | -| go.EASING_INOUTQUINT | go.EASING_OUTINQUINT | - -以下可用于 `gui.animate()` 函数: - -|---|---| -| gui.EASING_LINEAR | | -| gui.EASING_INBACK | gui.EASING_OUTBACK | -| gui.EASING_INOUTBACK | gui.EASING_OUTINBACK | -| gui.EASING_INBOUNCE | gui.EASING_OUTBOUNCE | -| gui.EASING_INOUTBOUNCE | gui.EASING_OUTINBOUNCE | -| gui.EASING_INELASTIC | gui.EASING_OUTELASTIC | -| gui.EASING_INOUTELASTIC | gui.EASING_OUTINELASTIC | -| gui.EASING_INSINE | gui.EASING_OUTSINE | -| gui.EASING_INOUTSINE | gui.EASING_OUTINSINE | -| gui.EASING_INEXPO | gui.EASING_OUTEXPO | -| gui.EASING_INOUTEXPO | gui.EASING_OUTINEXPO | -| gui.EASING_INCIRC | gui.EASING_OUTCIRC | -| gui.EASING_INOUTCIRC | gui.EASING_OUTINCIRC | -| gui.EASING_INQUAD | gui.EASING_OUTQUAD | -| gui.EASING_INOUTQUAD | gui.EASING_OUTINQUAD | -| gui.EASING_INCUBIC | gui.EASING_OUTCUBIC | -| gui.EASING_INOUTCUBIC | gui.EASING_OUTINCUBIC | -| gui.EASING_INQUART | gui.EASING_OUTQUART | -| gui.EASING_INOUTQUART | gui.EASING_OUTINQUART | -| gui.EASING_INQUINT | gui.EASING_OUTQUINT | -| gui.EASING_INOUTQUINT | gui.EASING_OUTINQUINT | - -![Linear interpolation](images/properties/easing_linear.png){.inline} -![In back](images/properties/easing_inback.png){.inline} -![Out back](images/properties/easing_outback.png){.inline} -![In-out back](images/properties/easing_inoutback.png){.inline} -![Out-in back](images/properties/easing_outinback.png){.inline} -![In bounce](images/properties/easing_inbounce.png){.inline} -![Out bounce](images/properties/easing_outbounce.png){.inline} -![In-out bounce](images/properties/easing_inoutbounce.png){.inline} -![Out-in bounce](images/properties/easing_outinbounce.png){.inline} -![In elastic](images/properties/easing_inelastic.png){.inline} -![Out elastic](images/properties/easing_outelastic.png){.inline} -![In-out elastic](images/properties/easing_inoutelastic.png){.inline} -![Out-in elastic](images/properties/easing_outinelastic.png){.inline} -![In sine](images/properties/easing_insine.png){.inline} -![Out sine](images/properties/easing_outsine.png){.inline} -![In-out sine](images/properties/easing_inoutsine.png){.inline} -![Out-in sine](images/properties/easing_outinsine.png){.inline} -![In exponential](images/properties/easing_inexpo.png){.inline} -![Out exponential](images/properties/easing_outexpo.png){.inline} -![In-out exponential](images/properties/easing_inoutexpo.png){.inline} -![Out-in exponential](images/properties/easing_outinexpo.png){.inline} -![In circlic](images/properties/easing_incirc.png){.inline} -![Out circlic](images/properties/easing_outcirc.png){.inline} -![In-out circlic](images/properties/easing_inoutcirc.png){.inline} -![Out-in circlic](images/properties/easing_outincirc.png){.inline} -![In quadratic](images/properties/easing_inquad.png){.inline} -![Out quadratic](images/properties/easing_outquad.png){.inline} -![In-out quadratic](images/properties/easing_inoutquad.png){.inline} -![Out-in quadratic](images/properties/easing_outinquad.png){.inline} -![In cubic](images/properties/easing_incubic.png){.inline} -![Out cubic](images/properties/easing_outcubic.png){.inline} -![In-out cubic](images/properties/easing_inoutcubic.png){.inline} -![Out-in cubic](images/properties/easing_outincubic.png){.inline} -![In quartic](images/properties/easing_inquart.png){.inline} -![Out quartic](images/properties/easing_outquart.png){.inline} -![In-out quartic](images/properties/easing_inoutquart.png){.inline} -![Out-in quartic](images/properties/easing_outinquart.png){.inline} -![In quintic](images/properties/easing_inquint.png){.inline} -![Out quintic](images/properties/easing_outquint.png){.inline} -![In-out quintic](images/properties/easing_inoutquint.png){.inline} -![Out-in quintic](images/properties/easing_outinquint.png){.inline} - -## 自定义缓动 - -可以使用 `vector` 和其中的一系列值代替预置缓动函数. 矢量值从 (`0`) 过渡到 (`1`). 引擎会从矢量中取样并自动线性插值生成缓动曲线. - -示例如下: - -```lua -local values = { 0, 0.4, 0.2, 0.2, 0.5. 1 } -local my_easing = vmath.vector(values) -``` - -生成的缓动曲线如下: - -![Custom curve](images/animation/custom_curve.png) - -下面的例子是让游戏对象的 y 轴位置依照自定义曲线从当前位置到 200 来回跳跃: - -```lua -local values = { 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1 } -local square_easing = vmath.vector(values) -go.animate("go", "position.y", go.PLAYBACK_LOOP_PINGPONG, 200, square_easing, 2.0) -``` - -![Square curve](images/animation/square_curve.png) - -## 播放完成回调函数 - -所有动画函数 (`go.animate()`, `gui.animate()`, `gui.play_flipbook()`, `gui.play_spine_anim()`, `sprite.play_flipbook()`, `spine.play_anim()` 和 `model.play_anim()`) 可以在最后一个参数上传入Lua回调函数. 当动画播放完成时会调用这个函数. 对于循环动画, 和使用 `go.cancel_animations()` 手动取消播放的动画, 不会调用回调函数. 动画播放完成的回调函数里可以发送消息或者继续播放其他动画. - -不同动画函数的回调函数参数有些许区别. 具体请参照动画函数的 API 文档. - -```lua -local function done_bouncing(self, url, property) - -- 动画播放完成. 进行各种处理... -end - -function init(self) - go.animate(".", "position.y", go.PLAYBACK_ONCE_FORWARD, 100, go.EASING_OUTBOUNCE, 2, 0, done_bouncing) -end -``` +* [逐帧动画](/manuals/flipbook-animation) - 按顺序显示图片而形成的动画 +* [Spine 动画](/manuals/spine) - 2D 骨骼动画 +* [3D 模型动画](/manuals/model-animation) - 3D 蒙皮动画 +* [属性动画](/manuals/property-animation) - 以position, scale, rotation 等属性插值变换而形成的动画 diff --git a/docs/zh/manuals/collection-proxy.md b/docs/zh/manuals/collection-proxy.md index 196cc7cf..93e53a38 100644 --- a/docs/zh/manuals/collection-proxy.md +++ b/docs/zh/manuals/collection-proxy.md @@ -128,7 +128,16 @@ end ## 时间步 -集合代理的更新周期可以使用 _time step_ 进行缩放. 也就是说即使游戏是 60 FPS 的, 代理游戏世界的速度可以更快或者更慢, 影响物理世界和 `update()` 函数的 `dt` 参数. 还可以设置更新执行模式, 用以确定这种时间缩放是断续执行 (缩放值小于 1.0 时才有意义) 还是持续执行. +集合代理的更新周期可以使用 _time step_ 进行缩放. 也就是说即使游戏是 60 FPS 的, 集合代理游戏世界的速度还是可以变得可以更快或者更慢, 收以下几方面影响: + +* 物理模拟器步进 +* `update()` 函数里的 `dt` +* [游戏对象和gui属性动画](https://defold.com/manuals/animation/#property-animation-1) +* [逐帧动画](https://defold.com/manuals/animation/#flip-book-animation) +* [粒子特效模拟器](https://defold.com/manuals/particlefx/) +* lua逻辑计时器速度 + +还可以设置刷新执行模式, 可以控制游戏刷新是分散的(速度缩放小于1.0有效) 还是连续的. 通过发送 `set_time_step` 消息给集合代理组件来设置时间步缩放系数与执行模式: @@ -165,6 +174,10 @@ DEBUG:SCRIPT: update() with timestep (dt) 0.016666667535901 `update()` 仍然是每秒调用 60 次, 但是 `dt` 值变了. 可以看到只有 1/5 (0.2) 的 `update()` 调用包含 1/60 秒的 `dt` 参数, 其他都是 0. 物理模拟也基于 dt 每 5 帧步进一次. +:::注意 +可以使用集合的时间步功能来暂停游戏, 例如弹出窗口或者游戏窗口失去焦点时, 使用 `msg.post("#myproxy", "set_time_step", {factor = 0, mode = 0})` 暂停游戏, 然后使用 `msg.post("#myproxy", "set_time_step", {factor = 1, mode = 1})` 继续游戏. +::: + 详情请见 [`set_time_step`](/ref/collectionproxy#set_time_step). ## 注意事项与常见问题 diff --git a/docs/zh/manuals/flipbook-animation.md b/docs/zh/manuals/flipbook-animation.md new file mode 100644 index 00000000..b52ae9cc --- /dev/null +++ b/docs/zh/manuals/flipbook-animation.md @@ -0,0 +1,111 @@ +--- +title: Defold 中的逐帧动画 +brief: 本教程介绍了如何在 Defold 中使用逐帧动画. +--- + +# 逐帧动画 + +逐帧动画就是由一些列静态图片轮流显示生成的动画. 这种技术类似于老式翻页动画 (详见 http://en.wikipedia.org/wiki/Traditional_animation). 由于每帧的独立性使得这种技术很自由. 但是每帧一张图片会很耗费内存. 相似图片越多动画过渡越平滑同时也带来了巨大的工作量. Defold 逐帧动画使用来自于 [图集](/manuals/atlas), 或者 [瓷砖图源](/manuals/tilesource) 里水平排列的图片. + +![Animation sheet](images/animation/animsheet.png){.inline} +![Run loop](images/animation/runloop.gif){.inline} + +## 播放逐帧动画 + +Sprite 和 GUI 方块节点可以用来播放逐帧动画而且可以在运行时进行控制. + +Sprites +: 通过调用 [`sprite.play_flipbook()`](/ref/sprite/?q=play_flipbook#sprite.play_flipbook:url-id-[complete_function]-[play_properties]) 函数播放逐帧动画. 示例见下文. + +GUI 方块节点 +: 通过调用 [`gui.play_flipbook()`](/ref/gui/?q=play_flipbook#gui.play_flipbook:node-animation-[complete_function]-[play_properties]) 函数播放逐帧动画. 示例见下文. + +::: 注意 +ping-pong 播放模式把动画从第一帧播放到最后一帧再反向播放到 **第二帧** , 而不是第一帧. 这样便于连续播放的衔接. +::: + +### Sprite 示例 + +假设你的游戏有个 "dodge" 功能, 按下指定的键主角就进行闪避动作. 为此你建立了四组动画: + +"idle" +: 主角待机的循环动画. + +"dodge_idle" +: 主角闪避动作的循环动画. + +"start_dodge" +: 主角从站立姿态到闪避动作的一次性动画. + +"stop_dodge" +: 主角从闪避动作到站立姿态的一次性动画. + +逻辑代码如下: + +```lua + +local function play_idle_animation(self) + if self.dodge then + sprite.play_flipbook("#sprite", hash("dodge_idle")) + else + sprite.play_flipbook("#sprite", hash("idle")) + end +end + +function on_input(self, action_id, action) + -- "dodge" 就是输入动作 + if action_id == hash("dodge") then + if action.pressed then + sprite.play_flipbook("#sprite", hash("start_dodge"), play_idle_animation) + -- 记录闪避动作已开始 + self.dodge = true + elseif action.released then + sprite.play_flipbook("#sprite", hash("stop_dodge"), play_idle_animation) + -- 记录闪避动作完成 + self.dodge = false + end + end +end +``` + +### GUI 方块节点示例 + +给节点选择图片或者动画时, 实际上也同时指定了图片来源 (图集或者瓷砖图源) 以及默认动画. 节点图源是静态的, 但是当前播放的动画是可以在运行时指定的. 静态图片被视作单帧动画, 所以运行时切换图片相当于播放另一个动画: + +```lua +local function flipbook_done(self) + msg.post("#", "jump_completed") +end + +function init(self) + local character_node = gui.get_node("character") + -- 新动画/图片播放时 + -- 节点图源要存在默认动画. + gui.play_flipbook(character_node, "jump_left", flipbook_done) +end +``` + + +## 播放完成回调函数 + +动画函数 (`sprite.play_flipbook()` 和 `gui.play_flipbook()`) 可以在最后一个参数上传入Lua回调函数. 当动画播放完成时会调用这个函数. 对于循环动画, 和使用 `go.cancel_animations()` 手动取消播放的动画, 不会调用回调函数. 动画播放完成的回调函数里可以发送消息或者继续播放其他动画. 例如: + +```lua +local function flipbook_done(self) + msg.post("#", "jump_completed") +end + +function init(self) + sprite.play_flipbook("#character", "jump_left", flipbook_done) +end +``` + +```lua +local function flipbook_done(self) + msg.post("#", "jump_completed") +end + +function init(self) + gui.play_flipbook(gui.get_node("character"), "jump_left", flipbook_done) +end +``` diff --git a/docs/zh/manuals/model-animation.md b/docs/zh/manuals/model-animation.md new file mode 100644 index 00000000..4d96fd1a --- /dev/null +++ b/docs/zh/manuals/model-animation.md @@ -0,0 +1,86 @@ +--- +title: Defold 中的 3D 动画 +brief: 本教程介绍了如何在 Defold 中使用 3D 动画. +--- + +# 3D 蒙皮动画 + +3D 模型的骨骼动画和 Spine 动画类似但是是针对于 3D 空间的. 3D 模型不是像剪裁动画那样先分成各个部分然后用骨骼连起来做动画. 而是使用骨骼精细控制模型上各个三角形如何移动. + +关于如何导入 3D 模型动画, 详情请见 [模型教程](/manuals/model). + +![Blender animation](images/animation/blender_animation.png){.inline srcset="images/animation/blender_animation@2x.png 2x"} +![Wiggle loop](images/animation/suzanne.gif){.inline} + + +## 3D Model 动画 + +通过调用 [`model.play_anim()`](/ref/model#model.play_anim) 函数播放模型动画: + +```lua +function init(self) + -- 在 #model 上来回播放 "wiggle" 动画 + model.play_anim("#model", "wiggle", go.PLAYBACK_LOOP_PINGPONG) +end +``` + +::: 注意 +Defold 目前只支持烘焙动画. 动画每个骨骼每一帧都要有矩阵数据, 而不是单独的位置, 旋转和缩放数据. + +动画是线性插值的. 如果需要曲线插值动画要在输出时烘焙. + +不支持 Collada 中的动画剪辑. 想要一个模型多个动画, 就要分别导出为 *.dae* 文件然后在 Defold 里组成 *.animationset* 文件. +::: + + +### 骨骼层级 + +模型骨骼作为游戏对象展示出来. + +通过骨骼名称, 就可以在运行时得到骨骼实例. 函数 [`model.get_go()`](/ref/model#model.get_go) 返回指定骨骼的 id. + +```lua +-- 得到 wiggler 模型的中央骨骼 +local bone_go = model.get_go("#wiggler", "Bone_002") + +-- 然后可以任意操作该游戏对象... +``` + +### 播放头 + +除了调用 `model.play_anim()` 还有更高级的动画播放方法, 可以使用 `go.animate()` (详见 [属性动画](/manuals/property-animation)) 控制 *Model* 组件的 `cursor` 属性实现动画播放控制: + +```lua +-- 设置 #model 上的动画但不播放 +model.play_anim("#model", "wiggle", go.PLAYBACK_NONE) +-- 把播放头设置为动画起始位置 +go.set("#model", "cursor", 0) +-- 基于 in-out quad 缓动对播放头进行从 0 到 1 的 pingpong 补间. +go.animate("#model", "cursor", go.PLAYBACK_LOOP_PINGPONG, 1, go.EASING_INOUTQUAD, 3) +``` + +## 播放完成回调函数 + +动画函数 `model.play_anim()` 可以在最后一个参数上传入Lua回调函数. 当动画播放完成时会调用这个函数. 对于循环动画, 和使用 `go.cancel_animations()` 手动取消播放的动画, 不会调用回调函数. 动画播放完成的回调函数里可以发送消息或者继续播放其他动画. 例如: + +```lua +local function wiggle_done(self, message_id, message, sender) + -- 播放完毕 +end + +function init(self) + model.play_anim("#model", "wiggle", go.PLAYBACK_ONCE_FORWARD, nil, wiggle_done) +end +``` + +## 播放模式 + +动画可以单次播放也可以循环播放. 取决于播放模式: + +* go.PLAYBACK_NONE +* go.PLAYBACK_ONCE_FORWARD +* go.PLAYBACK_ONCE_BACKWARD +* go.PLAYBACK_ONCE_PINGPONG +* go.PLAYBACK_LOOP_FORWARD +* go.PLAYBACK_LOOP_BACKWARD +* go.PLAYBACK_LOOP_PINGPONG diff --git a/docs/zh/manuals/property-animation.md b/docs/zh/manuals/property-animation.md new file mode 100644 index 00000000..ff43811f --- /dev/null +++ b/docs/zh/manuals/property-animation.md @@ -0,0 +1,181 @@ +--- +title: Defold 中的属性动画 +brief: 本教程介绍了如何在 Defold 中使用属性动画. +--- + +# 属性动画 + +数值类的属性 (numbers, vector3, vector4 和 quaterions) 以及着色器常量都可以由内置的属性动画系统制作属性动画, 即使用 `go.animate()` 函数. 引擎会在属性值之间进行 "补间" 依照指定的播放和缓动模式进行播放. 你也可以自定义缓动函数. + +![Property animation](images/animation/property_animation.png){.inline srcset="images/animation/property_animation@2x.png 2x"} +![Bounce loop](images/animation/bounce.gif){.inline} + +## 属性动画 + +制作游戏对象或者组件的属性动画, 可以使用函数 `go.animate()`. 对于 GUI 节点属性, 可以使用函数 `gui.animate()`. + +```lua +-- 设置 y 轴位置为 200 +go.set(".", "position.y", 200) +-- 制作动画 +go.animate(".", "position.y", go.PLAYBACK_LOOP_PINGPONG, 100, go.EASING_OUTBOUNCE, 2) +``` + +停止某个属性的所有动画, 调用 `go.cancel_animations()`, 对于 GUI 节点, 调用 `gui.cancel_animation()`: + +```lua +-- 停止当前游戏对象欧拉 z 轴旋转动画 +go.cancel_animation(".", "euler.z") +``` + +如果取消组合属性的动画, 例如 `position`, 其所有子属性 (`position.x`, `position.y` 和 `position.z`) 动画也会一同取消. + +[属性教程](/manuals/properties) 涵盖游戏对象, 组件和 GUI 节点的所有属性. + + +## GUI 节点属性动画 + +几乎所有 GUI 节点属性都可以制作动画. 比如说, 把一个节点的 `color` 设置成透明看不见然后制作属性动画到全白使其可见 (也就是没有染色). + +```lua +local node = gui.get_node("button") +local color = gui.get_color(node) +-- 节点白色动画 +gui.animate(node, gui.PROP_COLOR, vmath.vector4(1, 1, 1, 1), gui.EASING_INOUTQUAD, 0.5) +-- 边框红色动画 +gui.animate(node, "outline.x", 1, gui.EASING_INOUTQUAD, 0.5) +-- 位置延 x 轴移动 100 像素动画 +gui.animate(node, hash("position.x"), 100, gui.EASING_INOUTQUAD, 0.5) +``` + +## 播放完成回调函数 + +动画函数 (`go.animate()` 和 `gui.animate()`) 可以在最后一个参数上传入Lua回调函数. 当动画播放完成时会调用这个函数. 对于循环动画, 不会调用回调函数, 也不能通过调用 `go.cancel_animations()` or `gui.cancel_animation()` 取消动画. 动画播放完成的回调函数里可以发送消息或者继续播放其他动画. + +## 缓动 + +缓动决定动画基于时间的变化. 下面列出了内置的缓动函数. + +以下可用于 `go.animate()` 函数: + +|---|---| +| go.EASING_LINEAR | | +| go.EASING_INBACK | go.EASING_OUTBACK | +| go.EASING_INOUTBACK | go.EASING_OUTINBACK | +| go.EASING_INBOUNCE | go.EASING_OUTBOUNCE | +| go.EASING_INOUTBOUNCE | go.EASING_OUTINBOUNCE | +| go.EASING_INELASTIC | go.EASING_OUTELASTIC | +| go.EASING_INOUTELASTIC | go.EASING_OUTINELASTIC | +| go.EASING_INSINE | go.EASING_OUTSINE | +| go.EASING_INOUTSINE | go.EASING_OUTINSINE | +| go.EASING_INEXPO | go.EASING_OUTEXPO | +| go.EASING_INOUTEXPO | go.EASING_OUTINEXPO | +| go.EASING_INCIRC | go.EASING_OUTCIRC | +| go.EASING_INOUTCIRC | go.EASING_OUTINCIRC | +| go.EASING_INQUAD | go.EASING_OUTQUAD | +| go.EASING_INOUTQUAD | go.EASING_OUTINQUAD | +| go.EASING_INCUBIC | go.EASING_OUTCUBIC | +| go.EASING_INOUTCUBIC | go.EASING_OUTINCUBIC | +| go.EASING_INQUART | go.EASING_OUTQUART | +| go.EASING_INOUTQUART | go.EASING_OUTINQUART | +| go.EASING_INQUINT | go.EASING_OUTQUINT | +| go.EASING_INOUTQUINT | go.EASING_OUTINQUINT | + +以下可用于 `gui.animate()` 函数: + +|---|---| +| gui.EASING_LINEAR | | +| gui.EASING_INBACK | gui.EASING_OUTBACK | +| gui.EASING_INOUTBACK | gui.EASING_OUTINBACK | +| gui.EASING_INBOUNCE | gui.EASING_OUTBOUNCE | +| gui.EASING_INOUTBOUNCE | gui.EASING_OUTINBOUNCE | +| gui.EASING_INELASTIC | gui.EASING_OUTELASTIC | +| gui.EASING_INOUTELASTIC | gui.EASING_OUTINELASTIC | +| gui.EASING_INSINE | gui.EASING_OUTSINE | +| gui.EASING_INOUTSINE | gui.EASING_OUTINSINE | +| gui.EASING_INEXPO | gui.EASING_OUTEXPO | +| gui.EASING_INOUTEXPO | gui.EASING_OUTINEXPO | +| gui.EASING_INCIRC | gui.EASING_OUTCIRC | +| gui.EASING_INOUTCIRC | gui.EASING_OUTINCIRC | +| gui.EASING_INQUAD | gui.EASING_OUTQUAD | +| gui.EASING_INOUTQUAD | gui.EASING_OUTINQUAD | +| gui.EASING_INCUBIC | gui.EASING_OUTCUBIC | +| gui.EASING_INOUTCUBIC | gui.EASING_OUTINCUBIC | +| gui.EASING_INQUART | gui.EASING_OUTQUART | +| gui.EASING_INOUTQUART | gui.EASING_OUTINQUART | +| gui.EASING_INQUINT | gui.EASING_OUTQUINT | +| gui.EASING_INOUTQUINT | gui.EASING_OUTINQUINT | + +![Linear interpolation](images/properties/easing_linear.png){.inline} +![In back](images/properties/easing_inback.png){.inline} +![Out back](images/properties/easing_outback.png){.inline} +![In-out back](images/properties/easing_inoutback.png){.inline} +![Out-in back](images/properties/easing_outinback.png){.inline} +![In bounce](images/properties/easing_inbounce.png){.inline} +![Out bounce](images/properties/easing_outbounce.png){.inline} +![In-out bounce](images/properties/easing_inoutbounce.png){.inline} +![Out-in bounce](images/properties/easing_outinbounce.png){.inline} +![In elastic](images/properties/easing_inelastic.png){.inline} +![Out elastic](images/properties/easing_outelastic.png){.inline} +![In-out elastic](images/properties/easing_inoutelastic.png){.inline} +![Out-in elastic](images/properties/easing_outinelastic.png){.inline} +![In sine](images/properties/easing_insine.png){.inline} +![Out sine](images/properties/easing_outsine.png){.inline} +![In-out sine](images/properties/easing_inoutsine.png){.inline} +![Out-in sine](images/properties/easing_outinsine.png){.inline} +![In exponential](images/properties/easing_inexpo.png){.inline} +![Out exponential](images/properties/easing_outexpo.png){.inline} +![In-out exponential](images/properties/easing_inoutexpo.png){.inline} +![Out-in exponential](images/properties/easing_outinexpo.png){.inline} +![In circlic](images/properties/easing_incirc.png){.inline} +![Out circlic](images/properties/easing_outcirc.png){.inline} +![In-out circlic](images/properties/easing_inoutcirc.png){.inline} +![Out-in circlic](images/properties/easing_outincirc.png){.inline} +![In quadratic](images/properties/easing_inquad.png){.inline} +![Out quadratic](images/properties/easing_outquad.png){.inline} +![In-out quadratic](images/properties/easing_inoutquad.png){.inline} +![Out-in quadratic](images/properties/easing_outinquad.png){.inline} +![In cubic](images/properties/easing_incubic.png){.inline} +![Out cubic](images/properties/easing_outcubic.png){.inline} +![In-out cubic](images/properties/easing_inoutcubic.png){.inline} +![Out-in cubic](images/properties/easing_outincubic.png){.inline} +![In quartic](images/properties/easing_inquart.png){.inline} +![Out quartic](images/properties/easing_outquart.png){.inline} +![In-out quartic](images/properties/easing_inoutquart.png){.inline} +![Out-in quartic](images/properties/easing_outinquart.png){.inline} +![In quintic](images/properties/easing_inquint.png){.inline} +![Out quintic](images/properties/easing_outquint.png){.inline} +![In-out quintic](images/properties/easing_inoutquint.png){.inline} +![Out-in quintic](images/properties/easing_outinquint.png){.inline} + +## 自定义缓动 + +可以使用 `vector` 和其中的一系列值代替预置缓动函数. 矢量值从 (`0`) 过渡到 (`1`). 引擎会从矢量中取样并自动线性插值生成缓动曲线. + +示例如下: + +```lua +local values = { 0, 0.4, 0.2, 0.2, 0.5. 1 } +local my_easing = vmath.vector(values) +``` + +生成的缓动曲线如下: + +![Custom curve](images/animation/custom_curve.png) + +下面的例子是让游戏对象的 y 轴位置依照自定义曲线从当前位置到 200 来回跳跃: + +```lua +local values = { 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1 } +local square_easing = vmath.vector(values) +go.animate("go", "position.y", go.PLAYBACK_LOOP_PINGPONG, 200, square_easing, 2.0) +``` + +![Square curve](images/animation/square_curve.png) diff --git a/docs/zh/manuals/spine.md b/docs/zh/manuals/spine.md index 0d5c0edf..c5946fc6 100644 --- a/docs/zh/manuals/spine.md +++ b/docs/zh/manuals/spine.md @@ -7,6 +7,9 @@ brief: 本教程介绍了如何通过 _Spine_ 或者 _Dragon Bone_ 把骨骼动 _Spine_ 是由 Esoteric Software 开发的第三方动画工具, 可以让你使用 _骨骼_ 绑定的技术创建动画. 这对于角色或者动物动画非常方便, 对制作其他动画也很有帮助, 比如绳子, 车辆或者树叶. +![Spine animation](images/animation/spine_animation.png){.inline} +![Run loop](images/animation/frog_runloop.gif){.inline} + Defold 实现了 [Spine JSON 格式](http://esotericsoftware.com/spine-json-format) 的运行时和动画表达. Defold 支持了主要的 Spine 动画功能, 包括反向运动学 (IK). @@ -79,7 +82,7 @@ Spine Json Atlas : Spine 动画需要的图集. -## 创建 SpineModel 组件 +## 创建 Spine model 组件 创建并配置好 _Spine scene_ 之后, 就可以创建 SpineModel 组件了. 详情请见 [SpineModel 教程](/manuals/spinemodel). @@ -88,8 +91,144 @@ Atlas 在 GUI 场景也可以使用 Spine 动画. 详情请见 [GUI spine 教程](/manuals/gui-spine). ## 播放 Spine 动画 +在 Spine 模型上播放动画, 只需调用 [`spine.play_anim()`](/ref/spine#spine.play_anim) 函数: + +```lua +local function anim_done(self) + -- 动画播放完成, 做其他事情... +end + +function init(self) + -- 在 "spinemodel" 组件上播放 "walk" 动画同时与上一个动画 + -- 在前 0.1 内混合, 然后进行回调. + local anim_props = { blend_duration = 0.1 } + spine.play_anim("#spinemodel", "run", go.PLAYBACK_LOOP_FORWARD, anim_props, anim_done) +end +``` + +![Spine model in game](images/animation/spine_ingame.png){srcset="images/animation/spine_ingame@2x.png 2x"} + +如果动画是以 `go.PLAYBACK_ONCE_*` 模式播放, 然后在 `spine.play_anim()` 里指定回调函数, 则动画播放完成后会调用回调函数. 关于回调函数详见下文. + +### 播放头 + +除了 `spine.play_anim()` 还有更高级的方法, *Spine Model* 组件暴露了一个 "cursor" 属性可以通过 `go.animate()` 进行控制: + +```lua +-- 设置 spine model 动画但是不播放. +spine.play_anim("#spinemodel", "run_right", go.PLAYBACK_NONE) + +-- 设置播放头为 0 +go.set("#spinemodel", "cursor", 0) + +-- 基于 in-out quad 缓动慢慢对播放头进行从 0 到 1 的 pingpong 补间. +go.animate("#spinemodel", "cursor", go.PLAYBACK_LOOP_PINGPONG, 1, go.EASING_INOUTQUAD, 6) +``` + +::: 注意 +补间和设置播放头时, 时间轴事件不会被触发. +::: + +### 骨骼层级 + +Spine 骨架的各个骨骼实例在游戏对象内展示出来. 在 Spine model 组件的 *Outline* 视图内, 可以看到完整的嵌套关系. 在此层级嵌套关系中你可以看到骨骼的名称和其所在的位置. + +![Spine model hierarchy](images/animation/spine_bones.png){srcset="images/animation/spine_bones@2x.png 2x"} + +通过骨骼名称, 就可以在运行时得到骨骼实例. 函数 [`spine.get_go()`](/ref/spine#spine.get_go) 返回指定骨骼的 id, 然后就可以用来进行设置父级之类的操作: + +```lua +-- 把手枪绑定到英雄手上 +local hand = spine.get_go("heroine#spinemodel", "front_hand") +msg.post("pistol", "set_parent", { parent_id = hand }) +``` + +### 时间轴事件 + +Spine 动画可以基于精确的时间触发事件. 对于需要做同步行为的功能非常有帮助, 例如播放走路声音, 场景粒子效果, 在骨骼层级上进行绑定和解绑或者实现你需要的其他功能. + +在 Spine 软件里可以使用时间轴设置事件: + +![Spine events](images/animation/spine_events.png) + +各种事件由事件 id 表示 (上例中是 "bump") 而且时间轴上的事件可以包含一些数据: + +Integer +: 整数值. + +Float +: 浮点数值. + +String +: 字符串值. + +动画播放遇到事件时, `spine_event` 消息会被发回到调用 `spine.play()` 函数的脚本上. 消息数据参数就是事件附带的数据, 连同其他一些有用的数据: + +`t` +: 自动画播放第一帧开始经过的时间. + +`animation_id` +: 动画名, 哈希值. + +`string` +: 事件附带字符串值, 哈希值. + +`float` +: 事件附带浮点数值. + +`integer` +: 事件附带整数值. + +`event_id` +: 事件 id, 哈希值. + +`blend_weight` +: 此时动画混合情况. 0 表示动画还没有被混合, 1 当前动画混合 100%. + +```lua +-- Spine 动画包含与动画同步的音效. +-- 作为消息传到这里. +function on_message(self, message_id, message, sender) + if message_id == hash("spine_event") and message.event_id == hash("play_sound") then + -- 播放动画音效. 事件数据包括声音组件和声音增益. + local url = msg.url("sounds") + url.fragment = message.string + sound.play(url, { gain = message.float }) + end +end +`````` + +## 播放完成回调函数 + +动画播放函数 `spine.play_anim()` 可以在最后一个参数上传入Lua回调函数. 当动画播放完成时会调用这个函数. 对于循环动画, 不会调用回调函数, 也不能通过调用 `go.cancel_animations()` or `gui.cancel_animation()` 取消动画. 动画播放完成的回调函数里可以发送消息或者继续播放其他动画. + +```lua +local function anim_done(self) + -- 播放完成, 做点什么... +end + +function init(self) + -- 在组件 "spinemodel" 上播放 "walk" 并且与上个动画 + -- 进行 0.1 秒的混合, 然后调用回调函数. + local anim_props = { blend_duration = 0.1 } + spine.play_anim("#spinemodel", "run", go.PLAYBACK_LOOP_FORWARD, anim_props, anim_done) +end +``` + +## 播放模式 + +动画可以单次播放也可以循环播放. 取决于播放模式: + +* go.PLAYBACK_NONE +* go.PLAYBACK_ONCE_FORWARD +* go.PLAYBACK_ONCE_BACKWARD +* go.PLAYBACK_ONCE_PINGPONG +* go.PLAYBACK_LOOP_FORWARD +* go.PLAYBACK_LOOP_BACKWARD +* go.PLAYBACK_LOOP_PINGPONG + +pingpong 模式先正向播放, 再反向播放. -Defold 通过 Lua 接口实现了全方位控制 Spine 动画播放的运行环境. 详情请见 [动画教程](/manuals/animation). ## 图集相关注意事项 diff --git a/docs/zh/manuals/spinemodel.md b/docs/zh/manuals/spinemodel.md index 0fff891e..e96f4013 100644 --- a/docs/zh/manuals/spinemodel.md +++ b/docs/zh/manuals/spinemodel.md @@ -47,28 +47,14 @@ SpineModel 组件用于把 _Spine_ 骨骼动画在 Defold 中呈现出来. ### 运行时动画 -Defold 提供运行时控制动画的功能: - -```lua -local play_properties = { blend_duration = 0.1 } -spine.play_anim("#spinemodel", "jump", go.PLAYBACK_ONCE_FORWARD, play_properties) -``` - -可以手动播放动画甚至使用属性动画系统控制播放头: - -```lua --- set the run animation -spine.play_anim("#spinemodel", "run", go.PLAYBACK_NONE) --- animate the cursor -go.animate("#spinemodel", "cursor", go.PLAYBACK_LOOP_PINGPONG, 1, go.EASING_LINEAR, 10) -``` +Defold 提供强大的运行时控制动画的功能, 参见 [spine 动画教程](/manuals/spine). ### 修改属性 Spine模型可以使用 `go.get()` 和 `go.set()` 方法修改其属性: `animation` -: 当前Spine模型动画 (`hash`) (只读). 使用 `spine.play_anim()` 方法来更改播放动画 (见上文). +: 当前Spine模型动画 (`hash`) (只读). 使用 `spine.play_anim()` 方法来更改播放动画 (参见 [spine 动画教程](/manuals/spine)). `cursor` : 标准化动画头 (`number`). From 3fd48b07a4d6aa953cc0c8e2d053e5336b9e7e39 Mon Sep 17 00:00:00 2001 From: COCO Date: Tue, 16 Mar 2021 18:47:54 +0800 Subject: [PATCH 018/134] animation fix --- docs/zh/manuals/flipbook-animation.md | 2 +- docs/zh/manuals/model-animation.md | 2 +- docs/zh/manuals/property-animation.md | 2 +- docs/zh/manuals/spine.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/zh/manuals/flipbook-animation.md b/docs/zh/manuals/flipbook-animation.md index b52ae9cc..d8280c6c 100644 --- a/docs/zh/manuals/flipbook-animation.md +++ b/docs/zh/manuals/flipbook-animation.md @@ -88,7 +88,7 @@ end ## 播放完成回调函数 -动画函数 (`sprite.play_flipbook()` 和 `gui.play_flipbook()`) 可以在最后一个参数上传入Lua回调函数. 当动画播放完成时会调用这个函数. 对于循环动画, 和使用 `go.cancel_animations()` 手动取消播放的动画, 不会调用回调函数. 动画播放完成的回调函数里可以发送消息或者继续播放其他动画. 例如: +动画函数 (`sprite.play_flipbook()` 和 `gui.play_flipbook()`) 可以在最后一个参数上传入Lua回调函数. 当动画播放完成时会调用这个函数. 对于循环动画和用 `go.cancel_animations()` 手动取消播放的动画, 不会调用回调函数. 动画播放完成的回调函数里可以发送消息或者继续播放其他动画. 例如: ```lua local function flipbook_done(self) diff --git a/docs/zh/manuals/model-animation.md b/docs/zh/manuals/model-animation.md index 4d96fd1a..061d2114 100644 --- a/docs/zh/manuals/model-animation.md +++ b/docs/zh/manuals/model-animation.md @@ -61,7 +61,7 @@ go.animate("#model", "cursor", go.PLAYBACK_LOOP_PINGPONG, 1, go.EASING_INOUTQUAD ## 播放完成回调函数 -动画函数 `model.play_anim()` 可以在最后一个参数上传入Lua回调函数. 当动画播放完成时会调用这个函数. 对于循环动画, 和使用 `go.cancel_animations()` 手动取消播放的动画, 不会调用回调函数. 动画播放完成的回调函数里可以发送消息或者继续播放其他动画. 例如: +动画函数 `model.play_anim()` 可以在最后一个参数上传入Lua回调函数. 当动画播放完成时会调用这个函数. 对于循环动画和用 `go.cancel_animations()` 手动取消播放的动画, 不会调用回调函数. 动画播放完成的回调函数里可以发送消息或者继续播放其他动画. 例如: ```lua local function wiggle_done(self, message_id, message, sender) diff --git a/docs/zh/manuals/property-animation.md b/docs/zh/manuals/property-animation.md index ff43811f..82a4e619 100644 --- a/docs/zh/manuals/property-animation.md +++ b/docs/zh/manuals/property-animation.md @@ -50,7 +50,7 @@ gui.animate(node, hash("position.x"), 100, gui.EASING_INOUTQUAD, 0.5) ## 播放完成回调函数 -动画函数 (`go.animate()` 和 `gui.animate()`) 可以在最后一个参数上传入Lua回调函数. 当动画播放完成时会调用这个函数. 对于循环动画, 不会调用回调函数, 也不能通过调用 `go.cancel_animations()` or `gui.cancel_animation()` 取消动画. 动画播放完成的回调函数里可以发送消息或者继续播放其他动画. +动画函数 (`go.animate()` 和 `gui.animate()`) 可以在最后一个参数上传入Lua回调函数. 当动画播放完成时会调用这个函数. 对于循环动画和用 `go.cancel_animations()` 或 `gui.cancel_animation()` 取消的动画,不会调用回调函数. 回调函数里可以发送消息或者继续播放其他动画. ## 缓动 diff --git a/docs/zh/manuals/spine.md b/docs/zh/manuals/spine.md index c5946fc6..ac9f3147 100644 --- a/docs/zh/manuals/spine.md +++ b/docs/zh/manuals/spine.md @@ -200,7 +200,7 @@ end ## 播放完成回调函数 -动画播放函数 `spine.play_anim()` 可以在最后一个参数上传入Lua回调函数. 当动画播放完成时会调用这个函数. 对于循环动画, 不会调用回调函数, 也不能通过调用 `go.cancel_animations()` or `gui.cancel_animation()` 取消动画. 动画播放完成的回调函数里可以发送消息或者继续播放其他动画. +动画播放函数 `spine.play_anim()` 可以在最后一个参数上传入Lua回调函数. 当动画播放完成时会调用这个函数. 对于循环动画和用 `spine.cancel()` 取消的动画不会调用回调函数. 回调函数里可以发送消息或者继续播放其他动画. ```lua local function anim_done(self) From 02e229572416b9b55a01d751e90bd7f02c3896fa Mon Sep 17 00:00:00 2001 From: COCO Date: Mon, 5 Apr 2021 16:35:42 +0800 Subject: [PATCH 019/134] run as admin --- docs/zh/shared/windows-faq.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/zh/shared/windows-faq.md b/docs/zh/shared/windows-faq.md index 40683ab9..7b72c27a 100644 --- a/docs/zh/shared/windows-faq.md +++ b/docs/zh/shared/windows-faq.md @@ -1,3 +1,7 @@ #### Q: 为什么编辑器中无纹理的 GUI box 节点透明显示, 但是构建运行后能正常显示? A: 这个错误发生在 [使用 AMD Radeon GPU 的机器](https://github.com/defold/editor2-issues/issues/2723) 上. 注意更新显卡驱动. + +#### Q: 打开图集或者场景视图时报错 'com.sun.jna.Native.open.class java.lang.Error: Access is denied'? + +A: 试试以管理员身份打开 Defold. 右键点击 Defold 可执行程序选择 "以管理员身份运行". From 36a405cda5e37d3a4714dcbc678b3ec7201b81b5 Mon Sep 17 00:00:00 2001 From: COCO Date: Wed, 7 Apr 2021 11:21:30 +0800 Subject: [PATCH 020/134] update bob --- docs/zh/manuals/bob.md | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/docs/zh/manuals/bob.md b/docs/zh/manuals/bob.md index cd655078..6ef58da0 100644 --- a/docs/zh/manuals/bob.md +++ b/docs/zh/manuals/bob.md @@ -19,7 +19,7 @@ Bob 运行于命令行界面 `java` (再Windows上是 `java.exe`) 后跟bob的ja $ java -jar bob.jar --help usage: bob [options] [commands] -a,--archive 编译数据包 - -ar,--architectures 逗号分割发布架构 + -ar,--architectures 逗号分割发布架构, 例如 "arm64-android,armv7-android" --binary-output 指定可执行文件存放地址 默认地址是 @@ -94,7 +94,7 @@ usage: bob [options] [commands] `resolve` : 解析所有外部依赖库. -可用平台: +支持平台和架构: `x86_64-darwin` : macOS 64 bit @@ -108,20 +108,16 @@ usage: bob [options] [commands] `x86_64-linux` : Linux 64 bit -`arm64-darwin` -: iOS 64 bit +`x86_64-ios` +: iOS macOS 64 bit (iOS 模拟器) `armv7-darwin` -: iOS 32 bit - -`x86_64-ios` -: iOS macOS 64 bit (iOS Simulator) +: iOS 支持 32-bit `armv7-darwin` 和 64-bit `arm64-darwin` 架构. 默认情况下, `--architectures` 参数值为 `armv7-darwin,arm64-darwin`. `armv7-android` -: Android 32 bit +: Android 支持 32 bit `armv7-android` 和 64 bit `arm64-android` 架构. 默认情况下, `--architectures` 参数值为 `armv7-android,arm64-android`. -`js-web` -: HTML5 +`js-web` : HTML5 支持 `js-web` 和 `wasm-web` 架构. 默认情况下, `--architectures` 参数值为 `js-web,wasm-web`. 默认情况下, Bob 在当前目录下寻找项目来编译. 切换到 Defold 项目目录下使用 bob, 它会把数据编译到默认输出 *build/default* 目录下. From 3cd24c6e56b378d6ce86d043da3e1ed2a7a72502 Mon Sep 17 00:00:00 2001 From: COCO Date: Sun, 11 Apr 2021 19:20:52 +0800 Subject: [PATCH 021/134] update about AndroidX support --- docs/zh/manuals/android.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/zh/manuals/android.md b/docs/zh/manuals/android.md index 380e7a80..4a9a3703 100644 --- a/docs/zh/manuals/android.md +++ b/docs/zh/manuals/android.md @@ -142,13 +142,13 @@ D/defold ( 6210): DEBUG:SCRIPT: Hello there, log! ## 使用 AndroidX -AndroidX 一個較大改動就是, 不再維護 Android Support Library 了. AndroidX 應用使用雲計算功能和新庫完整取代了 Support Library. [Asset Portal](/assets) 裏的許多擴展包已經支持 AndroidX 并且隨著時間推移以前依賴 Android Support Library 將會全部支持 AndroidX. 在使用支持 AndroidX 的擴展包時要記得在先你的項目中開啓 AndroidX 支持: +AndroidX 一個較大改動就是, 不再維護 Android Support Library 了. AndroidX 應用使用雲計算功能和新庫完整取代了 Support Library. [Asset Portal](/assets) 裏的绝大多数擴展包已經支持 AndroidX. 如果希望使用旧版安卓库而不是 AndroidX, 可以主动关闭它: -1. 如果已存在應用清單文件要在 `armv7-android` 和 `arm64-android` 裏加入 `jetifier: true`. +1. 如果已存在應用清單文件要在 `armv7-android` 和 `arm64-android` 裏加入 `jetifier: false`. -2. 如果還沒有應用清單文件可以去 [Defold App Manifest generator](https://britzl.github.io/manifestation/) 生成一個, 記得勾選 AndroidX 選項. +2. 如果還沒有應用清單文件可以去 [Defold App Manifest generator](https://britzl.github.io/manifestation/) 生成一個, 記得勾選 "Use Android Support lib" 選項. -![](images/android/enable_androidx.png) +![](images/android/enable_supportlibrary.png) ## 常见问题 From 447cd3e1efaf497152fe777a483a2bf31d16dd53 Mon Sep 17 00:00:00 2001 From: COCO Date: Tue, 13 Apr 2021 11:48:05 +0800 Subject: [PATCH 022/134] software render --- docs/zh/shared/linux-faq.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/zh/shared/linux-faq.md b/docs/zh/shared/linux-faq.md index 5bb2ffee..10e85c2b 100644 --- a/docs/zh/shared/linux-faq.md +++ b/docs/zh/shared/linux-faq.md @@ -40,6 +40,15 @@ $ ./Defold ``` +#### Q: 我的 OpenGL 驱动过期了. 还能用 Defold 吗? + +A: 能用, 但是需要打开 Defold 软件渲染. 可以设置环境变量 LIBGL_ALWAYS_SOFTWARE 值为 1: + +```bash +~/bin/Defold$ LIBGL_ALWAYS_SOFTWARE=1 ./Defold +``` + + #### Q: 在 Ubuntu 20.04 上運行 Defold 報錯 "com.jogamp.opengl.GLException: Graphics configuration failed" ? A: 這個版本在運行 Defold 時會出現新驅動程序 (Iris) 問題. 可以嘗試使用舊版本驅動程序: From b288a366899924517c89dce9239a27fca95fe403 Mon Sep 17 00:00:00 2001 From: COCO Date: Sat, 24 Apr 2021 10:56:50 +0800 Subject: [PATCH 023/134] linux-faq.md update --- docs/zh/shared/linux-faq.md | 68 +++++++++++++++++++++++++------------ 1 file changed, 47 insertions(+), 21 deletions(-) diff --git a/docs/zh/shared/linux-faq.md b/docs/zh/shared/linux-faq.md index 10e85c2b..4c9ea671 100644 --- a/docs/zh/shared/linux-faq.md +++ b/docs/zh/shared/linux-faq.md @@ -4,6 +4,7 @@ A: 启动 Defold 之前修改缩放参数. [参见](https://unix.stackexchange.c ```bash $ gsettings set org.gnome.desktop.interface scaling-factor 2 +$ ./Defold ``` @@ -16,52 +17,77 @@ $ GTK_CSD=0 ./Defold ``` -#### Q: 在新建, 打开项目时 Defold 编辑器崩溃? +#### Q: 在 Defold 编辑器里打开集合或者游戏对象时崩溃报关于 "com.jogamp.opengl" 的错误. + +A: 某些Linux版本 (如 Ubuntu 18) 下 [Mesa](https://docs.mesa3d.org/) 版所使用的 jogamp/jogl Defold 版本有冲突. +可以在调用 `glGetString(GL_VERSION)` 是设置`MESA_GL_VERSION_OVERRIDE` 为2.1或者更高的值以覆盖 GL 默认的驱动版本. +可以使用如下命令查看系统上支持 `glxinfo` 的最高 OpenGL 版本: + +```bash +glxinfo | grep version +``` -A: 某些版本 (比如 Ubuntu 18) 上 Defold 使用的 jogamp/jogl 版本与系统 Mesa 版本冲突. +输出举例 (注意 "OpenGL version string: x.y"): -详情请见: +``` +server glx version string: 1.4 +client glx version string: 1.4 +GLX version: 1.4 +Max core profile version: 4.6 +Max compat profile version: 4.6 +Max GLES1 profile version: 1.1 +Max GLES[23] profile version: 3.2 +OpenGL core profile version string: 4.6 (Core Profile) Mesa 20.2.6 +OpenGL core profile shading language version string: 4.60 +OpenGL version string: 4.6 (Compatibility Profile) Mesa 20.2.6 +OpenGL shading language version string: 4.60 +OpenGL ES profile version string: OpenGL ES 3.2 Mesa 20.2.6 +OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.20 +GL_EXT_shader_implicit_conversions, GL_EXT_shader_integer_mix, +``` - - https://github.com/defold/editor2-issues/issues/1905 - - https://github.com/defold/editor2-issues/issues/1886 +使用版本 2.1 或者更高的匹配显卡的版本: -使用如下代码可以绕过冲突: +```bash +$ MESA_GL_VERSION_OVERRIDE=2.1 ./Defold +``` ```bash -$ export MESA_GL_VERSION_OVERRIDE=2.1 -$ ./Defold +$ MESA_GL_VERSION_OVERRIDE=4.6 ./Defold ``` -如果问题没有解决可以尝试 (根据你自己的驱动匹配选取大于等于 2.1 的版本号): + +A: 某些Linux版本 (如 Ubuntu 20.04) 在運行 Defold 時會出現新的 [Mesa](https://docs.mesa3d.org/) 驅動程序 (Iris) 的問題. 可以嘗試使用舊版本驅動程序: ```bash -$ export MESA_GL_VERSION_OVERRIDE=3.1 +$ export MESA_LOADER_DRIVER_OVERRIDE=i965 $ ./Defold ``` -#### Q: 我的 OpenGL 驱动过期了. 还能用 Defold 吗? +#### Q: 在 Defold 编辑器里打开集合或者游戏对象时崩溃报关于 "libffi.so" 的错误. -A: 能用, 但是需要打开 Defold 软件渲染. 可以设置环境变量 LIBGL_ALWAYS_SOFTWARE 值为 1: +A: 这是由于Linux系统的 [libffi](https://sourceware.org/libffi/) 版本与 Defold (版本 6 或 7) 需要的版本不一致. +确保 `libffi.so.6` 或 `libffi.so.7` 已安装在 `/usr/lib/x86_64-linux-gnu` 路径下. 可以使用如下命令下载 `libffi.so.7`: ```bash -~/bin/Defold$ LIBGL_ALWAYS_SOFTWARE=1 ./Defold +$ wget http://ftp.br.debian.org/debian/pool/main/libf/libffi/libffi7_3.3-5_amd64.deb +$ sudo dpkg -i libffi7_3.3-5_amd64.deb ``` - -#### Q: 在 Ubuntu 20.04 上運行 Defold 報錯 "com.jogamp.opengl.GLException: Graphics configuration failed" ? - -A: 這個版本在運行 Defold 時會出現新驅動程序 (Iris) 問題. 可以嘗試使用舊版本驅動程序: +然后需要在环境变量 `LD_PRELOAD` 中指定安装路径再启动 Defold: ```bash -$ export MESA_LOADER_DRIVER_OVERRIDE=i965 -$ ./Defold +$ LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libffi.so.7 ./Defold ``` -可能还需要指定载入 libffi 版本 6 才能启动 Defold: + +#### Q: 我的 OpenGL 驱动过期了. 还能用 Defold 吗? + +A: 能用, 但是需要打开 Defold 软件渲染. 可以设置环境变量 LIBGL_ALWAYS_SOFTWARE 值为 1: ```bash -$ export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libffi.so.6 +~/bin/Defold$ LIBGL_ALWAYS_SOFTWARE=1 ./Defold ``` From 2fde132116839fe6de70105a7582a5a827cb1550 Mon Sep 17 00:00:00 2001 From: COCO Date: Thu, 29 Apr 2021 15:21:54 +0800 Subject: [PATCH 024/134] 4.28.2021 updates --- docs/zh/manuals/bob.md | 65 +++++++++++++++-------------- docs/zh/manuals/physics-joints.md | 9 ++-- docs/zh/manuals/physics-shapes.md | 5 +-- docs/zh/manuals/project-settings.md | 7 +++- docs/zh/manuals/shader.md | 4 +- docs/zh/manuals/sound.md | 5 ++- 6 files changed, 52 insertions(+), 43 deletions(-) diff --git a/docs/zh/manuals/bob.md b/docs/zh/manuals/bob.md index 6ef58da0..522e9b72 100644 --- a/docs/zh/manuals/bob.md +++ b/docs/zh/manuals/bob.md @@ -18,63 +18,64 @@ Bob 运行于命令行界面 `java` (再Windows上是 `java.exe`) 后跟bob的ja ```text $ java -jar bob.jar --help usage: bob [options] [commands] - -a,--archive 编译数据包 + -a,--archive 编译数据包 -ar,--architectures 逗号分割发布架构, 例如 "arm64-android,armv7-android" - - --binary-output 指定可执行文件存放地址 + -u,--auth 作者認證標記 + --binary-output 指定可执行文件存放地址 默认地址是 "//" - -bo,--bundle-output 打包输出目录 -br,--build-report 指定编译报告的存放存放地址 报告为JSON格式 -brhtml,--build-report-html 指定编译报告的存放存放地址 报告为HTML格式 - --build-server 编译服务器 (当使用原生扩展 + --build-server 编译服务器 (当使用原生扩展 时使用) - -d,--debug 使用dmengine的debug版本(当 + -bo,--bundle-output 打包輸出目錄 + --bundle-format Android 打包格式 + -d,--debug 使用dmengine的debug版本(当 编译时). 弃用, 使用--variant 代替 - --defoldsdk 指定defold sdk (sha1) + --debug-ne-upload 把文件打包為upload.zip之後上傳到 + 編譯服務器 + --defoldsdk 指定defold sdk (sha1) 使用版本 - -e,--email 用户电邮 - -h,--help 帮助文档 - -i,--input 指定源目录, 默认是当前 + --exclude-build-folder 逗號分割的排除目錄列表 + -e,--email 用户电邮 + -h,--help 帮助文档 + -i,--input 指定源目录, 默认是当前 目录 - --identity 指定签名 (iOS) - -k,--keep-unused 指定未使用资源仍然打包 + --identity 指定签名 (iOS) + -k,--keep-unused 指定未使用资源仍然打包 输出 - -l,--liveupdate 要在发布后使用热更新功能 - 参数填yes - -mp,--mobileprovisioning 指定mobileprovisioning profile (iOS) - -o,--output 输出目录. 默认是 + --keystore Android 打包密鑰文件. + --keystore-pass Android 打包密鑰密碼文件路徑. + --keystore-alias Android 打包密鑰別名文件路徑. + -l,--liveupdate 要在发布后使用热更新功能 + 参数填 yes + -mp,--mobileprovisioning 指定 mobileprovisioning profile (iOS) + -o,--output 输出目录. 默认是 "build/default" - -p,--platform 发布平台 (打包时) - -r,--root 指定编译目录. 默认是 + -p,--platform 发布平台 (打包时) + -r,--root 指定编译目录. 默认是 当前目录 - --settings 指定项目设置文件的 + --settings 指定项目设置文件的 路径. 可以使用多个 文件. 设置根据文件 从左到右应用. - --strip-executable 去掉dmengine的debug信息 + --strip-executable 去掉dmengine的debug信息 (编译 iOS 或 Android时) -tc,--texture-compression 使用纹理档中指定的 纹理压缩 -tp,--texture-profiles 使用纹理压缩档 (弃用) - -u,--auth 用户auth符 - --use-vanilla-lua 只使用 vanilla 源代码 (即 + --use-vanilla-lua 只使用 vanilla 源代码 (即 不要字节码) - -v,--verbose 冗余输出 - --variant 指定使用 debug, release 或者 headless - dmengine的版本 (编译时) - --version 打印输出 + -v,--verbose 冗余输出 + --variant 指定使用 debug, release 或者 headless + 的dmengine版本 (编译时) + --version 打印输出 版本号 - --with-symbols 生成标记文件 (如果 + --with-symbols 生成标记文件 (如果 可用) - --bundle-format 使用哪种格式打 Android 包. - --keystore 使用哪个密匙注册 - Android 包. - --keystore-pass 密匙密码路径用于打 Android 包. - --keystore-alias 密匙别名用于打 Android 包. ``` 支持的命令: diff --git a/docs/zh/manuals/physics-joints.md b/docs/zh/manuals/physics-joints.md index 9ca1ea33..c76b50fb 100644 --- a/docs/zh/manuals/physics-joints.md +++ b/docs/zh/manuals/physics-joints.md @@ -7,10 +7,11 @@ brief: Defold 支持 2D 物理关节约束. 本教程介绍了其用法. Defold 支持物理关节. 一个关键基于某种限制连接两个物体. 支持的关节类型如下: -* Fixed (physics.JOINT_TYPE_FIXED) - 限制两物体最大距离的固定关节. 在 Box2D 被称为绳子关节. -* Hinge (physics.JOINT_TYPE_HINGE) - 把两个物体通过一个锚点钉在一起的钉子关节. 两物体相对位置固定而相对旋转没有限制. 这种关节可以开启马达给一个最大扭力与速度. 在 Box2D 被称为旋转关节. -* Spring (physics.JOINT_TYPE_SPRING) - 限制两个物体之间距离范围的弹簧关节. 弹簧关节通过设定其频率和阻尼比可以让物体像是被软弹簧连接. 在 Box2D 被称为距离关节. -* Slider (physics.JOINT_TYPE_SLIDER) - 限制两物体只能在某个指定轴上相对移动而不允许相对转动的滑动关节. 在 Box2D 被称为活塞关节. +* **Fixed (physics.JOINT_TYPE_FIXED)** - 限制两物体最大距离的固定关节. 在 Box2D 被称为绳子关节. +* **Hinge (physics.JOINT_TYPE_HINGE)** - 把两个物体通过一个锚点钉在一起的钉子关节. 两物体相对位置固定而相对旋转没有限制. 这种关节可以开启马达给一个最大扭力与速度. 在 Box2D 被称为旋转关节. +* **Weld (physics.JOINT_TYPE_WELD)** - 用於完全保持對象之間的位置關係的關節. 通過調整頻率和阻尼率軟化的焊接關節可以產生類似彈簧的效果. 在 Box2D 被称为焊接关节. +* **Spring (physics.JOINT_TYPE_SPRING)** - 限制两个物体之间距离范围的弹簧关节. 弹簧关节通过设定其频率和阻尼比可以让物体像是被软弹簧连接. 在 Box2D 被称为距离关节. +* **Slider (physics.JOINT_TYPE_SLIDER)** - 限制两物体只能在某个指定轴上相对移动而不允许相对转动的滑动关节. 在 Box2D 被称为活塞关节. ## 建立关节 diff --git a/docs/zh/manuals/physics-shapes.md b/docs/zh/manuals/physics-shapes.md index 384ea05d..4508d27a 100644 --- a/docs/zh/manuals/physics-shapes.md +++ b/docs/zh/manuals/physics-shapes.md @@ -36,7 +36,7 @@ brief: 碰撞对象的形状可以包含多个简单形状组成也可以由一 复杂形状可以由瓷砖地图生成或者使用凸多边形. ## 瓷砖地图碰撞形状 -Defold 包含一个功能就是从瓷砖地图中自动生成物理碰撞形状. [瓷砖地图教程](/manuals/tilemap/) 介绍了新建瓷砖图源的碰撞组与把瓷砖分配给碰撞组的 ([例子](/examples/tilemap/collisions/)). +Defold 包含一个功能就是从瓷砖地图中自动生成瓷磚圖源的物理碰撞形状. [瓷砖圖源教程](/manuals/tilesource/#tile-source-collision-shapes) 介绍了新建瓷砖图源的碰撞组与把瓷砖分配给碰撞组的 ([例子](/examples/tilemap/collisions/)). 在瓷砖地图上添加碰撞: @@ -63,8 +63,7 @@ Defold 有一个功能就是让你用3个或多个点建立凸多边形. 可以 # 缩放碰撞形状 - -可以让碰撞形状继承游戏对象的缩放. 在 *game.project* 里的物理部分勾选 [Allow Dynamic Transforms](/manuals/project-settings/#Allow Dynamic Transforms) 即可. 注意缩放继承只支持等比缩放, 如果不等比, 去三周最小值. +碰撞對象及其形狀繼承于游戲對象. 不想要該功能的話可以取消勾選 *game.project* 中物理部分下的 [Allow Dynamic Transforms](/manuals/project-settings/#allow-dynamic-transforms). 注意只有等比縮放受支持, 數值不等比的話以最小的一項數值為准. # 旋转碰撞形状 diff --git a/docs/zh/manuals/project-settings.md b/docs/zh/manuals/project-settings.md index e37b2682..8424a05d 100644 --- a/docs/zh/manuals/project-settings.md +++ b/docs/zh/manuals/project-settings.md @@ -140,10 +140,10 @@ debug线的不透明度, `0`--`1`. 默认是 `0.9`. 设定物理世界与游戏世界的数值映射比例, `0.01`--`1.0`. 如果设置为 `0.02`, 相当于物理引擎视50个游戏单位为1米 ($1 / 0.02$). 默认值是 `1.0`. #### Allow Dynamic Transforms -设定物理世界碰撞物体是否进行像游戏对象同等的缩放. +設置物理碰撞對象縮放是否繼承于其父級游戲對象. 默認為 `true`. #### Debug Scale -设置物理元物体画多大, 比如原向量和法线, 默认是`30`. +设置物理元物体画多大, 比如原向量和法线, 默认是 `30`. #### Max Collisions 设置向脚本报告多少个碰撞, 默认是 `64`. @@ -238,6 +238,9 @@ HTTP超时秒数. 设置为 `0` 则关闭超时, 默认关闭. #### Max Sound Instances 同一时间声音实例最大数目, 也就是实际同时播放声音最大数目. 默认是 `256`. +#### Use Thread +勾選的話, 系統將使用綫程進行聲音播放以減少因爲主綫程過載造成的卡頓. 默認勾選. + ## Sprite #### Max Count diff --git a/docs/zh/manuals/shader.md b/docs/zh/manuals/shader.md index 507aa014..93840314 100644 --- a/docs/zh/manuals/shader.md +++ b/docs/zh/manuals/shader.md @@ -186,6 +186,8 @@ void main() ## 深入学习 -- 著名着色器开源站 Shadertoy (https://www.shadertoy.com) 上有大量开发者开源着色器. 可以通过学习各种着色技术作为自己的灵感源泉. 其中很多着色器改改就能应用到 Defold 中去. [Shadertoy 教程](https://www.defold.com/tutorials/shadertoy/) 介绍了把网站着色器用于 Defold 的具体步骤. +- [Shadertoy](https://www.shadertoy.com) 上有大量开发者开源着色器. 可以通过学习各种着色技术作为自己的灵感源泉. 其中很多着色器改改就能应用到 Defold 中去. [Shadertoy 教程](https://www.defold.com/tutorials/shadertoy/) 介绍了把网站着色器用于 Defold 的具体步骤. - [渐变教程](https://www.defold.com/tutorials/grading/) 介绍了使用纹理采样进行全屏颜色渐变效果的编写方法. + +- [The Book of Shaders](https://thebookofshaders.com/00/) 介紹了將著色器應用於項目的方法, 有利於提高性能和視覺效果. diff --git a/docs/zh/manuals/sound.md b/docs/zh/manuals/sound.md index 9b5c7c91..bc236b79 100644 --- a/docs/zh/manuals/sound.md +++ b/docs/zh/manuals/sound.md @@ -27,7 +27,10 @@ Defold 支持声音但是不那么强大. 要注意两个概念: : 从项目中选择一个声音文件. 文件需要 _Wave_ 或者 _Ogg Vorbis_ 格式. Defold 支持 16bit 位深和 44100 采样率的声音文件. *Looping* -: 开启此选项声音会循环播放除非手动停止. +: 开启此选项声音会循环播放除非循環次數達到 _Loopcount_ 或者手动停止. + +*Loopcount* +: 停止前要循環播放的次數 (0 表示除非手動停止否則永遠循環). *Group* : 声音属于的组. 如果置空, 此声音默认归属 "master" 组. From adfa000421512163505b20ffe92ee645f88edada Mon Sep 17 00:00:00 2001 From: COCO Date: Sun, 2 May 2021 21:44:01 +0800 Subject: [PATCH 025/134] Basis Universal format --- docs/zh/manuals/texture-profiles.md | 63 ++++++++++++++--------------- 1 file changed, 30 insertions(+), 33 deletions(-) diff --git a/docs/zh/manuals/texture-profiles.md b/docs/zh/manuals/texture-profiles.md index cc169bfd..19f5f44a 100644 --- a/docs/zh/manuals/texture-profiles.md +++ b/docs/zh/manuals/texture-profiles.md @@ -17,10 +17,12 @@ Defold 可以自动把图片数据处理成纹理并进行压缩 (称为 *Atlas* 因为所有硬件压缩都是有损的, 纹理数据可能会不如压缩前好看. 造成这种现象的原因高度取决于材质和压缩算法. 为了得到最好的效果就需要多多尝试. 别忘了 Google 是你的好伙伴. -软件压缩方面可以在打包时选择如何保存纹理数据 (压缩或者原图). Defold 支持 WebP 和 ZLib (默认) 算法. WebP 支持有损无损两种方式, 通常比 ZLib 效果好, ZLib 效果一般. +软件压缩方面可以在打包时选择如何保存纹理数据 (压缩或者原图). Defold 支持 [基础通用](https://github.com/BinomialLLC/basis_universal) 纹理压缩, 它能把图片压缩为一个中间格式. 这种格式可以在运行时解码为适合硬件 GPU 使用的数据. +基础通用格式是高质量有损格式. +打包时还会使用 LZ4 算法进一步对图片进行压缩以减小包体. ::: 注意 -压缩属于资源密集型耗时操作, 图片多的话可以 _大大_ 增加编译时间. 就连选择纹理压缩格式和类型也非常耗时. +压缩属于资源密集型耗时操作, 图片多的话可以 _大大_ 增加编译时间, 还取决于你选择的纹理格式和压缩类型. ::: ## 纹理档案 @@ -79,7 +81,7 @@ Defold 可以自动把图片数据处理成纹理并进行压缩 (称为 *Atlas* : 指定平台. `OS_ID_GENERIC` 匹配所有平台, `OS_ID_WINDOWS` 对应 Windows 平台, `OS_ID_IOS` 对应 iOS 平台. 注意如果使用 `OS_ID_GENERIC`, 设定将会对所有平台生效. ::: 注意 -如果两个 [路径样式](#path-settings) 匹配一个文件并且这两个路径分别指定不同的平台, 那么这 **两个** 档案都会生效, 所以会生成 **两个** 纹理. +如果两个 [路径样式](#path-settings) 匹配一个文件并且这两个路径分别指定不同的平台, 那么这两个档案 **都会** 生效, 所以会生成 **两个** 纹理. ::: *Formats* @@ -109,12 +111,20 @@ Defold 可以自动把图片数据处理成纹理并进行压缩 (称为 *Atlas* 硬件可以直接处理未压缩纹理以及 *有损* 压缩纹理. 固定硬件压缩意思是纹理大小是一定的, 而不论纹理的内容. 一定意义上原图内容决定了硬件压缩后纹理的质量. -目前支持以下有损压缩. +因为基础通用压缩解码取决于设备的 GPU 功能, 推荐配合基础通用压缩的格式为: +`TEXTURE_FORMAT_RGB`, `TEXTURE_FORMAT_RGBA`, `TEXTURE_FORMAT_RGB_16BPP`, `TEXTURE_FORMAT_RGBA_16BPP`, `TEXTURE_FORMAT_LUMINANCE` 与 `TEXTURE_FORMAT_LUMINANCE_ALPHA`. - +基础通用压缩解码支持各种输出格式, 例如 `ASTC4x4`, `BCx`, `ETC2`, `ETC1` 与 `PVRTC1`. +更多更新详情请见 + +::: 注意 +为了引入基础通用编码器, 目前指定硬件输出格式关闭. + +如何同时支持这两种格式还在探索当中. +远期未来目标是引入内容管线插件来解决这个问题. +::: + +目前支持以下有损压缩格式: PVRTC : 也是一种图块压缩方法. 在4比特模式 (4BPP) 下每个图块 4×4 像素. 在2比特模式 (2BPP) 下每个图块 8×4 像素. 每个图块占用 64 比特 (8 字节) 内存空间. 这种格式原本用于 iPhone, iPod Touch, 和 iPad. 目前使用 PowerVR GPU 的 Android 设备, 也支持这种格式. Defold 支持 PVRTC1, 在格式id中用后缀 "V1" 表示. @@ -136,36 +146,23 @@ ETC | `TEXTURE_FORMAT_RGBA_PVRTC4BPPV1` | 1:8 固定. | 预乘 alpha. 正方形图片. 非正方形图片会被裁剪. | | `TEXTURE_FORMAT_RGB_ETC1` | 1:6 固定 | 无 alpha 通道. | - ## 压缩类型 支持以下软件压缩类型. 载入内存时需要解压. -| 类型 | 格式 | 描述 | +::: 注意 +目前 `WEBP` 压缩会回退为 `BASIS_UASTC` 压缩. + +如何同时支持这两种格式还在探索当中. +远期未来目标是引入内容管线插件来解决这个问题. +::: + +| Type | Formats | Note | | --------------------------------- | ------------------------- | ---- | -| `COMPRESSION_TYPE_DEFAULT` | 所有格式 | 简单无损压缩, 默认值. | -| `COMPRESSION_TYPE_WEBP` | 所有格式 | WebP 无损压缩. 高质量小体积. | -| `COMPRESSION_TYPE_WEBP_LOSSY` | 所有非硬件压缩格式 | WebP 有损压缩. 降低质量再降低体积. | +| `COMPRESSION_TYPE_DEFAULT` | All formats | 常见有损压缩. 默认类型. | +| `COMPRESSION_TYPE_BASIS_UASTC` | All RGB/RGBA formats | 基础通用高质, 有损压缩. 质量等级越低体积越小. | +| `COMPRESSION_TYPE_WEBP` | All formats | WebP 无损压缩. 质量等级越高体积越小. | +| `COMPRESSION_TYPE_WEBP_LOSSY` | All non hardware compressed formats. | WebP 有损压缩. 质量等级越低体积越小. | 对于硬件压缩纹理格式PVRTC或ETC, WebP无损压缩过程使用内部中间格式将压缩的硬件纹理格式数据转换为更适合WebP图像压缩的数据. 然后在运行时加载时将其转换回压缩的硬件纹理格式. 硬件压缩纹理格式PVRTC和ETC目前不支持WebP有损类型. From 40c9c217ab2a12f4ed2ab6492d52475ca0088b17 Mon Sep 17 00:00:00 2001 From: COCO Date: Thu, 6 May 2021 18:14:05 +0800 Subject: [PATCH 026/134] sound & mesh --- docs/zh/manuals/project-settings.md | 10 ++++++++++ docs/zh/manuals/sound.md | 23 +++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/docs/zh/manuals/project-settings.md b/docs/zh/manuals/project-settings.md index 8424a05d..736eebcd 100644 --- a/docs/zh/manuals/project-settings.md +++ b/docs/zh/manuals/project-settings.md @@ -262,6 +262,16 @@ HTTP超时秒数. 设置为 `0` 则关闭超时, 默认关闭. #### Max Count spine 模型最大数目, 默认是 `128`. +## Mesh + +#### Max Count +每个集合最大容纳3D模型面数, 默认是 `128`. + +## Model + +#### Max Count +每个集合最大容纳3D模型组件个数, 默认是 `128`. + ## GUI #### Max Count diff --git a/docs/zh/manuals/sound.md b/docs/zh/manuals/sound.md index bc236b79..bd9d4be1 100644 --- a/docs/zh/manuals/sound.md +++ b/docs/zh/manuals/sound.md @@ -186,6 +186,29 @@ msg.post("/sound_gate#script", "play_gated_sound", { soundcomponent = "/sounds#e 对于 `play_sound` 消息没法过滤因为该消息由 Defold 引擎内部保留. 如果使用引擎保留消息名会造成运行不正确. ::: + +## 运行时控制 +可以通关一些列属性在运行时控制声音 (用法参见 [API](/ref/sound/)). 以下属性可以使用 `go.get()` 和 `go.set()` 来进行操作: + +`gain` +: 声音组件音量 (`number`). + +`pan` +: 声音组件角度 (`number`). 取值从 -1 (向左-45度) 到 1 (向右45度). + +`speed` +: 声音组件速度 (`number`). 取值 1.0 为一般速度, 0.5 半速, 2.0 两倍速. + +`sound` +: 声音资源路径 (`hash`). 可以使用 `resource.set_sound(path, buffer)` 来变更声音资源. 例如: + +```lua +local boom = sys.load_resource("/sounds/boom.wav") +local path = go.get("#sound", "sound") +resource.set_sound(path, boom) +``` + + ## 相关项目配置 在 *game.project* 文件里有些关于声音组件的 [设置项目](/manuals/project-settings#sound). From 17161433cfa1be3d23b0df369ac74c4e1d131179 Mon Sep 17 00:00:00 2001 From: COCO Date: Tue, 18 May 2021 09:18:28 +0800 Subject: [PATCH 027/134] gamepad event mapping --- docs/zh/manuals/input-gamepads.md | 44 ++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/docs/zh/manuals/input-gamepads.md b/docs/zh/manuals/input-gamepads.md index e5f1d00b..bc274f6a 100644 --- a/docs/zh/manuals/input-gamepads.md +++ b/docs/zh/manuals/input-gamepads.md @@ -72,7 +72,7 @@ function on_input(self, action_id, action) end ``` -## Connect and Disconnect +## Connect 和 Disconnect 游戏手柄还有 `Connected` 和 `Disconnected` 两种事件用以通知手柄连接和断开. ```lua @@ -127,3 +127,45 @@ end ```html ``` + +## 安卓手柄 +(自从 Defold 1.2.183 版本开始) + +Android 和其他平台一样支持手柄的输入事件. 手柄支持基于 [Android 按键和运动事件输入系统](https://developer.android.com/training/game-controllers/controller-input). 通过上文提到的 *gamepad* 文件把安卓输入事件转化成 Defold 手柄事件. + +安卓手柄输入按键到 *gamepad* 文件手柄事件对应表如下: + +| 按键输入 | 事件编号 | +|-----------------------------|-------| +| AKEYCODE_BUTTON_A | 0 | +| AKEYCODE_BUTTON_B | 1 | +| AKEYCODE_BUTTON_C | 2 | +| AKEYCODE_BUTTON_X | 3 | +| AKEYCODE_BUTTON_L1 | 4 | +| AKEYCODE_BUTTON_R1 | 5 | +| AKEYCODE_BUTTON_Y | 6 | +| AKEYCODE_BUTTON_Z | 7 | +| AKEYCODE_BUTTON_L2 | 8 | +| AKEYCODE_BUTTON_R2 | 9 | +| AKEYCODE_DPAD_CENTER | 10 | +| AKEYCODE_DPAD_DOWN | 11 | +| AKEYCODE_DPAD_LEFT | 12 | +| AKEYCODE_DPAD_RIGHT | 13 | +| AKEYCODE_DPAD_UP | 14 | +| AKEYCODE_BUTTON_START | 15 | +| AKEYCODE_BUTTON_SELECT | 16 | +| AKEYCODE_BUTTON_THUMBL | 17 | +| AKEYCODE_BUTTON_THUMBR | 18 | + +([Android KeyEvent 定义](https://developer.android.com/ndk/reference/group/input#group___input_1gafccd240f973cf154952fb917c9209719)) + +| 摇杆输入 | 事件编号 | +|-----------------------------|-------| +| AMOTION_EVENT_AXIS_X | 0 | +| AMOTION_EVENT_AXIS_Y | 1 | +| AMOTION_EVENT_AXIS_Z | 2 | +| AMOTION_EVENT_AXIS_RZ | 3 | + +([Android MotionEvent 定义](https://developer.android.com/ndk/reference/group/input#group___input_1ga157d5577a5b2f5986037d0d09c7dc77d)) + +为了正确使用手柄事件映射请参考上表以及 Google Play Store 上的手柄映射测试小工具. From c09ca2a8e5548c56ea3adb2d2d5ef3d30aa25080 Mon Sep 17 00:00:00 2001 From: COCO Date: Sat, 22 May 2021 12:26:15 +0800 Subject: [PATCH 028/134] admob url --- docs/zh/manuals/ads.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh/manuals/ads.md b/docs/zh/manuals/ads.md index 97f395a1..69bdb03d 100644 --- a/docs/zh/manuals/ads.md +++ b/docs/zh/manuals/ads.md @@ -36,7 +36,7 @@ CPM = 千人成本. 广告商为一千个浏览量支付的报酬. 不同广告 在 [Defold 资源中心](/tags/stars/ads/) 提供了一些广告商的支持程序: -* [AdMob](https://defold.com/assets/admob/) - 谷歌广告. +* [AdMob](https://defold.com/assets/admob-defold/) - 谷歌 AdMob 广告. * [Enhance](https://defold.com/assets/enhance/) - 广告商大集合. 编译后需要额外的安装步骤. * [Facebook Instant Games](https://defold.com/assets/facebookinstantgames/) - 脸书广告. * [IronSource](https://defold.com/assets/ironsource/) - IronSource 广告. From 6d9ce167b0fa646b4e6db3a6dcd5ae7f5d69efbe Mon Sep 17 00:00:00 2001 From: COCO Date: Fri, 28 May 2021 10:10:07 +0800 Subject: [PATCH 029/134] Minor edit to building blocks intro text --- docs/zh/manuals/building-blocks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh/manuals/building-blocks.md b/docs/zh/manuals/building-blocks.md index e1d051e3..29e1328d 100644 --- a/docs/zh/manuals/building-blocks.md +++ b/docs/zh/manuals/building-blocks.md @@ -5,7 +5,7 @@ brief: 本教程详述游戏对象, 组件和集合是如何工作的. # 构成 -Defold 核心设计中的一些概念可能一时不容易理解. 本教程介绍了 Defold 游戏的各个组成部分. 看完本教程后, 可以去参考 [定位教程](/manuals/addressing) 和 [消息传递教程](/manuals/message-passing). 编辑器中提供了一些 [教程](/tutorials/getting-started) 也可以帮助学习理解. +理解 Defold 核心设计中的各种概念是很重要的. 本教程介绍了 Defold 游戏的各个组成部分. 看完本教程后, 可以去参考 [定位教程](/manuals/addressing) 和 [消息传递教程](/manuals/message-passing). 编辑器中提供了一些 [教程](/tutorials/getting-started) 也可以帮助学习理解. ![Building blocks](images/building_blocks/building_blocks.png){srcset="images/building_blocks/building_blocks@2x.png 2x"} From da1a1d18f3ed74ed44a72013869434b3b93ee0ba Mon Sep 17 00:00:00 2001 From: COCO Date: Fri, 18 Jun 2021 19:35:35 +0800 Subject: [PATCH 030/134] update gamepad & ios --- docs/zh/manuals/input-gamepads.md | 5 +++++ docs/zh/manuals/ios.md | 7 ++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/zh/manuals/input-gamepads.md b/docs/zh/manuals/input-gamepads.md index bc274f6a..328832c2 100644 --- a/docs/zh/manuals/input-gamepads.md +++ b/docs/zh/manuals/input-gamepads.md @@ -156,6 +156,7 @@ Android 和其他平台一样支持手柄的输入事件. 手柄支持基于 [An | AKEYCODE_BUTTON_SELECT | 16 | | AKEYCODE_BUTTON_THUMBL | 17 | | AKEYCODE_BUTTON_THUMBR | 18 | +| AKEYCODE_BUTTON_MODE | 19 | ([Android KeyEvent 定义](https://developer.android.com/ndk/reference/group/input#group___input_1gafccd240f973cf154952fb917c9209719)) @@ -165,6 +166,10 @@ Android 和其他平台一样支持手柄的输入事件. 手柄支持基于 [An | AMOTION_EVENT_AXIS_Y | 1 | | AMOTION_EVENT_AXIS_Z | 2 | | AMOTION_EVENT_AXIS_RZ | 3 | +| AMOTION_EVENT_AXIS_LTRIGGER | 4 | +| AMOTION_EVENT_AXIS_RTRIGGER | 5 | +| AMOTION_EVENT_AXIS_HAT_X | 6 | +| AMOTION_EVENT_AXIS_HAT_Y | 7 | ([Android MotionEvent 定义](https://developer.android.com/ndk/reference/group/input#group___input_1ga157d5577a5b2f5986037d0d09c7dc77d)) diff --git a/docs/zh/manuals/ios.md b/docs/zh/manuals/ios.md index 7d27178a..0c70ae95 100644 --- a/docs/zh/manuals/ios.md +++ b/docs/zh/manuals/ios.md @@ -200,7 +200,12 @@ Notifications, Settings 和 Spotlight 這三項不要拖放圖標. ## 安装 iOS 打包应用 -编辑器对iOS应用打包后生成 *.ipa* 文件. 要安装此文件, 可以使用 Xcode (通过 "Devices and Simulators" 窗口). 或者使用命令行工具 [ios-deploy](https://github.com/phonegap/ios-deploy) 或者使用 iTunes. +编辑器对iOS应用打包后生成 *.ipa* 文件. 要安装此文件, 可以使用以下所列举工具之一: + +* Xcode 的 "Devices and Simulators" 窗口 +* [ios-deploy](https://github.com/ios-control/ios-deploy) 命令行工具 +* macOS App Store 里的 [Apple Configurator 2](https://apps.apple.com/us/app/apple-configurator-2/) +* iTunes 可以使用 `xcrun simctl` 命令行工具与 Xcode 的 iOS 模拟器进行交互: From 601b4424672ebf913c398e9b2d67115811f5cc50 Mon Sep 17 00:00:00 2001 From: COCO Date: Mon, 21 Jun 2021 13:43:52 +0800 Subject: [PATCH 031/134] project settings --- docs/zh/manuals/project-settings.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/zh/manuals/project-settings.md b/docs/zh/manuals/project-settings.md index 736eebcd..93ae253d 100644 --- a/docs/zh/manuals/project-settings.md +++ b/docs/zh/manuals/project-settings.md @@ -183,6 +183,11 @@ debug顶点最大数目. 用于物理形状渲染与其他一些功能, 默认 #### Texture Profiles 项目使用的纹理档配置文件, 默认是 `/builtins/graphics/default.texture_profiles`. +## Shader + +#### Output SPIR-V +为 Metal 和 Vulkan 编译输出 SPIR-V 着色器. + ## Input #### Repeat Delay @@ -221,6 +226,9 @@ HTTP超时秒数. 设置为 `0` 则关闭超时, 默认关闭. #### Max Instances 一个集合里容纳游戏对象实例的最大数目, 默认是`1024`. +#### Max Input Stack Entries +输入栈内最大游戏对象数目, 默认是`16`. + ## Sound #### Gain From 35feca81876ddc13408b254f773a9cc0aa9e468c Mon Sep 17 00:00:00 2001 From: COCO Date: Mon, 28 Jun 2021 20:20:01 +0800 Subject: [PATCH 032/134] libffi version --- docs/zh/shared/linux-faq.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/zh/shared/linux-faq.md b/docs/zh/shared/linux-faq.md index 4c9ea671..59a36321 100644 --- a/docs/zh/shared/linux-faq.md +++ b/docs/zh/shared/linux-faq.md @@ -71,8 +71,8 @@ A: 这是由于Linux系统的 [libffi](https://sourceware.org/libffi/) 版本与 确保 `libffi.so.6` 或 `libffi.so.7` 已安装在 `/usr/lib/x86_64-linux-gnu` 路径下. 可以使用如下命令下载 `libffi.so.7`: ```bash -$ wget http://ftp.br.debian.org/debian/pool/main/libf/libffi/libffi7_3.3-5_amd64.deb -$ sudo dpkg -i libffi7_3.3-5_amd64.deb +$ wget http://ftp.br.debian.org/debian/pool/main/libf/libffi/libffi7_3.3-6_amd64.deb +$ sudo dpkg -i libffi7_3.3-6_amd64.deb ``` 然后需要在环境变量 `LD_PRELOAD` 中指定安装路径再启动 Defold: From ad7ed0c61de4ecf78627c6d15ea20f346bedb69b Mon Sep 17 00:00:00 2001 From: COCO Date: Sun, 11 Jul 2021 13:59:11 +0800 Subject: [PATCH 033/134] scaling --- docs/zh/shared/linux-faq.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/zh/shared/linux-faq.md b/docs/zh/shared/linux-faq.md index 59a36321..6ebaa840 100644 --- a/docs/zh/shared/linux-faq.md +++ b/docs/zh/shared/linux-faq.md @@ -7,6 +7,16 @@ $ gsettings set org.gnome.desktop.interface scaling-factor 2 $ ./Defold ``` +A: 另一种办法, 尤其是在你希望把界面放大到非整数倍时, 可以修改 `Defold/config` 文件, 在`vmargs` 一行加入 `glass.gtk.uiScale`: [source](https://forum.defold.com/t/4k-hidpi-monitor-support-solved/64108/12?u=britzl) + +``` +vmargs = -Dglass.gtk.uiScale=1.5,-Dfile.encoding=UTF-8,... +vmargs = -Dglass.gtk.uiScale=175%,-Dfile.encoding=UTF-8,... +vmargs = -Dglass.gtk.uiScale=192dpi,-Dfile.encoding=UTF-8,... +``` + +此值的意义参见 [Arch Linux HiDPI wiki 文章](https://wiki.archlinux.org/title/HiDPI#JavaFX). + #### Q:在 Elementary OS 上使用 Defold 编辑器, 鼠标点选上的都是后面的东西? From eda6c341fe3dc8fecf618668cbf3f3698d8b1832 Mon Sep 17 00:00:00 2001 From: COCO Date: Tue, 13 Jul 2021 20:00:53 +0800 Subject: [PATCH 034/134] image compression --- docs/zh/manuals/texture-profiles.md | 73 ++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 2 deletions(-) diff --git a/docs/zh/manuals/texture-profiles.md b/docs/zh/manuals/texture-profiles.md index 19f5f44a..48257bac 100644 --- a/docs/zh/manuals/texture-profiles.md +++ b/docs/zh/manuals/texture-profiles.md @@ -102,7 +102,18 @@ Defold 可以自动把图片数据处理成纹理并进行压缩 (称为 *Atlas* : 纹理编码格式. 可用格式见下文. *Compression* -: 压缩图片的质量等级. 取值从 `FAST` (质量最差, 速度最快) 到 `BEST` (质量最高, 速度最慢). +: 选择图片压缩质量等级. + +| 等级 | 说明 | +| -------- | --------------------------------------------- | +| `FAST` | 压缩速度最快. 图片质量最低 | +| `NORMAL` | 默认压缩. 图片质量最高 | +| `HIGH` | 最慢压缩. 缩小图片文件大小 | +| `BEST` | 慢压缩. 图片文件大小最小 | + +::: 注意 +为了避免歧义, 从版本 1.2.185 开始, 等级枚举用词做了调整. +::: *Type* : 压缩类型, 可选值有 `COMPRESSION_TYPE_DEFAULT`, `COMPRESSION_TYPE_WEBP` 和 `COMPRESSION_TYPE_WEBP_LOSSY`. 详见下文 [压缩类型](#compression-types). @@ -158,7 +169,7 @@ ETC 远期未来目标是引入内容管线插件来解决这个问题. ::: -| Type | Formats | Note | +| 类型 | 格式 | 说明 | | --------------------------------- | ------------------------- | ---- | | `COMPRESSION_TYPE_DEFAULT` | All formats | 常见有损压缩. 默认类型. | | `COMPRESSION_TYPE_BASIS_UASTC` | All RGB/RGBA formats | 基础通用高质, 有损压缩. 质量等级越低体积越小. | @@ -166,3 +177,61 @@ ETC | `COMPRESSION_TYPE_WEBP_LOSSY` | All non hardware compressed formats. | WebP 有损压缩. 质量等级越低体积越小. | 对于硬件压缩纹理格式PVRTC或ETC, WebP无损压缩过程使用内部中间格式将压缩的硬件纹理格式数据转换为更适合WebP图像压缩的数据. 然后在运行时加载时将其转换回压缩的硬件纹理格式. 硬件压缩纹理格式PVRTC和ETC目前不支持WebP有损类型. + + +## 图片压缩测试 + +为了便于更好地理解, 这里举了一个例子. +注意图片质量, 压缩时间和压缩量取决于原始图片, 不同图片可能效果不同. + +原始图片 (1024x512): +![New profiles file](images/texture_profiles/kodim03_pow2.png) + +### 压缩时间 + +| 等级 | 压缩时间 | 倍率 | +| ----------------------------- | --------------- | +| `FAST` | 0m0.143s | 0.5x | +| `NORMAL` | 0m0.294s | 1.0x | +| `HIGH` | 0m1.764s | 6.0x | +| `BEST` | 0m1.109s | 3.8x | + +### 失真 + +这里使用 `basisu` 工具进行比较 (比较参数 PSNR) +100 dB 表示不失真 (也就是说和原始图片完全相同). + +| 等级 | 数据 | +| ------------------------------------------------------------ | +| `FAST` | Max: 34 Mean: 0.470 RMS: 1.088 PSNR: 47.399 dB | +| `NORMAL` | Max: 35 Mean: 0.439 RMS: 1.061 PSNR: 47.620 dB | +| `HIGH` | Max: 37 Mean: 0.898 RMS: 1.606 PSNR: 44.018 dB | +| `BEST` | Max: 51 Mean: 1.298 RMS: 2.478 PSNR: 40.249 dB | + +### 压缩文件大小 + +原始文件 1572882 字节. + +| 等级 | 文件大小 | 压缩率 | +| ---------------------------------- | +| `FAST` | 357225 | 22.71 % | +| `NORMAL` | 365548 | 23.24 % | +| `HIGH` | 277186 | 17.62 % | +| `BEST` | 254380 | 16.17 % | + + +### 图片质量 + +下面给出压缩后的图片 (使用`basisu` 工具的 ASTC 编码进行了修正) + +`FAST` +![fast compression level](images/texture_profiles/kodim03_pow2.fast.png) + +`NORMAL` +![normal compression level](images/texture_profiles/kodim03_pow2.normal.png) + +`HIGH` +![high compression level](images/texture_profiles/kodim03_pow2.high.png) + +`BEST` +![best compression level](images/texture_profiles/kodim03_pow2.best.png) From 81ae25fe721fdd3eb02c6d5ca45286f42d4cdea9 Mon Sep 17 00:00:00 2001 From: COCO Date: Tue, 10 Aug 2021 17:50:36 +0800 Subject: [PATCH 035/134] update gamepads --- docs/zh/manuals/input-gamepads.md | 84 ++++++++++++++++++++++--------- 1 file changed, 60 insertions(+), 24 deletions(-) diff --git a/docs/zh/manuals/input-gamepads.md b/docs/zh/manuals/input-gamepads.md index 328832c2..28f253c8 100644 --- a/docs/zh/manuals/input-gamepads.md +++ b/docs/zh/manuals/input-gamepads.md @@ -73,7 +73,7 @@ end ``` ## Connect 和 Disconnect -游戏手柄还有 `Connected` 和 `Disconnected` 两种事件用以通知手柄连接和断开. +游戏手柄还有 `Connected` 和 `Disconnected` 两种事件用以通知手柄的连接(包括一开始就连着的手柄)和断开. ```lua function on_input(self, action_id, action) @@ -89,6 +89,21 @@ function on_input(self, action_id, action) end ``` +## 手柄原始数据 +(更新于 Defold 1.2.183) + +手柄输入绑定提供了一个 `Raw` 事件给出按键, 十字键或者摇杆的原始 (不使用阈值) 数据. + +```lua +function on_input(self, action_id, action) + if action_id == hash("raw") then + pprint(action.gamepad_buttons) + pprint(action.gamepad_axis) + pprint(action.gamepad_hats) + end +end +``` + ## 手柄配置文件 在 Windows 上, 只支持 XBox 360 兼容手柄. 安装方法请见 http://www.wikihow.com/Use-Your-Xbox-360-Controller-for-Windows @@ -110,6 +125,11 @@ end ![Gamepad settings](images/input/gamepad_setting.png){srcset="images/input/gamepad_setting@2x.png 2x"} +### 未映射手柄 +(更新于 Defold 1.2.186) + +如果手柄没有配置消息映射的话, 就只有 "connected", "disconnected" 和 "raw" 三种事件. 这种情况下只能使用手柄原始数据来控制游戏. + ## HTML5上的游戏手柄 HTML5平台同样支持游戏手柄, 效果和原生应用一样. 游戏手柄的支持基于 [标准游戏手柄API](https://www.w3.org/TR/gamepad/), 并且受绝大多数浏览器支持 ([详见此图表](https://caniuse.com/?search=gamepad)). 万一遇到不支持的浏览器 Defold 会忽略所有游戏手柄的操作. 可以通过检查浏览器的`navigator`对象中是否存在`getGamepads`函数来判断其是否支持游戏手柄: @@ -129,34 +149,50 @@ end ``` ## 安卓手柄 -(自从 Defold 1.2.183 版本开始) +(更新于 Defold 1.2.183) Android 和其他平台一样支持手柄的输入事件. 手柄支持基于 [Android 按键和运动事件输入系统](https://developer.android.com/training/game-controllers/controller-input). 通过上文提到的 *gamepad* 文件把安卓输入事件转化成 Defold 手柄事件. 安卓手柄输入按键到 *gamepad* 文件手柄事件对应表如下: -| 按键输入 | 事件编号 | -|-----------------------------|-------| -| AKEYCODE_BUTTON_A | 0 | -| AKEYCODE_BUTTON_B | 1 | -| AKEYCODE_BUTTON_C | 2 | -| AKEYCODE_BUTTON_X | 3 | -| AKEYCODE_BUTTON_L1 | 4 | -| AKEYCODE_BUTTON_R1 | 5 | -| AKEYCODE_BUTTON_Y | 6 | -| AKEYCODE_BUTTON_Z | 7 | -| AKEYCODE_BUTTON_L2 | 8 | -| AKEYCODE_BUTTON_R2 | 9 | -| AKEYCODE_DPAD_CENTER | 10 | -| AKEYCODE_DPAD_DOWN | 11 | -| AKEYCODE_DPAD_LEFT | 12 | -| AKEYCODE_DPAD_RIGHT | 13 | -| AKEYCODE_DPAD_UP | 14 | -| AKEYCODE_BUTTON_START | 15 | -| AKEYCODE_BUTTON_SELECT | 16 | -| AKEYCODE_BUTTON_THUMBL | 17 | -| AKEYCODE_BUTTON_THUMBR | 18 | -| AKEYCODE_BUTTON_MODE | 19 | +| 按键输入 | 事件编号 | 引擎版本 | +|-----------------------------|-------|---------| +| AKEYCODE_BUTTON_A | 0 | 1.2.183 | +| AKEYCODE_BUTTON_B | 1 | 1.2.183 | +| AKEYCODE_BUTTON_C | 2 | 1.2.183 | +| AKEYCODE_BUTTON_X | 3 | 1.2.183 | +| AKEYCODE_BUTTON_L1 | 4 | 1.2.183 | +| AKEYCODE_BUTTON_R1 | 5 | 1.2.183 | +| AKEYCODE_BUTTON_Y | 6 | 1.2.183 | +| AKEYCODE_BUTTON_Z | 7 | 1.2.183 | +| AKEYCODE_BUTTON_L2 | 8 | 1.2.183 | +| AKEYCODE_BUTTON_R2 | 9 | 1.2.183 | +| AKEYCODE_DPAD_CENTER | 10 | 1.2.183 | +| AKEYCODE_DPAD_DOWN | 11 | 1.2.183 | +| AKEYCODE_DPAD_LEFT | 12 | 1.2.183 | +| AKEYCODE_DPAD_RIGHT | 13 | 1.2.183 | +| AKEYCODE_DPAD_UP | 14 | 1.2.183 | +| AKEYCODE_BUTTON_START | 15 | 1.2.183 | +| AKEYCODE_BUTTON_SELECT | 16 | 1.2.183 | +| AKEYCODE_BUTTON_THUMBL | 17 | 1.2.183 | +| AKEYCODE_BUTTON_THUMBR | 18 | 1.2.183 | +| AKEYCODE_BUTTON_MODE | 19 | 1.2.183 | +| AKEYCODE_BUTTON_1 | 20 | 1.2.186 | +| AKEYCODE_BUTTON_2 | 21 | 1.2.186 | +| AKEYCODE_BUTTON_3 | 22 | 1.2.186 | +| AKEYCODE_BUTTON_4 | 23 | 1.2.186 | +| AKEYCODE_BUTTON_5 | 24 | 1.2.186 | +| AKEYCODE_BUTTON_6 | 25 | 1.2.186 | +| AKEYCODE_BUTTON_7 | 26 | 1.2.186 | +| AKEYCODE_BUTTON_8 | 27 | 1.2.186 | +| AKEYCODE_BUTTON_9 | 28 | 1.2.186 | +| AKEYCODE_BUTTON_10 | 29 | 1.2.186 | +| AKEYCODE_BUTTON_11 | 30 | 1.2.186 | +| AKEYCODE_BUTTON_12 | 31 | 1.2.186 | +| AKEYCODE_BUTTON_13 | 32 | 1.2.186 | +| AKEYCODE_BUTTON_14 | 33 | 1.2.186 | +| AKEYCODE_BUTTON_15 | 34 | 1.2.186 | +| AKEYCODE_BUTTON_16 | 35 | 1.2.186 | ([Android KeyEvent 定义](https://developer.android.com/ndk/reference/group/input#group___input_1gafccd240f973cf154952fb917c9209719)) From 6fbf5315b5ad17352863420a686c3e2fef69752a Mon Sep 17 00:00:00 2001 From: COCO Date: Thu, 19 Aug 2021 14:58:34 +0800 Subject: [PATCH 036/134] increase memory --- docs/zh/shared/editor-faq.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/zh/shared/editor-faq.md b/docs/zh/shared/editor-faq.md index d3ea505a..70902fec 100644 --- a/docs/zh/shared/editor-faq.md +++ b/docs/zh/shared/editor-faq.md @@ -18,3 +18,11 @@ 答: 这个错是由于编辑器尝试建立 https 连接而服务器证书无法验证导致. 详情请见 [这里](https://github.com/defold/defold/blob/master/editor/README_TROUBLESHOOTING_PKIX.md). + + +#### Q: 操作中遇到 "java.lang.OutOfMemoryError: Java heap space" 报错? +A: Defold 编辑器基于 Java, 所以某种情况下可能会造成内存不足. 可以尝试手动编辑配置文件来增加内存使用量. 配置文件叫做 `config`, 在 macOS 位于 `Defold.app/Contents/Resources/` 文件夹下. 在 Windows 位于 `Defold.exe` 可执行文件同一个文件夹下, 在 Linux 位于 `Defold` 可执行文件同一个文件夹下. 打开 `config` 文件, 在 `vmargs` 后顶头加入 `-Xmx6gb` 参数. 加入 `-Xmx6gb` 的意思是使用 6 GB 内存 (默认 4GB). 如下所示: + +``` +vmargs = -Xmx6gb,-Dfile.encoding=UTF-8,-Djna.nosys=true,-Ddefold.launcherpath=${bootstrap.launcherpath},-Ddefold.resourcespath=${bootstrap.resourcespath},-Ddefold.version=${build.version},-Ddefold.editor.sha1=${build.editor_sha1},-Ddefold.engine.sha1=${build.engine_sha1},-Ddefold.buildtime=${build.time},-Ddefold.channel=${build.channel},-Ddefold.archive.domain=${build.archive_domain},-Djava.net.preferIPv4Stack=true,-Dsun.net.client.defaultConnectTimeout=30000,-Dsun.net.client.defaultReadTimeout=30000,-Djogl.texture.notexrect=true,-Dglass.accessible.force=false,--illegal-access=warn,--add-opens=java.base/java.lang=ALL-UNNAMED,--add-opens=java.desktop/sun.awt=ALL-UNNAMED,--add-opens=java.desktop/sun.java2d.opengl=ALL-UNNAMED,--add-opens=java.xml/com.sun.org.apache.xerces.internal.jaxp=ALL-UNNAMED +``` From 9f949682e541caecdb70c6d39b8772b4922bd89f Mon Sep 17 00:00:00 2001 From: COCO Date: Thu, 26 Aug 2021 15:52:40 +0800 Subject: [PATCH 037/134] caching assets --- docs/zh/manuals/caching-assets.md | 51 +++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 docs/zh/manuals/caching-assets.md diff --git a/docs/zh/manuals/caching-assets.md b/docs/zh/manuals/caching-assets.md new file mode 100644 index 00000000..acc36e6c --- /dev/null +++ b/docs/zh/manuals/caching-assets.md @@ -0,0 +1,51 @@ +--- +title: 资源缓存 +brief: 跟教程介绍了如何利用资源缓存提高编译速度. +--- + +# 资源缓存 + +Defold 编译通常需要几秒钟, 但是随着项目和资源的扩大, 耗时也会增加. 对于大项目而言, 编译时间大量消耗在编译字体和压缩纹理上, 所以引入资源缓存功能使得再次编译时只编译改变了的资源, 那些没改变的资源直接从缓存获取以提高编译效率. + +Defold 使用了三重缓存: + +1. 项目缓存 +2. 本地缓存 +3. 原创缓存 + + +## 项目缓存 + +Defold 默认把编译好的资源缓存到项目的 `build/default` 文件夹中. 下次编译时只编译改变了的资源, 未改变的资源从项目缓存中获取. 这种缓存在编辑器和命令行都会开启. + +可以手动删除项目目录下 `build/default` 中的文件, 或者使用 [命令行编译工具 Bob](/manuals/bob) 的 `clean` 命令, 达到清除项目缓存的目的. + + +## 本地缓存 + +自 Defold 1.2.187 版本引入 + +本地缓存作为可选功能, 把编译后的资源保存在本机或者云盘上. 这相当于是项目缓存的备份. 本地缓存还可以供项目的合作开发人员共享. 目前该缓存只能使用命令行工具开启. 即命令行参数 `resource-cache-local` 项: + +```sh +java -jar bob.jar --resource-cache-local /Users/john.doe/defold_local_cache +``` + +本地缓存通过基于 Defold 引擎版本, 资源文件, 项目编译参数等计算出的校验码进行访问. 这样做就能保证不同 Defold 版本之间资源缓存的唯一性. + +::: 注意 +本地缓存文件永远存在. 想要清除只能手动删除这些文件. +::: + + +## 远程缓存 + +自 Defold 1.2.187 版本引入 + +远程缓存作为可选功能, 把编译后的资源保存至服务器然后通过 HTTP 请求进行访问. 目前该缓存只能使用命令行工具开启. 即命令行参数 `resource-cache-remote` 项: + +```sh +java -jar bob.jar --resource-cache-remote https://http://192.168.0.100/ +``` + +远程缓存同样通过校验码进行访问. 使用 HTTP 请求的 GET, PUT 方法和 HEAD 获取缓存文件. Defold 不提供远程服务器程序. 开发者可以自行搭建. 比如 [这个使用 Python 做的简单的服务器程序](https://github.com/britzl/httpserver-python). From 3864422e8b171c05df1cab5dad377b4b96ea4f05 Mon Sep 17 00:00:00 2001 From: COCO Date: Wed, 6 Oct 2021 13:10:29 +0800 Subject: [PATCH 038/134] update 2021/10/6 --- docs/zh/manuals/debugging-native-code.md | 2 +- docs/zh/manuals/project-settings.md | 175 +++++++++++++++++------ 2 files changed, 129 insertions(+), 48 deletions(-) diff --git a/docs/zh/manuals/debugging-native-code.md b/docs/zh/manuals/debugging-native-code.md index 8b525873..713717e5 100644 --- a/docs/zh/manuals/debugging-native-code.md +++ b/docs/zh/manuals/debugging-native-code.md @@ -72,7 +72,7 @@ Defold 几经测试鲜有崩溃情况出现. 但是崩溃这种事谁能保证 从 `_crash` 文件或者 [日志文件](/manuals/debugging-game-and-system-logs), 都可以进行代码文件映射. 即把调用堆栈里的每个地址映射到文件名和代码行, 利于寻找代码的问题. -注意引擎版本要选择正确. 不然映射会错乱. 需要编译原生扩展, 命令行要加入 [--with-symbols](https://www.defold.com/manuals/bob/) 参数才能下载到所需的全部数据: +注意引擎版本要选择正确. 不然映射会错乱. 需要编译原生扩展, 命令行要加入 [--with-symbols](https://www.defold.com/manuals/bob/) 参数给 [bob](https://www.defold.com/manuals/bob/) 或者在编辑器打包对话框里点选 "Generate debug symbols" 才能下载到所需的全部数据: * iOS 与 macOS - `build.zip` 里的 `dmengine.dSYM` 文件夹下包含了调试映射数据. * Android 与 Linux - 可执行文件中就包含全部调试映射数据. diff --git a/docs/zh/manuals/project-settings.md b/docs/zh/manuals/project-settings.md index 93ae253d..fa2bba9a 100644 --- a/docs/zh/manuals/project-settings.md +++ b/docs/zh/manuals/project-settings.md @@ -13,7 +13,9 @@ brief: 本教程介绍了如何在 Defold 中进行项目配置工作. 下面是根据不同模块排序的各种设置. 其中有一些不在编辑器中显示 (标注为 "隐藏设置"), 但是可以右键点击 "game.project" 然后选择 Open With ▸ Text Editor 来进行手动编辑. -## Project +## 各类设置 + +### Project #### Title 项目标题. @@ -47,7 +49,9 @@ $ adb shell cat /mnt/sdcard/Android/data/com.defold.dmengine/files/log.txt #### Bundle Exclude Resources 项目中排除的以逗号分隔的资源列表. -## Bootstrap +--- + +### Bootstrap #### Main Collection 打开应用启动的起始集合, 默认 `/logic/main.collection`. @@ -55,22 +59,28 @@ $ adb shell cat /mnt/sdcard/Android/data/com.defold.dmengine/files/log.txt #### Render 指定使用哪个渲染文件, 它决定了渲染流程, 默认 `/builtins/render/default.render`. -## Library +--- + +### Library #### Include Dirs 使用库共享机制从项目中共享出去的以逗号分隔的目录列表. -## Script +--- + +### Script #### Shared State 打开则共享脚本的Lua状态, 默认关闭. -## Engine +--- + +### Engine #### Run While Iconified 当游戏应用程序窗口最小化时允许其在后台继续运行 (仅桌面平台有效), 默认值是 `false`. -## Display +### Display #### Width 应用窗口像素为单位宽度, 默认 `960`. @@ -88,10 +98,10 @@ $ adb shell cat /mnt/sdcard/Android/data/com.defold.dmengine/files/log.txt 设置应用启动是否使用全屏. 如果关闭, 应用会以窗口形式启动. #### Frame Cap -如果 `Vsync` 开启, 则为锁帧频率匹配最接近的交换间隔. 否则的话依据锁帧设置计时器, 0 代表不锁帧. 此设置相当于 `display.update_frequency`. +如果 `Vsync` 开启, 则为锁帧频率匹配最接近的交换间隔. 否则的话依据锁帧设置计时器, 0 代表不锁帧. 此设置相当于 `display.update_frequency`. ([见下文](#vsync-frame-cap-and-swap-interval)). #### Vsync -垂直同步, 根据硬件的帧率进行刷新. 可以被驱动程序或者操作系统平台设置覆盖. +垂直同步, 根据硬件的帧率进行刷新. 可以被驱动程序或者操作系统平台设置覆盖. ([见下文](#vsync-frame-cap-and-swap-interval)). #### Display Profiles 指定使用哪个显示样式文件, 默认 `/builtins/render/default.display_profilesc`. 详情请见 [GUI 排版教程](/manuals/gui-layouts/#新建显示档案). @@ -99,7 +109,9 @@ $ adb shell cat /mnt/sdcard/Android/data/com.defold.dmengine/files/log.txt #### Dynamic Orientation 开启的话会在设备转动时动态切换横竖显示方向. 注意开发用app(指dmengine)不参考此设置. -## Render +--- + +### Render #### Clear Color Red 清除红色通道, 建立游戏窗口和渲染脚本中使用. 1.2.167 版新增. @@ -113,7 +125,9 @@ $ adb shell cat /mnt/sdcard/Android/data/com.defold.dmengine/files/log.txt #### Clear Color ALpha 清除alpha通道, 建立游戏窗口和渲染脚本中使用. 1.2.167 版新增. -## Physics +--- + +### Physics #### Type 使用何种物理引擎, `2D` (默认) 还是 `3D`. @@ -163,7 +177,9 @@ debug线的不透明度, `0`--`1`. 默认是 `0.9`. #### Trigger Overlap Capacity 物理 trigger 的最大重叠数量. 默认是 `16`. -## Graphics +--- + +### Graphics #### Default Texture Min Filter 设置缩小过滤方式, `linear` (默认) 或者 `nearest`. @@ -183,12 +199,14 @@ debug顶点最大数目. 用于物理形状渲染与其他一些功能, 默认 #### Texture Profiles 项目使用的纹理档配置文件, 默认是 `/builtins/graphics/default.texture_profiles`. -## Shader +### Shader #### Output SPIR-V 为 Metal 和 Vulkan 编译输出 SPIR-V 着色器. -## Input +--- + +### Input #### Repeat Delay 按下输入保持时等待多少秒后开始算作重复输入, 默认是 `0.5`. @@ -205,7 +223,9 @@ debug顶点最大数目. 用于物理形状渲染与其他一些功能, 默认 #### Use Accelerometer 开启后游戏引擎会在每帧接收加速度计数据. 关闭会获得少许性能提升, 默认开启. -## Resource +--- + +### Resource #### Http Cache 开启后, 会开启HTTP缓存用于设备上的游戏引擎从缓存中快速导入网络数据, 默认关闭. @@ -216,12 +236,16 @@ debug顶点最大数目. 用于物理形状渲染与其他一些功能, 默认 #### Max Resources 一次可以加载资源的最大数目, 默认是 `1024`. -## Network +--- + +### Network #### Http Timeout HTTP超时秒数. 设置为 `0` 则关闭超时, 默认关闭. -## Collection +--- + +### Collection #### Max Instances 一个集合里容纳游戏对象实例的最大数目, 默认是`1024`. @@ -229,7 +253,9 @@ HTTP超时秒数. 设置为 `0` 则关闭超时, 默认关闭. #### Max Input Stack Entries 输入栈内最大游戏对象数目, 默认是`16`. -## Sound +--- + +### Sound #### Gain 全局增益 (音量), `0`--`1`, 默认值是 `1`. @@ -249,41 +275,53 @@ HTTP超时秒数. 设置为 `0` 则关闭超时, 默认关闭. #### Use Thread 勾選的話, 系統將使用綫程進行聲音播放以減少因爲主綫程過載造成的卡頓. 默認勾選. -## Sprite +--- + +### Sprite #### Max Count -每个集合最大sprite数目, 默认是 `128`. +每个集合最大sprite数目, 默认是 `128`. [(参见最大组件数优化)](#component_max_count_optimzations). #### Subpixels 开启后允许sprite不与像素对齐, 默认开启. -## Tilemap +--- + +### Tilemap #### Max Count -每个集合的瓷砖地图最大数目, 默认是 `16`. +每个集合的瓷砖地图最大数目, 默认是 `16`. [(参见最大组件数优化)](#component_max_count_optimzations). #### Max Tile Count 每个集合可同时显示的瓷砖最大数目, 默认是 `2048`. -## Spine +--- + +### Spine #### Max Count spine 模型最大数目, 默认是 `128`. -## Mesh +--- + +### Mesh #### Max Count -每个集合最大容纳3D模型面数, 默认是 `128`. +每个集合最大容纳3D模型面数, 默认是 `128`. [(参见最大组件数优化)](#component_max_count_optimzations). -## Model +--- + +### Model #### Max Count -每个集合最大容纳3D模型组件个数, 默认是 `128`. +每个集合最大容纳3D模型组件个数, 默认是 `128`. [(参见最大组件数优化)](#component_max_count_optimzations). + +--- -## GUI +### GUI #### Max Count -GUI 组件最大数目, 默认是 `64`. +GUI 组件最大数目, 默认是 `64`. [(参见最大组件数优化)](#component_max_count_optimzations). #### Max Particlefx Count 同一时间粒子发射器最大数目, 默认是 `64`. @@ -291,38 +329,50 @@ GUI 组件最大数目, 默认是 `64`. #### Max Particle Count 同一时间粒子最大数目, 默认是 `1024`. -## Label +--- + +### Label #### Max Count -label 最大数目, 默认是 `64`. +label 最大数目, 默认是 `64`. [(参见最大组件数优化)](#component_max_count_optimzations). #### Subpixels 开启后允许 lables 不与像素对齐, 默认开启. -## Particle FX +--- + +### Particle FX #### Max Count -同一时间粒子发射器最大数目, 默认是 `64`. +同一时间粒子发射器最大数目, 默认是 `64`. [(参见最大组件数优化)](#component_max_count_optimzations). #### Max Particle Count 同一时间粒子最大数目, 默认是 `1024`. -## Collection proxy +--- + +### Collection proxy #### Max Count -集合代理最大数目, 默认是 `8`. +集合代理最大数目, 默认是 `8`. [(参见最大组件数优化)](#component_max_count_optimzations). + +--- -## Collection factory +### Collection factory #### Max Count -集合工厂最大数目, 默认是 `128`. +集合工厂最大数目, 默认是 `128`. [(参见最大组件数优化)](#component_max_count_optimzations). + +--- -## Factory +### Factory #### Max Count -游戏对象工厂最大数目, 默认是 `128`. +游戏对象工厂最大数目, 默认是 `128`. [(参见最大组件数优化)](#component_max_count_optimzations). -## iOS +--- + +### iOS #### App Icon 57x57--180x180 用于应用图标的图片 (.png) 文件, 宽高分辨率表示为 `W` × `H`. @@ -354,7 +404,9 @@ Storyboard 文件 (.storyboard). 其创建方法详情请见 [iOS 教程](/manua #### Localizations 以逗号分割的语言名称缩写或者是 ISO 语言代号 (见 [CFBundleLocalizations](https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/20001431-109552)). -## Android +--- + +### Android #### App Icon 36x36--192x192 用于应用图标的图片 (.png) 文件, 宽高分辨率表示为 `W` × `H`. @@ -392,7 +444,9 @@ Google Cloud Messaging Sender Id. 此值由 Google 签发, 设置后才能开启 #### Debuggable 指定应用是否可以使用诸如 [GAPID](https://github.com/google/gapid) 或者 [Android Studio](https://developer.android.com/studio/profile/android-profiler) 之类的工具来调试. 这将开启 Android manifest 的 `android:debuggable` 选项. -## macOS +--- + +### macOS #### App Icon 用于macOS应用图标的图片 (.png) 文件. @@ -403,7 +457,9 @@ Google Cloud Messaging Sender Id. 此值由 Google 签发, 设置后才能开启 #### Bundle Identifier 打包id使得 macOS 认识你的应用的版本更新. 你的打包 ID 必须在 Apple 注册且确保应用唯一性. iOS 与 macOS 应用不可以使用同一id. -## Windows +--- + +### Windows #### App Icon 用于Windows应用图标的图片 (.ico) 文件. 对于如何创建图标文件详情请见 [Windows 教程](/manuals/windows). @@ -411,7 +467,9 @@ Google Cloud Messaging Sender Id. 此值由 Google 签发, 设置后才能开启 #### Iap Provider 指定使用哪个应用商店. 合法值是 `None` 和 `Gameroom`, 默认是 `None`. -## HTML5 +--- + +### HTML5 #### Heap Size 指定Emscripten所使用的堆大小 (兆字节) . 默认值是 256MB. @@ -443,12 +501,16 @@ Google Cloud Messaging Sender Id. 此值由 Google 签发, 设置后才能开启 #### Scale Mode 指定游戏 canvas 所使用的缩放方式. 默认是 `Downscale Fit`. -## IAP +--- + +### IAP #### Auto Finish Transactions 开启后自动完成 IAP 交易. 如果关闭, 在交易成功后你需要手动调用 `iap.finish()` , 默认开启. -## Live update +--- + +### Live update #### Private Key 如果设置了, 则在编译热更新内容时使用指定的私匙. 如果不设置, 则自动生成一个私匙. @@ -456,16 +518,22 @@ Google Cloud Messaging Sender Id. 此值由 Google 签发, 设置后才能开启 #### Public Key 如果设置了, 则在编译热更新内容时使用指定的公匙. 如果不设置, 则自动生成一个私匙. -## Native extension +--- + +### Native extension #### _App Manifest_ 如果设置了, 则在自定义引擎编译时使用指定的 manifest. 此设置可以让你移除引擎不必要的部分来减小包体. 注意此设置尚在测试中. 使用方法详情请见 [这个帖子](https://forum.defold.com/t/native-extensions/4946/142). -## Profiler +--- + +### Profiler #### Track Cpu 如果开启, 则在编译版本中开启 CPU profiling. 通常, 你只能在 debug 版本中进行调试. +--- + ## File format 设置文件的格式时简单的文本 (INI 格式) 并且可以使用标准文本编辑器编辑. 其格式看起来像这样: @@ -489,6 +557,7 @@ main_collection = /main/main.collectionc 当引用了一个文件, 比如上面的例子, 路径尾需要加一个 'c' 字符, 表明引用的时编译后的文件. 注意包含 *game.project* 的文件夹将作为项目根目录, 这就是路径开头使用 '/' 的原因. + ## 在引擎启动时设定配置值 引擎启动时, 可以从命令行输入设置来覆盖 *game.project* 里的设定: @@ -507,6 +576,17 @@ $ dmengine --config=test.my_value=4711 --config=test2.my_value2=1234 local my_value = tonumber(sys.get_config("test.my_value")) ``` +## 最大组件数优化 +配置文件 `game.project` 包含针对各种资源同时存在的最大数目的配置项, 容器大都是每个载入的集合 (也叫做游戏世界). Defold 引擎使用这些最大值来预分配内存以避免游戏运行时内存动态分配及内存碎片化. + +用于表示组件和其他资源的 Defold 数据结构优化为尽可能少用内存, 但当配置这些最大值时仍要留意是否保证了满足游戏运行的需求. + +另一方面 Defold 编译处理会分析游戏内容, 如果明确分析出必要的内存需求则会覆盖最大值设置: + +* 如果集合不含工厂组件则仅分配各个组件必须的内存忽略最大值设置. +* 如果集合包含工厂组件则分析工厂可实例化的游戏对象组件的必要内存并为其实例化分配足够内存. + + ## 垂直同步, 帧数锁定 和 刷新间隔 首先要注意的是桌面平台上垂直同步可以被显卡设置控制. 比如如果在显卡控制面板里强制开启了垂直同步那么从 Defold 的角度是没法读写这个设置的. 大多数移动设备也都默认开启了垂直同步. @@ -514,6 +594,7 @@ local my_value = tonumber(sys.get_config("test.my_value")) 交换间隔是指在垂直空白期 (v-blank) 同步中交换前后缓冲的间隔, 是屏幕图片从前缓冲更新数据的硬件事件. 取值为1就是每个v-blank做一次交换缓冲, 取值为2就是每两个(每隔一个)v-blank做一次交换缓冲, 以此类推. 取值为0则做交换缓冲时不等待v-blank时间\*. 调用 [```set_vsync_swap_interval```](/ref/sys/#sys.set_vsync_swap_interval:swap_interval) 方法可以设置 `swap_interval` 的值. + ### 注意事项 目前, Defold 在初始化时查询屏幕刷新率并且把它作为固定 `dt` 的依据. 如果你需要支持可变刷新率 (比如 GSync 或者 FreeSync) 或者其他刷新率不是很有参考性的情况下, 关闭 `Vsync`来使引擎测量每帧实际 `dt` 而不是固定dt. From 903a6c06597660cbfaceb040c5f552740b439650 Mon Sep 17 00:00:00 2001 From: COCO Date: Sat, 16 Oct 2021 12:35:27 +0800 Subject: [PATCH 039/134] update 2021/10/16 blend-modes.md --- docs/zh/shared/blend-modes.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/zh/shared/blend-modes.md b/docs/zh/shared/blend-modes.md index b136502c..bd37901a 100644 --- a/docs/zh/shared/blend-modes.md +++ b/docs/zh/shared/blend-modes.md @@ -4,7 +4,10 @@ Alpha : 普通混合: `src.a * src.rgb + (1 - src.a) * dst.rgb` Add -: 使用相应的 sprite 像素颜色值提亮背景: `src.rgb + dst.rgb` +: 使用相应组件的像素颜色值提亮背景: `src.rgb + dst.rgb` Multiply -: 使用相应的 sprite 像素颜色值调暗背景: `src.rgb * dst.rgb` +: 使用相应组件的像素颜色值调暗背景: `src.rgb * dst.rgb` + +Screen +: Multiply 的反向操作. 使用相应组件的像素颜色值提亮背景: `src.rgb - dst.rgb * dst.rgb` From 6041435b4d14c79cb197e45aebe7ad2c6218ab5f Mon Sep 17 00:00:00 2001 From: COCO Date: Fri, 12 Nov 2021 12:31:10 +0800 Subject: [PATCH 040/134] update 2021/11/12 --- docs/zh/manuals/dev-app.md | 33 ++---- docs/zh/manuals/editor-keyboard-shortcuts.md | 114 ++++++++++++++++++ docs/zh/manuals/editor-preferences.md | 49 ++++++++ docs/zh/manuals/editor.md | 116 ++----------------- docs/zh/manuals/properties.md | 8 +- docs/zh/manuals/spawning.md | 13 --- 6 files changed, 184 insertions(+), 149 deletions(-) create mode 100644 docs/zh/manuals/editor-keyboard-shortcuts.md create mode 100644 docs/zh/manuals/editor-preferences.md delete mode 100644 docs/zh/manuals/spawning.md diff --git a/docs/zh/manuals/dev-app.md b/docs/zh/manuals/dev-app.md index 78bb6260..d3be4e02 100644 --- a/docs/zh/manuals/dev-app.md +++ b/docs/zh/manuals/dev-app.md @@ -9,37 +9,20 @@ brief: 本教程介绍了如何在设备上安装开发用app以方便开发流 ## 安装开发用app -使用引擎Debug打包的应用都可以用作开发用app. Android 上我们以及提供了 Defold 引擎的开发用app, 但是在 iOS 上的开发用app需要你使用自己的 signing identity 和 provisioning profile 手动打包并签名. +Debug 模式下编译的任何 iOS 或 Android 应用都可以作为开发用app. 事实上, 我们推荐这么做因为开发用app包含正确的项目配置而且拥有和开发时使用的相同的 [原生扩展](/manuals/extensions/). 还有 [Defold 的独立项目](https://github.com/defold/dev-app) (不包含原生扩展的项目) 也设计做为开发用app使用. -### 在 iOS 上安装 - -打包成 Debug 变体的 iOS 应用可以用作开发用app. 推荐就使用你当前的项目打包成 Debug 变体就好. 这样可以保证你的应用使用了正确的项目设置和 [原生扩展](/manuals/extensions/). 关于如何打包ios应用详情请见 [iOS 教程](/manuals/ios/#iOS应用打包). 记得使用 Debug 变体! - -### 在 Android 上安装 - -对ios的建议同样适用于 Android. 然而我们已经编译好了一个开发用 *.apk* 文件. +![launch](images/dev-app/launch.png) ::: 注意 只有在不使用 [原生扩展](/manuals/extensions/) 的项目可以使用我们提供的开发用apk. 否则你需要自己手动打debug包并且加入你所使用的原生扩展. ::: -* 访问 http://d.defold.com Defold下载网站. -* 从列表中选择所需引擎版本. -* 选择 *engine/armv7-android/dmengine.apk* Android开发用app (Armv7). +### Installing on iOS -![Download dmengine](images/dev-app/download_dmengine.png) +依照 [iOS 教程介绍的步骤](/manuals/ios/#creating-an-ios-application-bundle) 打包 iOS 应用. 记得 variant 要选择 Debug! -下载此文件, 在下载存放目录下输入以下 `adb` 命令安装 *.apk*: +### Installing on Android -```sh -$ adb install dmengine.apk -4445 KB/s (8706017 bytes in 1.912s) - pkg: /data/local/tmp/dmengine.apk -Success -``` - -此时 "dmengine" 应用已安装好. - -![dmengine on the device](images/dev-app/dmengine_on_device.png) +依照 [Android 教程介绍的步骤](https://defold.com/manuals/android/#creating-an-android-application-bundle) 打包 Android 应用. ## 启动游戏 @@ -51,8 +34,6 @@ Success 4. 选择 Project ▸ Build 运行游戏. 如果用网络连接的话可能需要等一小会儿. 5. 游戏运行时, 就可以照常使用 [热重载](/manuals/hot-reload/) 功能了. -![launch](images/dev-app/launch.png) - ### 在 Windows 上使用 USB 连接 iOS 设备 要在 Windows 上使用 USB 连接运行于 iOS 设备上的app, 首先 [安装 iTunes](https://www.apple.com/lae/itunes/download/). 安装完之后还需从iOS设备的设置菜单里 [开启 Personal Hotspot](https://support.apple.com/en-us/HT204023). 如果跳出 "Trust This Computer?" 则选择 Trust. 这样设备就会出现在 Project ▸ Targets 列表中了. @@ -81,7 +62,7 @@ Linux 上同样开启 Personal Hotspot 然后 "Trust This Computer". : 确保你的设备 UDID 包含在手机应用签名 provisioning 中. Targets 菜单没有设备 -: 无线连接时确保设备和计算机处于相同子网. +: 确保设备于计算机处于相同 wifi 网络之下. 确保使用 Debug 模式编译开发用app. 弹出消息说版本不匹配 : 这是由于更新了编辑器没更新应用. 用新编辑器重新编译安装应用即可. diff --git a/docs/zh/manuals/editor-keyboard-shortcuts.md b/docs/zh/manuals/editor-keyboard-shortcuts.md new file mode 100644 index 00000000..85954978 --- /dev/null +++ b/docs/zh/manuals/editor-keyboard-shortcuts.md @@ -0,0 +1,114 @@ +--- +title: 编辑器快捷键 +brief: 本教程介绍了当前编辑器快捷键以及如何自定义快捷键. +--- + +# 键盘快捷键 + +## 默认快捷键 + +| 命令 | Windows | macOS | Linux | +|---------|---------|-------|-------| +| Add | A | A | A | +| Add secondary | Shift+A | Shift+A | Shift+A | +| Backwards tab trigger | Shift+Tab | Shift+Tab | Shift+Tab | +| Beginning of file | Ctrl+Home | Cmd+Up | Ctrl+Home | +| Beginning of line | | Ctrl+A | | +| Beginning of line text | Home | Home | Home | +| Build | Ctrl+B | Cmd+B | Ctrl+B | +| Close | Ctrl+W | Cmd+W | Ctrl+W | +| Close all | Shift+Ctrl+W | Shift+Cmd+W | Shift+Ctrl+W | +| Continue | F5 | F5 | F5 | +| Copy | Ctrl+C | Cmd+C | Ctrl+C | +| Cut | Ctrl+X | Cmd+X | Ctrl+X | +| Delete | Delete | Delete | Delete | +| Delete backward | Backspace | Backspace | Backspace | +| Delete line | | Ctrl+D | | +| Delete next word | Ctrl+Delete | Alt+Delete | Ctrl+Delete | +| Delete prev word | Ctrl+Backspace | Alt+Backspace | Ctrl+Backspace | +| Delete to end of line | Shift+Ctrl+Delete | Cmd+Delete | Shift+Ctrl+Delete | +| Documentation | F1 | F1 | F1 | +| Down | Down | Down | Down | +| End of file | Ctrl+End | Cmd+Down | Ctrl+End | +| End of line | End | Ctrl+E | End | +| Enter | Enter | Enter | Enter | +| Erase tool | Shift+E | Shift+E | Shift+E | +| Escape | Esc | Esc | Esc | +| Find next | Ctrl+G | Cmd+G | Ctrl+G | +| Find prev | Shift+Ctrl+G | Shift+Cmd+G | Shift+Ctrl+G | +| Find text | Ctrl+F | Cmd+F | Ctrl+F | +| Frame selection | F | F | F | +| Goto line | Ctrl+L | Cmd+L | Ctrl+L | +| Hide selected | Ctrl+E | Cmd+E | Ctrl+E | +| Hot reload | Ctrl+R | Cmd+R | Ctrl+R | +| Left | Left | Left | Left | +| Move down | Alt+Down | Alt+Down | Alt+Down | +| Move tool | W | W | W | +| Move up | Alt+Up | Alt+Up | Alt+Up | +| New file | Ctrl+N | Cmd+N | Ctrl+N | +| Next word | Ctrl+Right | Alt+Right | Ctrl+Right | +| Open | Ctrl+O | Cmd+O | Ctrl+O | +| Open asset | Shift+Ctrl+R | Cmd+P | Shift+Ctrl+R | +| Page down | Page Down | Page Down | Page Down | +| Page up | Page Up | Page Up | Page Up | +| Paste | Ctrl+V | Cmd+V | Ctrl+V | +| Preferences | Ctrl+Comma | Cmd+Comma | Ctrl+Comma | +| Prev word | Ctrl+Left | Alt+Left | Ctrl+Left | +| Proposals | Ctrl+Space | Ctrl+Space | Ctrl+Space | +| Quit | Ctrl+Q | Cmd+Q | Ctrl+Q | +| Realign camera | Period | Period | Period | +| Rebuild | Shift+Ctrl+B | Shift+Cmd+B | Shift+Ctrl+B | +| Rebundle | Ctrl+U | Cmd+U | Ctrl+U | +| Redo | Shift+Ctrl+Z | Shift+Cmd+Z | Shift+Ctrl+Z | +| Reindent | Ctrl+I | Ctrl+I | Ctrl+I | +| Reload stylesheet | | Ctrl+R | | +| Rename | F2 | F2 | F2 | +| Replace next | Shift+Ctrl+H | Alt+Cmd+G | Shift+Ctrl+H | +| Replace text | | Alt+Cmd+F | | +| Right | Right | Right | Right | +| Rotate tool | E | E | E | +| Save all | Ctrl+S | Cmd+S | Ctrl+S | +| Scale tool | R | R | R | +| Scene stop | Ctrl+T | Cmd+T | Ctrl+T | +| Search in files | Shift+Ctrl+F | Shift+Cmd+F | Shift+Ctrl+F | +| Select all | Ctrl+A | Cmd+A | Ctrl+A | +| Select beginning of file | Shift+Ctrl+Home | Shift+Cmd+Up | Shift+Ctrl+Home | +| Select beginning of line | | Shift+Ctrl+A | | +| Select beginning of line text | Shift+Home | Shift+Home | Shift+Home | +| Select down | Shift+Down | Shift+Down | Shift+Down | +| Select end of file | Shift+Ctrl+End | Shift+Cmd+Down | Shift+Ctrl+End | +| Select end of line | Shift+End | Shift+Alt+Down | Shift+End | +| Select left | Shift+Left | Shift+Left | Shift+Left | +| Select next occurrence | Ctrl+D | Cmd+D | Ctrl+D | +| Select next word | Shift+Ctrl+Right | Shift+Alt+Right | Shift+Ctrl+Right | +| Select page down | Shift+Page Down | Shift+Page Down | Shift+Page Down | +| Select page up | Shift+Page Up | Shift+Page Up | Shift+Page Up | +| Select prev word | Shift+Ctrl+Left | Shift+Ctrl+Left | Shift+Ctrl+Left | +| Select right | Shift+Right | Shift+Right | Shift+Right | +| Show last hidden | Shift+Ctrl+E | Shift+Cmd+E | Shift+Ctrl+E | +| Show palette | Space | Space | Space | +| Split selection into lines | Shift+Ctrl+L | Shift+Cmd+L | Shift+Ctrl+L | +| Step into | F11 | F11 | F11 | +| Step out | Shift+F11 | Shift+F11 | Shift+F11 | +| Step over | F10 | F10 | F10 | +| Stop debugger | Shift+F5 | | Shift+F5 | +| Tab | Tab | Tab | Tab | +| Toggle breakpoint | F9 | F9 | F9 | +| Toggle comment | Ctrl+Slash | Cmd+Slash | Ctrl+Slash | +| Toggle component guides | Ctrl+H | Ctrl+Cmd+H | Ctrl+H | +| Toggle pane bottom | F7 | F7 | F7 | +| Toggle pane left | F6 | F6 | F6 | +| Toggle pane right | F8 | F8 | F8 | +| Toggle visibility filters | Shift+Ctrl+I | Shift+Cmd+I | Shift+Ctrl+I | +| Undo | Ctrl+Z | Cmd+Z | Ctrl+Z | +| Up | Up | Up | Up | +| Up major | Shift+Up | Shift+Up | Shift+Up | +| Zoom in | Ctrl+'+' | Cmd+'+' | Ctrl+'+' | +| Zoom out | Ctrl+'-' | Cmd+'-' | Ctrl+'-' | + + +## 自定义快捷键 + +可以创建一个配置文件自定义快捷键 (比如在根目录创建 `keymap.edn`). 然后选择 File ▸ Preferences, 设置 Path to custom keymap 为刚才创建的配置文件. 然后重启 Defold 即可, 每次修改快捷键配置文件之后也要重启生效. + +自定义快捷键配置文件示例: [Windows](examples/keymap_win.edn), [MacOS](examples/keymap_macos.edn) 和 [Linux](examples/keymap_linux.edn) diff --git a/docs/zh/manuals/editor-preferences.md b/docs/zh/manuals/editor-preferences.md new file mode 100644 index 00000000..00e5d03a --- /dev/null +++ b/docs/zh/manuals/editor-preferences.md @@ -0,0 +1,49 @@ +--- +title: 编辑器配置 +brief: 可以通过设置窗口修改编辑器配置. +--- + +# 编辑器配置 + +可以通过设置窗口修改编辑器配置. 选择菜单栏 File -> Preferences 即可打开设置窗口. + +## General + +![](images/editor/preferences_general.png) + +Enable Texture Compression +: 开启编译 [纹理压缩](/manuals/texture-profiles). + +Escape Quits Game +: 用 Esc 键关闭正在运行的编译好的游戏. + +Track Active Tab in Asset Browser +: 在 *编辑器* 面板编辑的文件自动在资源浏览器 (也叫 *Asset* 面板) 中选中. + +Path to custom keymap +: [自定义快捷键](/manuals/editor-keyboard-shortcuts) 配置文件的绝对路径. + +Code editor font +: 编码窗口所使用的系统字体. + + +## Code + +![](images/editor/preferences_code.png) + +Custom Editor +: 自定义编辑器的绝对路径. 在 macOS 上应指向 .app 内的可执行程序 (比如 `/Applications/Atom.app/Contents/MacOS/Atom`). + +Open File +: 自定义编辑器开启时要打开的文件的表达式. 其中 `{file}` 在开启时会被真实文件名代替. + +Open File at Line +: 自定义编辑器开启时要打开的文件以及指定光标放置的行数. 表达式 `{file}` 在开启时会被真是文件名代替, 而 `{line}` 被行号代替. + + +## Extensions + +![](images/editor/preferences_extensions.png) + +Build Server +: 编译包含 [原生扩展](/manuals/extensions) 项目时使用的编译服务器的 URL. diff --git a/docs/zh/manuals/editor.md b/docs/zh/manuals/editor.md index dbf6df2f..fb97fa0d 100644 --- a/docs/zh/manuals/editor.md +++ b/docs/zh/manuals/editor.md @@ -140,115 +140,13 @@ Defold 编辑器被划分为许多面板, 或称视图, 以展示和编辑数据 ![Update from editor](images/editor/update-main.png){srcset="images/editor/update-main@2x.png 2x"} -## 快捷键 - -### 默認快捷鍵 - -| Command | Windows | macOS | Linux | -|---------|---------|-------|-------| -| Add | A | A | A | -| Add secondary | Shift+A | Shift+A | Shift+A | -| Backwards tab trigger | Shift+Tab | Shift+Tab | Shift+Tab | -| Beginning of file | Ctrl+Home | Cmd+Up | Ctrl+Home | -| Beginning of line | | Ctrl+A | | -| Beginning of line text | Home | Home | Home | -| Build | Ctrl+B | Cmd+B | Ctrl+B | -| Close | Ctrl+W | Cmd+W | Ctrl+W | -| Close all | Shift+Ctrl+W | Shift+Cmd+W | Shift+Ctrl+W | -| Continue | F5 | F5 | F5 | -| Copy | Ctrl+C | Cmd+C | Ctrl+C | -| Cut | Ctrl+X | Cmd+X | Ctrl+X | -| Delete | Delete | Delete | Delete | -| Delete backward | Backspace | Backspace | Backspace | -| Delete line | | Ctrl+D | | -| Delete next word | Ctrl+Delete | Alt+Delete | Ctrl+Delete | -| Delete prev word | Ctrl+Backspace | Alt+Backspace | Ctrl+Backspace | -| Delete to end of line | Shift+Ctrl+Delete | Cmd+Delete | Shift+Ctrl+Delete | -| Documentation | F1 | F1 | F1 | -| Down | Down | Down | Down | -| End of file | Ctrl+End | Cmd+Down | Ctrl+End | -| End of line | End | Ctrl+E | End | -| Enter | Enter | Enter | Enter | -| Erase tool | Shift+E | Shift+E | Shift+E | -| Escape | Esc | Esc | Esc | -| Find next | Ctrl+G | Cmd+G | Ctrl+G | -| Find prev | Shift+Ctrl+G | Shift+Cmd+G | Shift+Ctrl+G | -| Find text | Ctrl+F | Cmd+F | Ctrl+F | -| Frame selection | F | F | F | -| Goto line | Ctrl+L | Cmd+L | Ctrl+L | -| Hide selected | Ctrl+E | Cmd+E | Ctrl+E | -| Hot reload | Ctrl+R | Cmd+R | Ctrl+R | -| Left | Left | Left | Left | -| Move down | Alt+Down | Alt+Down | Alt+Down | -| Move tool | W | W | W | -| Move up | Alt+Up | Alt+Up | Alt+Up | -| New file | Ctrl+N | Cmd+N | Ctrl+N | -| Next word | Ctrl+Right | Alt+Right | Ctrl+Right | -| Open | Ctrl+O | Cmd+O | Ctrl+O | -| Open asset | Shift+Ctrl+R | Cmd+P | Shift+Ctrl+R | -| Page down | Page Down | Page Down | Page Down | -| Page up | Page Up | Page Up | Page Up | -| Paste | Ctrl+V | Cmd+V | Ctrl+V | -| Preferences | Ctrl+Comma | Cmd+Comma | Ctrl+Comma | -| Prev word | Ctrl+Left | Alt+Left | Ctrl+Left | -| Proposals | Ctrl+Space | Ctrl+Space | Ctrl+Space | -| Quit | Ctrl+Q | Cmd+Q | Ctrl+Q | -| Realign camera | Period | Period | Period | -| Rebuild | Shift+Ctrl+B | Shift+Cmd+B | Shift+Ctrl+B | -| Rebundle | Ctrl+U | Cmd+U | Ctrl+U | -| Redo | Shift+Ctrl+Z | Shift+Cmd+Z | Shift+Ctrl+Z | -| Reindent | Ctrl+I | Ctrl+I | Ctrl+I | -| Reload stylesheet | | Ctrl+R | | -| Rename | F2 | F2 | F2 | -| Replace next | Shift+Ctrl+H | Alt+Cmd+G | Shift+Ctrl+H | -| Replace text | | Alt+Cmd+F | | -| Right | Right | Right | Right | -| Rotate tool | E | E | E | -| Save all | Ctrl+S | Cmd+S | Ctrl+S | -| Scale tool | R | R | R | -| Scene stop | Ctrl+T | Cmd+T | Ctrl+T | -| Search in files | Shift+Ctrl+F | Shift+Cmd+F | Shift+Ctrl+F | -| Select all | Ctrl+A | Cmd+A | Ctrl+A | -| Select beginning of file | Shift+Ctrl+Home | Shift+Cmd+Up | Shift+Ctrl+Home | -| Select beginning of line | | Shift+Ctrl+A | | -| Select beginning of line text | Shift+Home | Shift+Home | Shift+Home | -| Select down | Shift+Down | Shift+Down | Shift+Down | -| Select end of file | Shift+Ctrl+End | Shift+Cmd+Down | Shift+Ctrl+End | -| Select end of line | Shift+End | Shift+Alt+Down | Shift+End | -| Select left | Shift+Left | Shift+Left | Shift+Left | -| Select next occurrence | Ctrl+D | Cmd+D | Ctrl+D | -| Select next word | Shift+Ctrl+Right | Shift+Alt+Right | Shift+Ctrl+Right | -| Select page down | Shift+Page Down | Shift+Page Down | Shift+Page Down | -| Select page up | Shift+Page Up | Shift+Page Up | Shift+Page Up | -| Select prev word | Shift+Ctrl+Left | Shift+Ctrl+Left | Shift+Ctrl+Left | -| Select right | Shift+Right | Shift+Right | Shift+Right | -| Show last hidden | Shift+Ctrl+E | Shift+Cmd+E | Shift+Ctrl+E | -| Show palette | Space | Space | Space | -| Split selection into lines | Shift+Ctrl+L | Shift+Cmd+L | Shift+Ctrl+L | -| Step into | F11 | F11 | F11 | -| Step out | Shift+F11 | Shift+F11 | Shift+F11 | -| Step over | F10 | F10 | F10 | -| Stop debugger | Shift+F5 | | Shift+F5 | -| Tab | Tab | Tab | Tab | -| Toggle breakpoint | F9 | F9 | F9 | -| Toggle comment | Ctrl+Slash | Cmd+Slash | Ctrl+Slash | -| Toggle component guides | Ctrl+H | Ctrl+Cmd+H | Ctrl+H | -| Toggle pane bottom | F7 | F7 | F7 | -| Toggle pane left | F6 | F6 | F6 | -| Toggle pane right | F8 | F8 | F8 | -| Toggle visibility filters | Shift+Ctrl+I | Shift+Cmd+I | Shift+Ctrl+I | -| Undo | Ctrl+Z | Cmd+Z | Ctrl+Z | -| Up | Up | Up | Up | -| Up major | Shift+Up | Shift+Up | Shift+Up | -| Zoom in | Ctrl+'+' | Cmd+'+' | Ctrl+'+' | -| Zoom out | Ctrl+'-' | Cmd+'-' | Ctrl+'-' | - - -### 自定義快捷鍵 - -可以創建配置文件以自定義快捷鍵 (例如 home 文件夾下的 `keymap.edn` 文件). 然後選擇 File ▸ Preferences, 設置 Path to custom keymap 為自定義的配置文件. 設置好之後重啓 Defold 才會生效, 每次修改都要重啓. - -這些配置文件可以用來參考: [Windows](examples/keymap_win.edn), [MacOS](examples/keymap_macos.edn) 和 [Linux](examples/keymap_linux.edn) +## 配置 + +可以 [通过设置窗口](/manuals/editor-preferences) 修改编辑器配置. + +## 键盘快捷键 + +键盘快捷键及自定义方法详见 [键盘快捷键教程](/manuals/editor-keyboard-shortcuts). ## 编辑器日志 使用编辑器时如果遇到了麻烦可以 [向我们汇报](/manuals/getting-help/#获得帮助), 并且连同编辑器日志一起上报. 编辑器日志存放路径如下: diff --git a/docs/zh/manuals/properties.md b/docs/zh/manuals/properties.md index c092e0d7..78d26c28 100644 --- a/docs/zh/manuals/properties.md +++ b/docs/zh/manuals/properties.md @@ -66,8 +66,11 @@ local color = gui.get_color(node) | 属性 | 描述 | 类型 | | | ---------- | -------------------------------------- | --------------- | ---------------- | | *size* | sprite 原始尺寸 --- 从图集图片而定的尺寸. | `vector3` | `get`{.mark} | -| *texture0* | sprite 纹理路径hash. | `hash` | `get`{.mark}| +| *image* | sprite 纹理路径hash. | `hash` | `get`{.mark}| | *scale* | sprite 非等比缩放. | `vector3` | `get+set`{.mark}| +| *material* | sprite 使用的材质. | `hash` | `get+set`{.mark}| +| *cursor* | 动画播放头位置 (取值范围 0--1). | `number` | `get+set`{.mark}| +| *playback_rate* | 逐帧动画播放速率. | `number` | `get+set`{.mark}| *COLLISION OBJECT 组件属性* @@ -96,6 +99,7 @@ local color = gui.get_color(node) | *texture0* | 模型的纹理路径hash. | `hash` | `get`{.mark}| | *cursor* | 当前动画播放头 (取值范围 0-1). | `number` | `get+set`{.mark} | | *playback_rate* | 当前动画播放速率. 即播放速度倍数. | `number` | `get+set`{.mark} | +| *material* | 模型所用材质. | `hash` | `get+set`{.mark}| *LABEL 组件属性* @@ -106,6 +110,8 @@ local color = gui.get_color(node) | *outline* | 文本标签的轮廓. | `vector4` | `get+set`{.mark} | | *shadow* | 文本标签的阴影. | `vector4` | `get+set`{.mark} | | *size* | 文本标签的大小. 如果开启换行的话文本标签大小会被约束. | `vector3` | `get+set`{.mark} | +| *material* | 文本标签所用材质. | `hash` | `get+set`{.mark}| +| *font* | 文本标签所用字体. | `hash` | `get+set`{.mark}| ## GUI 节点属性 diff --git a/docs/zh/manuals/spawning.md b/docs/zh/manuals/spawning.md deleted file mode 100644 index cc4f2f39..00000000 --- a/docs/zh/manuals/spawning.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: Defold中的动态实例化 -brief: 本教程介绍了如何实例化游戏对象. ---- - -# 资源与实例化 - -本教程介绍了 Defold's 动态实例化的使用方法. - -Defold 在运行时使用两种组件用作实例化. 比如实例化主角开枪发射的子弹, 事实特效, 或者, 敌人被打败时掉落的物品. - - - From 4533e78538c1373538ff1cf78666e1727cc6c84b Mon Sep 17 00:00:00 2001 From: COCO Date: Thu, 2 Dec 2021 15:29:39 +0800 Subject: [PATCH 041/134] allow dynamic transforms update --- docs/zh/manuals/project-settings.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/zh/manuals/project-settings.md b/docs/zh/manuals/project-settings.md index fa2bba9a..62941210 100644 --- a/docs/zh/manuals/project-settings.md +++ b/docs/zh/manuals/project-settings.md @@ -154,10 +154,10 @@ debug线的不透明度, `0`--`1`. 默认是 `0.9`. 设定物理世界与游戏世界的数值映射比例, `0.01`--`1.0`. 如果设置为 `0.02`, 相当于物理引擎视50个游戏单位为1米 ($1 / 0.02$). 默认值是 `1.0`. #### Allow Dynamic Transforms -設置物理碰撞對象縮放是否繼承于其父級游戲對象. 默認為 `true`. +設置物理碰撞對象的变化是否繼承于其父級游戲對象, 所谓变化包括父级的移动, 缩放和缩放, 即使当前物体是动态物理物体也可继承父级的变化. 默認為 `true`. #### Debug Scale -设置物理元物体画多大, 比如原向量和法线, 默认是 `30`. +设置物理标识画多大, 比如原向量和法线, 默认是 `30`. #### Max Collisions 设置向脚本报告多少个碰撞, 默认是 `64`. From fdd1df5a50c184f9fd09d34838bdad090ca5655f Mon Sep 17 00:00:00 2001 From: COCO Date: Mon, 13 Dec 2021 19:04:49 +0800 Subject: [PATCH 042/134] Bundle update --- docs/zh/manuals/bundling.md | 23 +++++++++++++++++++++++ docs/zh/manuals/project-settings.md | 19 +++++++++++++------ 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/docs/zh/manuals/bundling.md b/docs/zh/manuals/bundling.md index cc5d613b..e1d8f623 100644 --- a/docs/zh/manuals/bundling.md +++ b/docs/zh/manuals/bundling.md @@ -56,4 +56,27 @@ brief: 本教程介绍了如何打包应用. ## 命令行打包 +编辑器使用命令行工具 [Bob](/manuals/bob/) 进行应用打包. + 日常开发中一般使用 Defold 编辑器编译和打包应用. 如果需要自动生成机制, 比如发布新版本时批处理所有平台或者使用持续集成环境持续生成最新版本. 可以使用 [Bob 命令行工具](/manuals/bob/) 编译和打包. + +## Bundle 结构 + +Bundle 的逻辑结构是这样的: + +![](images/bundling/bundle_schematic_01.png) + +Bundle 会被输出到一个文件夹. 不同平台位置各异, 还有可能作为 zip 文件包含进 `.apk` 或者 `.ipa` 中. +Bundle 文件夹的内容每个平台也不一样. + +除了可执行文件, 打包过程中也会收集相关平台所必须的资源 (比如安卓平台用的 .xml 资源文件). + +通过 [bundle_resources](https://defold.com/manuals/project-settings/#bundle-resources) 项, 设置应打包进 bundle 里的资源. +可以针对不同平台分别设置. + +游戏资源被保存在 `game.arcd` 文件中, 使用 LZ4 算法逐个压缩. +通过 [custom_resources](https://defold.com/manuals/project-settings/#custom-resources) 项, 设置应打包 (同时也被压缩) 进 game.arcd 里的资源. +这类资源可以使用 [sys.load_resource()](https://defold.com/ref/sys/#sys.load_resource) 函数来进行访问. + + + diff --git a/docs/zh/manuals/project-settings.md b/docs/zh/manuals/project-settings.md index 62941210..99cd6c8f 100644 --- a/docs/zh/manuals/project-settings.md +++ b/docs/zh/manuals/project-settings.md @@ -37,17 +37,24 @@ $ adb shell cat /mnt/sdcard/Android/data/com.defold.dmengine/files/log.txt 项目的 *Library URL* 列表. 详情请见 [Libraries 教程](/manuals/libraries/). #### Custom Resources +`custom_resources` 项目中包含的以逗号分隔的资源列表. 如指定的是目录, 则目录下所有文件及其子目录都会包含进去. 这些资源可以通过 [`sys.load_resource()`](/ref/sys/#sys.load_resource) 载入. #### Bundle Resources +`bundle_resources` 需要根据平台单独打包的以逗号分隔的资源目录列表. 目录必须是以项目根目录开始的绝对路径, 比如像 `/res`. 资源目录里要包含 `platform`, 或者 `architecure-platform` 的子目录. - 支持的 platform 有 `ios`, `android`, `osx`, `win32`, `linux`, `web`. +支持的 platform 有 `ios`, `android`, `osx`, `win32`, `linux`, `web`, `switch`. - 允许名叫 `common` 的子目录, 用以容纳平台间共享的资源. +支持包含名为 `common` 的文件夹, 可以在其中加入各平台公用的资源文件. + +不同平台访问 bundle 资源的方法不一样. 使用 Lua 的 `io` 模块是可行的. 但是要特别注意写对各平台的文件路径. +(举例: 在安卓平台上要这么写 "file:///android_asset/") #### Bundle Exclude Resources +`bundle_exclude_resources` 项目中排除的以逗号分隔的资源列表. +也就是说, 这些资源会被从 `bundle_resources` 设置的基础上被剔除. --- @@ -114,16 +121,16 @@ $ adb shell cat /mnt/sdcard/Android/data/com.defold.dmengine/files/log.txt ### Render #### Clear Color Red -清除红色通道, 建立游戏窗口和渲染脚本中使用. 1.2.167 版新增. +清除红色通道, 建立游戏窗口和渲染脚本中使用. #### Clear Color Green -清除绿色通道, 建立游戏窗口和渲染脚本中使用. 1.2.167 版新增. +清除绿色通道, 建立游戏窗口和渲染脚本中使用. #### Clear Color Blue -清除蓝色通道, 建立游戏窗口和渲染脚本中使用. 1.2.167 版新增. +清除蓝色通道, 建立游戏窗口和渲染脚本中使用. #### Clear Color ALpha -清除alpha通道, 建立游戏窗口和渲染脚本中使用. 1.2.167 版新增. +清除alpha通道, 建立游戏窗口和渲染脚本中使用. --- From dca745e4fd1f60314c525138e4d6d49d30cec914 Mon Sep 17 00:00:00 2001 From: COCO Date: Fri, 31 Dec 2021 11:30:49 +0800 Subject: [PATCH 043/134] update faq --- docs/zh/shared/windows-faq.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/zh/shared/windows-faq.md b/docs/zh/shared/windows-faq.md index 7b72c27a..65a74588 100644 --- a/docs/zh/shared/windows-faq.md +++ b/docs/zh/shared/windows-faq.md @@ -5,3 +5,7 @@ A: 这个错误发生在 [使用 AMD Radeon GPU 的机器](https://github.com/de #### Q: 打开图集或者场景视图时报错 'com.sun.jna.Native.open.class java.lang.Error: Access is denied'? A: 试试以管理员身份打开 Defold. 右键点击 Defold 可执行程序选择 "以管理员身份运行". + +#### Q: 爲什麽在 Windows 上使用 Intel UHD 集成 GPU 渲染不正常 (但是 HTML5 版本正常)? + +A: 確保你的驅動版本大於等於 27.20.100.8280. 參見 [Intel Driver Support Asistant](https://www.intel.com/content/www/us/en/search.html?ws=text#t=Downloads&layout=table&cf:Downloads=%5B%7B%22actualLabel%22%3A%22Graphics%22%2C%22displayLabel%22%3A%22Graphics%22%7D%2C%7B%22actualLabel%22%3A%22Intel%C2%AE%20UHD%20Graphics%20Family%22%2C%22displayLabel%22%3A%22Intel%C2%AE%20UHD%20Graphics%20Family%22%7D%2C%7B%22actualLabel%22%3A%22Intel%C2%AE%20UHD%20Graphics%20630%22%2C%22displayLabel%22%3A%22Intel%C2%AE%20UHD%20Graphics%20630%22%7D%5D). 更多信息請見 [這個帖子](https://forum.defold.com/t/sprite-game-object-is-not-rendering/69198/35?u=britzl). \ No newline at end of file From ed539b50cedcc6c09a5e4021a6af9c82a40473a3 Mon Sep 17 00:00:00 2001 From: COCO Date: Sat, 15 Jan 2022 13:50:23 +0800 Subject: [PATCH 044/134] bullet & bob --- docs/zh/manuals/bob.md | 109 ++++++++++++++--------------- docs/zh/manuals/physics-objects.md | 3 + 2 files changed, 54 insertions(+), 58 deletions(-) diff --git a/docs/zh/manuals/bob.md b/docs/zh/manuals/bob.md index 522e9b72..fbdd29e0 100644 --- a/docs/zh/manuals/bob.md +++ b/docs/zh/manuals/bob.md @@ -18,64 +18,57 @@ Bob 运行于命令行界面 `java` (再Windows上是 `java.exe`) 后跟bob的ja ```text $ java -jar bob.jar --help usage: bob [options] [commands] - -a,--archive 编译数据包 - -ar,--architectures 逗号分割发布架构, 例如 "arm64-android,armv7-android" - -u,--auth 作者認證標記 - --binary-output 指定可执行文件存放地址 - 默认地址是 - "//" - -br,--build-report 指定编译报告的存放存放地址 - 报告为JSON格式 - -brhtml,--build-report-html 指定编译报告的存放存放地址 - 报告为HTML格式 - --build-server 编译服务器 (当使用原生扩展 - 时使用) - -bo,--bundle-output 打包輸出目錄 - --bundle-format Android 打包格式 - -d,--debug 使用dmengine的debug版本(当 - 编译时). 弃用, 使用--variant - 代替 - --debug-ne-upload 把文件打包為upload.zip之後上傳到 - 編譯服務器 - --defoldsdk 指定defold sdk (sha1) - 使用版本 - --exclude-build-folder 逗號分割的排除目錄列表 - -e,--email 用户电邮 - -h,--help 帮助文档 - -i,--input 指定源目录, 默认是当前 - 目录 - --identity 指定签名 (iOS) - -k,--keep-unused 指定未使用资源仍然打包 - 输出 - --keystore Android 打包密鑰文件. - --keystore-pass Android 打包密鑰密碼文件路徑. - --keystore-alias Android 打包密鑰別名文件路徑. - -l,--liveupdate 要在发布后使用热更新功能 - 参数填 yes - -mp,--mobileprovisioning 指定 mobileprovisioning profile (iOS) - -o,--output 输出目录. 默认是 - "build/default" - -p,--platform 发布平台 (打包时) - -r,--root 指定编译目录. 默认是 - 当前目录 - --settings 指定项目设置文件的 - 路径. 可以使用多个 - 文件. 设置根据文件 - 从左到右应用. - --strip-executable 去掉dmengine的debug信息 - (编译 iOS 或 Android时) - -tc,--texture-compression 使用纹理档中指定的 - 纹理压缩 - -tp,--texture-profiles 使用纹理压缩档 (弃用) - --use-vanilla-lua 只使用 vanilla 源代码 (即 - 不要字节码) - -v,--verbose 冗余输出 - --variant 指定使用 debug, release 或者 headless - 的dmengine版本 (编译时) - --version 打印输出 - 版本号 - --with-symbols 生成标记文件 (如果 - 可用) +-a,--archive 编译数据包 +-ar,--architectures 逗号分割发布平台包含的架构 + --archive-resource-padding 游戏包中的资源对齐间隔. 默认值为4. +-bf,--bundle-format 游戏包格式 (Android: 'apk' 和 'aab') + --binary-output 指定可执行文件存放地址, 默认地址是 + "//" +-bo,--bundle-output 打包输出目录 +-br,--build-report 指定编译生成的JSON报告的存放地址 +-brhtml,--build-report-html 指定编译生成的HTML报告的存放地址 + --build-artifacts 编译对象, 不指定的话默认为编译engine. + 可选项为 'engine', 'plugins'. + 以逗号分隔. + --build-server 编译服务器 (使用原生扩展时需指定) +-ce,--certificate 已弃用! 指定证书 (Android) +-d,--debug 使用dmengine的debug版本(当 + 编译时). 已弃用, 使用--variant代替 + --debug-ne-upload 把文件打包為upload.zip后上傳到 + 編譯服務器 + --defoldsdk 指定defold sdk (sha1) 使用版本 +-e,--email 用户电邮 + --exclude-build-folder 逗號分割的排除目錄列表 +-h,--help 帮助文档 +-i,--input 指定源目录, 默认是当前目录 + --identity 指定签名 (iOS) +-k,--keep-unused 使未使用的资源仍然被打包输出 + --keystore Android 打包密鑰文件. + --keystore-alias Android 打包密鑰別名文件路徑. + --keystore-pass Android 打包密鑰密碼文件路徑. +-l,--liveupdate 要在发布后使用热更新功能, 该参数填 yes +-mp,--mobileprovisioning 指定 mobileprovisioning profile (iOS) +-o,--output 输出目录. 默认是 "build/default" +-p,--platform 发布平台 (打包时) +-pk,--private-key 已弃用! 指定密钥 (Android) +-r,--root 指定编译目录. 默认是当前目录 + --resource-cache-local 本地资源缓存地址. + --resource-cache-remote 远程资源缓存URL. + --resource-cache-remote-pass 远程资源存取认证的密码/令牌. + --resource-cache-remote-user 远程资源存取认证的用户名. + --settings 指定项目设置文件的路径. 可以使用多个 + 文件. 设置根据文件, 从左到右应用. + --strip-executable 去掉dmengine的debug信息 (编译 iOS 或 Android时) +-tc,--texture-compression 使用纹理档中指定的纹理压缩 +-tp,--texture-profiles 使用纹理压缩档 (已弃用) +-u,--auth 用户认证令牌 + --use-vanilla-lua 只输出源代码 + (例如, 不要字节码) +-v,--verbose 冗余输出 + --variant 指定使用 debug, release 或者 headless + 的dmengine版本 (编译时) + --version 打印输出版本号 + --with-symbols 生成标记文件 (如果可用) ``` 支持的命令: diff --git a/docs/zh/manuals/physics-objects.md b/docs/zh/manuals/physics-objects.md index b7c0d9ce..6caad1ff 100644 --- a/docs/zh/manuals/physics-objects.md +++ b/docs/zh/manuals/physics-objects.md @@ -83,6 +83,9 @@ Angular damping Locked rotation : 关闭碰撞对象的旋转, 无论力如何施加都不会旋转. +Bullet +: 开启此项将会在该碰撞物体和其他动态碰撞物体直接进行连续碰撞检测 (CCD). 如果一方碰撞物体不是 `Dynamic` 的, 则忽略该选项. + Group : 此碰撞对象所归属的碰撞组. 可以自由定义16个组. 比如 "players", "bullets", "enemies" 或 "world". 如果瓷砖地图上设置了 *Collision Shape*, 则使用的是瓷砖图源里的组名而不是该属性定义的组名. From 540f8f6fdb0a29471f06b0bfb1e77d353679c635 Mon Sep 17 00:00:00 2001 From: COCO Date: Sun, 30 Jan 2022 12:15:39 +0800 Subject: [PATCH 045/134] script properties update --- docs/zh/manuals/script-properties.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/docs/zh/manuals/script-properties.md b/docs/zh/manuals/script-properties.md index 21abfa63..893d7f69 100644 --- a/docs/zh/manuals/script-properties.md +++ b/docs/zh/manuals/script-properties.md @@ -19,13 +19,14 @@ brief: 本教程介绍了如何对脚本组件添加属性以及如何在运行 脚本组件中属性由 `go.property()` 函数定义. 函数应位于顶级---不应在 `init()` 和 `update()` 之类的函数内部调用. 默认值决定了值类型: number, boolean, hash, `msg.url`, `vmath.vector3`, `vmath.vector4` 还是 `vmath.quaternion`. (好像最新版已经提供了属性类型的设置功能) ```lua --- Define script properties for health and an attack target +-- can.script +-- 对 health 和 target 创建脚本属性 go.property("health", 100) go.property("target", msg.url()) function init(self) - -- store initial position of target. - -- self.target is an url referencing another objects. + -- 初始化 target 位置. + -- self.target 是用 url 引用的另一个游戏对象. self.target_pos = go.get_position(self.target) ... end @@ -72,11 +73,11 @@ end ```lua -- another.script --- increase "my_property" in "myobject#script" by 1 +-- 对 "myobject#script" 里的 "my_property" 实施增 1 local val = go.get("myobject#my_script", "my_property") go.set("myobject#my_script", "my_property", val + 1) --- animate "my_property" in "myobject#my_script" +-- 对 "myobject#my_script" 里的 "my_property" 实施动画 go.animate("myobject#my_script", "my_property", go.PLAYBACK_LOOP_PINGPONG, 100, go.EASING_LINEAR, 2.0) ``` @@ -86,7 +87,11 @@ go.animate("myobject#my_script", "my_property", go.PLAYBACK_LOOP_PINGPONG, 100, ```lua local props = { health = 50, target = msg.url("player") } -factory.create("#can_factory", nil, nil, props) +local id = factory.create("#can_factory", nil, nil, props) + +-- 访问工厂创建对象的脚本属性 +local url = msg.url(nil, id, "can") +local can_health = go.get(url, "health") ``` 当使用 `collectionfactory.create()` 创建对象时需要匹配id与对应的属性. 保存在一个表里传入 `create()` 函数: From 56fb1d11b955d6628eb83c971ed15214b136a52c Mon Sep 17 00:00:00 2001 From: COCO Date: Sun, 13 Feb 2022 15:40:15 +0800 Subject: [PATCH 046/134] editor-styling --- docs/zh/manuals/editor-styling.md | 129 ++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 docs/zh/manuals/editor-styling.md diff --git a/docs/zh/manuals/editor-styling.md b/docs/zh/manuals/editor-styling.md new file mode 100644 index 00000000..02a56791 --- /dev/null +++ b/docs/zh/manuals/editor-styling.md @@ -0,0 +1,129 @@ +--- +title: 编辑器风格 +brief: 您可以使用自定义 stylesheet 修改编辑器配色, 文本及其他可视元素. +--- + +# 编辑器风格 + +您可以使用自定义 stylesheet 修改编辑器配色, 文本及其他可视元素: + +* 在用户目录下创建文件夹并命名为 `.defold`. + * Windows 路径 `C:\Users\**Your Username**\.defold` + * macOS 路径 `/Users/**Your Username**/.defold` + * Linux 路径 `~/.defold` + * 在 `.defold` 目录下创建一个 `editor.css` 文件. + +编辑器启动时会加载您的自定义 stylesheet 作为优先默认风格. 编辑器使用 JavaFX 编写用户界面所以 stylesheets 几乎等价于浏览器里支持的网页 CSS 文件. 官方默认的 stylesheets 保存于 [GitHub 上](https://github.com/defold/defold/tree/editor-dev/editor/styling/stylesheets/base). + +## 修改颜色 + +默认颜色在 [`_palette.scss`](https://github.com/defold/defold/blob/editor-dev/editor/styling/stylesheets/base/_palette.scss) 中定义, 类似如下设置: + +``` +* { + // Background + -df-background-darker: derive(#212428, -10%); + -df-background-dark: derive(#212428, -5%); + -df-background: #212428; + -df-background-light: derive(#212428, 10%); + -df-background-lighter: derive(#212428, 20%); + + // Component + -df-component-darker: derive(#464c55, -20%); + -df-component-dark: derive(#464c55, -10%); + -df-component: #464c55; + -df-component-light: derive(#464c55, 10%); + -df-component-lighter: derive(#464c55, 20%); + + // Text & icons + -df-text-dark: derive(#b4bac1, -10%); + -df-text: #b4bac1; + -df-text-selected: derive(#b4bac1, 20%); + + and so on... +``` + +基本配色主题分为三大部分 (分为深色浅色两种方案): + +* Background color - 面板, 窗口, 对话框的背景颜色 +* Component color - 按钮, 卷动条手柄, 文字描边颜色 +* Text color - 文字和图标颜色 + +默认情况下, 如果在系统用户目录下的 `.defold` 文件夹下提供自定义 `editor.scss` stylesheet: + +``` +* { + -df-background-darker: derive(#0a0a42, -10%); + -df-background-dark: derive(#0a0a42, -5%); + -df-background: #0a0a42; + -df-background-light: derive(#0a0a42, 10%); + -df-background-lighter: derive(#0a0a42, 20%); +} +``` + +则您的编辑器配色会如下图所示: + +![](images/editor/editor-styling-color.png) + + +## 修改字体 + +编辑器使用两种字体: 代码编写和单行距文本(报错文字)用 `Dejavu Sans Mono`, 其他 UI 用 `Source Sans Pro`. 文字定义主要保存在 [`_typography.scss`](https://github.com/defold/defold/blob/editor-dev/editor/styling/stylesheets/base/_typography.scss) 中, 如下所示: + +``` +@font-face { + src: url("SourceSansPro-Light.ttf"); +} + +@font-face { + src: url("DejaVuSansMono.ttf"); +} + +$default-font-mono: 'Dejavu Sans Mono'; +$default-font: 'Source Sans Pro'; +$default-font-bold: 'Source Sans Pro Semibold'; +$default-font-italic: 'Source Sans Pro Italic'; +$default-font-light: 'Source Sans Pro Light'; + +.root { + -fx-font-size: 13px; + -fx-font-family: $default-font; +} + +Text.strong { + -fx-font-family: $default-font-bold; +} + +and so on... +``` + +主要字体定义在树形结构根部以便于调整修改. 将如下 `editor.scss` 应用后: + +``` +@import url('https://fonts.googleapis.com/css2?family=Architects+Daughter&display=swap'); + +.root { + -fx-font-family: "Architects Daughter"; +} +``` + +则您的编辑器文本会如下图所示: + +![](images/editor/editor-styling-fonts.png) + +使用本地字体代替网络字体也是可以的: + +``` +@font-face { + font-family: 'Comic Sans MS'; + src: local("cs.ttf"); +} + +.root { + -fx-font-family: 'Comic Sans MS'; +} +``` + +::: 注意 +代码编辑器所用字体是在编辑器设置中定义的! +::: From e1cfaf4fa6f944fb7c177eee3fdd84fe2d21ab13 Mon Sep 17 00:00:00 2001 From: COCO Date: Tue, 15 Feb 2022 22:32:35 +0800 Subject: [PATCH 047/134] build server url --- docs/zh/manuals/editor-preferences.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh/manuals/editor-preferences.md b/docs/zh/manuals/editor-preferences.md index 00e5d03a..13b44d47 100644 --- a/docs/zh/manuals/editor-preferences.md +++ b/docs/zh/manuals/editor-preferences.md @@ -46,4 +46,4 @@ Open File at Line ![](images/editor/preferences_extensions.png) Build Server -: 编译包含 [原生扩展](/manuals/extensions) 项目时使用的编译服务器的 URL. +: 编译包含 [原生扩展](/manuals/extensions) 项目时使用的编译服务器的 URL. 可以在编译服务器的请求 URL 中加入用户名和验证令牌. 使用格式举例: `username:token@build.defold.com`. 在使用用户自己的编译服务器并开启认证时, 任天堂 Switch 编译需要这种用户认证 ([更多信息详见编译服务器文档](https://github.com/defold/extender/blob/dev/README_SECURITY.md)). From 91b39b89b633d7b4da141b89c090aed8c1d8ee24 Mon Sep 17 00:00:00 2001 From: COCO Date: Thu, 17 Feb 2022 14:16:35 +0800 Subject: [PATCH 048/134] editor templates --- docs/zh/manuals/editor-templates.md | 46 +++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 docs/zh/manuals/editor-templates.md diff --git a/docs/zh/manuals/editor-templates.md b/docs/zh/manuals/editor-templates.md new file mode 100644 index 00000000..9cf7763b --- /dev/null +++ b/docs/zh/manuals/editor-templates.md @@ -0,0 +1,46 @@ +--- +title: 项目模板 +brief: 在编辑器新建项目窗口中可以加入自定义模板. +--- + +# 项目模板 + +在编辑器新建项目窗口中可以加入自定义模板.: + +![custom project templates](images/editor/custom_project_templates.png) + +要在窗口中添加自定义项目模板页需要在系统用户目录的 `.defold` 文件夹下加入 `welcome.edn` 文件: + +* 找到系统用户目录下 `.defold`文件夹的位置: + * Windows `C:\Users\**Your Username**\.defold` + * macOS `/Users/**Your Username**/.defold` + * Linux `~/.defold` +* 在 `.defold` 文件夹下新建 `welcome.edn` 文件. + +`welcome.edn` 文件使用的是可扩展数据注解格式. 例如: + +``` +{:new-project + {:categories [ + {:label "My Templates" + :templates [ + {:name "My project" + :description "My template with everything set up the way I want it." + :image "empty.svg" + :zip-url "https://github.com/britzl/template-project/archive/master.zip" + :skip-root? true}, + {:name "My other project" + :description "My other template with everything set up the way I want it." + :image "empty.svg" + :zip-url "https://github.com/britzl/template-other-project/archive/master.zip" + :skip-root? true}] + }] + } +} +``` + +这样就建立好了如上图的模板列表. + +::: 注意 +模板图片只能使用 [编辑器自带的图片](https://github.com/defold/defold/tree/dev/editor/resources/welcome/images). +::: From 883af4bc57f59937563f2d57a3c3fe5d091416ba Mon Sep 17 00:00:00 2001 From: COCO Date: Wed, 23 Feb 2022 19:51:09 +0800 Subject: [PATCH 049/134] spine extension update --- docs/zh/manuals/components.md | 7 +- docs/zh/manuals/glossary.md | 4 +- docs/zh/manuals/gui-spine.md | 64 +------ docs/zh/manuals/gui.md | 23 +-- docs/zh/manuals/importing-assets.md | 1 - docs/zh/manuals/importing-graphics.md | 12 +- docs/zh/manuals/model-animation.md | 2 +- docs/zh/manuals/properties.md | 9 - docs/zh/manuals/shader.md | 1 - docs/zh/manuals/spine.md | 243 +------------------------- docs/zh/manuals/spinemodel.md | 76 +------- 11 files changed, 17 insertions(+), 425 deletions(-) diff --git a/docs/zh/manuals/components.md b/docs/zh/manuals/components.md index 21fa23bb..d89673fe 100644 --- a/docs/zh/manuals/components.md +++ b/docs/zh/manuals/components.md @@ -23,10 +23,15 @@ Defold 提供以下组件类型: * [Particle FX](/manuals/particlefx) - 创建粒子 * [Script](/manuals/script) - 添加游戏逻辑 * [Sound](/manuals/sound) - 播放音效音乐 -* [Spine model](/manuals/spinemodel) - 渲染spine动画 * [Sprite](/manuals/sprite) - 显示2D图像 (可以带逐帧动画) * [Tilemap](/manuals/tilemap) - 显示一组瓷砖图 +其他组件可以通过载入扩展插件的方式导入项目: + +* [Rive model](/extension-rive) - 渲染 Rive 动画 +* [Spine model](/extension-spine) - 渲染 Spine 动画 + + ## 开启关闭组件 游戏对象在创建时其组件是开启的. 如果需要关闭组件可以给组件发送 [`disable`](/ref/go/#disable) 消息: diff --git a/docs/zh/manuals/glossary.md b/docs/zh/manuals/glossary.md index 9aca324e..7d5b8034 100644 --- a/docs/zh/manuals/glossary.md +++ b/docs/zh/manuals/glossary.md @@ -13,7 +13,7 @@ brief: 本教程列举了使用 Defold 工作中会遇到的各种专用词汇 ## Atlas -![Atlas](images/icons/atlas.png){.left} 图集是为了增加性能减少显存消耗而把许多单张图片合并而成的一张大图. 其中可以包括静态图和逐帧动画序列图. 图集可被 GUI, Sprite, Spine model 和 ParticleFX 组件所共享. 详情请见 [图集教程](/manuals/atlas). +![Atlas](images/icons/atlas.png){.left} 图集是为了增加性能减少显存消耗而把许多单张图片合并而成的一张大图. 其中可以包括静态图和逐帧动画序列图. 图集可以被多种组件所共享. 详情请见 [图集教程](/manuals/atlas). ## Builtins @@ -169,4 +169,4 @@ msg.post("#weapon", "disable") ## Vertex shader -![Vertex shader](images/icons/vertex-shader.png){.left} 顶点着色器用于计算多边形在屏幕上投射的位置. 对于各种可视组件, 比如 sprite, spine 模型 或者 3D 模型, 它们的形状由多边形顶点构成. 顶点着色程序负责处理顶点 (在全局游戏空间) 的位置并且负责计算出每个多边形顶点的在屏幕上的映射位置. 详情请见 [Shader manual](/manuals/shader). +![Vertex shader](images/icons/vertex-shader.png){.left} 顶点着色器用于计算多边形在屏幕上投射的位置. 对于各种可视组件, 比如 sprite, 瓷砖地图 或者 3D 模型, 它们的形状由多边形顶点构成. 顶点着色程序负责处理顶点 (在全局游戏空间) 的位置并且负责计算出每个多边形顶点的在屏幕上的映射位置. 详情请见 [Shader manual](/manuals/shader). diff --git a/docs/zh/manuals/gui-spine.md b/docs/zh/manuals/gui-spine.md index 4412f8ae..d4a8435f 100644 --- a/docs/zh/manuals/gui-spine.md +++ b/docs/zh/manuals/gui-spine.md @@ -3,66 +3,4 @@ title: Defold GUI Spine 节点 brief: 本教程介绍了 Defold GUI 场景中骨骼动画 Spine 节点的使用. --- -# GUI Spine 节点 - -Spine 动画模型可以作为 GUI 节点也可以作为游戏对象加入场景. 本教程介绍了导入的 Spine 动画数据在 GUI 场景下的使用. - -## 创建 spine 节点 - -首先你应该导入动画数据并建立 Spine Scene 资源. [Spine 动画](/manuals/spine) 文档介绍了其方法. - -接着, Spine Scene 资源的内容要加入到 GUI 场景中去. 加入方法 右键点击 *Outline* 中的 *Spine Scenes* 部分, 选择 Add ▸ Spine Scenes.... 选择要加入的 Spine Scenes (可加多个). - -![添加 Spine Scene](images/gui-spine/add.png){srcset="images/gui-spine/add@2x.png 2x"} - -最后, 右键点击 *Outline* 中的 *Nodes* 部分, 选择 Add ▸ Spine 来创建 Spine 节点. - -![New spine node](images/gui-spine/new_node.png){srcset="images/gui-spine/new_node@2x.png 2x"} - -新节点自动被选中. 注意设置其属性: - -Spine Scene -: 此节点使用的 Spine Scene 数据源. - -Spine Default Animation -: 场景初始化时节点默认的动画. - -Skin -: 场景初始化时节点用于动画的皮肤. - -## 运行时动画控制 - -使用脚本可以在运行时控制Spine节点. 要在一个节点上开始播放动画, 只要调用 [`gui.play_spine_anim()`](/ref/gui/#gui.play_spine_anim:node-animation_id-playback-[play_properties]-[complete_function]) 函数: - -```lua -local catnode = gui.get_node("cat_note") -local play_properties = { blend_time = 0.3, offset = 0, playback_rate = 1 } -gui.play_spine_anim(catnode, hash("run"), gui.PLAYBACK_ONCE_FORWARD, play_properties, function(self, node) - print("Animation done!") -end) -``` - -## 骨骼层级 - -Spine 骨架中的各个骨骼都可以像 GUI 节点一样使用. 节点名就是 Spine 里设置的骨骼名. - -![Spine 骨骼名](images/gui-spine/bone.png){srcset="images/gui-spine/bone@2x.png 2x"} - -比如, 要做一个骨骼节点下增添一个节点, 使用 [`gui.get_spine_bone()`](/ref/gui#gui.get_spine_bone) 函数加节点名来获取此节点, 然后再在上面加入一个节点: - -```lua --- Attach a text node to the tail of the cat -local cat = gui.get_node("cat_node") -local textnode = gui.new_text_node(vmath.vector3(400, 0, 0), "Hello tail!") -local tail = gui.get_spine_bone(cat, "tail") -gui.set_parent(textnode, tail) -``` - -同样可以用 [`gui.get_node()`](/ref/gui#gui.get_node) 函数获取骨骼节点, 此时引用名要用 Spine 节点名加正斜杠斜杠 (`/`) 加子节点名: - -```lua --- Attach a text node to the tail of the cat -local textnode = gui.new_text_node(vmath.vector3(400, 0, 0), "Hello tail!") -local tail = gui.get_node("cat_node/tail") -gui.set_parent(textnode, tail) -``` +[该教程已被移至这里](/extension-spine). \ No newline at end of file diff --git a/docs/zh/manuals/gui.md b/docs/zh/manuals/gui.md index 57d47bda..e030bd20 100644 --- a/docs/zh/manuals/gui.md +++ b/docs/zh/manuals/gui.md @@ -88,19 +88,13 @@ Template node
-Spine node -: ![spine node](images/icons/spine-model.png){.left} - 显示spine模型和动画. 详情请见 [Spine 节点教程](/manuals/gui-spine). - -
- ParticleFX node : ![particlefx node](images/icons/particlefx.png){.left} 显示粒子特效. 详情请见 [粒子特效节点教程](/manuals/gui-particlefx).
-右键点击 *Nodes* 文件夹选择 Add ▸ 然后点击 Box, Text, Pie, Template, SpineParticleFx 即可创建节点. +右键点击 *Nodes* 文件夹选择 Add ▸ 然后点击 Box, Text, Pie, TemplateParticleFx 即可创建节点. ![Add nodes](images/gui/add_node.png){srcset="images/gui/add_node@2x.png 2x"} @@ -152,15 +146,6 @@ Pie Fill Angle (pie 节点) Template (template 节点) : 节点模板界面文件. 详情请见 [Template 节点教程](/manuals/gui-template) -Spine Scene (spine 节点) -: 节点上显示的spine scene. 详情请见 [Spine 节点教程](/manuals/gui-spine) - -Default Animation (spine 节点) -: 节点上自动播放的spine动画. 详情请见 [Spine 节点教程](/manuals/gui-spine) - -Skin (spine 节点) -: 节点上使用的spine皮肤. 详情请见 [Spine 节点教程](/manuals/gui-spine) - ParticleFX (particlefx 节点) : 节点上显示的粒子特效. 详情请见 [ParticleFX 节点教程](/manuals/gui-particlefx) @@ -227,7 +212,7 @@ Adjust Mode 如果场景的 *Adjust Reference* 设置为 `Disabled` 的话, 此设置被忽略. -Clipping Mode (box, pie 和 spine 节点) +Clipping Mode (box 和 pie 节点) : 剔除模式: - `None` 正常渲染. @@ -235,10 +220,10 @@ Clipping Mode (box, pie 和 spine 节点) 详情请见 [GUI 蒙版教程](/manuals/gui-clipping) -Clipping Visible (box, pie 和 spine 节点) +Clipping Visible (box 和 pie 节点) : 蒙版可见. 详情请见 [GUI clipping manual](/manuals/gui-clipping) -Clipping Inverted (box, pie 和 spine 节点) +Clipping Inverted (box 和 pie 节点) : 反转蒙版. 详情请见 [GUI clipping manual](/manuals/gui-clipping) diff --git a/docs/zh/manuals/importing-assets.md b/docs/zh/manuals/importing-assets.md index 909a5d69..009cf758 100644 --- a/docs/zh/manuals/importing-assets.md +++ b/docs/zh/manuals/importing-assets.md @@ -24,7 +24,6 @@ Defold 支持 PNG 和 JPEG 图片格式. 其中 PNG 图片必须是 32 位 RGBA * 图片可以用来实现2D游戏常见的各种可视内容. 详情请见 [如何导入和使用2D图像](/manuals/importing-graphics). * 声音文件可以用 [声音组件](/manuals/sound)来播放. -* Spine 动画数据可以用于 [Spine 组件](/manuals/spinemodel) 来显示. * 字体文件 可以用于 [Label 组件](/manuals/label) 和GUI中的 [text 节点](/manuals/gui-text). * Collada 模型可以用于 [Model 组件](/manuals/model) 来显示3D模型和动画. [关于3D模型导入详见这里](/manuals/importing-models). diff --git a/docs/zh/manuals/importing-graphics.md b/docs/zh/manuals/importing-graphics.md index 8daf5c53..351890af 100644 --- a/docs/zh/manuals/importing-graphics.md +++ b/docs/zh/manuals/importing-graphics.md @@ -5,7 +5,7 @@ brief: 本教程介绍了如何导入和使用2D图像. # 导入2D图像 -Defold 支持2D游戏常见的可视内容. 可以使用 Defold 制作静态或动态Sprite, UI 组件, 粒子特效, 瓷砖地图, 位图字体和 Spine 动画. 先导入图片文件再创建相应资源以使用它们. 把文件系统任意图片文件拖放到 Defold 编辑器的 *资源面板* 中即完成导入操作. +Defold 支持2D游戏常见的可视内容. 可以使用 Defold 制作静态或动态Sprite, UI 组件, 粒子特效, 瓷砖地图 和 位图字体. 先导入图片文件再创建相应资源以使用它们. 把文件系统任意图片文件拖放到 Defold 编辑器的 *资源面板* 中即完成导入操作. ![Importing files](images/graphics/import.png){srcset="images/graphics/import@2x.png 2x"} @@ -71,13 +71,3 @@ Defold 支持 PNG 和 JPEG 图片格式. 其他格式要先转换成支持格式 ![gui](images/graphics/gui.png){srcset="images/graphics/gui@2x.png 2x"} 关于GUI详情请见 [GUI教程](/manuals/gui). - -![spine](images/icons/spine-model.png){.icon} Spine model -: Spine models 从 Spine scene 资源中获取数据. 包括两部分: - - 1. 一个描述骨骼与动画的 Spine Json 文件. - 2. 依附于骨骼的图片图集. Spine models 不能使用瓷砖图集资源. - - ![spine](images/graphics/spine.png){srcset="images/graphics/spine@2x.png 2x"} - -关于 Spine models 详情请见 [Spine model 教程](/manuals/spinemodel). diff --git a/docs/zh/manuals/model-animation.md b/docs/zh/manuals/model-animation.md index 061d2114..0ac36d67 100644 --- a/docs/zh/manuals/model-animation.md +++ b/docs/zh/manuals/model-animation.md @@ -5,7 +5,7 @@ brief: 本教程介绍了如何在 Defold 中使用 3D 动画. # 3D 蒙皮动画 -3D 模型的骨骼动画和 Spine 动画类似但是是针对于 3D 空间的. 3D 模型不是像剪裁动画那样先分成各个部分然后用骨骼连起来做动画. 而是使用骨骼精细控制模型上各个三角形如何移动. +3D 模型使用骨骼控制模型上各个三角形的移动. 关于如何导入 3D 模型动画, 详情请见 [模型教程](/manuals/model). diff --git a/docs/zh/manuals/properties.md b/docs/zh/manuals/properties.md index 78d26c28..ee9f7937 100644 --- a/docs/zh/manuals/properties.md +++ b/docs/zh/manuals/properties.md @@ -82,15 +82,6 @@ local color = gui.get_color(node) | *linear_damping* | 碰撞对象当前的线性阻尼. | `vector3` | `get+set`{.mark} | | *angular_damping* | 碰撞对象当前的旋转阻尼. | `vector3` | `get+set`{.mark} | -*SPINE MODEL 组件属性* - -| 属性 | 描述 | 类型 | | -| ---------- | -------------------------------------- | --------------- | ---------------- | -| *animation* | 当前动画. | `hash` | `get`{.mark} | -| *skin* | 当前皮肤. (不支持属性动画) | `hash` | `get+set`{.mark} | -| *cursor* | 当前动画播放头 (取值范围 0-1). | `number` | `get+set`{.mark} | -| *playback_rate* | 当前动画播放速率. 即播放速度倍数. | `number` | `get+set`{.mark} | - *MODEL (3D) 组件属性* | 属性 | 描述 | 类型 | | diff --git a/docs/zh/manuals/shader.md b/docs/zh/manuals/shader.md index 93840314..0f62cfac 100644 --- a/docs/zh/manuals/shader.md +++ b/docs/zh/manuals/shader.md @@ -49,7 +49,6 @@ Attributes : 顶点上的相关属性. 属性经由引擎传送给着色器. 只要在着色程序中声明一下即可使用. 不同类型组件有不同的属性: - Sprite 有 `position` 和 `texcoord0`. - Tilegrid 有 `position` 和 `texcoord0`. - - Spine model 有 `position` 和 `texcoord0`. - GUI node 有 `position`, `textcoord0` 和 `color`. - ParticleFX 有 `position`, `texcoord0` 和 `color`. - Model 有 `position`, `texcoord0` 和 `normal`. diff --git a/docs/zh/manuals/spine.md b/docs/zh/manuals/spine.md index ac9f3147..0b86f46a 100644 --- a/docs/zh/manuals/spine.md +++ b/docs/zh/manuals/spine.md @@ -3,245 +3,4 @@ title: Defold 中的 Spine 骨骼动画 brief: 本教程介绍了如何通过 _Spine_ 或者 _Dragon Bone_ 把骨骼动画带入 Defold. --- -# Spine 动画 - -_Spine_ 是由 Esoteric Software 开发的第三方动画工具, 可以让你使用 _骨骼_ 绑定的技术创建动画. 这对于角色或者动物动画非常方便, 对制作其他动画也很有帮助, 比如绳子, 车辆或者树叶. - -![Spine animation](images/animation/spine_animation.png){.inline} -![Run loop](images/animation/frog_runloop.gif){.inline} - -Defold 实现了 [Spine JSON 格式](http://esotericsoftware.com/spine-json-format) 的运行时和动画表达. - -Defold 支持了主要的 Spine 动画功能, 包括反向运动学 (IK). - -::: 注意 -目前, Defold 不支持翻转 X 或者 Y 轴的动画关键帧. Defold 只支持骨骼驱动的网格动画, 不支持单个三角形顶点动画. 一定要做的话就用骨骼 100% 绑定一个三角形来做骨骼动画. -::: - -::: 注意 -Defold 支持 Spine runtime 2.x 功能. 少量支持 Spine 3.x 功能. 为了保证兼容性请只使用 Spine 2.x 功能! -::: - -## 概念 - -*Spine JSON 数据文件* -: 此数据文件包含骨架, 所有图片插槽名, 皮肤和动画数据. 虽然图片文件并不嵌入在这个文件里. Spine 和 Dragon Bones 都可以生成这个文件, 喜欢用哪个就用哪个. - -*Spine scene* -: 把 Spine JSON 数据文件和 Defold 图集文件做捆绑以便在骨骼插槽上显示图片内容. - -*Spine model* -: _SpineModel_ 组件是最终游戏对象里用的用于显示动画的组件. 此组件包含骨骼游戏对象树状关系, 要播放的动画, 要使用的皮肤以及渲染时要使用的材质. 详情请见 [SpineModel 教程](/manuals/spinemodel). - -*Spine Node* -: 在 GUI 场景播放 Spine 动画用的组件, 相当于游戏场景的 Spine model 组件. 详情请见 [GUI spine 教程](/manuals/gui-spine). - -## 动画工具 - -Defold 支持的 Spine JSON 数据文件可以用 Esoteric Software 的 _Spine_ 软件, 或者 _Dragon Bones_ 软件输出. - -_Spine_ 软件主页 http://esotericsoftware.com - -![Spine](images/spine/spine.png) - -_Dragon Bones_ 软件主页 http://dragonbones.com - -![Dragon Bones](images/spine/dragonbones.png) - -::: 注意 -_Dragon Bones_ 输出的 Spine JSON 数据文件应该能正常使用. 如果发现 _Dragon Bones_ 输出文件在 Defold 中显示不正确, 我们推荐先用官方 [Spine Skeleton Viewer](http://esotericsoftware.com/spine-skeleton-viewer) 检查数据是否能正确读出. Spine Skeleton Viewer 能够指出数据文件问题所在, 比如实例或者数据项缺失. -::: - - -## 导入 Spine 角色和动画 - -在 Spine 创建好模型和动画之后, 可以方便地导入到 Defold 中: - -- 把动画输出为 Spine JSON 版本文件. -- 把输出的 JSON 文件放入项目目录中. -- 把所需所有碎图放入项目目录中. -- 把所有碎图建立 _图集_. (建立图集相关内容请参考 [2D 图像教程](/manuals/2dgraphics) 以及下面列举的一些注意事项) - -![Export JSON from Spine](images/spine/spine_json_export.png) - -如果使用 _Dragon Bones_, 选择 *Spine* 作为输出类型. 选择 *Images* 作为图片类型. 这样可以把 *.json* 及其所需图片输出到一个文件夹中. 如上所属导入 Defold 即可. - -![Export JSON from Dragon Bones](images/spine/dragonbones_json_export.png) - -数据存入 Defold 后, 就可以创建 _Spine scene_ 资源文件了: - -- 新建 _Spine scene_ 资源文件 (从主菜单选择 New ▸ Spine Scene File) -- 双击文件打开 spine scene 编辑器. -- 设置 *Properties*. - -![Setup the Spine Scene](images/spine/spinescene.png){srcset="images/spine/spinescene@2x.png 2x"} - -Spine Json -: Spine JSON 数据文件. - -Atlas -: Spine 动画需要的图集. - -## 创建 Spine model 组件 - -创建并配置好 _Spine scene_ 之后, 就可以创建 SpineModel 组件了. 详情请见 [SpineModel 教程](/manuals/spinemodel). - -## 创建 Spine GUI nodes - -在 GUI 场景也可以使用 Spine 动画. 详情请见 [GUI spine 教程](/manuals/gui-spine). - -## 播放 Spine 动画 -在 Spine 模型上播放动画, 只需调用 [`spine.play_anim()`](/ref/spine#spine.play_anim) 函数: - -```lua -local function anim_done(self) - -- 动画播放完成, 做其他事情... -end - -function init(self) - -- 在 "spinemodel" 组件上播放 "walk" 动画同时与上一个动画 - -- 在前 0.1 内混合, 然后进行回调. - local anim_props = { blend_duration = 0.1 } - spine.play_anim("#spinemodel", "run", go.PLAYBACK_LOOP_FORWARD, anim_props, anim_done) -end -``` - -![Spine model in game](images/animation/spine_ingame.png){srcset="images/animation/spine_ingame@2x.png 2x"} - -如果动画是以 `go.PLAYBACK_ONCE_*` 模式播放, 然后在 `spine.play_anim()` 里指定回调函数, 则动画播放完成后会调用回调函数. 关于回调函数详见下文. - -### 播放头 - -除了 `spine.play_anim()` 还有更高级的方法, *Spine Model* 组件暴露了一个 "cursor" 属性可以通过 `go.animate()` 进行控制: - -```lua --- 设置 spine model 动画但是不播放. -spine.play_anim("#spinemodel", "run_right", go.PLAYBACK_NONE) - --- 设置播放头为 0 -go.set("#spinemodel", "cursor", 0) - --- 基于 in-out quad 缓动慢慢对播放头进行从 0 到 1 的 pingpong 补间. -go.animate("#spinemodel", "cursor", go.PLAYBACK_LOOP_PINGPONG, 1, go.EASING_INOUTQUAD, 6) -``` - -::: 注意 -补间和设置播放头时, 时间轴事件不会被触发. -::: - -### 骨骼层级 - -Spine 骨架的各个骨骼实例在游戏对象内展示出来. 在 Spine model 组件的 *Outline* 视图内, 可以看到完整的嵌套关系. 在此层级嵌套关系中你可以看到骨骼的名称和其所在的位置. - -![Spine model hierarchy](images/animation/spine_bones.png){srcset="images/animation/spine_bones@2x.png 2x"} - -通过骨骼名称, 就可以在运行时得到骨骼实例. 函数 [`spine.get_go()`](/ref/spine#spine.get_go) 返回指定骨骼的 id, 然后就可以用来进行设置父级之类的操作: - -```lua --- 把手枪绑定到英雄手上 -local hand = spine.get_go("heroine#spinemodel", "front_hand") -msg.post("pistol", "set_parent", { parent_id = hand }) -``` - -### 时间轴事件 - -Spine 动画可以基于精确的时间触发事件. 对于需要做同步行为的功能非常有帮助, 例如播放走路声音, 场景粒子效果, 在骨骼层级上进行绑定和解绑或者实现你需要的其他功能. - -在 Spine 软件里可以使用时间轴设置事件: - -![Spine events](images/animation/spine_events.png) - -各种事件由事件 id 表示 (上例中是 "bump") 而且时间轴上的事件可以包含一些数据: - -Integer -: 整数值. - -Float -: 浮点数值. - -String -: 字符串值. - -动画播放遇到事件时, `spine_event` 消息会被发回到调用 `spine.play()` 函数的脚本上. 消息数据参数就是事件附带的数据, 连同其他一些有用的数据: - -`t` -: 自动画播放第一帧开始经过的时间. - -`animation_id` -: 动画名, 哈希值. - -`string` -: 事件附带字符串值, 哈希值. - -`float` -: 事件附带浮点数值. - -`integer` -: 事件附带整数值. - -`event_id` -: 事件 id, 哈希值. - -`blend_weight` -: 此时动画混合情况. 0 表示动画还没有被混合, 1 当前动画混合 100%. - -```lua --- Spine 动画包含与动画同步的音效. --- 作为消息传到这里. -function on_message(self, message_id, message, sender) - if message_id == hash("spine_event") and message.event_id == hash("play_sound") then - -- 播放动画音效. 事件数据包括声音组件和声音增益. - local url = msg.url("sounds") - url.fragment = message.string - sound.play(url, { gain = message.float }) - end -end -`````` - -## 播放完成回调函数 - -动画播放函数 `spine.play_anim()` 可以在最后一个参数上传入Lua回调函数. 当动画播放完成时会调用这个函数. 对于循环动画和用 `spine.cancel()` 取消的动画不会调用回调函数. 回调函数里可以发送消息或者继续播放其他动画. - -```lua -local function anim_done(self) - -- 播放完成, 做点什么... -end - -function init(self) - -- 在组件 "spinemodel" 上播放 "walk" 并且与上个动画 - -- 进行 0.1 秒的混合, 然后调用回调函数. - local anim_props = { blend_duration = 0.1 } - spine.play_anim("#spinemodel", "run", go.PLAYBACK_LOOP_FORWARD, anim_props, anim_done) -end -``` - -## 播放模式 - -动画可以单次播放也可以循环播放. 取决于播放模式: - -* go.PLAYBACK_NONE -* go.PLAYBACK_ONCE_FORWARD -* go.PLAYBACK_ONCE_BACKWARD -* go.PLAYBACK_ONCE_PINGPONG -* go.PLAYBACK_LOOP_FORWARD -* go.PLAYBACK_LOOP_BACKWARD -* go.PLAYBACK_LOOP_PINGPONG - -pingpong 模式先正向播放, 再反向播放. - - -## 图集相关注意事项 - -动画通过去掉图片文件后缀的方法识别引用图片. 在 Spine 软件里图片文件位于 *Images* 目录下: - -![Spine images hierarchy](images/spine/spine_images.png) - -上图中图片没有嵌套关系. 但是通常, 图片会被分组放入子目录下, 其引用就包含了子目录前缀. 比如, 骨骼插槽对文件 *head_parts/eyes.png* 的引用就是 *head_parts/eyes*. 输出的 JSON 文件图片引用也是这个所以 Defold 图集中图片名要与之相匹配. - -在 Defold 里 Add Images 时, 图片会以文件名去掉后缀的方法命名. 所以对于 *eyes.png* 自动命名就是 "eyes". 这样正好但是这是不带路径的情况. - -对于带路径的 "head_parts/eyes" 该怎么办? 最简单的办法就是建立动画组 (图集 *Outline* 视图根节点右键选择 *Add Animation Group*). 然后手动命名为 "head_parts/eyes" (名字里的 `/` 字符合法) 再把 "eyes.png" 放入这个动画组. - -![Atlas path names](images/spine/atlas_names.png){srcset="images/spine/atlas_names@2x.png 2x"} - -关于 Spine 动画控制详情请见 [动画教程](/manuals/animation). +[该教程已被移至这里](/extension-spine) \ No newline at end of file diff --git a/docs/zh/manuals/spinemodel.md b/docs/zh/manuals/spinemodel.md index e96f4013..e7c0a71f 100644 --- a/docs/zh/manuals/spinemodel.md +++ b/docs/zh/manuals/spinemodel.md @@ -3,78 +3,4 @@ title: Defold 中的 Spine 模型组件 brief: 本教程介绍了在Defold中如何创建 SpineModel 组件. --- -# Spine 模型 - -SpineModel 组件用于把 _Spine_ 骨骼动画在 Defold 中呈现出来. - -## 创建 Spine Model 组件 - -选择一个游戏对象: - -方法一 直接创建组件(右键点击 游戏对象选择 Add Component ▸ Spine Model) - -方法二 先创建文件 (在 *资源* 浏览器中 右键点击, 在上下文菜单中选择 New... ▸ Spine Model), 再在游戏对象上 右键点击 , 选择 Add Component File). - -## Spine Model *属性*: - -除了常见的 *Id*, *Position* 和 *Rotation* 属性外, 还有 Spine Model 的特有属性: - -*Spine scene* -: 设置先前创建的 Spine Scene. - -*Blend Mode* -: 默认混合模式是 `Alpha`, 想用别的可以修改这个属性. - -*Material* -: 如果想要使用自定义材质显示Spine模型, 在此指定. - -*Default animation* -: 设置Spine模型默认的动画. - -*Skin* -: 如果模型包含皮肤的话,这里可以设置Spine模型的默认皮肤. - -此时就可以在编辑器里看到Spine模型了: - -![编辑器中的Spine模型](images/spinemodel/spinemodel.png){srcset="images/spinemodel/spinemodel@2x.png 2x"} - -### 混合模式 -:[blend-modes](../shared/blend-modes.md) - -## 运行时操作 - -有一系列方法可以在运行时修改Spine模型 (参见 [API文档](/ref/spine/)). - -### 运行时动画 - -Defold 提供强大的运行时控制动画的功能, 参见 [spine 动画教程](/manuals/spine). - -### 修改属性 - -Spine模型可以使用 `go.get()` 和 `go.set()` 方法修改其属性: - -`animation` -: 当前Spine模型动画 (`hash`) (只读). 使用 `spine.play_anim()` 方法来更改播放动画 (参见 [spine 动画教程](/manuals/spine)). - -`cursor` -: 标准化动画头 (`number`). - -`material` -: Spine模型材质 (`hash`). 可使用 `go.set()` 修改. 参见 [这个例子的 API 用法](/ref/spine/#material). - -`playback_rate` -: 动画播放速率 (`number`). - -`skin` -: 当前组件的皮肤 (`hash`). - -## 材质常量 - -{% include shared/material-constants.md component='spine' variable='tint' %} - -`tint` -: 3D网格颜色 (`vector4`). 四元数 x, y, z, 和 w 分别对应红, 绿, 蓝和不透明度. - -## 相关项目配置 - -在 *game.project* 文件里有些关于Spine模型的 [设置项目](/manuals/project-settings#spine). +[该教程已被移至这里](/extension-spine) \ No newline at end of file From 4d78c262c825ce524807d5d99f5705388bd351a8 Mon Sep 17 00:00:00 2001 From: COCO Date: Sat, 14 May 2022 16:30:18 +0800 Subject: [PATCH 050/134] Fix typo in the "optimizations" word in Chinese docs --- docs/zh/manuals/project-settings.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/zh/manuals/project-settings.md b/docs/zh/manuals/project-settings.md index d8b42dd3..2e049b9b 100644 --- a/docs/zh/manuals/project-settings.md +++ b/docs/zh/manuals/project-settings.md @@ -287,7 +287,7 @@ HTTP超时秒数. 设置为 `0` 则关闭超时, 默认关闭. ### Sprite #### Max Count -每个集合最大sprite数目, 默认是 `128`. [(参见最大组件数优化)](#component_max_count_optimzations). +每个集合最大sprite数目, 默认是 `128`. [(参见最大组件数优化)](#component_max_count_optimizations). #### Subpixels 开启后允许sprite不与像素对齐, 默认开启. @@ -297,7 +297,7 @@ HTTP超时秒数. 设置为 `0` 则关闭超时, 默认关闭. ### Tilemap #### Max Count -每个集合的瓷砖地图最大数目, 默认是 `16`. [(参见最大组件数优化)](#component_max_count_optimzations). +每个集合的瓷砖地图最大数目, 默认是 `16`. [(参见最大组件数优化)](#component_max_count_optimizations). #### Max Tile Count 每个集合可同时显示的瓷砖最大数目, 默认是 `2048`. @@ -314,21 +314,21 @@ spine 模型最大数目, 默认是 `128`. ### Mesh #### Max Count -每个集合最大容纳3D模型面数, 默认是 `128`. [(参见最大组件数优化)](#component_max_count_optimzations). +每个集合最大容纳3D模型面数, 默认是 `128`. [(参见最大组件数优化)](#component_max_count_optimizations). --- ### Model #### Max Count -每个集合最大容纳3D模型组件个数, 默认是 `128`. [(参见最大组件数优化)](#component_max_count_optimzations). +每个集合最大容纳3D模型组件个数, 默认是 `128`. [(参见最大组件数优化)](#component_max_count_optimizations). --- ### GUI #### Max Count -GUI 组件最大数目, 默认是 `64`. [(参见最大组件数优化)](#component_max_count_optimzations). +GUI 组件最大数目, 默认是 `64`. [(参见最大组件数优化)](#component_max_count_optimizations). #### Max Particlefx Count 同一时间粒子发射器最大数目, 默认是 `64`. @@ -341,7 +341,7 @@ GUI 组件最大数目, 默认是 `64`. [(参见最大组件数优化)](#compone ### Label #### Max Count -label 最大数目, 默认是 `64`. [(参见最大组件数优化)](#component_max_count_optimzations). +label 最大数目, 默认是 `64`. [(参见最大组件数优化)](#component_max_count_optimizations). #### Subpixels 开启后允许 lables 不与像素对齐, 默认开启. @@ -351,7 +351,7 @@ label 最大数目, 默认是 `64`. [(参见最大组件数优化)](#component_m ### Particle FX #### Max Count -同一时间粒子发射器最大数目, 默认是 `64`. [(参见最大组件数优化)](#component_max_count_optimzations). +同一时间粒子发射器最大数目, 默认是 `64`. [(参见最大组件数优化)](#component_max_count_optimizations). #### Max Particle Count 同一时间粒子最大数目, 默认是 `1024`. @@ -361,21 +361,21 @@ label 最大数目, 默认是 `64`. [(参见最大组件数优化)](#component_m ### Collection proxy #### Max Count -集合代理最大数目, 默认是 `8`. [(参见最大组件数优化)](#component_max_count_optimzations). +集合代理最大数目, 默认是 `8`. [(参见最大组件数优化)](#component_max_count_optimizations). --- ### Collection factory #### Max Count -集合工厂最大数目, 默认是 `128`. [(参见最大组件数优化)](#component_max_count_optimzations). +集合工厂最大数目, 默认是 `128`. [(参见最大组件数优化)](#component_max_count_optimizations). --- ### Factory #### Max Count -游戏对象工厂最大数目, 默认是 `128`. [(参见最大组件数优化)](#component_max_count_optimzations). +游戏对象工厂最大数目, 默认是 `128`. [(参见最大组件数优化)](#component_max_count_optimizations). --- From ffe5e2db4e1e98f3dc375f69ad463caaa1b75321 Mon Sep 17 00:00:00 2001 From: COCO Date: Sun, 22 May 2022 15:14:16 +0800 Subject: [PATCH 051/134] Update to material.md - Constants buffers --- docs/zh/manuals/material.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh/manuals/material.md b/docs/zh/manuals/material.md index ba91e744..a89fdbf3 100644 --- a/docs/zh/manuals/material.md +++ b/docs/zh/manuals/material.md @@ -149,7 +149,7 @@ Filter Min/Mag self.constants = render.constant_buffer() -- <1> self.constants.tint = vmath.vector4(1, 0, 0, 1) -- <2> ... -render.draw(self.my_pred, self.constants) -- <3> +render.draw(self.my_pred, {constants = self.constants}) -- <3> ``` 1. 新建常量缓存 2. 设置 `tint` 常量为白色 From 0e21e125d4e1c8684c481b381c23d7bf32d53672 Mon Sep 17 00:00:00 2001 From: COCO Date: Mon, 23 May 2022 21:01:08 +0800 Subject: [PATCH 052/134] Verify Graphics Calls --- docs/zh/manuals/project-settings.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/zh/manuals/project-settings.md b/docs/zh/manuals/project-settings.md index 2e049b9b..ec032715 100644 --- a/docs/zh/manuals/project-settings.md +++ b/docs/zh/manuals/project-settings.md @@ -206,6 +206,11 @@ debug顶点最大数目. 用于物理形状渲染与其他一些功能, 默认 #### Texture Profiles 项目使用的纹理档配置文件, 默认是 `/builtins/graphics/default.texture_profiles`. +#### Verify Graphics Calls +校验每个 graphics call 的返回值, 并且把遇到的错误保存到 log 里. + +--- + ### Shader #### Output SPIR-V From 9635e061437323cb2ce624a7b033e9643c9103f2 Mon Sep 17 00:00:00 2001 From: COCO Date: Thu, 26 May 2022 19:53:27 +0800 Subject: [PATCH 053/134] H5 parameters --- docs/zh/manuals/html5.md | 71 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/docs/zh/manuals/html5.md b/docs/zh/manuals/html5.md index ce6e21a9..fc8a175e 100644 --- a/docs/zh/manuals/html5.md +++ b/docs/zh/manuals/html5.md @@ -218,5 +218,76 @@ DEFOLD_ENGINE_ARGUMENTS HTML5 支持 `sys.save()`, `sys.load()` 和 `io.open()` 之类的文件操作, 但是与其他平台实现方法不同. 基于安全考虑浏览器里运行的 Javascript 无权直接读写本地文件. Emscripten (即 Defold) 使用 [IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB) 代替, 它是基于浏览器的持久化存储方案, 基于浏览器的虚拟文件系统. 与其他平台的区别主要是比直接读写文件要慢而且实质上读写的是一个数据库. 浏览器开发者工具通常都提供了 IndexedDB 的读写功能. + +## 给 HTML5 游戏传递参数 + +一些情况下我们需要在游戏启动前或者启动时为其提供某些参数. 可能是用户 id, session 令牌或者告诉游戏启动时为当前玩家加载哪一关. 有多种方法实现这样的功能, 下面就列举一些. + +### 引擎参数 + +用于在引进加载时指定引擎参数. 这些参数在运行时可以使用 `sys.get_config()` 得到. 在 `index.html` 里修改 `extra_params` 对象的 `engine_arguments` 项, 加入键值对以提供参数: + + +``` +