Keep your place in this quest

Log in or sign up for free to subscribe, follow lesson progress, and access more learning content.

碰撞系统

工作原理

  • 每个对象都有一个基于其精灵大小的 AABB(轴对齐包围盒)
  • 精灵可以有自定义的碰撞边界(在精灵编辑器中设置)
  • 对于动态对象,每帧都会检查碰撞

碰撞类型说明

  1. - 对象完全被碰撞系统忽略
  2. 静态 - 充当不可移动的墙(用于地形、平台)
  3. 动态 - 移动并被其他碰撞体推开(用于玩家、敌人)
  4. 触发器 - 检测重叠但不阻止移动(用于收集物品、区域)

碰撞解析

  • 动态对象会自动被推出静态和其他动态对象
  • 触发器从不阻止移动 - 仅检测重叠

onCollision 回调

onCollision(objA, objB) 函数在对象重叠时被调用。回调模式为:

objA 类型 objB 类型 生成回调? 备注
动态 静态 动态被推出静态
动态 动态 是(双向) 两个对象都会获得回调
动态 触发器 检测到触发器
触发器 触发器 两个触发器相互检测
静态 静态 静态不生成回调
静态 触发器 两者均不生成回调

关键规则:

  • objA 始终是动态或触发器
  • 当两个动态对象碰撞时,两者均会获得回调(各自作为 objA)
  • 当两个触发器重叠时,会生成一个回调(第一个触发器作为 objA)
  • 静态对象从未出现为 objA

示例:检测不同的碰撞类型

func onCollision(objA, objB) {
    var typeA = getCollisionType(objA)
    var typeB = getCollisionType(objB)

    // 玩家(动态)碰到一个硬币(触发器)
    if (getName(objA) == "player" && typeB == COLLISION_TRIGGER()) {
        print("收集到!")
        removeObject(gameScene, objB)
    }

    // 两个触发器重叠(例如,检测区域)
    if (typeA == COLLISION_TRIGGER() && typeB == COLLISION_TRIGGER()) {
        print(getName(objA) + " 进入了 " + getName(objB) + " 的区域")
    }

    // 玩家被敌人击中(均为动态)
    if (getName(objA) == "player" && getName(objB) == "enemy") {
        print("玩家被击中!")
    }
}

物理系统

Tiniest Engine 具有内置的物理系统,自动处理动态对象的重力和速度。

物理工作原理

每帧,引擎会自动:

  1. 将场景重力应用到每个动态对象的速度
  2. 将速度应用到每个动态对象的位置
// 物理管道(由引擎自动处理):
velocity += gravity * dt
position += velocity * dt

设置重力

在场景中设置重力,使动态对象下落:

func start() {
    // 设置向下重力(每秒 300 像素平方)
    setGravityY(gameScene, 300)

    // 可选:水平重力(风的效果)
    setGravityX(gameScene, 0)

    setScene(gameScene)
}

使用速度

使用速度控制对象,而不是直接设置位置:

var player = Object("player")
var jumpForce = -200  // 负值 = 向上

func start() {
    setCollisionType(player, COLLISION_DYNAMIC())
    addObject(gameScene, player)
    setGravityY(gameScene, 300)
    setScene(gameScene)
}

func onUpdate(dt) {
    // 通过速度进行水平移动
    if (isKeyHeld(KEY_LEFT())) {
        setVelocityX(player, -100)
    } else if (isKeyHeld(KEY_RIGHT())) {
        setVelocityX(player, 100)
    } else {
        setVelocityX(player, 0)
    }

    // 通过设置向上速度进行跳跃
    if (isKeyPressed(KEY_SPACE())) {
        setVelocityY(player, jumpForce)
    }
}

物理函数

函数 描述
getVelocityX(obj) 返回对象的 X 速度
setVelocityX(obj, vx) 设置对象的 X 速度
getVelocityY(obj) 返回对象的 Y 速度
setVelocityY(obj, vy) 设置对象的 Y 速度
getGravityX(scene) 返回场景重力 X 分量
setGravityX(scene, gx) 设置场景重力 X 分量
getGravityY(scene) 返回场景重力 Y 分量
setGravityY(scene, gy) 设置场景重力 Y(正值 = 向下)

重要提示: 只有 COLLISION_DYNAMIC() 对象受到重力影响,并且其速度会自动应用