mirror of
				https://gitee.com/ruanwujing/green-pack-cocos
				synced 2025-10-30 19:06:24 +00:00 
			
		
		
		
	拼图
This commit is contained in:
		
							
								
								
									
										138
									
								
								assets/resources/effects/puzzle.effect
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								assets/resources/effects/puzzle.effect
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,138 @@ | ||||
| // Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. | ||||
| CCEffect %{ | ||||
|   techniques: | ||||
|   - passes: | ||||
|     - vert: sprite-vs:vert | ||||
|       frag: sprite-fs:frag | ||||
|       depthStencilState: | ||||
|         depthTest: false | ||||
|         depthWrite: false | ||||
|       blendState: | ||||
|         targets: | ||||
|         - blend: true | ||||
|           blendSrc: src_alpha | ||||
|           blendDst: one_minus_src_alpha | ||||
|           blendDstAlpha: one_minus_src_alpha | ||||
|       rasterizerState: | ||||
|         cullMode: none | ||||
|       properties: | ||||
|         rows: {value: 4} | ||||
|         columns: {value: 8} | ||||
|         sizeExpand: {value: 0.6} | ||||
|         radius: {value: 0.15} | ||||
| }% | ||||
|  | ||||
| CCProgram sprite-vs %{ | ||||
|   precision highp float; | ||||
|   #include <builtin/uniforms/cc-global> | ||||
|   #if USE_LOCAL | ||||
|     #include <builtin/uniforms/cc-local> | ||||
|   #endif | ||||
|   #if SAMPLE_FROM_RT | ||||
|     #include <common/common-define> | ||||
|   #endif | ||||
|   in vec3 a_position; | ||||
|   in vec2 a_texCoord; | ||||
|   in vec4 a_color; | ||||
|  | ||||
|   out vec4 color; | ||||
|   out vec2 uv0; | ||||
|  | ||||
|  | ||||
|   vec4 vert () { | ||||
|     vec4 pos = vec4(a_position, 1); | ||||
|  | ||||
|     #if USE_LOCAL | ||||
|       pos = cc_matWorld * pos; | ||||
|     #endif | ||||
|  | ||||
|     #if USE_PIXEL_ALIGNMENT | ||||
|       pos = cc_matView * pos; | ||||
|       pos.xyz = floor(pos.xyz); | ||||
|       pos = cc_matProj * pos; | ||||
|     #else | ||||
|       pos = cc_matViewProj * pos; | ||||
|     #endif | ||||
|  | ||||
|     uv0 = a_texCoord; | ||||
|     #if SAMPLE_FROM_RT | ||||
|       CC_HANDLE_RT_SAMPLE_FLIP(uv0); | ||||
|     #endif | ||||
|     color = a_color; | ||||
|  | ||||
|     return pos; | ||||
|   } | ||||
| }% | ||||
|  | ||||
| CCProgram sprite-fs %{ | ||||
|   precision highp float; | ||||
|   #include <builtin/internal/embedded-alpha> | ||||
|   #include "../chunks/sdf2d" | ||||
|   uniform Const { | ||||
|     float rows; | ||||
|     float columns; | ||||
|     float sizeExpand; | ||||
|     float radius; | ||||
|   }; | ||||
|   in vec4 color; | ||||
|   in vec2 uv0; | ||||
|    | ||||
|   float smin(float a,float b,float k){ | ||||
|       float h = clamp(0.5+0.5*(a-b)/k,0.0,1.0); | ||||
|       return mix(a,b,h)-k*h*(1.0-h); | ||||
|   } | ||||
|   float smax(float a,float b,float k){ | ||||
|       return -smin(-a,-b,k); | ||||
|   } | ||||
|   float isOdd(float x) { | ||||
|     return fract(x/2.0) * 2.0; | ||||
|   } | ||||
|   #pragma builtin(local) | ||||
|   layout(set = 2, binding = 12) uniform sampler2D cc_spriteTexture; | ||||
|  | ||||
|  | ||||
|   vec4 frag () { | ||||
|     vec4 o = vec4(1, 1, 1, 1);       | ||||
|  | ||||
|     vec2 id = floor(uv0 * vec2(columns, rows)); | ||||
|     vec2 uv_center = (id + 0.5) / vec2(columns, rows); | ||||
|  | ||||
|     float exp = sizeExpand + 1.0; | ||||
|     vec2 uv = (uv0 - uv_center) * vec2(columns, rows) * exp; | ||||
|     o *= CCSampleWithAlphaSeparated(cc_spriteTexture, (uv0 - uv_center) * exp + uv_center); | ||||
|     float d = sdBox(uv, vec2(0.5, 0.5)); | ||||
|  | ||||
|     float rad = radius; | ||||
|     float dd = 0.1; | ||||
|     float odd = isOdd(id.x + id.y); | ||||
|     float s = sign(odd - 0.5); | ||||
|  | ||||
|     float dc_top = sdCircle(uv + vec2(0, 0.5 - dd * s), rad); | ||||
|     float dc_bottom = sdCircle(uv + vec2(0, -0.5 + dd * s), rad); | ||||
|     float dc_left = sdCircle(uv + vec2(0.5 + dd * s, 0), rad); | ||||
|     float dc_right = sdCircle(uv + vec2(-0.5 - dd * s, 0), rad); | ||||
|  | ||||
|     float k = 0.02; | ||||
|     float nOdd = 1.0 - odd; | ||||
|  | ||||
|     float dt = smax(d, -dc_top, k) * odd + smin(d, dc_top , k) * nOdd; | ||||
|     float edge = step(id.y, 0.5); | ||||
|     d = dt * (1.0 - edge) + d * edge; | ||||
|  | ||||
|     float db = smax(d, -dc_bottom, k) * odd + smin(d, dc_bottom, k) * nOdd; | ||||
|     edge = step(rows - 1.5, id.y); | ||||
|     d = db * (1.0 - edge) + d * edge; | ||||
|  | ||||
|     float dl = smin(d, dc_left, k) * odd + smax(d, -dc_left, k) * nOdd; | ||||
|     edge = step(id.x, 0.5); | ||||
|     d = dl * (1.0 - edge) + d * edge; | ||||
|  | ||||
|     float dr = smin(d, dc_right, k) * odd + smax(d, -dc_right, k) * nOdd; | ||||
|     edge = step(columns - 1.5, id.x); | ||||
|     d = dr * (1.0 - edge) + d * edge; | ||||
|  | ||||
|     float c = smoothstep(0.01, -0.01, d); | ||||
|     o *= c; | ||||
|     return o; | ||||
|   } | ||||
| }% | ||||
							
								
								
									
										11
									
								
								assets/resources/effects/puzzle.effect.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								assets/resources/effects/puzzle.effect.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| { | ||||
|   "ver": "1.7.1", | ||||
|   "importer": "effect", | ||||
|   "imported": true, | ||||
|   "uuid": "8db6f7be-b91e-44ba-be47-5857f763dcc2", | ||||
|   "files": [ | ||||
|     ".json" | ||||
|   ], | ||||
|   "subMetas": {}, | ||||
|   "userData": {} | ||||
| } | ||||
							
								
								
									
										32
									
								
								assets/resources/materials/puzzle.mtl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								assets/resources/materials/puzzle.mtl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| { | ||||
|   "__type__": "cc.Material", | ||||
|   "_name": "", | ||||
|   "_objFlags": 0, | ||||
|   "__editorExtras__": {}, | ||||
|   "_native": "", | ||||
|   "_effectAsset": { | ||||
|     "__uuid__": "8db6f7be-b91e-44ba-be47-5857f763dcc2", | ||||
|     "__expectedType__": "cc.EffectAsset" | ||||
|   }, | ||||
|   "_techIdx": 0, | ||||
|   "_defines": [ | ||||
|     {} | ||||
|   ], | ||||
|   "_states": [ | ||||
|     { | ||||
|       "rasterizerState": {}, | ||||
|       "depthStencilState": {}, | ||||
|       "blendState": { | ||||
|         "targets": [ | ||||
|           {} | ||||
|         ] | ||||
|       } | ||||
|     } | ||||
|   ], | ||||
|   "_props": [ | ||||
|     { | ||||
|       "rows": 6, | ||||
|       "columns": 10 | ||||
|     } | ||||
|   ] | ||||
| } | ||||
							
								
								
									
										11
									
								
								assets/resources/materials/puzzle.mtl.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								assets/resources/materials/puzzle.mtl.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| { | ||||
|   "ver": "1.0.21", | ||||
|   "importer": "material", | ||||
|   "imported": true, | ||||
|   "uuid": "0080e1e8-609b-41f2-ad39-2a1c3fb9b4dc", | ||||
|   "files": [ | ||||
|     ".json" | ||||
|   ], | ||||
|   "subMetas": {}, | ||||
|   "userData": {} | ||||
| } | ||||
							
								
								
									
										1196
									
								
								assets/resources/scenes/puzzle.scene
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1196
									
								
								assets/resources/scenes/puzzle.scene
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										11
									
								
								assets/resources/scenes/puzzle.scene.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								assets/resources/scenes/puzzle.scene.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| { | ||||
|   "ver": "1.1.50", | ||||
|   "importer": "scene", | ||||
|   "imported": true, | ||||
|   "uuid": "946213b2-dc04-4756-8c82-e9df6ac4d571", | ||||
|   "files": [ | ||||
|     ".json" | ||||
|   ], | ||||
|   "subMetas": {}, | ||||
|   "userData": {} | ||||
| } | ||||
							
								
								
									
										9
									
								
								assets/resources/ui/images.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								assets/resources/ui/images.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "1.2.0", | ||||
