更新小手,更新难度出现机制

This commit is contained in:
COMPUTER\EDY 2026-09-16 18:13:28 +08:00
parent c2f51a01ee
commit 60e58dfc46
23 changed files with 1491 additions and 1179 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,85 @@
const { ccclass, property } = cc._decorator;
@ccclass
export default class GuideHand extends cc.Component {
@property(cc.Material)
rippleMaterial: cc.Material = null;
@property
swingAngle: number = 8;
@property
ringWidth: number = 0.1;
@property(cc.Vec2)
tipPosition: cc.Vec2 = cc.v2(-58, 148);
private baseAngle: number = 0;
private elapsed: number = 0;
private rippleDuration: number = 0;
private ripple: cc.Node = null;
private material: cc.Material = null;
onLoad() {
this.baseAngle = this.node.angle;
const ripple = this.ripple = new cc.Node("handRipple");
ripple.active = false;
ripple.parent = this.node.parent;
// 光圈放在手的后面,独立于手旋转,点击位置保持不动。
ripple.setSiblingIndex(this.node.getSiblingIndex());
const sprite = ripple.addComponent(cc.Sprite);
sprite.spriteFrame = this.node.getComponent(cc.Sprite).spriteFrame;
sprite.sizeMode = cc.Sprite.SizeMode.CUSTOM;
ripple.setContentSize(220, 220);
sprite.setMaterial(0, this.rippleMaterial);
this.material = sprite.getMaterial(0);
this.material.setProperty("ringWidth", this.ringWidth);
this.material.setProperty("center", [0.5, 0.5]);
// 对齐 ripple_shrink:第三圈延后 0.6 秒,扩散到半径 0.475 时完全淡出。
this.rippleDuration = 0.6 + 0.475 / Number(this.material.getProperty("waveSpeed", 0));
}
onEnable() {
this.elapsed = 0;
this.node.angle = this.baseAngle;
this.ripple.active = false;
this.material.setProperty("time", 0);
}
update(dt: number) {
const pressDuration = 0.24;
const releaseDuration = 0.32;
const cycleDuration = pressDuration + this.rippleDuration;
const previousTime = this.elapsed;
this.elapsed = (this.elapsed + dt) % cycleDuration;
if (this.elapsed < previousTime) this.ripple.active = false;
const progress = this.elapsed < pressDuration
? this.elapsed / pressDuration
: Math.max(0, 1 - (this.elapsed - pressDuration) / releaseDuration);
this.node.angle = this.baseAngle + this.swingAngle * (1 - Math.cos(progress * Math.PI)) / 2;
if (this.elapsed < pressDuration) {
this.ripple.active = false;
return;
}
if (!this.ripple.active) {
// 按下瞬间的指尖坐标;松手时光圈不跟着移动。
const angle = this.node.angle;
this.node.angle = this.baseAngle + this.swingAngle;
const tip = this.node.convertToWorldSpaceAR(this.tipPosition);
this.ripple.setPosition(this.node.parent.convertToNodeSpaceAR(tip));
this.node.angle = angle;
this.ripple.active = true;
}
this.material.setProperty("time", this.elapsed - pressDuration);
}
onDisable() {
this.node.angle = this.baseAngle;
if (cc.isValid(this.ripple)) this.ripple.active = false;
}
onDestroy() {
if (cc.isValid(this.ripple)) this.ripple.destroy();
}
}

View File

@ -0,0 +1,10 @@
{
"ver": "1.1.0",
"uuid": "6ea48c03-1eaa-4ac5-9ac4-740b837f9201",
"importer": "typescript",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}

View File

