This commit is contained in:
YHH
2025-06-24 19:34:37 +08:00
parent 68a615bc7b
commit 0f18a1979e
62 changed files with 10606 additions and 2113 deletions

View File

@@ -1,102 +0,0 @@
import { Component } from '@esengine/ecs-framework';
/**
* 生命值组件 - 管理实体的生命值和相关状态
*
* 展示游戏逻辑组件的设计:
* 1. 包含生命值的核心数据
* 2. 提供简单的查询方法
* 3. 复杂的伤害处理逻辑留给系统处理
*/
export class HealthComponent extends Component {
/** 最大生命值 */
public maxHealth: number;
/** 当前生命值 */
public currentHealth: number;
/** 生命值回复速度(每秒回复量) */
public regenRate: number = 0;
/** 最后受到伤害的时间(用于延迟回血等机制) */
public lastDamageTime: number = 0;
/** 是否无敌 */
public invincible: boolean = false;
/** 无敌持续时间 */
public invincibleDuration: number = 0;
constructor(maxHealth: number = 100, regenRate: number = 0) {
super();
this.maxHealth = maxHealth;
this.currentHealth = maxHealth;
this.regenRate = regenRate;
}
/**
* 检查是否死亡
*/
isDead(): boolean {
return this.currentHealth <= 0;
}
/**
* 检查是否满血
*/
isFullHealth(): boolean {
return this.currentHealth >= this.maxHealth;
}
/**
* 获取生命值百分比0-1
*/
getHealthPercentage(): number {
return this.currentHealth / this.maxHealth;
}
/**
* 检查生命值是否低于指定百分比
*/
isHealthBelowPercentage(percentage: number): boolean {
return this.getHealthPercentage() < percentage;
}
/**
* 设置生命值(不超过最大值)
*/
setHealth(health: number) {
this.currentHealth = Math.max(0, Math.min(health, this.maxHealth));
}
/**
* 增加生命值(治疗)
*/
heal(amount: number) {
this.currentHealth = Math.min(this.currentHealth + amount, this.maxHealth);
}
/**
* 减少生命值(受伤)
* 注意:这里只修改数据,具体的伤害逻辑(如死亡处理)应该在系统中实现
*/
takeDamage(damage: number) {
if (this.invincible) return;
this.currentHealth = Math.max(0, this.currentHealth - damage);
this.lastDamageTime = Date.now();
}
/**
* 设置无敌状态
*/
setInvincible(duration: number) {
this.invincible = true;
this.invincibleDuration = duration;
}
/**
* 重置到满血状态
*/
reset() {
this.currentHealth = this.maxHealth;
this.invincible = false;
this.invincibleDuration = 0;
this.lastDamageTime = 0;
}
}

View File

@@ -1,9 +0,0 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "0f20d48a-7b30-4081-a9de-709432b6737b",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -1,124 +0,0 @@
import { Component } from '@esengine/ecs-framework';
import { Vec2 } from 'cc';
/**
* 玩家输入组件 - 存储玩家的输入状态
*
* 标记组件示例:
* 1. 标识这是一个玩家控制的实体
* 2. 存储输入状态数据
* 3. 输入处理逻辑在InputSystem中实现
*/
export class PlayerInputComponent extends Component {
/** 移动输入方向(-1到1 */
public moveDirection: Vec2 = new Vec2();
/** 按键状态 */
public keys: { [key: string]: boolean } = {};
/** 鼠标位置 */
public mousePosition: Vec2 = new Vec2();
/** 鼠标按键状态 */
public mouseButtons: { left: boolean; right: boolean; middle: boolean } = {
left: false,
right: false,
middle: false
};
/** 是否启用输入 */
public inputEnabled: boolean = true;
/** 输入敏感度 */
public sensitivity: number = 1.0;
constructor() {
super();
}
/**
* 设置移动方向
*/
setMoveDirection(x: number, y: number) {
this.moveDirection.set(x, y);
// 标准化方向向量(对角线移动不应该更快)
if (this.moveDirection.lengthSqr() > 1) {
this.moveDirection.normalize();
}
}
/**
* 设置按键状态
*/
setKey(key: string, pressed: boolean) {
this.keys[key] = pressed;
}
/**
* 检查按键是否按下
*/
isKeyPressed(key: string): boolean {
return this.keys[key] || false;
}
/**
* 检查是否有移动输入
*/
hasMovementInput(): boolean {
return this.moveDirection.lengthSqr() > 0.01;
}
/**
* 获取标准化的移动方向
*/
getNormalizedMoveDirection(): Vec2 {
const result = new Vec2(this.moveDirection);
if (result.lengthSqr() > 0) {
result.normalize();
}
return result;
}
/**
* 设置鼠标位置
*/
setMousePosition(x: number, y: number) {
this.mousePosition.set(x, y);
}
/**
* 设置鼠标按键状态
*/
setMouseButton(button: 'left' | 'right' | 'middle', pressed: boolean) {
this.mouseButtons[button] = pressed;
}
/**
* 检查鼠标按键是否按下
*/
isMouseButtonPressed(button: 'left' | 'right' | 'middle'): boolean {
return this.mouseButtons[button];
}
/**
* 清除所有输入状态
*/
clearInput() {
this.moveDirection.set(0, 0);
this.keys = {};
this.mouseButtons.left = false;
this.mouseButtons.right = false;
this.mouseButtons.middle = false;
}
/**
* 禁用输入
*/
disableInput() {
this.inputEnabled = false;
this.clearInput();
}
/**
* 启用输入
*/
enableInput() {
this.inputEnabled = true;
}
}

