mirror of
https://gitee.com/ccc_28/level-render
synced 2024-12-25 03:08:40 +00:00
demo
This commit is contained in:
parent
ba2b8f4a83
commit
cfa4631e91
@ -0,0 +1,2 @@
|
|||||||
|
[InternetShortcut]
|
||||||
|
URL=https://docs.cocos.com/creator/manual/en/scripting/setup.html#custom-script-template
|
5
.creator/default-meta.json
Normal file
5
.creator/default-meta.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"image": {
|
||||||
|
"type": "sprite-frame"
|
||||||
|
}
|
||||||
|
}
|
24
.gitignore
vendored
Normal file
24
.gitignore
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
|
||||||
|
#///////////////////////////
|
||||||
|
# Cocos Creator 3D Project
|
||||||
|
#///////////////////////////
|
||||||
|
library/
|
||||||
|
temp/
|
||||||
|
local/
|
||||||
|
build/
|
||||||
|
profiles/
|
||||||
|
native
|
||||||
|
#//////////////////////////
|
||||||
|
# NPM
|
||||||
|
#//////////////////////////
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
#//////////////////////////
|
||||||
|
# VSCode
|
||||||
|
#//////////////////////////
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
#//////////////////////////
|
||||||
|
# WebStorm
|
||||||
|
#//////////////////////////
|
||||||
|
.idea/
|
36
README.en.md
36
README.en.md
@ -1,36 +0,0 @@
|
|||||||
# LevelRender
|
|
||||||
|
|
||||||
#### Description
|
|
||||||
{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**}
|
|
||||||
|
|
||||||
#### Software Architecture
|
|
||||||
Software architecture description
|
|
||||||
|
|
||||||
#### Installation
|
|
||||||
|
|
||||||
1. xxxx
|
|
||||||
2. xxxx
|
|
||||||
3. xxxx
|
|
||||||
|
|
||||||
#### Instructions
|
|
||||||
|
|
||||||
1. xxxx
|
|
||||||
2. xxxx
|
|
||||||
3. xxxx
|
|
||||||
|
|
||||||
#### Contribution
|
|
||||||
|
|
||||||
1. Fork the repository
|
|
||||||
2. Create Feat_xxx branch
|
|
||||||
3. Commit your code
|
|
||||||
4. Create Pull Request
|
|
||||||
|
|
||||||
|
|
||||||
#### Gitee Feature
|
|
||||||
|
|
||||||
1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
|
|
||||||
2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
|
|
||||||
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
|
|
||||||
4. The most valuable open source project [GVP](https://gitee.com/gvp)
|
|
||||||
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
|
|
||||||
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
|
|
45
README.md
45
README.md
@ -1,39 +1,16 @@
|
|||||||
# LevelRender
|
# Cocos Creator 层级渲染 + 虚拟列表 + 分帧加载 demo
|
||||||
|
|
||||||
#### 介绍
|
引擎版本号 3.8.2
|
||||||
{**以下是 Gitee 平台说明,您可以替换此简介**
|
|
||||||
Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台
|
|
||||||
无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)}
|
|
||||||
|
|
||||||
#### 软件架构
|
**层级渲染**:由原本的按照深度遍历节点树渲染改为分层节点树渲染,从而达到两个item之间合批,像背包模块或并排按钮之间的合批特别适用。
|
||||||
软件架构说明
|
|
||||||
|
|
||||||
|
**虚拟列表**:item的数量无论多少,item的实例化数量始终在可视区域内数量+1行的数量。并对超出视图外的item进行复用。并且有屏幕适配功能
|
||||||
|
|
||||||
#### 安装教程
|
**分帧加载**:当一个item实例化时间过长时,下一个item将在下一帧创建,这样避免一帧时间创建所有item带来的卡顿。
|
||||||
|
|
||||||
1. xxxx
|
> 使用注意
|
||||||
2. xxxx
|
>
|
||||||
3. xxxx
|
> * 虽说在3.8.2中实现,但实际如何和3.8.2相差不大的版本都能强制打开使用
|
||||||
|
> * mask组件并不能在层级渲染节点下使用,在开启层级渲染的节点下使用mask则无法达到相应效果
|
||||||
#### 使用说明
|
> * 层级渲染合批需满足合批条件
|
||||||
|
> * 引擎3.7开始合批原生化了,如果原生平台需要层级渲染,则需要改c++代码。
|
||||||
1. xxxx
|
|
||||||
2. xxxx
|
|
||||||
3. xxxx
|
|
||||||
|
|
||||||
#### 参与贡献
|
|
||||||
|
|
||||||
1. Fork 本仓库
|
|
||||||
2. 新建 Feat_xxx 分支
|
|
||||||
3. 提交代码
|
|
||||||
4. 新建 Pull Request
|
|
||||||
|
|
||||||
|
|
||||||
#### 特技
|
|
||||||
|
|
||||||
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
|
|
||||||
2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com)
|
|
||||||
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目
|
|
||||||
4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
|
|
||||||
5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
|
|
||||||
6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
|
|
||||||
|
9
assets/demo.meta
Normal file
9
assets/demo.meta
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"ver": "1.2.0",
|
||||||
|
"importer": "directory",
|
||||||
|
"imported": true,
|
||||||
|
"uuid": "fc68b2f0-95ee-42cc-babd-05af9127f47b",
|
||||||
|
"files": [],
|
||||||
|
"subMetas": {},
|
||||||
|
"userData": {}
|
||||||
|
}
|
169
assets/demo/CCCExtension.ts
Normal file
169
assets/demo/CCCExtension.ts
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
import { EPSILON, Node, RenderData, StencilManager, UIRenderer, approx, cclegacy, clamp, gfx, log } from "cc";
|
||||||
|
enum Stage {
|
||||||
|
// Stencil disabled
|
||||||
|
DISABLED = 0,
|
||||||
|
// Clear stencil buffer
|
||||||
|
CLEAR = 1,
|
||||||
|
// Entering a new level, should handle new stencil
|
||||||
|
ENTER_LEVEL = 2,
|
||||||
|
// In content
|
||||||
|
ENABLED = 3,
|
||||||
|
// Exiting a level, should restore old stencil or disable
|
||||||
|
EXIT_LEVEL = 4,
|
||||||
|
// Clear stencil buffer & USE INVERTED
|
||||||
|
CLEAR_INVERTED = 5,
|
||||||
|
// Entering a new level & USE INVERTED
|
||||||
|
ENTER_LEVEL_INVERTED = 6,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class CCCExtension {
|
||||||
|
static init() {
|
||||||
|
this._extendRender3_x();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static _extendRender3_x() {
|
||||||
|
const batch2d = cclegacy[`internal`][`Batcher2D`];
|
||||||
|
let __renderQueue: Node[][] = [];
|
||||||
|
|
||||||
|
const levelSplit = (node: Node, lv: number, itemIndex) => {
|
||||||
|
if (!__renderQueue[lv]) {
|
||||||
|
__renderQueue[lv] = [];
|
||||||
|
}
|
||||||
|
__renderQueue[lv].push(node);
|
||||||
|
lv++;
|
||||||
|
node["__renderLv"] = lv;
|
||||||
|
node["__levelRender"] = true;
|
||||||
|
node["__itemIndex"] = itemIndex;
|
||||||
|
const cs = node.children;
|
||||||
|
for (let i = 0; i < cs.length; ++i) {
|
||||||
|
const c = cs[i];
|
||||||
|
if (!__renderQueue[lv]) {
|
||||||
|
__renderQueue[lv] = [];
|
||||||
|
}
|
||||||
|
lv = levelSplit(c, lv, itemIndex);
|
||||||
|
}
|
||||||
|
return lv;
|
||||||
|
}
|
||||||
|
Object.defineProperty(batch2d.prototype, "walk", {
|
||||||
|
value: function (node: Node, level = 0) {
|
||||||
|
if (!node[`activeInHierarchy`]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const children = node.children;
|
||||||
|
const uiProps = node._uiProps;
|
||||||
|
const render = uiProps.uiComp as UIRenderer;
|
||||||
|
// Save opacity
|
||||||
|
let parentOpacity = 1;
|
||||||
|
if (node.parent) {
|
||||||
|
parentOpacity = node.parent._uiProps.opacity;
|
||||||
|
}
|
||||||
|
let opacity = parentOpacity;
|
||||||
|
// TODO Always cascade ui property's local opacity before remove it
|
||||||
|
const selfOpacity = render && render.color ? render.color.a / 255 : 1;
|
||||||
|
|
||||||
|
opacity *= selfOpacity * uiProps.localOpacity;
|
||||||
|
// TODO Set opacity to ui property's opacity before remove it
|
||||||
|
if (uiProps[`setOpacity`]) {
|
||||||
|
uiProps[`setOpacity`](opacity);
|
||||||
|
} else {
|
||||||
|
uiProps[`_opacity`] = opacity;
|
||||||
|
}
|
||||||
|
if (!approx(opacity, 0, EPSILON)) {
|
||||||
|
if (uiProps.colorDirty) {
|
||||||
|
// Cascade color dirty state
|
||||||
|
this._opacityDirty++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render assembler update logic
|
||||||
|
if (render && render.enabledInHierarchy) {
|
||||||
|
render.fillBuffers(this);// for rendering
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update cascaded opacity to vertex buffer
|
||||||
|
if (this._opacityDirty && render && !render.useVertexOpacity && render.renderData && render.renderData.vertexCount > 0) {
|
||||||
|
// HARD COUPLING
|
||||||
|
updateOpacity(render.renderData, opacity);
|
||||||
|
const buffer = render.renderData.getMeshBuffer();
|
||||||
|
if (buffer) {
|
||||||
|
buffer.setDirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (children.length > 0 && !node._static) {
|
||||||
|
if (!node[`__levelRender`]) {
|
||||||
|
__renderQueue = [];
|
||||||
|
for (let i = 0; i < children.length; ++i) {
|
||||||
|
const child = children[i];
|
||||||
|
const enableLevelRender = node[`__enableLevelRender`];
|
||||||
|
if (!enableLevelRender) {
|
||||||
|
this.walk(child, level);
|
||||||
|
} else {
|
||||||
|
levelSplit(child, 0, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (__renderQueue.length > 0) {
|
||||||
|
const list = __renderQueue.shift();
|
||||||
|
if (list.length > 0) {
|
||||||
|
while (list.length > 0) {
|
||||||
|
const n = list.shift();
|
||||||
|
this.walk(n, level);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uiProps.colorDirty) {
|
||||||
|
// Reduce cascaded color dirty state
|
||||||
|
this._opacityDirty--;
|
||||||
|
// Reset color dirty
|
||||||
|
uiProps.colorDirty = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Restore opacity
|
||||||
|
// this._pOpacity = parentOpacity;
|
||||||
|
|
||||||
|
// Post render assembler update logic
|
||||||
|
// ATTENTION: Will also reset colorDirty inside postUpdateAssembler
|
||||||
|
if (render && render.enabledInHierarchy) {
|
||||||
|
render.postUpdateAssembler(this);
|
||||||
|
if ((render.stencilStage as any === Stage.ENTER_LEVEL || render.stencilStage as any === Stage.ENTER_LEVEL_INVERTED)
|
||||||
|
&& (StencilManager.sharedManager!.getMaskStackSize() > 0)) {
|
||||||
|
this.autoMergeBatches(this._currComponent!);
|
||||||
|
this.resetRenderStates();
|
||||||
|
StencilManager.sharedManager!.exitMask();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
level += 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updateOpacity(renderData: RenderData, opacity: number) {
|
||||||
|
const vfmt = renderData.vertexFormat;
|
||||||
|
const vb = renderData.chunk.vb;
|
||||||
|
let attr; let format; let stride;
|
||||||
|
// Color component offset
|
||||||
|
let offset = 0;
|
||||||
|
for (let i = 0; i < vfmt.length; ++i) {
|
||||||
|
attr = vfmt[i];
|
||||||
|
format = gfx.FormatInfos[attr.format];
|
||||||
|
if (format.hasAlpha) {
|
||||||
|
stride = renderData.floatStride;
|
||||||
|
if (format.size / format.count === 1) {
|
||||||
|
const alpha = ~~clamp(Math.round(opacity * 255), 0, 255);
|
||||||
|
// Uint color RGBA8
|
||||||
|
for (let color = offset; color < vb.length; color += stride) {
|
||||||
|
vb[color] = ((vb[color] & 0xffffff00) | alpha) >>> 0;
|
||||||
|
}
|
||||||
|
} else if (format.size / format.count === 4) {
|
||||||
|
// RGBA32 color, alpha at position 3
|
||||||
|
for (let alpha = offset + 3; alpha < vb.length; alpha += stride) {
|
||||||
|
vb[alpha] = opacity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
offset += format.size >> 2;
|
||||||
|
}
|
||||||
|
}
|
9
assets/demo/CCCExtension.ts.meta
Normal file
9
assets/demo/CCCExtension.ts.meta
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"ver": "4.0.23",
|
||||||
|
"importer": "typescript",
|
||||||
|
"imported": true,
|
||||||
|
"uuid": "ee2a11c5-09da-45a4-ba35-e08e57b3e388",
|
||||||
|
"files": [],
|
||||||
|
"subMetas": {},
|
||||||
|
"userData": {}
|
||||||
|
}
|
334
assets/demo/Item.prefab
Normal file
334
assets/demo/Item.prefab
Normal file
@ -0,0 +1,334 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"__type__": "cc.Prefab",
|
||||||
|
"_name": "Item",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"__editorExtras__": {},
|
||||||
|
"_native": "",
|
||||||
|
"data": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"optimizationPolicy": 0,
|
||||||
|
"persistent": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.Node",
|
||||||
|
"_name": "Item",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"__editorExtras__": {},
|
||||||
|
"_parent": null,
|
||||||
|
"_children": [
|
||||||
|
{
|
||||||
|
"__id__": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_active": true,
|
||||||
|
"_components": [
|
||||||
|
{
|
||||||
|
"__id__": 8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__id__": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__id__": 12
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_prefab": {
|
||||||
|
"__id__": 14
|
||||||
|
},
|
||||||
|
"_lpos": {
|
||||||
|
"__type__": "cc.Vec3",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"_lrot": {
|
||||||
|
"__type__": "cc.Quat",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0,
|
||||||
|
"w": 1
|
||||||
|
},
|
||||||
|
"_lscale": {
|
||||||
|
"__type__": "cc.Vec3",
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"z": 1
|
||||||
|
},
|
||||||
|
"_mobility": 0,
|
||||||
|
"_layer": 33554432,
|
||||||
|
"_euler": {
|
||||||
|
"__type__": "cc.Vec3",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.Node",
|
||||||
|
"_name": "Label",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"__editorExtras__": {},
|
||||||
|
"_parent": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"_children": [],
|
||||||
|
"_active": true,
|
||||||
|
"_components": [
|
||||||
|
{
|
||||||
|
"__id__": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__id__": 5
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_prefab": {
|
||||||
|
"__id__": 7
|
||||||
|
},
|
||||||
|
"_lpos": {
|
||||||
|
"__type__": "cc.Vec3",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"_lrot": {
|
||||||
|
"__type__": "cc.Quat",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0,
|
||||||
|
"w": 1
|
||||||
|
},
|
||||||
|
"_lscale": {
|
||||||
|
"__type__": "cc.Vec3",
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"z": 1
|
||||||
|
},
|
||||||
|
"_mobility": 0,
|
||||||
|
"_layer": 33554432,
|
||||||
|
"_euler": {
|
||||||
|
"__type__": "cc.Vec3",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.UITransform",
|
||||||
|
"_name": "",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"__editorExtras__": {},
|
||||||
|
"node": {
|
||||||
|
"__id__": 2
|
||||||
|
},
|
||||||
|
"_enabled": true,
|
||||||
|
"__prefab": {
|
||||||
|
"__id__": 4
|
||||||
|
},
|
||||||
|
"_contentSize": {
|
||||||
|
"__type__": "cc.Size",
|
||||||
|
"width": 84.53,
|
||||||
|
"height": 40
|
||||||
|
},
|
||||||
|
"_anchorPoint": {
|
||||||
|
"__type__": "cc.Vec2",
|
||||||
|
"x": 0.5,
|
||||||
|
"y": 0.5
|
||||||
|
},
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.CompPrefabInfo",
|
||||||
|
"fileId": "99WXCytTpDJaUHgBnsSY90"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.Label",
|
||||||
|
"_name": "",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"__editorExtras__": {},
|
||||||
|
"node": {
|
||||||
|
"__id__": 2
|
||||||
|
},
|
||||||
|
"_enabled": true,
|
||||||
|
"__prefab": {
|
||||||
|
"__id__": 6
|
||||||
|
},
|
||||||
|
"_customMaterial": null,
|
||||||
|
"_srcBlendFactor": 2,
|
||||||
|
"_dstBlendFactor": 4,
|
||||||
|
"_color": {
|
||||||
|
"__type__": "cc.Color",
|
||||||
|
"r": 0,
|
||||||
|
"g": 0,
|
||||||
|
"b": 0,
|
||||||
|
"a": 255
|
||||||
|
},
|
||||||
|
"_string": "label",
|
||||||
|
"_horizontalAlign": 1,
|
||||||
|
"_verticalAlign": 1,
|
||||||
|
"_actualFontSize": 40,
|
||||||
|
"_fontSize": 40,
|
||||||
|
"_fontFamily": "Arial",
|
||||||
|
"_lineHeight": 40,
|
||||||
|
"_overflow": 0,
|
||||||
|
"_enableWrapText": true,
|
||||||
|
"_font": null,
|
||||||
|
"_isSystemFontUsed": true,
|
||||||
|
"_spacingX": 0,
|
||||||
|
"_isItalic": false,
|
||||||
|
"_isBold": false,
|
||||||
|
"_isUnderline": false,
|
||||||
|
"_underlineHeight": 2,
|
||||||
|
"_cacheMode": 2,
|
||||||
|
"_enableOutline": false,
|
||||||
|
"_outlineColor": {
|
||||||
|
"__type__": "cc.Color",
|
||||||
|
"r": 0,
|
||||||
|
"g": 0,
|
||||||
|
"b": 0,
|
||||||
|
"a": 255
|
||||||
|
},
|
||||||
|
"_outlineWidth": 2,
|
||||||
|
"_enableShadow": false,
|
||||||
|
"_shadowColor": {
|
||||||
|
"__type__": "cc.Color",
|
||||||
|
"r": 0,
|
||||||
|
"g": 0,
|
||||||
|
"b": 0,
|
||||||
|
"a": 255
|
||||||
|
},
|
||||||
|
"_shadowOffset": {
|
||||||
|
"__type__": "cc.Vec2",
|
||||||
|
"x": 2,
|
||||||
|
"y": 2
|
||||||
|
},
|
||||||
|
"_shadowBlur": 2,
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.CompPrefabInfo",
|
||||||
|
"fileId": "4b0Jv68x5C57fYyW1Xd0eL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.PrefabInfo",
|
||||||
|
"root": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"asset": {
|
||||||
|
"__id__": 0
|
||||||
|
},
|
||||||
|
"fileId": "f1eNllhSdJdamAkXyk8eNR",
|
||||||
|
"instance": null,
|
||||||
|
"targetOverrides": null,
|
||||||
|
"nestedPrefabInstanceRoots": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.UITransform",
|
||||||
|
"_name": "",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"__editorExtras__": {},
|
||||||
|
"node": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"_enabled": true,
|
||||||
|
"__prefab": {
|
||||||
|
"__id__": 9
|
||||||
|
},
|
||||||
|
"_contentSize": {
|
||||||
|
"__type__": "cc.Size",
|
||||||
|
"width": 100,
|
||||||
|
"height": 100
|
||||||
|
},
|
||||||
|
"_anchorPoint": {
|
||||||
|
"__type__": "cc.Vec2",
|
||||||
|
"x": 0.5,
|
||||||
|
"y": 0.5
|
||||||
|
},
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.CompPrefabInfo",
|
||||||
|
"fileId": "24rqGXNzdJG7douvaXvVPp"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.Sprite",
|
||||||
|
"_name": "",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"__editorExtras__": {},
|
||||||
|
"node": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"_enabled": true,
|
||||||
|
"__prefab": {
|
||||||
|
"__id__": 11
|
||||||
|
},
|
||||||
|
"_customMaterial": null,
|
||||||
|
"_srcBlendFactor": 2,
|
||||||
|
"_dstBlendFactor": 4,
|
||||||
|
"_color": {
|
||||||
|
"__type__": "cc.Color",
|
||||||
|
"r": 175,
|
||||||
|
"g": 211,
|
||||||
|
"b": 159,
|
||||||
|
"a": 255
|
||||||
|
},
|
||||||
|
"_spriteFrame": {
|
||||||
|
"__uuid__": "7d8f9b89-4fd1-4c9f-a3ab-38ec7cded7ca@f9941",
|
||||||
|
"__expectedType__": "cc.SpriteFrame"
|
||||||
|
},
|
||||||
|
"_type": 0,
|
||||||
|
"_fillType": 0,
|
||||||
|
"_sizeMode": 0,
|
||||||
|
"_fillCenter": {
|
||||||
|
"__type__": "cc.Vec2",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"_fillStart": 0,
|
||||||
|
"_fillRange": 0,
|
||||||
|
"_isTrimmedMode": true,
|
||||||
|
"_useGrayscale": false,
|
||||||
|
"_atlas": null,
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.CompPrefabInfo",
|
||||||
|
"fileId": "5c+opoJ2FJBom3VHk6i4OK"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "417cf4N2NNHB7VMscG3Qlox",
|
||||||
|
"_name": "",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"__editorExtras__": {},
|
||||||
|
"node": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"_enabled": true,
|
||||||
|
"__prefab": {
|
||||||
|
"__id__": 13
|
||||||
|
},
|
||||||
|
"lbl": {
|
||||||
|
"__id__": 5
|
||||||
|
},
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.CompPrefabInfo",
|
||||||
|
"fileId": "4fxIFH0GBOsIhVFP+yqEBn"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.PrefabInfo",
|
||||||
|
"root": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"asset": {
|
||||||
|
"__id__": 0
|
||||||
|
},
|
||||||
|
"fileId": "7aGBu2+tVB37gUIuab2WDf",
|
||||||
|
"instance": null,
|
||||||
|
"targetOverrides": null
|
||||||
|
}
|
||||||
|
]
|
13
assets/demo/Item.prefab.meta
Normal file
13
assets/demo/Item.prefab.meta
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"ver": "1.1.50",
|
||||||
|
"importer": "prefab",
|
||||||
|
"imported": true,
|
||||||
|
"uuid": "518ab7b7-13a6-4cf0-9ab1-f5e9c6094a8b",
|
||||||
|
"files": [
|
||||||
|
".json"
|
||||||
|
],
|
||||||
|
"subMetas": {},
|
||||||
|
"userData": {
|
||||||
|
"syncNodeName": "Item"
|
||||||
|
}
|
||||||
|
}
|
18
assets/demo/Item.ts
Normal file
18
assets/demo/Item.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { Label } from 'cc';
|
||||||
|
import { _decorator, Component, Node } from 'cc';
|
||||||
|
const { ccclass, property } = _decorator;
|
||||||
|
|
||||||
|
export interface IItem {
|
||||||
|
id: number
|
||||||
|
}
|
||||||
|
@ccclass('Item')
|
||||||
|
export class Item extends Component {
|
||||||
|
@property(Label)
|
||||||
|
lbl: Label = null;
|
||||||
|
|
||||||
|
setData(p: IItem) {
|
||||||
|
this.lbl.string = `${p.id}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
9
assets/demo/Item.ts.meta
Normal file
9
assets/demo/Item.ts.meta
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"ver": "4.0.23",
|
||||||
|
"importer": "typescript",
|
||||||
|
"imported": true,
|
||||||
|
"uuid": "417cfe0d-d8d3-4707-b54c-b1c1b7425a31",
|
||||||
|
"files": [],
|
||||||
|
"subMetas": {},
|
||||||
|
"userData": {}
|
||||||
|
}
|
11
assets/demo/LevelRender.ts
Normal file
11
assets/demo/LevelRender.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { _decorator, Component, Node } from 'cc';
|
||||||
|
const { ccclass, property, menu } = _decorator;
|
||||||
|
|
||||||
|
@ccclass('LevelRender')
|
||||||
|
@menu("性能优化/LevelRender")
|
||||||
|
export class LevelRender extends Component {
|
||||||
|
onLoad() {
|
||||||
|
this.node[`__enableLevelRender`] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
9
assets/demo/LevelRender.ts.meta
Normal file
9
assets/demo/LevelRender.ts.meta
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"ver": "4.0.23",
|
||||||
|
"importer": "typescript",
|
||||||
|
"imported": true,
|
||||||
|
"uuid": "4440b178-0803-41b1-bb7f-390c9a2b32a5",
|
||||||
|
"files": [],
|
||||||
|
"subMetas": {},
|
||||||
|
"userData": {}
|
||||||
|
}
|
304
assets/demo/RecycleScroll.ts
Normal file
304
assets/demo/RecycleScroll.ts
Normal file
@ -0,0 +1,304 @@
|
|||||||
|
import { Component, Node, Prefab, ScrollView, UITransform, Vec2, _decorator, error, instantiate, isValid, log, v2, v3 } from "cc";
|
||||||
|
const { ccclass, property, menu } = _decorator;
|
||||||
|
|
||||||
|
let createFlag = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 循环+分帧滑动面板
|
||||||
|
*/
|
||||||
|
@ccclass('RecycleScroll')
|
||||||
|
@menu("性能优化/RecycleScroll")
|
||||||
|
export default class RecycleScroll extends Component {
|
||||||
|
/** item预制 */
|
||||||
|
@property(Prefab)
|
||||||
|
itemPrefab: Prefab = null;
|
||||||
|
|
||||||
|
/** item间隔 */
|
||||||
|
@property(Vec2)
|
||||||
|
spacing: Vec2 = v2();
|
||||||
|
|
||||||
|
/** item数量 */
|
||||||
|
private _numItems: number = 0;
|
||||||
|
public get numItems() {
|
||||||
|
return this._numItems;
|
||||||
|
}
|
||||||
|
public set numItems(value: number) {
|
||||||
|
this._numItems = value;
|
||||||
|
this._hideAllItems();
|
||||||
|
this._initialize();
|
||||||
|
this._updateContentHeight();
|
||||||
|
this.updateAllItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 视图内显示列数 */
|
||||||
|
private _viewCol: number = 0;
|
||||||
|
/** 视图内显示行数 */
|
||||||
|
private _viewRow: number = 0;
|
||||||
|
/** 视图窗宽 */
|
||||||
|
private _viewW: number = 0;
|
||||||
|
/** 视图窗高 */
|
||||||
|
private _viewH: number = 0;
|
||||||
|
/** item格子宽 */
|
||||||
|
private _itemW: number = 0;
|
||||||
|
/** item格子高 */
|
||||||
|
private _itemH: number = 0;
|
||||||
|
/** content上一次y坐标 */
|
||||||
|
private _lastPosY: number = 0;
|
||||||
|
/** 是否已初始化 */
|
||||||
|
private _isInit: boolean = false;
|
||||||
|
/** item的index */
|
||||||
|
private _itemsUUIDToIndex: { [uuid: string]: number } = {};
|
||||||
|
|
||||||
|
// private _itemsIndexToNode: { [index: string]: Node } = {};
|
||||||
|
|
||||||
|
private _fleshInterval: number = 0.2;
|
||||||
|
private _fleshCounter: number = 0;
|
||||||
|
private _initTimer: number = 0.05;
|
||||||
|
private _initCounter: number = 0;
|
||||||
|
private _isResize: boolean = false;
|
||||||
|
private _itemStartPos: Vec2 = v2();
|
||||||
|
private _isResizeFinish: boolean = false;
|
||||||
|
private _lineIndex: number = -1;
|
||||||
|
|
||||||
|
/** item列表 */
|
||||||
|
public itemList: Node[] = [];
|
||||||
|
/** item父节点 */
|
||||||
|
public content: UITransform = null;
|
||||||
|
|
||||||
|
/** item刷新回调 */
|
||||||
|
public onItemRender(index: number, node: Node) { }
|
||||||
|
/** item点击回调 */
|
||||||
|
public onItemClicked(index: number, node: Node) { }
|
||||||
|
|
||||||
|
/** 刷新所有item */
|
||||||
|
public updateAllItems() {
|
||||||
|
this.itemList.forEach((item: Node) => this._updateItem(this._itemsUUIDToIndex[item.uuid], item, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
public scrollToIndexVertical(index: number, duration: number = 0.2) {
|
||||||
|
const contentUTF = this._getContentUTF();
|
||||||
|
const p = (this._itemH * index) / (contentUTF.height - this._viewH);
|
||||||
|
this.node.getComponent(ScrollView).scrollToPercentVertical(1 - p, duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getItemDirPos(itemIndex: number) {
|
||||||
|
const x = (itemIndex % this._viewCol) * this._itemW;
|
||||||
|
const y = -Math.floor(itemIndex / this._viewCol) * this._itemH + (this.spacing.y >> 1);
|
||||||
|
const contentUTF = this._getContentUTF();
|
||||||
|
const wpos = contentUTF.convertToWorldSpaceAR(v3(x, y));
|
||||||
|
const parentUTF = this._getContentUTF().node.parent.getComponent(UITransform);
|
||||||
|
const itemInViewPos = parentUTF.convertToNodeSpaceAR(wpos);
|
||||||
|
let horizon = 0;
|
||||||
|
let vertical = 0;
|
||||||
|
horizon = itemInViewPos.x < -this._viewW / 2 ? -1 : (itemInViewPos.x > this._viewW / 2 ? 1 : 0);
|
||||||
|
vertical = itemInViewPos.y < -this._viewH / 2 ? -1 : (itemInViewPos.y > this._viewH / 2 ? 1 : 0);
|
||||||
|
return [horizon, vertical];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected onLoad(): void {
|
||||||
|
this.node.on(Node.EventType.SIZE_CHANGED, this.onSizeChange, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected onSizeChange() {
|
||||||
|
this._isResize = true;
|
||||||
|
this._initCounter = 0;
|
||||||
|
this._itemsUUIDToIndex = {};
|
||||||
|
// this.itemList = [];
|
||||||
|
this._getContentUTF().node.removeAllChildren();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected onDestroy(): void {
|
||||||
|
this.node.targetOff(this);
|
||||||
|
// screen.off(`window-resize`, this.onWindowResize, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _hideAllItems() {
|
||||||
|
this.itemList.forEach((item: Node, index: number) => item.active = false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 获取content */
|
||||||
|
private _getContentUTF() {
|
||||||
|
return this.node.getComponent(ScrollView).content.getComponent(UITransform);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 初始化 */
|
||||||
|
private _initialize() {
|
||||||
|
if (this._isInit) return;
|
||||||
|
const scroll = this.node.getComponent(ScrollView);
|
||||||
|
scroll.enabled = false;
|
||||||
|
this._isInit = true;
|
||||||
|
const content = this._getContentUTF();
|
||||||
|
this.content = content;
|
||||||
|
content.node.removeAllChildren()
|
||||||
|
this.itemList = [];
|
||||||
|
const viewUTF = content.node.parent.getComponent(UITransform);
|
||||||
|
this._viewW = viewUTF.width;
|
||||||
|
this._viewH = viewUTF.height;
|
||||||
|
|
||||||
|
const itemData = this.itemPrefab.data.getComponent(UITransform);
|
||||||
|
this._itemW = itemData.width + this.spacing.x;
|
||||||
|
this._itemH = itemData.height + this.spacing.y;
|
||||||
|
|
||||||
|
this._lastPosY = content.node.position.y;
|
||||||
|
this._viewRow = Math.ceil(this._viewH / this._itemH) + 1;
|
||||||
|
this._viewCol = Math.floor(this._viewW / this._itemW);
|
||||||
|
const surplusW = this._viewW - (this._viewCol * this._itemW);
|
||||||
|
const startPos = v2((-this._viewW >> 1) + (this._itemW >> 1) + (surplusW >> 1), -this._itemH >> 1);
|
||||||
|
this._itemStartPos = startPos;
|
||||||
|
|
||||||
|
const cNum = this._viewRow * this._viewCol;
|
||||||
|
log(`实例化数量:${cNum}`);
|
||||||
|
|
||||||
|
let createNum = 0;
|
||||||
|
const createFunc = (index: number) => {
|
||||||
|
if (!isValid(content)) return; //异步创建,创建完回来父节点有可能已经被销毁
|
||||||
|
const item = instantiate(this.itemPrefab);
|
||||||
|
item.parent = content.node;
|
||||||
|
const x = (index % this._viewCol) * this._itemW;
|
||||||
|
const y = -Math.floor(index / this._viewCol) * this._itemH + (this.spacing.y >> 1);
|
||||||
|
const pos = v3(x + startPos.x, y + startPos.y);
|
||||||
|
item.setPosition(pos);
|
||||||
|
item.on(Node.EventType.TOUCH_END, () => {
|
||||||
|
this.onItemClicked(this._itemsUUIDToIndex[item.uuid], item);
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
this.itemList[index] = item;
|
||||||
|
|
||||||
|
item["needRender"] = true;
|
||||||
|
this._updateItem(index, item);
|
||||||
|
|
||||||
|
this._itemsUUIDToIndex[item.uuid] = index;
|
||||||
|
|
||||||
|
createNum++;
|
||||||
|
if (createNum == cNum) {
|
||||||
|
scroll.enabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
createFlag++;
|
||||||
|
/** 分帧创建item */
|
||||||
|
frameLoad(cNum, createFunc, 16, 0, createFlag);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 更新centent高度 */
|
||||||
|
private _updateContentHeight() {
|
||||||
|
const content = this._getContentUTF();
|
||||||
|
const col = Math.floor(this._viewW / this._itemW);
|
||||||
|
const row = Math.ceil(this.numItems / col);
|
||||||
|
content.height = row * (this.itemPrefab.data.getComponent(UITransform).height + this.spacing.y) - (this.spacing.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 获取item在view坐标系的对标 */
|
||||||
|
private _getPosInView(item: Node) {
|
||||||
|
const content = this._getContentUTF();
|
||||||
|
const viewUTF = content.node.parent.getComponent(UITransform);
|
||||||
|
const wpos = content.convertToWorldSpaceAR(item.position);
|
||||||
|
const lpos = viewUTF.convertToNodeSpaceAR(wpos);
|
||||||
|
return lpos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 更新item */
|
||||||
|
private _updateItem(index: number, item: Node, force = false) {
|
||||||
|
const isShow = index >= 0 && index < this.numItems;
|
||||||
|
item.active = isShow;
|
||||||
|
if (isShow) {
|
||||||
|
if (item["needRender"] || force) {
|
||||||
|
this.onItemRender(index, item);
|
||||||
|
item["needRender"] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public update(dt: number) {
|
||||||
|
if (this._isResize) {
|
||||||
|
this._initCounter += dt;
|
||||||
|
if (this._initCounter >= this._initTimer) {
|
||||||
|
this._isInit = false;
|
||||||
|
this._isResize = false;
|
||||||
|
this.numItems = this._numItems;
|
||||||
|
this._isResizeFinish = true;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const content = this._getContentUTF();
|
||||||
|
const currY = content.node.position.y;
|
||||||
|
const dtY = currY - this._lastPosY;
|
||||||
|
this._lastPosY = currY;
|
||||||
|
this._fleshCounter += dt;
|
||||||
|
if (dtY == 0 && !this._isResizeFinish) return;
|
||||||
|
const isDown = dtY < 0;
|
||||||
|
const viewHalfH = this._viewH >> 1;
|
||||||
|
const itemHalfH = this._itemH >> 1;
|
||||||
|
const lineIndex = Math.floor((currY - viewHalfH) / this._itemH);
|
||||||
|
let isLineChange = this._lineIndex != lineIndex;
|
||||||
|
if (!isLineChange && !this._isResizeFinish) return;
|
||||||
|
this._isResizeFinish = false;
|
||||||
|
this._lineIndex = lineIndex;
|
||||||
|
const pageHeight = this._itemH * this._viewRow;
|
||||||
|
const pageLen = this._viewRow * this._viewCol;
|
||||||
|
const pageIndex = Math.floor((currY - viewHalfH) / pageHeight);
|
||||||
|
const itemsLen = this.itemList.length;
|
||||||
|
for (let i = 0; i < itemsLen; ++i) {
|
||||||
|
const index = i;
|
||||||
|
const item = this.itemList[i];
|
||||||
|
const x = (index % this._viewCol) * this._itemW;
|
||||||
|
const y = -Math.floor(index / this._viewCol) * this._itemH + (this.spacing.y >> 1);
|
||||||
|
const pos = v3(x + this._itemStartPos.x, y + this._itemStartPos.y - pageIndex * (pageHeight));
|
||||||
|
item.setPosition(pos);
|
||||||
|
|
||||||
|
const posInView = this._getPosInView(item);
|
||||||
|
const lastIndex = this._itemsUUIDToIndex[item.uuid];
|
||||||
|
let currIndex = pageIndex * pageLen + i;
|
||||||
|
if (!isDown) {
|
||||||
|
if (posInView.y >= (viewHalfH + itemHalfH)) {
|
||||||
|
item.setPosition(v3(item.position.x, item.position.y - (this._viewRow * this._itemH)));
|
||||||
|
currIndex += itemsLen;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (posInView.y >= viewHalfH + itemHalfH) {
|
||||||
|
item.setPosition(v3(item.position.x, item.position.y - (this._viewRow * this._itemH)));
|
||||||
|
currIndex += itemsLen;
|
||||||
|
}
|
||||||
|
if (isLineChange) {
|
||||||
|
const posInView = this._getPosInView(item);
|
||||||
|
if (posInView.y <= -(viewHalfH + itemHalfH)) {
|
||||||
|
item.setPosition(v3(item.position.x, item.position.y + (this._viewRow * this._itemH)));
|
||||||
|
currIndex -= itemsLen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (currIndex != lastIndex) {
|
||||||
|
item["needRender"] = true;
|
||||||
|
this._updateItem(currIndex, item);
|
||||||
|
}
|
||||||
|
this._itemsUUIDToIndex[item.uuid] = currIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 分帧执行 */
|
||||||
|
function frameLoad(loopTimes: number, func: Function, frameTime: number = 16, __index: number = 0, flag = 0) {
|
||||||
|
let loop = loopTimes;
|
||||||
|
let start = new Date().getTime();
|
||||||
|
let end = 0;
|
||||||
|
let dt = 0;
|
||||||
|
for (let i = 0; i < loop; ++i) {
|
||||||
|
if (flag != createFlag) break;
|
||||||
|
if (__index >= loop) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
func && func(__index);
|
||||||
|
} catch (e) {
|
||||||
|
error(e);
|
||||||
|
}
|
||||||
|
__index++;
|
||||||
|
end = new Date().getTime();
|
||||||
|
dt = end - start;
|
||||||
|
if (dt > frameTime) {
|
||||||
|
setTimeout(() => {
|
||||||
|
frameLoad(loop, func, frameTime, __index, flag);
|
||||||
|
}, 10);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
9
assets/demo/RecycleScroll.ts.meta
Normal file
9
assets/demo/RecycleScroll.ts.meta
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"ver": "4.0.23",
|
||||||
|
"importer": "typescript",
|
||||||
|
"imported": true,
|
||||||
|
"uuid": "3b299c27-eed8-441c-8841-ccc1f1fd7c43",
|
||||||
|
"files": [],
|
||||||
|
"subMetas": {},
|
||||||
|
"userData": {}
|
||||||
|
}
|
1759
assets/demo/demo.scene
Normal file
1759
assets/demo/demo.scene
Normal file
File diff suppressed because it is too large
Load Diff
11
assets/demo/demo.scene.meta
Normal file
11
assets/demo/demo.scene.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"ver": "1.1.50",
|
||||||
|
"importer": "scene",
|
||||||
|
"imported": true,
|
||||||
|
"uuid": "5f18812b-2121-4a62-bccd-4b8af6ed4e1d",
|
||||||
|
"files": [
|
||||||
|
".json"
|
||||||
|
],
|
||||||
|
"subMetas": {},
|
||||||
|
"userData": {}
|
||||||
|
}
|
35
assets/demo/demo.ts
Normal file
35
assets/demo/demo.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import { _decorator, Component, Node } from 'cc';
|
||||||
|
import CCCExtension from './CCCExtension';
|
||||||
|
import RecycleScroll from './RecycleScroll';
|
||||||
|
import { Item } from './Item';
|
||||||
|
|
||||||
|
const { ccclass, property } = _decorator;
|
||||||
|
|
||||||
|
@ccclass('Launc')
|
||||||
|
export class Launc extends Component {
|
||||||
|
@property(RecycleScroll)
|
||||||
|
itemScroll: RecycleScroll = null;
|
||||||
|
|
||||||
|
onLoad(): void {
|
||||||
|
CCCExtension.init()
|
||||||
|
this.itemScroll.onItemRender = this.onItemRender.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
start() {
|
||||||
|
this.itemScroll.numItems = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
onItemRender(index: number, node: Node) {
|
||||||
|
node.getComponent(Item).setData({ id: index })
|
||||||
|
}
|
||||||
|
|
||||||
|
click() {
|
||||||
|
if (this.itemScroll.numItems == 15) {
|
||||||
|
this.itemScroll.numItems = 1000
|
||||||
|
} else {
|
||||||
|
this.itemScroll.numItems = 15
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
9
assets/demo/demo.ts.meta
Normal file
9
assets/demo/demo.ts.meta
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"ver": "4.0.23",
|
||||||
|
"importer": "typescript",
|
||||||
|
"imported": true,
|
||||||
|
"uuid": "c097bf58-892c-4906-98db-75abb313fbf8",
|
||||||
|
"files": [],
|
||||||
|
"subMetas": {},
|
||||||
|
"userData": {}
|
||||||
|
}
|
7
package.json
Normal file
7
package.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"name": "Scroll",
|
||||||
|
"uuid": "5cbf44aa-0cd2-42ab-bb41-9c9e06389bf3",
|
||||||
|
"creator": {
|
||||||
|
"version": "3.8.2"
|
||||||
|
}
|
||||||
|
}
|
3
settings/v2/packages/builder.json
Normal file
3
settings/v2/packages/builder.json
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"__version__": "1.3.7"
|
||||||
|
}
|
23
settings/v2/packages/cocos-service.json
Normal file
23
settings/v2/packages/cocos-service.json
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"__version__": "3.0.7",
|
||||||
|
"game": {
|
||||||
|
"name": "未知游戏",
|
||||||
|
"app_id": "UNKNOW",
|
||||||
|
"c_id": "0"
|
||||||
|
},
|
||||||
|
"appConfigMaps": [
|
||||||
|
{
|
||||||
|
"app_id": "UNKNOW",
|
||||||
|
"config_id": "159a4c"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"configs": [
|
||||||
|
{
|
||||||
|
"app_id": "UNKNOW",
|
||||||
|
"config_id": "159a4c",
|
||||||
|
"config_name": "Default",
|
||||||
|
"config_remarks": "",
|
||||||
|
"services": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
3
settings/v2/packages/device.json
Normal file
3
settings/v2/packages/device.json
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"__version__": "1.0.1"
|
||||||
|
}
|
150
settings/v2/packages/engine.json
Normal file
150
settings/v2/packages/engine.json
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
{
|
||||||
|
"__version__": "1.0.8",
|
||||||
|
"modules": {
|
||||||
|
"cache": {
|
||||||
|
"base": {
|
||||||
|
"_value": true
|
||||||
|
},
|
||||||
|
"graphcis": {
|
||||||
|
"_value": true
|
||||||
|
},
|
||||||
|
"gfx-webgl": {
|
||||||
|
"_value": true
|
||||||
|
},
|
||||||
|
"gfx-webgl2": {
|
||||||
|
"_value": true
|
||||||
|
},
|
||||||
|
"animation": {
|
||||||
|
"_value": true
|
||||||
|
},
|
||||||
|
"skeletal-animation": {
|
||||||
|
"_value": false
|
||||||
|
},
|
||||||
|
"3d": {
|
||||||
|
"_value": false
|
||||||
|
},
|
||||||
|
"2d": {
|
||||||
|
"_value": true
|
||||||
|
},
|
||||||
|
"xr": {
|
||||||
|
"_value": false
|
||||||
|
},
|
||||||
|
"ui": {
|
||||||
|
"_value": true
|
||||||
|
},
|
||||||
|
"particle": {
|
||||||
|
"_value": false
|
||||||
|
},
|
||||||
|
"physics": {
|
||||||
|
"_value": false,
|
||||||
|
"_option": "physics-ammo"
|
||||||
|
},
|
||||||
|
"physics-ammo": {
|
||||||
|
"_value": false
|
||||||
|
},
|
||||||
|
"physics-cannon": {
|
||||||
|
"_value": false
|
||||||
|
},
|
||||||
|
"physics-physx": {
|
||||||
|
"_value": false
|
||||||
|
},
|
||||||
|
"physics-builtin": {
|
||||||
|
"_value": false
|
||||||
|
},
|
||||||
|
"physics-2d": {
|
||||||
|
"_value": true,
|
||||||
|
"_option": "physics-2d-box2d"
|
||||||
|
},
|
||||||
|
"physics-2d-box2d": {
|
||||||
|
"_value": false
|
||||||
|
},
|
||||||
|
"physics-2d-builtin": {
|
||||||
|
"_value": false
|
||||||
|
},
|
||||||
|
"intersection-2d": {
|
||||||
|
"_value": true
|
||||||
|
},
|
||||||
|
"primitive": {
|
||||||
|
"_value": false
|
||||||
|
},
|
||||||
|
"profiler": {
|
||||||
|
"_value": true
|
||||||
|
},
|
||||||
|
"occlusion-query": {
|
||||||
|
"_value": false
|
||||||
|
},
|
||||||
|
"geometry-renderer": {
|
||||||
|
"_value": false
|
||||||
|
},
|
||||||
|
"debug-renderer": {
|
||||||
|
"_value": false
|
||||||
|
},
|
||||||
|
"particle-2d": {
|
||||||
|
"_value": true
|
||||||
|
},
|
||||||
|
"audio": {
|
||||||
|
"_value": true
|
||||||
|
},
|
||||||
|
"video": {
|
||||||
|
"_value": true
|
||||||
|
},
|
||||||
|
"webview": {
|
||||||
|
"_value": true
|
||||||
|
},
|
||||||
|
"tween": {
|
||||||
|
"_value": true
|
||||||
|
},
|
||||||
|
"websocket": {
|
||||||
|
"_value": false
|
||||||
|
},
|
||||||
|
"websocket-server": {
|
||||||
|
"_value": false
|
||||||
|
},
|
||||||
|
"terrain": {
|
||||||
|
"_value": false
|
||||||
|
},
|
||||||
|
"light-probe": {
|
||||||
|
"_value": false
|
||||||
|
},
|
||||||
|
"tiled-map": {
|
||||||
|
"_value": true
|
||||||
|
},
|
||||||
|
"spine": {
|
||||||
|
"_value": true
|
||||||
|
},
|
||||||
|
"dragon-bones": {
|
||||||
|
"_value": true
|
||||||
|
},
|
||||||
|
"marionette": {
|
||||||
|
"_value": false
|
||||||
|
},
|
||||||
|
"custom-pipeline": {
|
||||||
|
"_value": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"includeModules": [
|
||||||
|
"2d",
|
||||||
|
"animation",
|
||||||
|
"audio",
|
||||||
|
"base",
|
||||||
|
"dragon-bones",
|
||||||
|
"gfx-webgl",
|
||||||
|
"gfx-webgl2",
|
||||||
|
"intersection-2d",
|
||||||
|
"particle-2d",
|
||||||
|
"physics-2d-box2d",
|
||||||
|
"profiler",
|
||||||
|
"spine",
|
||||||
|
"tiled-map",
|
||||||
|
"tween",
|
||||||
|
"ui",
|
||||||
|
"video",
|
||||||
|
"webview"
|
||||||
|
],
|
||||||
|
"noDeprecatedFeatures": {
|
||||||
|
"value": false,
|
||||||
|
"version": ""
|
||||||
|
},
|
||||||
|
"flags": {}
|
||||||
|
}
|
||||||
|
}
|
23
settings/v2/packages/information.json
Normal file
23
settings/v2/packages/information.json
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"__version__": "1.0.1",
|
||||||
|
"information": {
|
||||||
|
"customSplash": {
|
||||||
|
"id": "customSplash",
|
||||||
|
"label": "customSplash",
|
||||||
|
"enable": true,
|
||||||
|
"customSplash": {
|
||||||
|
"complete": false,
|
||||||
|
"form": "https://creator-api.cocos.com/api/form/show?sid=fa6ec2019b107316262fad6f726e3d76"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"removeSplash": {
|
||||||
|
"id": "removeSplash",
|
||||||
|
"label": "removeSplash",
|
||||||
|
"enable": true,
|
||||||
|
"removeSplash": {
|
||||||
|
"complete": false,
|
||||||
|
"form": "https://creator-api.cocos.com/api/form/show?sid=fa6ec2019b107316262fad6f726e3d76"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3
settings/v2/packages/program.json
Normal file
3
settings/v2/packages/program.json
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"__version__": "1.0.4"
|
||||||
|
}
|
9
settings/v2/packages/project.json
Normal file
9
settings/v2/packages/project.json
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"__version__": "1.0.6",
|
||||||
|
"general": {
|
||||||
|
"designResolution": {
|
||||||
|
"width": 750,
|
||||||
|
"height": 1334
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
9
tsconfig.json
Normal file
9
tsconfig.json
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
/* Base configuration. Do not edit this field. */
|
||||||
|
"extends": "./temp/tsconfig.cocos.json",
|
||||||
|
|
||||||
|
/* Add your custom configuration here. */
|
||||||
|
"compilerOptions": {
|
||||||
|
"strict": false
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user