@ -17,6 +17,7 @@ import Utils from "./module/Pay/Utils";
import { getReviveCoinCost, MAX_REVIVE_COST_STEP } from "./module/Config/ReviveCostConfig";
import Vine from "./prop/vine";
import BlockAssetManager from "./module/Tool/BlockAssetManager";
import GuideHand from "./GuideHand";
import SpawnGate, { SpawnGateBatchResult, SpawnGateConfig } from "./SpawnGate";
const { ccclass, property } = cc._decorator;
@ -913,6 +914,16 @@ export default class MapConroler extends cc.Component {
cc.error('GuideMask 缺少道具按钮:', buttonName);
return;
}
// 在挂入场景前配置,避免 hand 激活时 onLoad 先于材质赋值。
const rippleSprite = this.node.parent.getChildByName('Bottom')
.getChildByName('rippleShrink').getComponent(cc.Sprite);
bottom.children.forEach(child => {
child.active = child === button;
const hand = child.getChildByName('hand');
if (!hand) return;
const animation = hand.getComponent(GuideHand) || hand.addComponent(GuideHand);
animation.rippleMaterial = rippleSprite.sharedMaterials[0];
});
this.propGuideMask = guide;
guide.parent = this.node.parent;
guide.setPosition(0, 0);
@ -921,7 +932,6 @@ export default class MapConroler extends cc.Component {
guide.setSiblingIndex(this.node.getSiblingIndex());
guide.getComponent(cc.Widget).updateAlignment();
bottom.getComponent(cc.Widget).updateAlignment();
bottom.children.forEach(child => child.active = child === button);
const clickEvent = new cc.Component.EventHandler();
clickEvent.target = this.node;
clickEvent.component = cc.js.getClassName(this);
@ -1347,38 +1357,28 @@ export default class MapConroler extends cc.Component {
}
const currentLevel = cc.fx.GameConfig.GM_INFO.level + 1;
const lastVisitedLevel = cc.fx.StorageMessage.getStorage("visitedLevels");
const isFirstTime = (lastVisitedLevel !== currentLevel);
this.node.parent.getChildByName("Top").getChildByName("difficultySpr").active = false;
if (isFirstTime) {
cc.fx.StorageMessage.setStorage("visitedLevels", currentLevel);
const passCheckJson = cc.fx.GameConfig.PASS_RATE;
// 直接查找匹配的记录
const levelData = passCheckJson.find(item => item.level === currentLevel);
if (levelData) {
// 找到了对应的记录
let passRateNode = this.node.parent.parent.getChildByName("popUpPassRate")
passRateNode.active = true;
this.node.parent.getChildByName("Top").getChildByName("difficultySpr").active = true;
let passRate = passRateNode.getChildByName("passRate");
// NumberToImage.numberToImageNodes4(levelData.pass_rate, 50, 0, "Black", passRate, true)
if (levelData.pass_rate)
passRate.getComponent(cc.Label).string = levelData.pass_rate.toString();
if (passRateNode) {
let targetY = cc.winSize.height / 2 - 500;
cc.tween(passRateNode)
.to(1.5, { y: targetY }, { easing: 'sineOut' })
.delay(2) // 停留2秒
.to(1, { opacity: 0 })
.start();
passRateNode.y = 0;
}
} else {
// console.log("未找到关卡数据");
const passCheckJson = cc.fx.GameConfig.PASS_RATE;
// 直接查找匹配的记录
const levelData = passCheckJson.find(item => item.level === currentLevel);
if (levelData) {
// 找到了对应的记录
let passRateNode = this.node.parent.parent.getChildByName("popUpPassRate")
passRateNode.active = true;
this.node.parent.getChildByName("Top").getChildByName("difficultySpr").active = true;
let passRate = passRateNode.getChildByName("passRate");
// NumberToImage.numberToImageNodes4(levelData.pass_rate, 50, 0, "Black", passRate, true)
if (levelData.pass_rate)
passRate.getComponent(cc.Label).string = levelData.pass_rate.toString();
if (passRateNode) {
let targetY = cc.winSize.height / 2 - 500;
cc.tween(passRateNode)
.to(1.5, { y: targetY }, { easing: 'sineOut' })
.delay(2) // 停留2秒
.to(1, { opacity: 0 })
.start();
passRateNode.y = 0;
}
} else {
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@ -8,8 +8,8 @@
"premultiplyAlpha": false,
"genMipmaps": false,
"packable": true,
"width": 174,
"height": 236,
"width": 170,
"height": 165,
"platformSettings": {},
"subMetas": {
"guide": {
@ -24,10 +24,10 @@
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 174,
"height": 236,
"rawWidth": 174,
"rawHeight": 236,
"width": 170,
"height": 165,
"rawWidth": 170,
"rawHeight": 165,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,

View File

@ -0,0 +1,13 @@
{
"ver": "1.1.3",
"uuid": "5784aa32-a327-49ba-b4b8-715662026462",
"importer": "folder",
"isBundle": false,
"bundleName": "",
"priority": 1,
"compressionType": {},
"optimizeHotUpdate": {},
"inlineSpriteFrames": {},
"isRemoteBundle": {},
"subMetas": {}
}

View File

@ -0,0 +1,13 @@
{
"ver": "1.1.3",
"uuid": "6a26a893-4131-4911-aa75-0b69d9c2bd37",
"importer": "folder",
"isBundle": false,
"bundleName": "",
"priority": 1,
"compressionType": {},
"optimizeHotUpdate": {},
"inlineSpriteFrames": {},
"isRemoteBundle": {},
"subMetas": {}
}

View File

@ -0,0 +1,13 @@
{
"ver": "1.1.3",
"uuid": "d4a8acaf-4115-4ec4-9c5f-e24ae54f4c60",
"importer": "folder",
"isBundle": false,
"bundleName": "",
"priority": 1,
"compressionType": {},
"optimizeHotUpdate": {},
"inlineSpriteFrames": {},
"isRemoteBundle": {},
"subMetas": {}
}

13
assets/pause/texture.meta Normal file
View File

@ -0,0 +1,13 @@
{
"ver": "1.1.3",
"uuid": "d22ba2f1-8f27-4214-a127-7f569ea99278",
"importer": "folder",
"isBundle": false,
"bundleName": "",
"priority": 1,
"compressionType": {},
"optimizeHotUpdate": {},
"inlineSpriteFrames": {},
"isRemoteBundle": {},
"subMetas": {}
}

View File

@ -1054,7 +1054,7 @@
},
{
"__type__": "cc.Node",
"_name": "New Sprite",
"_name": "hand",
"_objFlags": 0,
"_parent": {
"__id__": 3
@ -1079,20 +1079,20 @@
},
"_contentSize": {
"__type__": "cc.Size",
"width": 174,
"height": 236
"width": 170,
"height": 165
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
"y": 0
},
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
42.275,
-53.303,
37.964,
-58.92,
0,
0,
0,
@ -2303,7 +2303,7 @@
},
{
"__type__": "cc.Node",
"_name": "New Sprite",
"_name": "hand",
"_objFlags": 0,
"_parent": {
"__id__": 34
@ -2328,20 +2328,20 @@
},
"_contentSize": {
"__type__": "cc.Size",
"width": 174,
"height": 236
"width": 170,
"height": 165
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
"y": 0
},
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
42.275,
-53.303,
37.964,
-58.92,
0,
0,
0,
@ -3552,7 +3552,7 @@
},
{
"__type__": "cc.Node",
"_name": "New Sprite",
"_name": "hand",
"_objFlags": 0,
"_parent": {
"__id__": 68
@ -3577,20 +3577,20 @@
},
"_contentSize": {
"__type__": "cc.Size",
"width": 174,
"height": 236
"width": 170,
"height": 165
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
"y": 0
},
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
42.275,
-53.303,
37.964,
-58.92,
0,
0,
0,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

13
assets/res/public.meta Normal file
View File

@ -0,0 +1,13 @@
{
"ver": "1.1.3",
"uuid": "906500e0-19df-4e69-a2fa-ddd43d627b1a",
"importer": "folder",
"isBundle": false,
"bundleName": "",
"priority": 1,
"compressionType": {},
"optimizeHotUpdate": {},
"inlineSpriteFrames": {},
"isRemoteBundle": {},
"subMetas": {}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,38 @@
{
"ver": "2.3.7",
"uuid": "fc9f2f84-1605-4fd6-8826-c57053b1a3e2",
"importer": "texture",
"type": "sprite",
"wrapMode": "clamp",
"filterMode": "bilinear",
"premultiplyAlpha": false,
"genMipmaps": false,
"packable": true,
"width": 310,
"height": 310,
"platformSettings": {},
"subMetas": {
"hammer": {
"ver": "1.0.6",
"uuid": "28d2a4a2-6112-4092-af82-ac2da3393401",
"importer": "sprite-frame",
"rawTextureUuid": "fc9f2f84-1605-4fd6-8826-c57053b1a3e2",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"offsetX": -0.5,
"offsetY": 0,
"trimX": 16,
"trimY": 1,
"width": 277,
"height": 308,
"rawWidth": 310,
"rawHeight": 310,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"subMetas": {}
}
}
}

BIN
assets/res/public/hp.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -0,0 +1,38 @@
{
"ver": "2.3.7",
"uuid": "63cafdd3-c0f1-4017-be07-277d471b41a1",
"importer": "texture",
"type": "sprite",
"wrapMode": "clamp",
"filterMode": "bilinear",
"premultiplyAlpha": false,
"genMipmaps": false,
"packable": true,
"width": 317,
"height": 265,
"platformSettings": {},
"subMetas": {
"hp": {
"ver": "1.0.6",
"uuid": "b6b570b9-d928-4646-8a2a-70f18cc10991",
"importer": "sprite-frame",
"rawTextureUuid": "63cafdd3-c0f1-4017-be07-277d471b41a1",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"offsetX": 7.5,
"offsetY": -0.5,
"trimX": 21,
"trimY": 7,
"width": 290,
"height": 252,
"rawWidth": 317,
"rawHeight": 265,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"subMetas": {}
}
}
}

BIN
assets/res/public/ice.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -1,6 +1,6 @@
{
"ver": "2.3.7",
"uuid": "7bb60f6b-4f2f-41a0-a3a7-9134d936796c",
"uuid": "6fde94b8-f825-48c5-b1bd-f9152d7fbe7a",
"importer": "texture",
"type": "sprite",
"wrapMode": "clamp",
@ -8,26 +8,26 @@
"premultiplyAlpha": false,
"genMipmaps": false,
"packable": true,
"width": 1080,
"height": 2340,
"width": 310,
"height": 310,
"platformSettings": {},
"subMetas": {
"bgZhuanChang": {
"ice": {
"ver": "1.0.6",
"uuid": "a8264009-d0c9-4f38-8fd9-752d61996e53",
"uuid": "ac60b2a5-c833-400a-b640-6eb478c96f1f",
"importer": "sprite-frame",
"rawTextureUuid": "7bb60f6b-4f2f-41a0-a3a7-9134d936796c",
"rawTextureUuid": "6fde94b8-f825-48c5-b1bd-f9152d7fbe7a",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 1080,
"height": 2340,
"rawWidth": 1080,
"rawHeight": 2340,
"trimX": 30,
"trimY": 9,
"width": 250,
"height": 292,
"rawWidth": 310,
"rawHeight": 310,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,

BIN
assets/res/public/magic.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -0,0 +1,38 @@
{
"ver": "2.3.7",
"uuid": "d73ee0e4-97fa-40f3-b27b-33a00d2f63dc",
"importer": "texture",
"type": "sprite",
"wrapMode": "clamp",
"filterMode": "bilinear",
"premultiplyAlpha": false,
"genMipmaps": false,
"packable": true,
"width": 310,
"height": 310,
"platformSettings": {},
"subMetas": {
"magic": {
"ver": "1.0.6",
"uuid": "88e305a3-bb71-410b-b067-7748e9696122",
"importer": "sprite-frame",
"rawTextureUuid": "d73ee0e4-97fa-40f3-b27b-33a00d2f63dc",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"offsetX": -1,
"offsetY": -12.5,
"trimX": 22,
"trimY": 28,
"width": 264,
"height": 279,
"rawWidth": 310,
"rawHeight": 310,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"subMetas": {}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1,38 @@
{
"ver": "2.3.7",
"uuid": "b5b0e4cc-4660-4d0f-bc54-0f050c1b2f24",
"importer": "texture",
"type": "sprite",
"wrapMode": "clamp",
"filterMode": "bilinear",
"premultiplyAlpha": false,
"genMipmaps": false,
"packable": true,
"width": 110,
"height": 110,
"platformSettings": {},
"subMetas": {
"skyLine": {
"ver": "1.0.6",
"uuid": "419e6dd8-8ab5-4910-bf94-b82afe18191b",
"importer": "sprite-frame",
"rawTextureUuid": "b5b0e4cc-4660-4d0f-bc54-0f050c1b2f24",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"offsetX": -0.5,
"offsetY": 0,
"trimX": 11,
"trimY": 18,
"width": 87,
"height": 74,
"rawWidth": 110,
"rawHeight": 110,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"subMetas": {}
}
}
}