|
|
@@ -2,7 +2,7 @@
|
|
|
* @Author: mojunshou 1637302775@qq.com
|
|
|
* @Date: 2025-03-20 15:01:09
|
|
|
* @LastEditors: mojunshou 1637302775@qq.com
|
|
|
- * @LastEditTime: 2025-03-31 14:11:58
|
|
|
+ * @LastEditTime: 2025-03-31 17:33:44
|
|
|
* @Description: 消除游戏主场景
|
|
|
*/
|
|
|
import { _decorator, Color, EventTouch, instantiate, JsonAsset, Label, Node, Prefab, randomRangeInt, Sprite, Toggle, tween, UITransform, Vec2, Vec3, Widget } from "cc";
|
|
|
@@ -100,6 +100,12 @@ export class EliminateViewComp extends CCComp {
|
|
|
private amountLb: LabelChange = null!;
|
|
|
@property({ type: LabelChange, displayName: "额外奖励" })
|
|
|
private awardLb: LabelChange = null!;
|
|
|
+ @property({ type: Node, displayName: "tween微信钱Node" })
|
|
|
+ private tweenWechatNode: Node = null!;
|
|
|
+ @property({ type: Node, displayName: "tween红包Node" })
|
|
|
+ private tweenRedNode: Node = null!;
|
|
|
+
|
|
|
+
|
|
|
@property({ type: Prefab, displayName: "金币预制体" })
|
|
|
private coinPrefab: Prefab = null!;
|
|
|
@property({ type: Prefab, displayName: "红包预制体" })
|
|
|
@@ -1067,59 +1073,43 @@ export class EliminateViewComp extends CCComp {
|
|
|
})
|
|
|
|
|
|
this.scheduleOnce(() => {
|
|
|
- // 新的分数计算逻辑
|
|
|
- let baseScore = 0;
|
|
|
- // 计算基础分(每行/列 * 基础分值)
|
|
|
- baseScore = (eliminateRowNum + eliminateColumnNum) * this.eliminateBaseScore;
|
|
|
-
|
|
|
- // 格子数量分
|
|
|
- const gridScore = gridEliminateList.length;
|
|
|
+ let score = 0
|
|
|
+ for (let i = 1; i <= eliminateRowNum; i++) {
|
|
|
+ score += this.cols * i
|
|
|
+ }
|
|
|
+ for (let i = 1; i <= eliminateColumnNum; i++) {
|
|
|
+ score += this.rows * i
|
|
|
+ }
|
|
|
+ this.score += score
|
|
|
+ this.lab_score.string = this.score.toString();
|
|
|
|
|
|
- // 总分 = 基础分 + 格子数量分
|
|
|
- const totalScore = baseScore + gridScore;
|
|
|
+ const lastGrid = gridEliminateList[gridEliminateList.length - 1];
|
|
|
+ if (lastGrid?.gridNode && this.coinPrefab && this.amountLb?.node) {
|
|
|
+ const lastPos = lastGrid.gridNode.getWorldPosition();
|
|
|
|
|
|
- // 更新总分
|
|
|
- this.score += totalScore;
|
|
|
- this.lab_score.string = this.score.toString();
|
|
|
+ // 添加回调函数,在金币动画完成后显示微信分数增加
|
|
|
+ this.createCoinFlyAnimation(
|
|
|
+ this.coinPrefab,
|
|
|
+ lastPos,
|
|
|
+ this.amountLb.node.getWorldPosition(),
|
|
|
+ score,
|
|
|
+ () => {
|
|
|
+ // 显示微信分数增加动画
|
|
|
+ this.showWechatScoreAnimation();
|
|
|
+ }
|
|
|
+ );
|
|
|
|
|
|
- // 显示分数增加动画
|
|
|
- if (gridEliminateList.length > 0) {
|
|
|
- const lastGrid = gridEliminateList[gridEliminateList.length - 1];
|
|
|
- if (lastGrid?.gridNode) {
|
|
|
- const lastPos = lastGrid.gridNode.getWorldPosition();
|
|
|
-
|
|
|
- // 创建分数提示
|
|
|
- const scoreNode = new Node();
|
|
|
- this.node.addChild(scoreNode);
|
|
|
- scoreNode.setWorldPosition(lastPos);
|
|
|
-
|
|
|
- const scoreLabel = scoreNode.addComponent(Label);
|
|
|
- scoreLabel.string = `+${totalScore}`;
|
|
|
- scoreLabel.fontSize = 40;
|
|
|
- scoreLabel.color = Color.YELLOW;
|
|
|
-
|
|
|
- // 分数飞行动画
|
|
|
- tween(scoreNode)
|
|
|
- .to(0.5, {
|
|
|
- position: new Vec3(scoreNode.position.x, scoreNode.position.y + 100, 0),
|
|
|
- scale: new Vec3(1.5, 1.5, 1.5)
|
|
|
- })
|
|
|
- .to(0.3, { opacity: 0 })
|
|
|
- .call(() => {
|
|
|
- scoreNode.destroy();
|
|
|
- })
|
|
|
- .start();
|
|
|
-
|
|
|
- // 金币飞行动画
|
|
|
- if (this.coinPrefab && this.amountLb?.node) {
|
|
|
- this.createCoinFlyAnimation(
|
|
|
- this.coinPrefab,
|
|
|
- lastPos,
|
|
|
- this.amountLb.node.getWorldPosition(),
|
|
|
- totalScore
|
|
|
- );
|
|
|
+ // 添加回调函数,在红包动画完成后显示红包分数增加
|
|
|
+ this.createCoinFlyAnimation(
|
|
|
+ this.redPacketPrefab,
|
|
|
+ lastPos,
|
|
|
+ this.awardLb.node.getWorldPosition(),
|
|
|
+ 5,
|
|
|
+ () => {
|
|
|
+ // 显示红包分数增加动画
|
|
|
+ this.showRedPacketScoreAnimation();
|
|
|
}
|
|
|
- }
|
|
|
+ );
|
|
|
}
|
|
|
|
|
|
// 告诉调用者有消除发生
|
|
|
@@ -1172,74 +1162,141 @@ export class EliminateViewComp extends CCComp {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // 修改 createCoinFlyAnimation 方法为公共方法,扩展参数列表
|
|
|
- public createCoinFlyAnimation(prefab: Prefab, startPos: Vec3, endPos: Vec3, score: number, parent: Node = this.node) {
|
|
|
- const coinNum = Math.min(Math.max(Math.floor(score / 10), 1), 10);
|
|
|
+ // 修改 createCoinFlyAnimation 方法,添加回调
|
|
|
+ private createCoinFlyAnimation(prefab: Prefab, startPos: Vec3, endPos: Vec3, count: number, callback?: Function) {
|
|
|
+ if (!prefab) return;
|
|
|
|
|
|
- for (let i = 0; i < coinNum; i++) {
|
|
|
- if (!prefab) {
|
|
|
- console.warn('金币预制体未加载');
|
|
|
- return;
|
|
|
- }
|
|
|
+ let completedCount = 0;
|
|
|
+ const totalCoins = Math.min(count, 10); // 限制最大数量
|
|
|
|
|
|
+ for (let i = 0; i < totalCoins; i++) {
|
|
|
const coin = instantiate(prefab);
|
|
|
- parent.addChild(coin);
|
|
|
+ this.node.addChild(coin);
|
|
|
+ coin.setWorldPosition(startPos);
|
|
|
|
|
|
+ // 随机偏移起始位置
|
|
|
const randomOffset = new Vec3(
|
|
|
(Math.random() - 0.5) * 50,
|
|
|
(Math.random() - 0.5) * 50,
|
|
|
0
|
|
|
);
|
|
|
- const startPosition = startPos.clone().add(randomOffset);
|
|
|
- coin.setWorldPosition(startPosition);
|
|
|
|
|
|
- const controlPoint = new Vec3(
|
|
|
- (startPosition.x + endPos.x) / 2 + (Math.random() - 0.5) * 100,
|
|
|
- (startPosition.y + endPos.y) / 2 + Math.random() * 100,
|
|
|
- 0
|
|
|
- );
|
|
|
-
|
|
|
- this.scheduleOnce(() => {
|
|
|
- tween(coin)
|
|
|
- .parallel(
|
|
|
- tween().to(0.2, { scale: new Vec3(1.2, 1.2, 1.2) })
|
|
|
- .to(0.1, { scale: new Vec3(1, 1, 1) }),
|
|
|
- tween().by(0.3, { angle: 360 })
|
|
|
+ // 创建曲线动画
|
|
|
+ tween(coin)
|
|
|
+ .to(0.2, {
|
|
|
+ position: new Vec3(
|
|
|
+ coin.position.x + randomOffset.x,
|
|
|
+ coin.position.y + randomOffset.y,
|
|
|
+ 0
|
|
|
)
|
|
|
- .start();
|
|
|
+ })
|
|
|
+ .to(0.5, { worldPosition: endPos })
|
|
|
+ .call(() => {
|
|
|
+ coin.destroy();
|
|
|
+ completedCount++;
|
|
|
+
|
|
|
+ // 所有金币动画完成后执行回调
|
|
|
+ if (completedCount === totalCoins && callback) {
|
|
|
+ callback();
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .start();
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- const bezierCurve = (target: Node | undefined, ratio?: number) => {
|
|
|
- if (!target || ratio === undefined) return;
|
|
|
- const t = ratio;
|
|
|
- const pos = new Vec3();
|
|
|
- Vec3.multiplyScalar(pos, startPosition, (1 - t) * (1 - t));
|
|
|
- Vec3.scaleAndAdd(pos, pos, controlPoint, 2 * (1 - t) * t);
|
|
|
- Vec3.scaleAndAdd(pos, pos, endPos, t * t);
|
|
|
- target.setWorldPosition(pos);
|
|
|
- };
|
|
|
-
|
|
|
- tween(coin)
|
|
|
- .to(0.8, {
|
|
|
- worldPosition: endPos
|
|
|
- }, {
|
|
|
- easing: 'cubicIn',
|
|
|
- onUpdate: bezierCurve
|
|
|
- })
|
|
|
- .call(() => {
|
|
|
- tween(coin)
|
|
|
- .to(0.1, { scale: new Vec3(0.7, 0.7, 0.7) })
|
|
|
- .call(() => {
|
|
|
- coin.destroy();
|
|
|
- })
|
|
|
- .start();
|
|
|
- })
|
|
|
- .start();
|
|
|
+ // 显示微信分数增加动画
|
|
|
+ private showWechatScoreAnimation() {
|
|
|
+ if (!this.tweenWechatNode) return;
|
|
|
|
|
|
- //需要有个金币飘的icon和文字动画,在两边,然后最后展示最新的数字
|
|
|
- }, i * 0.1);
|
|
|
+ // 生成随机小数(小于1,保留2位小数)
|
|
|
+ const randomValue = Math.random() * 0.99;
|
|
|
+ const formattedValue = randomValue.toFixed(2);
|
|
|
+
|
|
|
+ // 获取并设置分数标签
|
|
|
+ const scoreLabel = this.tweenWechatNode.getChildByName("lab_num")?.getComponent(Label);
|
|
|
+ if (scoreLabel) {
|
|
|
+ scoreLabel.string = "+" + formattedValue;
|
|
|
}
|
|
|
+
|
|
|
+ // 保存原始位置
|
|
|
+ const originalPosition = this.tweenWechatNode.position.clone();
|
|
|
+
|
|
|
+ // 显示节点
|
|
|
+ this.tweenWechatNode.active = true;
|
|
|
+
|
|
|
+ // 创建向上移动的动画
|
|
|
+ tween(this.tweenWechatNode)
|
|
|
+ .to(0.8, {
|
|
|
+ position: new Vec3(
|
|
|
+ originalPosition.x,
|
|
|
+ originalPosition.y + 80,
|
|
|
+ originalPosition.z
|
|
|
+ ),
|
|
|
+ opacity: 255
|
|
|
+ })
|
|
|
+ .to(0.2, { opacity: 0 })
|
|
|
+ .call(() => {
|
|
|
+ // 重置位置
|
|
|
+ this.tweenWechatNode.setPosition(originalPosition);
|
|
|
+ this.tweenWechatNode.active = false;
|
|
|
+
|
|
|
+ // 更新总金额
|
|
|
+ if (this.amountLb) {
|
|
|
+ const currentAmount = parseFloat(this.amountLb.string);
|
|
|
+ const newAmount = currentAmount + parseFloat(formattedValue);
|
|
|
+ this.money = newAmount;
|
|
|
+ this.amountLb.string = newAmount.toFixed(2);
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .start();
|
|
|
}
|
|
|
|
|
|
+ // 显示红包分数增加动画
|
|
|
+ private showRedPacketScoreAnimation() {
|
|
|
+ if (!this.tweenRedNode) return;
|
|
|
+
|
|
|
+ // 生成随机小数(小于1,保留2位小数)
|
|
|
+ const randomValue = Math.random() * 0.99;
|
|
|
+ const formattedValue = randomValue.toFixed(2);
|
|
|
+
|
|
|
+ // 获取并设置分数标签
|
|
|
+ const scoreLabel = this.tweenRedNode.getChildByName("lab_num")?.getComponent(Label);
|
|
|
+ if (scoreLabel) {
|
|
|
+ scoreLabel.string = "+" + formattedValue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 保存原始位置
|
|
|
+ const originalPosition = this.tweenRedNode.position.clone();
|
|
|
+
|
|
|
+ // 显示节点
|
|
|
+ this.tweenRedNode.active = true;
|
|
|
+
|
|
|
+ // 创建向上移动的动画
|
|
|
+ tween(this.tweenRedNode)
|
|
|
+ .to(0.8, {
|
|
|
+ position: new Vec3(
|
|
|
+ originalPosition.x,
|
|
|
+ originalPosition.y + 80,
|
|
|
+ originalPosition.z
|
|
|
+ ),
|
|
|
+ opacity: 255
|
|
|
+ })
|
|
|
+ .to(0.2, { opacity: 0 })
|
|
|
+ .call(() => {
|
|
|
+ // 重置位置
|
|
|
+ this.tweenRedNode.setPosition(originalPosition);
|
|
|
+ this.tweenRedNode.active = false;
|
|
|
+
|
|
|
+ // 更新总红包金额
|
|
|
+ if (this.awardLb) {
|
|
|
+ const currentAmount = parseFloat(this.awardLb.string);
|
|
|
+ const newAmount = currentAmount + parseFloat(formattedValue);
|
|
|
+ this.cash = newAmount;
|
|
|
+ this.awardLb.string = newAmount.toFixed(2);
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .start();
|
|
|
+ }
|
|
|
|
|
|
// 提示
|
|
|
prompt(tipFlag = true) {
|
|
|
@@ -1718,6 +1775,7 @@ export class EliminateViewComp extends CCComp {
|
|
|
this.reopenGrid();
|
|
|
}
|
|
|
|
|
|
+ //重新清除网格
|
|
|
private reopenGrid() {
|
|
|
for (let rowIndex = 0; rowIndex < this.rows; rowIndex++) {
|
|
|
for (let columnIndex = 0; columnIndex < this.cols; columnIndex++) {
|