|   "importer": "directory", | ||||
|   "imported": true, | ||||
|   "uuid": "7a473951-f04b-4028-8ec6-741d8319818f", | ||||
|   "files": [], | ||||
|   "subMetas": {}, | ||||
|   "userData": {} | ||||
| } | ||||
							
								
								
									
										
											BIN
										
									
								
								assets/resources/ui/images/cyberpunk.jpeg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								assets/resources/ui/images/cyberpunk.jpeg
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 294 KiB | 
							
								
								
									
										134
									
								
								assets/resources/ui/images/cyberpunk.jpeg.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								assets/resources/ui/images/cyberpunk.jpeg.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,134 @@ | ||||
| { | ||||
|   "ver": "1.0.26", | ||||
|   "importer": "image", | ||||
|   "imported": true, | ||||
|   "uuid": "10336bef-42f1-4bfd-a795-1f29554ccdd8", | ||||
|   "files": [ | ||||
|     ".jpeg", | ||||
|     ".json" | ||||
|   ], | ||||
|   "subMetas": { | ||||
|     "6c48a": { | ||||
|       "importer": "texture", | ||||
|       "uuid": "10336bef-42f1-4bfd-a795-1f29554ccdd8@6c48a", | ||||
|       "displayName": "cyberpunk", | ||||
|       "id": "6c48a", | ||||
|       "name": "texture", | ||||
|       "userData": { | ||||
|         "wrapModeS": "clamp-to-edge", | ||||
|         "wrapModeT": "clamp-to-edge", | ||||
|         "minfilter": "linear", | ||||
|         "magfilter": "linear", | ||||
|         "mipfilter": "none", | ||||
|         "anisotropy": 0, | ||||
|         "isUuid": true, | ||||
|         "imageUuidOrDatabaseUri": "10336bef-42f1-4bfd-a795-1f29554ccdd8", | ||||
|         "visible": false | ||||
|       }, | ||||
|       "ver": "1.0.22", | ||||
|       "imported": true, | ||||
|       "files": [ | ||||
|         ".json" | ||||
|       ], | ||||
|       "subMetas": {} | ||||
|     }, | ||||
|     "f9941": { | ||||
|       "importer": "sprite-frame", | ||||
|       "uuid": "10336bef-42f1-4bfd-a795-1f29554ccdd8@f9941", | ||||
|       "displayName": "cyberpunk", | ||||
|       "id": "f9941", | ||||
|       "name": "spriteFrame", | ||||
|       "userData": { | ||||
|         "trimType": "auto", | ||||
|         "trimThreshold": 1, | ||||
|         "rotated": false, | ||||
|         "offsetX": 0, | ||||
|         "offsetY": 0, | ||||
|         "trimX": 0, | ||||
|         "trimY": 0, | ||||
|         "width": 800, | ||||
|         "height": 480, | ||||
|         "rawWidth": 800, | ||||
|         "rawHeight": 480, | ||||
|         "borderTop": 0, | ||||
|         "borderBottom": 0, | ||||
|         "borderLeft": 0, | ||||
|         "borderRight": 0, | ||||
|         "packable": false, | ||||
|         "pixelsToUnit": 100, | ||||
|         "pivotX": 0.5, | ||||
|         "pivotY": 0.5, | ||||
|         "meshType": 0, | ||||
|         "vertices": { | ||||
|           "rawPosition": [ | ||||
|             -400, | ||||
|             -240, | ||||
|             0, | ||||
|             400, | ||||
|             -240, | ||||
|             0, | ||||
|             -400, | ||||
|             240, | ||||
|             0, | ||||
|             400, | ||||
|             240, | ||||
|             0 | ||||
|           ], | ||||
|           "indexes": [ | ||||
|             0, | ||||
|             1, | ||||
|             2, | ||||
|             2, | ||||
|             1, | ||||
|             3 | ||||
|           ], | ||||
|           "uv": [ | ||||
|             0, | ||||
|             480, | ||||
|             800, | ||||
|             480, | ||||
|             0, | ||||
|             0, | ||||
|             800, | ||||
|             0 | ||||
|           ], | ||||
|           "nuv": [ | ||||
|             0, | ||||
|             0, | ||||
|             1, | ||||
|             0, | ||||
|             0, | ||||
|             1, | ||||
|             1, | ||||
|             1 | ||||
|           ], | ||||
|           "minPos": [ | ||||
|             -400, | ||||
|             -240, | ||||
|             0 | ||||
|           ], | ||||
|           "maxPos": [ | ||||
|             400, | ||||
|             240, | ||||
|             0 | ||||
|           ] | ||||
|         }, | ||||
|         "isUuid": true, | ||||
|         "imageUuidOrDatabaseUri": "10336bef-42f1-4bfd-a795-1f29554ccdd8@6c48a", | ||||
|         "atlasUuid": "" | ||||
|       }, | ||||
|       "ver": "1.0.12", | ||||
|       "imported": true, | ||||
|       "files": [ | ||||
|         ".json" | ||||
|       ], | ||||
|       "subMetas": {} | ||||
|     } | ||||
|   }, | ||||
|   "userData": { | ||||
|     "hasAlpha": false, | ||||
|     "type": "sprite-frame", | ||||
|     "fixAlphaTransparencyArtifacts": false, | ||||
|     "redirect": "10336bef-42f1-4bfd-a795-1f29554ccdd8@f9941" | ||||
|   } | ||||
| } | ||||
| @@ -59,11 +59,11 @@ export const ColorSDFAssembler: IAssembler = { | ||||
|  | ||||
|         const renderData = sprite.renderData!; | ||||
|         const chunk = renderData.chunk; | ||||
|         if (sprite["_flagChangedVersion"] !== sprite.node["_flagChangedVersion"] || renderData.vertDirty) { | ||||
|         if (sprite["_flagChangedVersion"] !== sprite.node["flagChangedVersion"] || renderData.vertDirty) { | ||||
|             // const vb = chunk.vertexAccessor.getVertexBuffer(chunk.bufferId); | ||||
|             this.updateWorldVerts(sprite, chunk); | ||||
|             renderData.vertDirty = false; | ||||
|             sprite["_flagChangedVersion"] = sprite.node["_flagChangedVersion"]; | ||||
|             sprite["_flagChangedVersion"] = sprite.node["flagChangedVersion"]; | ||||
|         } | ||||
|  | ||||
|         // quick version | ||||
| @@ -158,6 +158,8 @@ export const ColorSDFAssembler: IAssembler = { | ||||
|     updateColor (sprite: GPSpriteSDF) { | ||||
|         const renderData = sprite.renderData!; | ||||
|         const vData = renderData.chunk.vb; | ||||
|         if (!sprite.spriteFrame) | ||||
|             return | ||||
|         const uv = sprite.spriteFrame.uv; | ||||
|  | ||||
|         let colorOffset = 5; | ||||
|   | ||||
| @@ -107,6 +107,13 @@ export const GPRoundBoxAssembler: IAssembler = { | ||||
|             this.updateWorldVerts(sprite, chunk); | ||||
|             renderData.vertDirty = false; | ||||
|         } | ||||
|         if (sprite["_flagChangedVersion"] !== sprite.node["flagChangedVersion"] || renderData.vertDirty) { | ||||
|             // const vb = chunk.vertexAccessor.getVertexBuffer(chunk.bufferId); | ||||
|             this.updateWorldVerts(sprite, chunk); | ||||
|             renderData.vertDirty = false; | ||||
|             sprite["_flagChangedVersion"] = sprite.node["flagChangedVersion"]; | ||||
|         } | ||||
|  | ||||
|  | ||||
|         // quick version | ||||
|         const bid = chunk.bufferId; | ||||
|   | ||||
							
								
								
									
										174
									
								
								assets/scripts/puzzle/PuzzleAssembler.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										174
									
								
								assets/scripts/puzzle/PuzzleAssembler.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,174 @@ | ||||
| import { Color, IAssembler, IRenderData, RenderData, dynamicAtlasManager } from "cc"; | ||||
| import { PuzzleSprite } from "./PuzzleSprite"; | ||||
| const QUAD_INDICES = Uint16Array.from([0, 1, 2, 1, 3, 2]); | ||||
|  | ||||
| export const PuzzleAssembler: IAssembler = { | ||||
|     createData (sprite: PuzzleSprite) { | ||||
|         const renderData = sprite.requestRenderData(); | ||||
|         renderData.dataLength = 4; | ||||
|         renderData.resize(4, 6); | ||||
|         renderData.chunk.setIndexBuffer(QUAD_INDICES); | ||||
|         return renderData; | ||||
|     }, | ||||
|  | ||||
|     updateRenderData (sprite: PuzzleSprite) { | ||||
|         const frame = sprite.spriteFrame; | ||||
|  | ||||
|         dynamicAtlasManager.packToDynamicAtlas(sprite, frame); | ||||
|         this.updateUVs(sprite);// dirty need | ||||
|         //this.updateColor(sprite);// dirty need | ||||
|  | ||||
|         const renderData = sprite.renderData; | ||||
|         if (renderData && frame) { | ||||
|             if (renderData.vertDirty) { | ||||
|                 this.updateVertexData(sprite); | ||||
|             } | ||||
|             renderData.updateRenderData(sprite, frame); | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     updateWorldVerts (sprite: PuzzleSprite, chunk: { vb: any; }) { | ||||
|         const renderData = sprite.renderData!; | ||||
|         const vData = chunk.vb; | ||||
|  | ||||
|         const dataList: IRenderData[] = renderData.data; | ||||
|         const node = sprite.node; | ||||
|         const m = node.worldMatrix; | ||||
|  | ||||
|         const stride = renderData.floatStride; | ||||
|         let offset = 0; | ||||
|         const length = dataList.length; | ||||
|         for (let i = 0; i < length; i++) { | ||||
|             const curData = dataList[i]; | ||||
|             const x = curData.x; | ||||
|             const y = curData.y; | ||||
|             let rhw = m.m03 * x + m.m07 * y + m.m15; | ||||
|             rhw = rhw ? 1 / rhw : 1; | ||||
|  | ||||
|             offset = i * stride; | ||||
|             vData[offset + 0] = (m.m00 * x + m.m04 * y + m.m12) * rhw; | ||||
|             vData[offset + 1] = (m.m01 * x + m.m05 * y + m.m13) * rhw; | ||||
|             vData[offset + 2] = (m.m02 * x + m.m06 * y + m.m14) * rhw; | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     fillBuffers (sprite: PuzzleSprite) { | ||||
|         if (sprite === null) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         const renderData = sprite.renderData!; | ||||
|         const chunk = renderData.chunk; | ||||
|  | ||||
|         if (sprite["_flagChangedVersion"] !== sprite.node["flagChangedVersion"] || renderData.vertDirty) { | ||||
|             // const vb = chunk.vertexAccessor.getVertexBuffer(chunk.bufferId); | ||||
|             this.updateWorldVerts(sprite, chunk); | ||||
|             renderData.vertDirty = false; | ||||
|             sprite["_flagChangedVersion"] = sprite.node["flagChangedVersion"]; | ||||
|         } | ||||
|  | ||||
|         // quick version | ||||
|         const vidOrigin = chunk.vertexOffset; | ||||
|         const meshBuffer = chunk.meshBuffer; | ||||
|         const ib = chunk.meshBuffer.iData; | ||||
|         let indexOffset = meshBuffer.indexOffset; | ||||
|  | ||||
|         const vid = vidOrigin; | ||||
|  | ||||
|         // left bottom | ||||
|         ib[indexOffset++] = vid; | ||||
|         // right bottom | ||||
|         ib[indexOffset++] = vid + 1; | ||||
|         // left top | ||||
|         ib[indexOffset++] = vid + 2; | ||||
|  | ||||
|         // right bottom | ||||
|         ib[indexOffset++] = vid + 1; | ||||
|         // right top | ||||
|         ib[indexOffset++] = vid + 3; | ||||
|         // left top | ||||
|         ib[indexOffset++] = vid + 2; | ||||
|  | ||||
|         // IndexOffset should add 6 when vertices of a rect are visited. | ||||
|         meshBuffer.indexOffset += 6; | ||||
|         // slow version | ||||
|         // renderer.switchBufferAccessor().appendIndices(chunk); | ||||
|     }, | ||||
|  | ||||
|     updateVertexData (sprite: PuzzleSprite) { | ||||
|         const renderData: RenderData | null = sprite.renderData; | ||||
|         if (!renderData) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         const uiTrans = sprite.node._uiProps.uiTransformComp!; | ||||
|         const dataList: IRenderData[] = renderData.data; | ||||
|         const cw = uiTrans.width; | ||||
|         const ch = uiTrans.height; | ||||
|         const appX = uiTrans.anchorX * cw; | ||||
|         const appY = uiTrans.anchorY * ch; | ||||
|         let l = 0; | ||||
|         let b = 0; | ||||
|         let r = 0; | ||||
|         let t = 0; | ||||
|  | ||||
|         const frame = sprite.spriteFrame!; | ||||
|         const originSize = frame.originalSize; | ||||
|         const ow = originSize.width; | ||||
|         const oh = originSize.height; | ||||
|         const scaleX = cw / ow; | ||||
|         const scaleY = ch / oh; | ||||
|         const trimmedBorder = frame.trimmedBorder; | ||||
|         l = trimmedBorder.x * scaleX - appX; | ||||
|         b = trimmedBorder.z * scaleY - appY; | ||||
|         r = cw + trimmedBorder.y * scaleX - appX; | ||||
|         t = ch + trimmedBorder.w * scaleY - appY; | ||||
|  | ||||
|  | ||||
|         dataList[0].x = l; | ||||
|         dataList[0].y = b; | ||||
|  | ||||
|         dataList[1].x = r; | ||||
|         dataList[1].y = b; | ||||
|  | ||||
|         dataList[2].x = l; | ||||
|         dataList[2].y = t; | ||||
|  | ||||
|         dataList[3].x = r; | ||||
|         dataList[3].y = t; | ||||
|  | ||||
|         renderData.vertDirty = true; | ||||
|     }, | ||||
|  | ||||
|     updateUVs (sprite: PuzzleSprite) { | ||||
|         const renderData = sprite.renderData!; | ||||
|         const vData = renderData.chunk.vb; | ||||
|         const uv = sprite.uv; | ||||
|         // 01 11 00 10 | ||||
|         vData[3] = uv[0]; | ||||
|         vData[4] = uv[1]; | ||||
|         vData[12] = uv[2]; | ||||
|         vData[13] = uv[3]; | ||||
|         vData[21] = uv[4]; | ||||
|         vData[22] = uv[5]; | ||||
|         vData[30] = uv[6]; | ||||
|         vData[31] = uv[7]; | ||||
|     }, | ||||
|  | ||||
|     updateColor (sprite: PuzzleSprite) { | ||||
|         const renderData = sprite.renderData!; | ||||
|         const vData = renderData.chunk.vb; | ||||
|         let colorOffset = 5; | ||||
|         const color = sprite.color; | ||||
|         const colorR = color.r / 255; | ||||
|         const colorG = color.g / 255; | ||||
|         const colorB = color.b / 255; | ||||
|         const colorA = color.a / 255; | ||||
|         for (let i = 0; i < renderData.dataLength; i++, colorOffset += renderData.floatStride) { | ||||
|             vData[colorOffset] = colorR; | ||||
|             vData[colorOffset + 1] = colorG; | ||||
|             vData[colorOffset + 2] = colorB; | ||||
|             vData[colorOffset + 3] = colorA; | ||||
|         } | ||||
|     }, | ||||
| }; | ||||
							
								
								
									
										9
									
								
								assets/scripts/puzzle/PuzzleAssembler.ts.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								assets/scripts/puzzle/PuzzleAssembler.ts.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "4.0.23", | ||||
|   "importer": "typescript", | ||||
|   "imported": true, | ||||
|   "uuid": "a02a1645-241e-4702-988b-34876ae0ae10", | ||||
|   "files": [], | ||||
|   "subMetas": {}, | ||||
|   "userData": {} | ||||
| } | ||||
							
								
								
									
										310
									
								
								assets/scripts/puzzle/PuzzleSprite.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										310
									
								
								assets/scripts/puzzle/PuzzleSprite.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,310 @@ | ||||
| import { _decorator, CCInteger, cclegacy, Color, Component, InstanceMaterialType, Material, Node, NodeEventType, RenderTexture, Sprite, SpriteAtlas, SpriteFrame, UIRenderer } from 'cc'; | ||||
| import { BUILD, EDITOR } from 'cc/env'; | ||||
| import { PuzzleAssembler } from './PuzzleAssembler'; | ||||
| const { ccclass, property ,type, executionOrder} = _decorator; | ||||
| enum EventType { | ||||
|     SPRITE_FRAME_CHANGED = 'spriteframe-changed', | ||||
| } | ||||
| @ccclass('PuzzleSprite') | ||||
| export class PuzzleSprite extends UIRenderer { | ||||
|     // 尺寸模式,可以看枚举原本定义的地方有注释说明 | ||||
|     @property({serializable:true}) | ||||
|     protected _sizeMode = Sprite.SizeMode.TRIMMED; | ||||
|     @type(Sprite.SizeMode) | ||||
|     get sizeMode () { | ||||
|         return this._sizeMode; | ||||
|     } | ||||
|     set sizeMode (value) { | ||||
|         if (this._sizeMode === value) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         this._sizeMode = value; | ||||
|         if (value !== Sprite.SizeMode.CUSTOM) { | ||||
|             this._applySpriteSize(); | ||||
|         } | ||||
|     } | ||||
|     // 图集 | ||||
|     @property({serializable:true}) | ||||
|     protected _atlas: SpriteAtlas | null = null; | ||||
|     @type(SpriteAtlas) | ||||
|     get spriteAtlas () { | ||||
|         return this._atlas; | ||||
|     } | ||||
|     set spriteAtlas (value) { | ||||
|         if (this._atlas === value) { | ||||
|             return; | ||||
|         } | ||||
|         this._atlas = value; | ||||
|     } | ||||
|  | ||||
|     @property({serializable:true}) | ||||
|     protected _spriteFrame: SpriteFrame | null = null; | ||||
|     @type(SpriteFrame) | ||||
|     get spriteFrame () { | ||||
|         return this._spriteFrame; | ||||
|     } | ||||
|     set spriteFrame (value) { | ||||
|         if (this._spriteFrame === value) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         const lastSprite = this._spriteFrame; | ||||
|         this._spriteFrame = value; | ||||
|         this.markForUpdateRenderData(); | ||||
|         this._applySpriteFrame(lastSprite); | ||||
|         if (EDITOR) { | ||||
|             this.node.emit(EventType.SPRITE_FRAME_CHANGED, this); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private _row =1 | ||||
|     @property({type:CCInteger, step:1, min:1}) | ||||
|     public get row(){return this._row} | ||||
|     public set row(v){this._row = v;  | ||||
|         this._updateUVs() | ||||
|     } | ||||
|  | ||||
|     private _column = 1 | ||||
|     @property({type:CCInteger, step:1, min:1}) | ||||
|     public get column(){return this._column} | ||||
|     public set column(v){this._column = v;  | ||||
|         this._updateUVs() | ||||
|     } | ||||
|  | ||||
|     private _rowMax = 4 | ||||
|     @property({type:CCInteger, step:1, min:1}) | ||||
|     public get rowMax(){return this._rowMax} | ||||
|     public set rowMax(v){this._rowMax = v;  | ||||
|         this._updateUVs() | ||||
|     } | ||||
|  | ||||
|     private _columnMax = 4 | ||||
|     @property({type:CCInteger, step:1, min:1}) | ||||
|     public get columnMax(){return this._columnMax} | ||||
|     public set columnMax(v){this._columnMax = v;  | ||||
|         this._updateUVs() | ||||
|     } | ||||
|  | ||||
|     public uv= [0,1, 1,1, 0,0, 1,0] | ||||
|  | ||||
|     onLoad(): void { | ||||
|         this._flushAssembler(); | ||||
|     } | ||||
|  | ||||
|     public __preload () { | ||||
|         this.changeMaterialForDefine(); | ||||
|         super.__preload(); | ||||
|  | ||||
|         if (EDITOR) { | ||||
|             this._resized(); | ||||
|             this.node.on(NodeEventType.SIZE_CHANGED, this._resized, this); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public onEnable () { | ||||
|         console.log("onEnable") | ||||
|         super.onEnable(); | ||||
|  | ||||
|         // Force update uv, material define, active material, etc | ||||
|         this._activateMaterial(); | ||||
|         const spriteFrame = this._spriteFrame; | ||||
|         if (this.spriteFrame) | ||||
|             this._updateUVs(); | ||||
|     } | ||||
|  | ||||
|     public onDestroy () { | ||||
|         if (EDITOR) { | ||||
|             this.node.off(NodeEventType.SIZE_CHANGED, this._resized, this); | ||||
|         } | ||||
|         super.onDestroy(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @en | ||||
|      * Quickly switch to other sprite frame in the sprite atlas. | ||||
|      * If there is no atlas, the switch fails. | ||||
|      * | ||||
|      * @zh | ||||
|      * 选取使用精灵图集中的其他精灵。 | ||||
|      * @param name @en Name of the spriteFrame to switch. @zh 要切换的 spriteFrame 名字。 | ||||
|      */ | ||||
|     public changeSpriteFrameFromAtlas (name: string) { | ||||
|         if (!this._atlas) { | ||||
|             console.warn('SpriteAtlas is null.'); | ||||
|             return; | ||||
|         } | ||||
|         const sprite = this._atlas.getSpriteFrame(name); | ||||
|         this.spriteFrame = sprite; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @deprecated Since v3.7.0, this is an engine private interface that will be removed in the future. | ||||
|      */ | ||||
|     public changeMaterialForDefine () { | ||||
|         let texture; | ||||
|         const lastInstanceMaterialType = this._instanceMaterialType; | ||||
|         if (this._spriteFrame) { | ||||
|             texture = this._spriteFrame.texture; | ||||
|         } | ||||
|         let value = false; | ||||
|         if (texture instanceof cclegacy.TextureBase) { | ||||
|             const format = texture.getPixelFormat(); | ||||
|             value = (format === cclegacy.TextureBase.PixelFormat.RGBA_ETC1 || format === cclegacy.TextureBase.PixelFormat.RGB_A_PVRTC_4BPPV1 || format === cclegacy.TextureBase.PixelFormat.RGB_A_PVRTC_2BPPV1); | ||||
|         } | ||||
|  | ||||
|         if (value) { | ||||
|             this._instanceMaterialType = InstanceMaterialType.USE_ALPHA_SEPARATED; | ||||
|         } else { | ||||
|             this._instanceMaterialType = InstanceMaterialType.ADD_COLOR_AND_TEXTURE; | ||||
|         } | ||||
|         if (lastInstanceMaterialType !== this._instanceMaterialType) { | ||||
|             // this.updateMaterial(); | ||||
|             // d.ts里没有注上这个函数,直接调用会表红。 | ||||
|             this["updateMaterial"](); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     protected _updateBuiltinMaterial () { | ||||
|         let mat = super._updateBuiltinMaterial(); | ||||
|         if (this.spriteFrame && this.spriteFrame.texture instanceof RenderTexture) { | ||||
|             const defines = { SAMPLE_FROM_RT: true, ...mat.passes[0].defines }; | ||||
|             const renderMat = new Material(); | ||||
|             renderMat.initialize({ | ||||
|                 effectAsset: mat.effectAsset, | ||||
|                 defines, | ||||
|             }); | ||||
|             mat = renderMat; | ||||
|         } | ||||
|         return mat; | ||||
|     } | ||||
|  | ||||
|     protected _render (render) { | ||||
|         render.commitComp(this, this.renderData, this._spriteFrame, this._assembler, null); | ||||
|     } | ||||
|  | ||||
|     protected _canRender () { | ||||
|         if (!super._canRender()) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         const spriteFrame = this._spriteFrame; | ||||
|         if (!spriteFrame || !spriteFrame.texture) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     protected resetAssembler() { | ||||
|         this._assembler = null; | ||||
|         this._flushAssembler(); | ||||
|     } | ||||
|     protected _flushAssembler () { | ||||
|         const assembler = PuzzleAssembler; | ||||
|  | ||||
|         if (this._assembler !== assembler) { | ||||
|             this.destroyRenderData(); | ||||
|             this._assembler = assembler; | ||||
|         } | ||||
|  | ||||
|  | ||||
|         if (!this._renderData) { | ||||
|             if (this._assembler && this._assembler.createData) { | ||||
|                 this._renderData = this._assembler.createData(this); | ||||
|                 this._renderData!.material = this.getRenderMaterial(0); | ||||
|                 this.markForUpdateRenderData(); | ||||
|                 if (this.spriteFrame) { | ||||
|                     this._assembler.updateRenderData(this); | ||||
|                 } | ||||
|                 this._updateColor(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private _applySpriteSize () { | ||||
|         if (this._spriteFrame) { | ||||
|             if (BUILD || !this._spriteFrame.isDefault) { | ||||
|                 if (Sprite.SizeMode.RAW === this._sizeMode) { | ||||
|                     const size = this._spriteFrame.originalSize; | ||||
|                     this.node._uiProps.uiTransformComp!.setContentSize(size); | ||||
|                 } else if (Sprite.SizeMode.TRIMMED === this._sizeMode) { | ||||
|                     const rect = this._spriteFrame.rect; | ||||
|                     this.node._uiProps.uiTransformComp!.setContentSize(rect.width, rect.height); | ||||
|                 } | ||||
|             } | ||||
|             this.markForUpdateRenderData(true) | ||||
|             this._assembler.updateRenderData(this); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private _resized () { | ||||
|         if (!EDITOR) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (this._spriteFrame) { | ||||
|             const actualSize = this.node._uiProps.uiTransformComp!.contentSize; | ||||
|             let expectedW = actualSize.width; | ||||
|             let expectedH = actualSize.height; | ||||
|             if (this._sizeMode === Sprite.SizeMode.RAW) { | ||||
|                 const size = this._spriteFrame.originalSize; | ||||
|                 expectedW = size.width; | ||||
|                 expectedH = size.height; | ||||
|             } else if (this._sizeMode === Sprite.SizeMode.TRIMMED) { | ||||
|                 const rect = this._spriteFrame.rect; | ||||
|                 expectedW = rect.width; | ||||
|                 expectedH = rect.height; | ||||
|             } | ||||
|  | ||||
|             if (expectedW !== actualSize.width || expectedH !== actualSize.height) { | ||||
|                 this._sizeMode = Sprite.SizeMode.CUSTOM; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private _activateMaterial () { | ||||
|         const spriteFrame = this._spriteFrame; | ||||
|         const material = this.getRenderMaterial(0); | ||||
|         if (spriteFrame) { | ||||
|             if (material) { | ||||
|                 this.markForUpdateRenderData(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (this.renderData) { | ||||
|             this.renderData.material = material; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private _updateUVs () { | ||||
|         const _uv= [0,1, 1,1, 0,0, 1,0] | ||||
|         const blockWidth = 1 / this.columnMax | ||||
|         const blockHeight = 1 / this.rowMax | ||||
|         for (let i = 0; i < 4; i++) { | ||||
|             this.uv[i * 2] = (this.column - 1) * blockWidth + _uv[i * 2] * blockWidth; | ||||
|             this.uv[i * 2 + 1] = (this.row - 1) * blockHeight + _uv[i * 2 + 1] * blockHeight; | ||||
|         } | ||||
|         if (this._assembler) { | ||||
|             this._assembler.updateUVs(this); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private _applySpriteFrame (oldFrame: SpriteFrame | null) { | ||||
|         const spriteFrame = this._spriteFrame; | ||||
|  | ||||
|         let textureChanged = false; | ||||
|         if (spriteFrame) { | ||||
|             if (!oldFrame || oldFrame.texture !== spriteFrame.texture) { | ||||
|                 textureChanged = true; | ||||
|             } | ||||
|             if (textureChanged) { | ||||
|                 if (this.renderData) this.renderData.textureDirty = true; | ||||
|                 this.changeMaterialForDefine(); | ||||
|             } | ||||
|             this._applySpriteSize(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
							
								
								
									
										9
									
								
								assets/scripts/puzzle/PuzzleSprite.ts.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								assets/scripts/puzzle/PuzzleSprite.ts.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "4.0.23", | ||||
|   "importer": "typescript", | ||||
|   "imported": true, | ||||
|   "uuid": "f238c61b-614b-4131-9d46-b431ae863374", | ||||
|   "files": [], | ||||
|   "subMetas": {}, | ||||
|   "userData": {} | ||||
| } | ||||
							
								
								
									
										274
									
								
								assets/scripts/puzzle/PuzzleSpriteTest.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										274
									
								
								assets/scripts/puzzle/PuzzleSpriteTest.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,274 @@ | ||||
| import { _decorator, cclegacy, Component, InstanceMaterialType, Material, Node, NodeEventType, RenderTexture, Sprite, SpriteAtlas, SpriteFrame, UIRenderer } from 'cc'; | ||||
| import { BUILD, EDITOR } from 'cc/env'; | ||||
| import { PuzzleAssembler } from './PuzzleAssembler'; | ||||
| import { ColorSDFAssembler } from '../components/ColorSDFAssembler'; | ||||
| const { ccclass, property ,type} = _decorator; | ||||
| enum EventType { | ||||
|     SPRITE_FRAME_CHANGED = 'spriteframe-changed', | ||||
| } | ||||
| @ccclass('PuzzleSpriteTest') | ||||
| export class PuzzleSpriteTest extends UIRenderer { | ||||
|     // 尺寸模式,可以看枚举原本定义的地方有注释说明 | ||||
|     @property({serializable:true}) | ||||
|     protected _sizeMode = Sprite.SizeMode.TRIMMED; | ||||
|     @type(Sprite.SizeMode) | ||||
|     get sizeMode () { | ||||
|         return this._sizeMode; | ||||
|     } | ||||
|     set sizeMode (value) { | ||||
|         if (this._sizeMode === value) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         this._sizeMode = value; | ||||
|         if (value !== Sprite.SizeMode.CUSTOM) { | ||||
|             this._applySpriteSize(); | ||||
|         } | ||||
|     } | ||||
|     // 图集 | ||||
|     @property({serializable:true}) | ||||
|     protected _atlas: SpriteAtlas | null = null; | ||||
|     @type(SpriteAtlas) | ||||
|     get spriteAtlas () { | ||||
|         return this._atlas; | ||||
|     } | ||||
|     set spriteAtlas (value) { | ||||
|         if (this._atlas === value) { | ||||
|             return; | ||||
|         } | ||||
|         this._atlas = value; | ||||
|     } | ||||
|  | ||||
|     @property({serializable:true}) | ||||
|     protected _spriteFrame: SpriteFrame | null = null; | ||||
|     @type(SpriteFrame) | ||||
|     get spriteFrame () { | ||||
|         return this._spriteFrame; | ||||
|     } | ||||
|     set spriteFrame (value) { | ||||
|         if (this._spriteFrame === value) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         const lastSprite = this._spriteFrame; | ||||
|         this._spriteFrame = value; | ||||
|         this.markForUpdateRenderData(); | ||||
|         this._applySpriteFrame(lastSprite); | ||||
|         if (EDITOR) { | ||||
|             this.node.emit(EventType.SPRITE_FRAME_CHANGED, this); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     onLoad(): void { | ||||
|         this._flushAssembler(); | ||||
|     } | ||||
|  | ||||
|     public __preload () { | ||||
|         this.changeMaterialForDefine(); | ||||
|         super.__preload(); | ||||
|  | ||||
|         if (EDITOR) { | ||||
|             this._resized(); | ||||
|             this.node.on(NodeEventType.SIZE_CHANGED, this._resized, this); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public onEnable () { | ||||
|         super.onEnable(); | ||||
|  | ||||
|         // Force update uv, material define, active material, etc | ||||
|         this._activateMaterial(); | ||||
|         const spriteFrame = this._spriteFrame; | ||||
|         if (spriteFrame) { | ||||
|             this._updateUVs(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public onDestroy () { | ||||
|         if (EDITOR) { | ||||
|             this.node.off(NodeEventType.SIZE_CHANGED, this._resized, this); | ||||
|         } | ||||
|         super.onDestroy(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @en | ||||
|      * Quickly switch to other sprite frame in the sprite atlas. | ||||
|      * If there is no atlas, the switch fails. | ||||
|      * | ||||
|      * @zh | ||||
|      * 选取使用精灵图集中的其他精灵。 | ||||
|      * @param name @en Name of the spriteFrame to switch. @zh 要切换的 spriteFrame 名字。 | ||||
|      */ | ||||
|     public changeSpriteFrameFromAtlas (name: string) { | ||||
|         if (!this._atlas) { | ||||
|             console.warn('SpriteAtlas is null.'); | ||||
|             return; | ||||
|         } | ||||
|         const sprite = this._atlas.getSpriteFrame(name); | ||||
|         this.spriteFrame = sprite; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @deprecated Since v3.7.0, this is an engine private interface that will be removed in the future. | ||||
|      */ | ||||
|     public changeMaterialForDefine () { | ||||
|         let texture; | ||||
|         const lastInstanceMaterialType = this._instanceMaterialType; | ||||
|         if (this._spriteFrame) { | ||||
|             texture = this._spriteFrame.texture; | ||||
|         } | ||||
|         let value = false; | ||||
|         if (texture instanceof cclegacy.TextureBase) { | ||||
|             const format = texture.getPixelFormat(); | ||||
|             value = (format === cclegacy.TextureBase.PixelFormat.RGBA_ETC1 || format === cclegacy.TextureBase.PixelFormat.RGB_A_PVRTC_4BPPV1 || format === cclegacy.TextureBase.PixelFormat.RGB_A_PVRTC_2BPPV1); | ||||
|         } | ||||
|  | ||||
|         if (value) { | ||||
|             this._instanceMaterialType = InstanceMaterialType.USE_ALPHA_SEPARATED; | ||||
|         } else { | ||||
|             this._instanceMaterialType = InstanceMaterialType.ADD_COLOR_AND_TEXTURE; | ||||
|         } | ||||
|         if (lastInstanceMaterialType !== this._instanceMaterialType) { | ||||
|             // this.updateMaterial(); | ||||
|             // d.ts里没有注上这个函数,直接调用会表红。 | ||||
|             this["updateMaterial"](); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     protected _updateBuiltinMaterial () { | ||||
|         let mat = super._updateBuiltinMaterial(); | ||||
|         if (this.spriteFrame && this.spriteFrame.texture instanceof RenderTexture) { | ||||
|             const defines = { SAMPLE_FROM_RT: true, ...mat.passes[0].defines }; | ||||
|             const renderMat = new Material(); | ||||
|             renderMat.initialize({ | ||||
|                 effectAsset: mat.effectAsset, | ||||
|                 defines, | ||||
|             }); | ||||
|             mat = renderMat; | ||||
|         } | ||||
|         return mat; | ||||
|     } | ||||
|  | ||||
|     protected _render (render) { | ||||
|         render.commitComp(this, this.renderData, this._spriteFrame, this._assembler, null); | ||||
|     } | ||||
|  | ||||
|     protected _canRender () { | ||||
|         if (!super._canRender()) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         const spriteFrame = this._spriteFrame; | ||||
|         if (!spriteFrame || !spriteFrame.texture) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     protected resetAssembler() { | ||||
|         this._assembler = null; | ||||
|         this._flushAssembler(); | ||||
|     } | ||||
|     protected _flushAssembler () { | ||||
|         const assembler = ColorSDFAssembler; | ||||
|  | ||||
|         if (this._assembler !== assembler) { | ||||
|             this.destroyRenderData(); | ||||
|             this._assembler = assembler; | ||||
|         } | ||||
|  | ||||
|  | ||||
|         if (!this._renderData) { | ||||
|             if (this._assembler && this._assembler.createData) { | ||||
|                 this._renderData = this._assembler.createData(this); | ||||
|                 this._renderData!.material = this.getRenderMaterial(0); | ||||
|                 this.markForUpdateRenderData(); | ||||
|                 if (this.spriteFrame) { | ||||
|                     this._assembler.updateRenderData(this); | ||||
|                 } | ||||
|                 this._updateColor(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private _applySpriteSize () { | ||||
|         if (this._spriteFrame) { | ||||
|             if (BUILD || !this._spriteFrame.isDefault) { | ||||
|                 if (Sprite.SizeMode.RAW === this._sizeMode) { | ||||
|                     const size = this._spriteFrame.originalSize; | ||||
|                     this.node._uiProps.uiTransformComp!.setContentSize(size); | ||||
|                 } else if (Sprite.SizeMode.TRIMMED === this._sizeMode) { | ||||
|                     const rect = this._spriteFrame.rect; | ||||
|                     this.node._uiProps.uiTransformComp!.setContentSize(rect.width, rect.height); | ||||
|                 } | ||||
|             } | ||||
|             this.markForUpdateRenderData(true) | ||||
|             this._assembler.updateRenderData(this); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private _resized () { | ||||
|         if (!EDITOR) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (this._spriteFrame) { | ||||
|             const actualSize = this.node._uiProps.uiTransformComp!.contentSize; | ||||
|             let expectedW = actualSize.width; | ||||
|             let expectedH = actualSize.height; | ||||
|             if (this._sizeMode === Sprite.SizeMode.RAW) { | ||||
|                 const size = this._spriteFrame.originalSize; | ||||
|                 expectedW = size.width; | ||||
|                 expectedH = size.height; | ||||
|             } else if (this._sizeMode === Sprite.SizeMode.TRIMMED) { | ||||
|                 const rect = this._spriteFrame.rect; | ||||
|                 expectedW = rect.width; | ||||
|                 expectedH = rect.height; | ||||
|             } | ||||
|  | ||||
|             if (expectedW !== actualSize.width || expectedH !== actualSize.height) { | ||||
|                 this._sizeMode = Sprite.SizeMode.CUSTOM; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private _activateMaterial () { | ||||
|         const spriteFrame = this._spriteFrame; | ||||
|         const material = this.getRenderMaterial(0); | ||||
|         if (spriteFrame) { | ||||
|             if (material) { | ||||
|                 this.markForUpdateRenderData(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (this.renderData) { | ||||
|             this.renderData.material = material; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private _updateUVs () { | ||||
|         if (this._assembler) { | ||||
|             this._assembler.updateUVs(this); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private _applySpriteFrame (oldFrame: SpriteFrame | null) { | ||||
|         const spriteFrame = this._spriteFrame; | ||||
|  | ||||
|         let textureChanged = false; | ||||
|         if (spriteFrame) { | ||||
|             if (!oldFrame || oldFrame.texture !== spriteFrame.texture) { | ||||
|                 textureChanged = true; | ||||
|             } | ||||
|             if (textureChanged) { | ||||
|                 if (this.renderData) this.renderData.textureDirty = true; | ||||
|                 this.changeMaterialForDefine(); | ||||
|             } | ||||
|             this._applySpriteSize(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
							
								
								
									
										9
									
								
								assets/scripts/puzzle/PuzzleSpriteTest.ts.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								assets/scripts/puzzle/PuzzleSpriteTest.ts.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "4.0.23", | ||||
|   "importer": "typescript", | ||||
|   "imported": true, | ||||
|   "uuid": "bff05d5e-35b8-40ca-8ceb-939a046440e8", | ||||
|   "files": [], | ||||
|   "subMetas": {}, | ||||
|   "userData": {} | ||||
| } | ||||
		Reference in New Issue
	
	Block a user