消消方块阵换皮表情
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

157 lines
4.8 KiB

1 week ago
import { _decorator, Component, Node, Vec2, Rect, Sprite, Label, CCInteger } from 'cc';
const { ccclass, property } = _decorator;
// 城墙攻击点类型
export interface WallAttackPoint {
id: string; // A, B, C, D等
position: Vec2;
isObstructed: boolean; // 是否被障碍物阻挡
health: number; // 该位置的血量
maxHealth: number;
}
@ccclass('WallSystem')
export class WallSystem extends Component {
@property(Node)
wallNode: Node = null; // 城墙根节点
@property(CCInteger)
wallLength: number = 400; // 城墙总长度
@property(CCInteger)
attackPointCount: number = 4; // 攻击点数量 A,B,C,D
@property(CCInteger)
attackPointHealth: number = 100; // 每个攻击点的初始血量
private attackPoints: WallAttackPoint[] = [];
private wallRect: Rect = null; // 城墙碰撞区域
init() {
this.initAttackPoints();
this.initWallCollision();
}
// 初始化攻击点
private initAttackPoints() {
this.attackPoints = [];
// 计算攻击点间距
const spacing = this.wallLength / (this.attackPointCount - 1);
const startY = -this.wallLength / 2;
// 创建攻击点
for (let i = 0; i < this.attackPointCount; i++) {
const id = String.fromCharCode(65 + i); // A, B, C, D...
const position = new Vec2(
this.wallNode.position.x,
startY + i * spacing
);
this.attackPoints.push({
id,
position,
isObstructed: false,
health: this.attackPointHealth,
maxHealth: this.attackPointHealth
});
// 在场景中创建可视化攻击点标记
this.createAttackPointMarker(id, position);
}
}
// 创建攻击点标记
private createAttackPointMarker(id: string, position: Vec2) {
const marker = new Node(`WallPoint_${id}`);
marker.setParent(this.wallNode);
marker.setPosition(position.x, position.y, 0);
// 添加一个小图标作为标记
const sprite = marker.addComponent(Sprite);
// 这里应该设置一个合适的精灵帧,简化处理略
// 添加ID标签
const labelNode = new Node('Label');
labelNode.setParent(marker);
const label = labelNode.addComponent(Label);
label.string = id;
labelNode.setPosition(0, 20);
}
// 初始化城墙碰撞区域
private initWallCollision() {
// 假设城墙是一个矩形,位于左侧
this.wallRect = new Rect(
this.wallNode.position.x - 20, // x
-this.wallLength / 2, // y
40, // width
this.wallLength // height
);
}
// 检查点是否与城墙碰撞
isCollidingWithWall(point: Vec2): boolean {
return this.wallRect.contains(point);
}
// 获取最近的攻击点
getNearestAttackPoint(position: Vec2): WallAttackPoint {
let nearestPoint: WallAttackPoint = null;
let minDistance = Number.MAX_VALUE;
for (const point of this.attackPoints) {
if (point.isObstructed) continue; // 跳过被阻挡的点
const distance = Vec2.distance(position, point.position);
if (distance < minDistance) {
minDistance = distance;
nearestPoint = point;
}
}
return nearestPoint;
}
// 获取所有可用的攻击点(未被阻挡)
getAvailableAttackPoints(): WallAttackPoint[] {
return this.attackPoints.filter(point => !point.isObstructed);
}
// 检查攻击点是否被障碍物阻挡
updateAttackPointObstructions(obstaclePositions: Vec2[]) {
for (const point of this.attackPoints) {
// 检查是否有障碍物在攻击点附近(例如30像素内)
point.isObstructed = obstaclePositions.some(obstaclePos =>
Vec2.distance(obstaclePos, point.position) < 30
);
}
}
// 处理攻击
takeDamage(pointId: string, damage: number): boolean {
const point = this.attackPoints.find(p => p.id === pointId);
if (!point) return false;
point.health -= damage;
if (point.health <= 0) {
point.health = 0;
return true; // 该点已被摧毁
}
return false;
}
// 获取城墙位置信息
getWallRect(): Rect {
return this.wallRect;
}
// 获取所有攻击点
getAllAttackPoints(): WallAttackPoint[] {
return [...this.attackPoints];
}
}