rts-demo
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "0f20d48a-7b30-4081-a9de-709432b6737b",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "ab10dc4c-c8a3-4fd2-83d6-433d4195966b",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "e6ee57d6-d0eb-43f2-a601-9b7a2812de66",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -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-1,1为无阻尼) */
|
||||
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; // 避免浮点数精度问题
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "784d7c28-2b72-427c-8b04-da0fcf775acf",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
Reference in New Issue
Block a user