使用物理节点 I
在本教程中,我们将学习如何在 Dora SSR 游戏引擎中创建物理刚体节点对象,并设置不同物理对象之间的分组和碰撞关系。通过以下步骤,您将能够在物理世界中实现基础的物体重力运动. 形状设置和碰撞检测。
1. 创建物理世界与重力
首先,我们需要定义一个物理世界,并设置其重力方向和大小。在此示例中,重力被定义为垂直向下,大小为 -10
。
- Lua
- Teal
- TypeScript
- YueScript
local Vec2 <const> = require("Vec2")
local PhysicsWorld <const> = require("PhysicsWorld")
local gravity <const> = Vec2(0, -10) -- 定义重力方向和大小
local world = PhysicsWorld() -- 创建物理世界
world.y = -200 -- 调整物理世界的y轴位置
local Vec2 <const> = require("Vec2")
local PhysicsWorld <const> = require("PhysicsWorld")
local gravity <const> = Vec2(0, -10) -- 定义重力方向和大小
local world = PhysicsWorld() -- 创建物理世界
world.y = -200 -- 调整物理世界的y轴位置
import { Vec2, PhysicsWorld } from "Dora";
const gravity = Vec2(0, -10); // 定义重力方向和大小
const world = PhysicsWorld(); // 创建物理世界
world.y = -200; // 调整物理世界的y轴位置
_ENV = Dora
const gravity = Vec2 0, -10 -- 定义重力方向和大小
world = PhysicsWorld! -- 创建物理世界
world.y = -200 -- 调整物理世界的y轴位置
2. 定义物理刚体
物理刚体可以是静态(Static)或动态(Dynamic)的。静态刚体用于不可移动的物体(如地面),动态刚体则用于可移动的物体(如角色或障碍物)。此外物理刚体还有运动态(Kinematic)类型,用于定义具有无限大的质量但可以控制其进行运动的物体。
2.1 定义静态地形刚体
静态刚体常用于地面或墙体,通常不会受到重力影响。在下例中,我们创建了一个静态的地形刚体,并设置其为800x10的多边形形状。
- Lua
- Teal
- TypeScript
- YueScript
local BodyDef <const> = require("BodyDef")
local terrainDef = BodyDef()
terrainDef.type = "Static" -- 设置为静态刚体
terrainDef:attachPolygon(800, 10, 1, 0.8, 0.2) -- 附加一个宽800高10的矩形多边形
-- 注意 1, 0.8, 0.2 的参数分别为密度. 摩擦系数和弹性系数
local BodyDef <const> = require("BodyDef")
local terrainDef = BodyDef()
terrainDef.type = "Static" -- 设置为静态刚体
terrainDef:attachPolygon(800, 10, 1, 0.8, 0.2) -- 附加一个宽800高10的矩形多边形
-- 注意 1, 0.8, 0.2 的参数分别为密度. 摩擦系数和弹性系数
import { BodyDef, BodyMoveType } from "Dora";
const terrainDef = BodyDef();
terrainDef.type = BodyMoveType.Static; // 设置为静态刚体
terrainDef.attachPolygon(800, 10, 1, 0.8, 0.2); // 附加一个宽800高10的矩形多边形
// 注意 1, 0.8, 0.2 的参数分别为密度. 摩擦系数和弹性系数
terrainDef = with BodyDef!
.type = "Static" -- 设置为静态刚体
\attachPolygon 800, 10, 1, 0.8, 0.2 -- 附加一个宽800高10的矩形多边形
-- 注意 1, 0.8, 0.2 的参数分别为密度. 摩擦系数和弹性系数
2.2 定义动态多边形刚体
动态刚体会受到重力影响,并根据物理世界中的力进行运动。我们可以定义一个多边形刚体,在下例中我们定义了一个六边形。
- Lua
- Teal
- TypeScript
- YueScript
local BodyDef <const> = require("BodyDef")
local Vec2 <const> = require("Vec2")
local polygonDef = BodyDef()
polygonDef.type = "Dynamic" -- 设置为动态刚体
polygonDef.linearAcceleration = gravity -- 应用重力
polygonDef:attachPolygon({
Vec2(60, 0),
Vec2(30, -30),
Vec2(-30, -30),
Vec2(-60, 0),
Vec2(-30, 30),
Vec2(30, 30)
}, 1, 0.4, 0.4) -- 定义一个六边形
local BodyDef <const> = require("BodyDef")
local Vec2 <const> = require("Vec2")
local polygonDef = BodyDef()
polygonDef.type = "Dynamic" -- 设置为动态刚体
polygonDef.linearAcceleration = gravity -- 应用重力
polygonDef:attachPolygon({
Vec2(60, 0),
Vec2(30, -30),
Vec2(-30, -30),
Vec2(-60, 0),
Vec2(-30, 30),
Vec2(30, 30)
}, 1, 0.4, 0.4) -- 定义一个六边形
import { BodyDef, Vec2, BodyMoveType } from "Dora";
const polygonDef = BodyDef();
polygonDef.type = BodyMoveType.Dynamic; // 设置为动态刚体
polygonDef.linearAcceleration = gravity; // 应用重力
polygonDef.attachPolygon([
Vec2(60, 0),
Vec2(30, -30),
Vec2(-30, -30),
Vec2(-60, 0),
Vec2(-30, 30),
Vec2(30, 30)
], 1, 0.4, 0.4); // 定义一个六边形
polygonDef = with BodyDef!
.type = "Dynamic" -- 设置为动态刚体
.linearAcceleration = gravity -- 应用重力
\attachPolygon [
Vec2 60, 0,
Vec2 30, -30,
Vec2 -30, -30,
Vec2 -60, 0,
Vec2 -30, 30,
Vec2 30, 30
], 1, 0.4, 0.4 -- 定义一个六边形
2.3 定义动态圆形刚体
圆形刚体类似于多边形,但其形状为圆形,且同样会受到重力影响。
- Lua
- Teal
- TypeScript
- YueScript
local BodyDef <const> = require("BodyDef")
local diskDef = BodyDef()
diskDef.type = "Dynamic" -- 设置为动态刚体
diskDef.linearAcceleration = gravity -- 应用重力
diskDef:attachDisk(60, 1, 0.4, 0.4) -- 附加一个半径为60的圆形
local BodyDef <const> = require("BodyDef")
local diskDef = BodyDef()
diskDef.type = "Dynamic" -- 设置为动态刚体
diskDef.linearAcceleration = gravity -- 应用重力
diskDef:attachDisk(60, 1, 0.4, 0.4) -- 附加一个半径为60的圆形
import { BodyDef, BodyMoveType } from "Dora";
const diskDef = BodyDef();
diskDef.type = BodyMoveType.Dynamic; // 设置为动态刚体
diskDef.linearAcceleration = gravity; // 应用重力
diskDef.attachDisk(60, 1, 0.4, 0.4); // 附加一个半径为60的圆形
diskDef = with BodyDef!
.type = "Dynamic" -- 设置为动态刚体
.linearAcceleration = gravity -- 应用重力
\attachDisk 60, 1, 0.4, 0.4 -- 附加一个半径为60的圆形
3. 设置分组和碰撞关系
我们可以通过分组的方式来决定不同物体之间的碰撞关系。在此示例中,我们创建了三个分组,并通过 setShouldContact
方法来设置分组之间的碰撞规则。
- Lua
- Teal
- TypeScript
- YueScript
local groupZero <const> = 0
local groupOne <const> = 1
local groupTwo <const> = 2
world:setShouldContact(groupZero, groupOne, false) -- 组0与组1不碰撞
world:setShouldContact(groupZero, groupTwo, true) -- 组0与组2碰撞
world:setShouldContact(groupOne, groupTwo, true) -- 组1与组2碰撞
world.showDebug = true -- 显示调试信息
local groupZero <const> = 0
local groupOne <const> = 1
local groupTwo <const> = 2
world:setShouldContact(groupZero, groupOne, false) -- 组0与组1不碰撞
world:setShouldContact(groupZero, groupTwo, true) -- 组0与组2碰撞
world:setShouldContact(groupOne, groupTwo, true) -- 组1与组2碰撞
world.showDebug = true -- 显示调试信息
const groupZero = 0;
const groupOne = 1;
const groupTwo = 2;
world.setShouldContact(groupZero, groupOne, false); // 组0与组1不碰撞
world.setShouldContact(groupZero, groupTwo, true); // 组0与组2碰撞
world.setShouldContact(groupOne, groupTwo, true); // 组1与组2碰撞
world.showDebug = true; // 显示调试信息
groupZero = 0
groupOne = 1
groupTwo = 2
with world
\setShouldContact groupZero, groupOne, false -- 组0与组1不碰撞
\setShouldContact groupZero, groupTwo, true -- 组0与组2碰撞
\setShouldContact groupOne, groupTwo, true -- 组1与组2碰撞
.showDebug = true -- 显示调试信息
在实际游戏开发中,合理设置物理分组可以大大提高性能和降低不必要的计算。建议为游戏中的静态元素. 动态物体以及玩家角色等设置不同的分组,并根据需求调整碰撞关系。
4. 创建并添加刚体到物理世界
最后,我们将定义的物理刚体对象进行实例化,并添加到物理世界中。每个刚体可以分配到不同的分组中,并在物理世界中设置初始位置。
- Lua
- Teal
- TypeScript
- YueScript
local Body <const> = require("Body")
-- 创建并添加静态地形刚体
local terrain = Body(terrainDef, world, Vec2.zero)
terrain.group = groupTwo -- 设置刚体分组为组2
world:addChild(terrain)
-- 创建并添加动态多边形刚体
local polygon = Body(polygonDef, world, Vec2(0, 500), 15)
polygon.group = groupOne -- 设置刚体分组为组1
world:addChild(polygon)
-- 创建并添加动态圆形刚体
local disk = Body(diskDef, world, Vec2(50, 800))
disk.group = groupZero -- 设置刚体分组为组0
disk.angularRate = 90 -- 设置旋转速度
world:addChild(disk)
local Body <const> = require("Body")
-- 创建并添加静态地形刚体
local terrain = Body(terrainDef, world, Vec2.zero)
terrain.group = groupTwo -- 设置刚体分组为组2
world:addChild(terrain)
-- 创建并添加动态多边形刚体
local polygon = Body(polygonDef, world, Vec2(0, 500), 15)
polygon.group = groupOne -- 设置刚体分组为组1
world:addChild(polygon)
-- 创建并添加动态圆形刚体
local disk = Body(diskDef, world, Vec2(50, 800))
disk.group = groupZero -- 设置刚体分组为组0
disk.angularRate = 90 -- 设置旋转速度
world:addChild(disk)
import { Body } from "Dora";
// 创建并添加静态地形刚体
const terrain = Body(terrainDef, world, Vec2.zero);
terrain.group = groupTwo; // 设置刚体分组为组2
world.addChild(terrain);
// 创建并添加动态多边形刚体
const polygon = Body(polygonDef, world, Vec2(0, 500), 15);
polygon.group = groupOne; // 设置刚体分组为组1
world.addChild(polygon);
// 创建并添加动态圆形刚体
const disk = Body(diskDef, world, Vec2(50, 800));
disk.group = groupZero; // 设置刚体分组为组0
disk.angularRate = 90; // 设置旋转速度
world.addChild(disk);
-- 创建并添加静态地形刚体
with Body terrainDef, world, Vec2.zero
.group = groupTwo -- 设置刚体分组为组2
\addTo world
-- 创建并添加动态多边形刚体
with Body polygonDef, world, Vec2 0, 500, 15
.group = groupOne -- 设置刚体分组为组1
\addTo world
-- 创建并添加动态圆形刚体
with Body diskDef, world, Vec2 50, 800
.group = groupZero -- 设置刚体分组为组0
.angularRate = 90 -- 设置旋转速度
\addTo world
5. 总结
通过本教程,您学会了如何在 Dora SSR 游戏引擎中创建物理刚体,并通过分组的方式控制物体之间的碰撞关系。通过灵活设置刚体的属性. 形状和分组,您可以在物理世界中实现复杂的物理效果,并为您的游戏增添更多趣味性。
希望本教程能够帮助您更好地理解 Dora SSR 的物理系统,祝您开发愉快!