View File

@@ -1,9 +0,0 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "ab10dc4c-c8a3-4fd2-83d6-433d4195966b",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -1,62 +0,0 @@
import { Component } from '@esengine/ecs-framework';
import { Vec3 } from 'cc';
/**
* 位置组件 - 存储实体的空间位置信息
*
* 这是最基础的组件示例展示了ECS组件的设计原则
* 1. 主要存储数据,少量辅助方法
* 2. 单一职责:只负责位置相关的数据
* 3. 可复用:任何需要位置信息的实体都可以使用
*/
export class PositionComponent extends Component {
/** 3D位置坐标 */
public position: Vec3 = new Vec3();
/** 上一帧的位置(用于计算移动距离) */
public lastPosition: Vec3 = new Vec3();
constructor(x: number = 0, y: number = 0, z: number = 0) {
super();
this.position.set(x, y, z);
this.lastPosition.set(x, y, z);
}
/**
* 设置位置
*/
setPosition(x: number, y: number, z: number = 0) {
this.lastPosition.set(this.position);
this.position.set(x, y, z);
}
/**
* 移动位置
*/
move(deltaX: number, deltaY: number, deltaZ: number = 0) {
this.lastPosition.set(this.position);
this.position.x += deltaX;
this.position.y += deltaY;
this.position.z += deltaZ;
}
/**
* 计算到另一个位置的距离
*/
distanceTo(other: PositionComponent): number {
return Vec3.distance(this.position, other.position);
}
/**
* 获取本帧移动的距离
*/
getMovementDistance(): number {
return Vec3.distance(this.position, this.lastPosition);
}
/**
* 检查是否在指定范围内
*/
isWithinRange(target: PositionComponent, range: number): boolean {
return this.distanceTo(target) <= range;
}
}

View File

@@ -1,9 +0,0 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "e6ee57d6-d0eb-43f2-a601-9b7a2812de66",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -1,94 +0,0 @@
import { Component } from '@esengine/ecs-framework';
import { Vec3 } from 'cc';
/**
* 速度组件 - 存储实体的运动速度信息
*
* 设计原则展示:
* 1. 与PositionComponent分离遵循单一职责原则
* 2. 包含速度限制:避免无限加速
* 3. 提供常用的速度操作方法
*/
export class VelocityComponent extends Component {
/** 当前速度向量 */
public velocity: Vec3 = new Vec3();
/** 最大速度限制 */
public maxSpeed: number = 100;
/** 阻尼系数0-11为无阻尼 */
public damping: number = 1.0;
constructor(x: number = 0, y: number = 0, z: number = 0, maxSpeed: number = 100) {
super();
this.velocity.set(x, y, z);
this.maxSpeed = maxSpeed;
}
/**
* 设置速度
*/
setVelocity(x: number, y: number, z: number = 0) {
this.velocity.set(x, y, z);
this.clampToMaxSpeed();
}
/**
* 添加速度(加速度效果)
*/
addVelocity(x: number, y: number, z: number = 0) {
this.velocity.x += x;
this.velocity.y += y;
this.velocity.z += z;
this.clampToMaxSpeed();
}
/**
* 应用阻尼
*/
applyDamping(deltaTime: number) {
if (this.damping < 1.0) {
const dampingFactor = Math.pow(this.damping, deltaTime);
this.velocity.multiplyScalar(dampingFactor);
}
}
/**
* 限制速度不超过最大值
*/
private clampToMaxSpeed() {
const speed = this.velocity.length();
if (speed > this.maxSpeed) {
this.velocity.normalize();
this.velocity.multiplyScalar(this.maxSpeed);
}
}
/**
* 获取当前速度大小
*/
getSpeed(): number {
return this.velocity.length();
}
/**
* 获取速度方向(单位向量)
*/
getDirection(): Vec3 {
const result = new Vec3();
Vec3.normalize(result, this.velocity);
return result;
}
/**
* 停止移动
*/
stop() {
this.velocity.set(0, 0, 0);
}
/**
* 检查是否在移动
*/
isMoving(): boolean {
return this.velocity.lengthSqr() > 0.01; // 避免浮点数精度问题
}
}

View File

@@ -1,9 +0,0 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "784d7c28-2b72-427c-8b04-da0fcf775acf",
"files": [],
"subMetas": {},
"userData": {}
}