first commit

This commit is contained in:
zzc
2026-04-30 00:13:37 +08:00
commit 493b4709bc
189 changed files with 24791 additions and 0 deletions

View File

@@ -0,0 +1,220 @@
import {
_decorator,
Component,
input,
EventTouch,
Node,
Input,
Vec3,
Collider2D,
Contact2DType,
SpriteFrame,
Sprite,
tween,
Prefab,
instantiate,
director,
} from "cc";
import { NoteControl } from "./NoteControl";
import { BombEffect } from "../effects/BombEffectControl";
import { EventDispatcher } from "../libs/EventDispatcher";
import { GlobalData } from "../config/GlobalData";
import { GameState } from "../config/Config";
const { ccclass, property } = _decorator;
@ccclass("DinoControl")
export class DinoControl extends Component {
// 小恐龙脖子图片
@property(SpriteFrame)
neckSpriteFrame: SpriteFrame = null;
// 小恐龙脖子的高度
private neckHeight: number = 62;
// x 轴的边界
private xMaxDistance: number = 180;
// 爆炸特效预制体
@property(Prefab)
bombEffectPrefab: Prefab = null;
// 获取线节点
@property(Node)
lineNode: Node = null;
onLoad() {
// 监听继续游戏事件
EventDispatcher.getTarget().on(
EventDispatcher.GAME_RESUME,
this.continueGame,
this,
);
// 监听小恐龙移动到线的位置
EventDispatcher.getTarget().on(
EventDispatcher.MOVE_DINO_TO_LINE,
this.moveDinoToLine,
this,
);
}
start() {
// 监听手指滑动事件
input.on(Input.EventType.TOUCH_MOVE, this.onTouchMove, this);
// 监听碰撞事件
this.node
.getComponent(Collider2D)
.on(Contact2DType.BEGIN_CONTACT, this.onCollisionEnter, this);
}
// 滑动事件
onTouchMove(event: EventTouch) {
// 获取小恐龙的位置
const dinoPos = this.node.position;
// 获取手指x移动距离
const deltaX = event.getDeltaX();
// 更新小恐龙的位置
// 目标位置
const targetPos = new Vec3(dinoPos.x + deltaX, dinoPos.y, dinoPos.z);
if (targetPos.x < -this.xMaxDistance) {
targetPos.x = -this.xMaxDistance;
} else if (targetPos.x > this.xMaxDistance) {
targetPos.x = this.xMaxDistance;
}
this.node.setPosition(targetPos);
// 移动距离大于0时小恐龙向右移动否则向左移动
if (deltaX > 0) {
this.node.scale = new Vec3(-1, 1, 1);
} else {
this.node.scale = new Vec3(1, 1, 1);
}
}
onCollisionEnter(selfCollider: Collider2D, otherCollider: Collider2D) {
// 如果游戏状态不是进行中,直接返回
if (GlobalData.gameState != GameState.PLAYING) {
return;
}
if (otherCollider.tag == 2) {
// 得分操作
GlobalData.curRoundTotalScore += GlobalData.addScore;
// 触发小恐龙吃到音符事件
EventDispatcher.getTarget().emit(EventDispatcher.DINO_EAT_NOTE);
// 小恐龙碰到了音符
otherCollider.node.getComponent(NoteControl).noteBeEaten();
// 增加脖子长度
this.addDinoNeckLength();
// 执行吃掉音符动画
this.playEatNoteAnimation();
// 播放爆炸特效
this.playBombEffect();
// 检测是否闯关成功
const isPassLevel = this.checkIsPassLevel();
if (isPassLevel) {
EventDispatcher.getTarget().emit(EventDispatcher.PASS_LEVLE);
}
}
}
// 增加脖子长度
addDinoNeckLength() {
// 添加脖子空节点
let neckChild = new Node();
// 给这个节点添加精灵组件
neckChild.addComponent(Sprite).spriteFrame = this.neckSpriteFrame;
// 设置这个空节点的父节点
neckChild.parent = this.node.getChildByName("dino_neck_box");
// 获取小恐龙身体
const bodyNode = this.node.getChildByName("dino_body");
// 获取小恐龙位置
const bodyPos = bodyNode.getPosition();
// 设置小恐龙新的位置(往下移动一个脖子的距离)
bodyNode.setPosition(bodyPos.x, bodyPos.y - this.neckHeight, 0);
}
// 执行吃掉音符动画
playEatNoteAnimation() {
// 获取当前所有脖子列表
const neckList: Node[] = this.node
.getChildByName("dino_neck_box")
.children.slice(0, 16) as Node[];
// 定义存储动画的 promise
let animationPromises = Promise.resolve();
// 遍历所有脖子
for (let i = 0; i < neckList.length; i++) {
let neckNode = neckList[i];
// 播放吃掉音符动画
animationPromises = animationPromises.then(() => {
return new Promise((resolve) => {
tween(neckNode)
.to(0.1, { scale: new Vec3(1.2, 1, 1) })
.to(0.1, { scale: new Vec3(1, 1, 1) })
.call(() => resolve())
.start();
});
});
}
}
// 播放爆炸特效
playBombEffect() {
// 实例化爆炸特效
let bombEffectNode = instantiate(this.bombEffectPrefab);
// 设置爆炸特效节点的位置
let bombPos = new Vec3(
this.node.position.x,
this.node.position.y + 100,
this.node.position.z,
);
// 设置位置
bombEffectNode.setPosition(bombPos);
// 设置爆炸特效节点的父节点
bombEffectNode.setParent(this.node.parent);
// 播放爆炸特效
bombEffectNode.getComponent(BombEffect).playBombEffect();
}
// 移动小恐龙到线的位置
moveDinoToLine() {
// 获取线的世界坐标
const linePos = this.lineNode.getWorldPosition();
// 获取小恐龙身体的世界坐标位置
const bodyPos = this.node.getChildByName("dino_body").getWorldPosition();
// 计算两个坐标 y 轴的差值
const deltaY = linePos.y - bodyPos.y;
// 移动小恐龙到线的位置动画
tween(this.node)
.by(1, { position: new Vec3(0, deltaY - 44, 0) })
.start();
}
// 检测是否通过本关
checkIsPassLevel(): boolean {
// 获取 note_manager 节点
const noteManager = director
.getScene()
.getChildByName("Canvas")
.getChildByName("note_manager");
if (noteManager?.children?.length === 0) return true;
return false;
}
// 继续游戏
continueGame() {
const isPassLevel = this.checkIsPassLevel();
if (isPassLevel) {
// 发送闯关成功事件
EventDispatcher.getTarget().emit(EventDispatcher.PASS_LEVLE);
}
}
update(deltaTime: number) {}
}