<pc-sprite-clip>
<pc-sprite-clip> 在父 <pc-sprite> 上声明一个命名片段,按顺序播放精灵帧。idle、run、jump 等片段构成角色动作库,由父级 clip 选择。
- 必须直接位于
<pc-sprite>下,且父项 type 为 animated 才播放。 - name 必填,且在同一精灵内唯一。缺失或与更早片段重复时,会警告且不添加。
播放方式
片段按精灵资源 frame-keys 的顺序播放,因此资源应按播放顺序列出帧。各片段使用自己的资源,可来自相同或不同图集,声明方法详见精灵资源。
fps 决定速度,帧数决定长度。例如 6 帧以 12 fps 播放持续半秒。默认 fps 为 0,不推进帧,停在首帧;应为要运动的片段设置帧率。父精灵 speed 同时乘到全部片段。
末帧行为由 loop 决定:
- 循环片段回到首帧,组件触发 loop。
- 不循环片段停在末帧,组件触发 end。再次将父级 clip 设为同名可重播,详见播放片段。
负 fps 倒放,但仍从第一帧开始;循环片段会从此反向遍历,其余帧按逆序播放;非循环片段因已处倒放终点,会立即结束。
属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
asset | 资源 ID | - | 必须引用 sprite 类型资源,按其 frame-keys 顺序播放 |
fps | Number(数字) | "0" | 每秒帧数,负值倒放,0 停在当前帧;从 0 开始的片段即停在首帧 |
loop | Boolean(布尔) | "false" | 是否循环,不循环则停在末帧 |
name | String(字符串) | - | 父精灵通过 clip 选择的片段名,必填且同一精灵内唯一 |
所有属性实时生效。fps 和 loop 会立即影响当前播放;asset 切换帧来源;name 会移除旧片段,若在播放则停止,再以新名添加,父级 clip 已指向新名时会播放。
asset 未指向已声明 <pc-asset> 时,片段无帧且不警告,因此无显示时应检查 id。
加载
父精灵组件存在后会立即添加片段并就绪。组件自行加载资源,因此帧到达前即可选中播放,加载后再显示。
因名称缺失或重复未添加的片段不会就绪。更早的同名片段移除或改名后,等待者会接管名称。
就绪跟随父组件。移除 pc-sprite,或其所在 pc-node 失去绑定时,片段释放底层对象并失去就绪,ready() 等待下轮。组件重建后会重新添加片段并再次触发 ready。直接位于 pc-model 下时,模型重载保留宿主,因此组件和片段不受影响。
示例
两枚硬币分别有循环 spin 和单次 collect。右侧 spin 使用负 fps 反转。Collect 播放单次后停在末帧,再点击可重播。试着为 collect 开 loop,修改 fps,或设为 0:
<pc-app>
<pc-asset id="atlas" type="textureatlas" src="https://developer.playcanvas.com/assets/sprites.png" srgb mipmaps="false" min-filter="nearest" mag-filter="nearest" data='{ "frames": {
"coin-spin-0": { "rect": [238, 32, 12, 12], "pivot": [0.5, 0.5] },
"coin-spin-1": { "rect": [238, 19, 12, 12], "pivot": [0.5, 0.5] },
"coin-spin-2": { "rect": [0, 13, 12, 12], "pivot": [0.5, 0.5] },
"coin-spin-3": { "rect": [150, 9, 12, 12], "pivot": [0.5, 0.5] },
"coin-spin-4": { "rect": [163, 9, 12, 12], "pivot": [0.5, 0.5] },
"coin-spin-5": { "rect": [176, 9, 12, 12], "pivot": [0.5, 0.5] },
"coin-collect-0": { "rect": [232, 6, 12, 12], "pivot": [0.5, 0.5] },
"coin-collect-1": { "rect": [0, 0, 12, 12], "pivot": [0.5, 0.5] },
"coin-collect-2": { "rect": [189, 0, 12, 12], "pivot": [0.5, 0.5] },
"coin-collect-3": { "rect": [202, 0, 12, 12], "pivot": [0.5, 0.5] },
"coin-collect-4": { "rect": [215, 0, 12, 12], "pivot": [0.5, 0.5] }
} }'></pc-asset>
<!-- One sprite asset per clip, its frame keys in playback order -->
<pc-asset id="coin-spin" type="sprite" atlas="atlas" frame-keys="coin-spin-0 coin-spin-1 coin-spin-2 coin-spin-3 coin-spin-4 coin-spin-5" pixels-per-unit="16"></pc-asset>
<pc-asset id="coin-collect" type="sprite" atlas="atlas" frame-keys="coin-collect-0 coin-collect-1 coin-collect-2 coin-collect-3 coin-collect-4" pixels-per-unit="16"></pc-asset>
<pc-scene>
<pc-entity name="camera" position="0 0 10">
<pc-camera projection="orthographic" ortho-height="1" clear-color="#161a3c"></pc-camera>
</pc-entity>
<pc-entity name="coin" position="-0.6 0 0">
<pc-sprite type="animated" clip="spin">
<pc-sprite-clip name="spin" asset="coin-spin" fps="10" loop></pc-sprite-clip>
<pc-sprite-clip name="collect" asset="coin-collect" fps="15"></pc-sprite-clip>
</pc-sprite>
</pc-entity>
<pc-entity name="coin" position="0.6 0 0">
<pc-sprite type="animated" clip="spin">
<!-- A negative fps plays the clip backwards -->
<pc-sprite-clip name="spin" asset="coin-spin" fps="-10" loop></pc-sprite-clip>
<pc-sprite-clip name="collect" asset="coin-collect" fps="15"></pc-sprite-clip>
</pc-sprite>
</pc-entity>
</pc-scene>
</pc-app>
<div class="controls">
<button id="collect">Collect</button>
<button id="spin">Spin</button>
</div>
<style>
.controls {
position: absolute;
top: 12px;
left: 12px;
display: flex;
gap: 8px;
}
</style>
<script type="module">
const coins = document.querySelectorAll('pc-sprite');
const play = name => coins.forEach(coin => coin.setAttribute('clip', name));
document.getElementById('collect').onclick = () => play('collect');
document.getElementById('spin').onclick = () => play('spin');
</script>
JavaScript 接口
可以通过 SpriteClipElement API创建和操作元素。
asset、fps、loop、name 均有对应 property。只读 spriteAnimationClip 返回底层 SpriteAnimationClip,未就绪时为 null,详见加载。它对自身触发与精灵组件相同的 play、pause、resume、stop、end、loop,还提供 isPlaying,以及资源加载后的秒制 duration:
import { whenReady } from '@playcanvas/web-components';
const clip = await whenReady('pc-sprite-clip[name="land"]');
clip.spriteAnimationClip.on('end', () => console.log('landed'));
运行时可以增删。追加片段后,若父级 clip 已匹配该名,会立即替换其他播放。移除当前片段会停止,并且直到其他片段播放前不显示内容。
const slime = document.querySelector('#slime');
slime.clip = 'wave'; // no clip has this name yet, so the current clip plays on
const clip = document.createElement('pc-sprite-clip');
clip.setAttribute('name', 'wave');
clip.setAttribute('asset', 'slime-wave');
clip.setAttribute('fps', '10');
slime.appendChild(clip); // wave plays as soon as the clip is added
另请参阅
<pc-sprite>:所属精灵组件。<pc-asset>:提供动画帧的精灵资源。
示例:精灵。