|
|
@@ -1,4 +1,4 @@
|
|
|
-import { _decorator, Component, Node, Prefab, instantiate, Vec3, EventTouch, Vec2, UITransform, find } from 'cc';
|
|
|
+import { _decorator, Component, Node, Prefab, instantiate, Vec3, EventTouch, Vec2, UITransform, find, Rect, Label, Color, Size } from 'cc';
|
|
|
const { ccclass, property } = _decorator;
|
|
|
|
|
|
@ccclass('BlockManager')
|
|
|
@@ -14,6 +14,26 @@ export class BlockManager extends Component {
|
|
|
})
|
|
|
public gridContainer: Node = null;
|
|
|
|
|
|
+ // 方块容器节点(kuang)
|
|
|
+ @property({
|
|
|
+ type: Node,
|
|
|
+ tooltip: '拖拽kuang节点到这里'
|
|
|
+ })
|
|
|
+ public kuangContainer: Node = null;
|
|
|
+
|
|
|
+ // 金币标签节点
|
|
|
+ @property({
|
|
|
+ type: Node,
|
|
|
+ tooltip: '拖拽CoinLabel节点到这里'
|
|
|
+ })
|
|
|
+ public coinLabelNode: Node = null;
|
|
|
+
|
|
|
+ // 玩家金币数量
|
|
|
+ private playerCoins: number = 200;
|
|
|
+
|
|
|
+ // 方块价格标签映射
|
|
|
+ private blockPriceMap: Map<Node, Node> = new Map();
|
|
|
+
|
|
|
// 已经生成的块
|
|
|
private blocks: Node[] = [];
|
|
|
// 当前拖拽的块
|
|
|
@@ -34,9 +54,13 @@ export class BlockManager extends Component {
|
|
|
// 网格间距
|
|
|
private gridSpacing = 54;
|
|
|
// 不参与占用的节点名称列表
|
|
|
- private readonly NON_BLOCK_NODES: string[] = ['Weapon'];
|
|
|
+ private readonly NON_BLOCK_NODES: string[] = ['Weapon', 'Price'];
|
|
|
// 临时保存方块的原始占用格子
|
|
|
private tempRemovedOccupiedGrids: { block: Node, occupiedGrids: { row: number, col: number }[] }[] = [];
|
|
|
+ // 方块原始位置(在kuang中的位置)
|
|
|
+ private originalPositions: Map<Node, Vec3> = new Map();
|
|
|
+ // 方块当前所在的区域
|
|
|
+ private blockLocations: Map<Node, string> = new Map();
|
|
|
|
|
|
start() {
|
|
|
// 如果没有指定GridContainer,尝试找到它
|
|
|
@@ -48,6 +72,27 @@ export class BlockManager extends Component {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // 如果没有指定kuangContainer,尝试找到它
|
|
|
+ if (!this.kuangContainer) {
|
|
|
+ this.kuangContainer = find('Canvas/GameLevelUI/kuang');
|
|
|
+ if (!this.kuangContainer) {
|
|
|
+ console.error('找不到kuang节点');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果没有指定coinLabelNode,尝试找到它
|
|
|
+ if (!this.coinLabelNode) {
|
|
|
+ this.coinLabelNode = find('Canvas/GameLevelUI/CoinNode/CoinLabel');
|
|
|
+ if (!this.coinLabelNode) {
|
|
|
+ console.error('找不到CoinLabel节点');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 初始化玩家金币显示
|
|
|
+ this.updateCoinDisplay();
|
|
|
+
|
|
|
// 初始化网格信息
|
|
|
this.initGridInfo();
|
|
|
|
|
|
@@ -58,6 +103,16 @@ export class BlockManager extends Component {
|
|
|
this.generateRandomBlocks();
|
|
|
}
|
|
|
|
|
|
+ // 更新金币显示
|
|
|
+ updateCoinDisplay() {
|
|
|
+ if (this.coinLabelNode) {
|
|
|
+ const label = this.coinLabelNode.getComponent(Label);
|
|
|
+ if (label) {
|
|
|
+ label.string = this.playerCoins.toString();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
// 初始化网格信息
|
|
|
initGridInfo() {
|
|
|
if (!this.gridContainer || this.gridInitialized) return;
|
|
|
@@ -139,14 +194,114 @@ export class BlockManager extends Component {
|
|
|
// 设置位置
|
|
|
block.position = offsets[i];
|
|
|
|
|
|
+ // 保存原始位置
|
|
|
+ this.originalPositions.set(block, offsets[i].clone());
|
|
|
+
|
|
|
+ // 标记方块位置为kuang
|
|
|
+ this.blockLocations.set(block, 'kuang');
|
|
|
+
|
|
|
// 添加到块数组
|
|
|
this.blocks.push(block);
|
|
|
|
|
|
+ // 查找并保存价格标签节点
|
|
|
+ this.findAndSavePriceNode(block);
|
|
|
+
|
|
|
// 添加触摸事件
|
|
|
this.setupDragEvents(block);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // 查找并保存价格标签节点
|
|
|
+ findAndSavePriceNode(block: Node) {
|
|
|
+ // 查找db01节点
|
|
|
+ let db01 = block.getChildByName('db01');
|
|
|
+
|
|
|
+ // 如果没有db01节点,创建一个
|
|
|
+ if (!db01) {
|
|
|
+ db01 = new Node('db01');
|
|
|
+ block.addChild(db01);
|
|
|
+ db01.position = new Vec3(0, -80, 0); // 放在方块下方
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查找Price节点
|
|
|
+ let priceNode = db01.getChildByName('Price');
|
|
|
+
|
|
|
+ // 如果没有Price节点,创建一个
|
|
|
+ if (!priceNode) {
|
|
|
+ priceNode = new Node('Price');
|
|
|
+ db01.addChild(priceNode);
|
|
|
+
|
|
|
+ // 添加UI变换组件
|
|
|
+ const transform = priceNode.addComponent(UITransform);
|
|
|
+ transform.contentSize = new Size(80, 30);
|
|
|
+
|
|
|
+ // 添加标签组件
|
|
|
+ const label = priceNode.addComponent(Label);
|
|
|
+ label.string = this.generateRandomPrice().toString();
|
|
|
+ label.fontSize = 20;
|
|
|
+ label.color = new Color(255, 255, 0, 255); // 黄色
|
|
|
+
|
|
|
+ // 居中显示
|
|
|
+ label.horizontalAlign = Label.HorizontalAlign.CENTER;
|
|
|
+ label.verticalAlign = Label.VerticalAlign.CENTER;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 保存价格节点引用
|
|
|
+ this.blockPriceMap.set(block, priceNode);
|
|
|
+
|
|
|
+ // 确保价格标签可见
|
|
|
+ priceNode.active = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 生成随机价格
|
|
|
+ generateRandomPrice(): number {
|
|
|
+ // 生成50-100之间的随机价格
|
|
|
+ return Math.floor(Math.random() * 51) + 50;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取方块价格
|
|
|
+ getBlockPrice(block: Node): number {
|
|
|
+ const priceNode = this.blockPriceMap.get(block);
|
|
|
+ if (priceNode) {
|
|
|
+ const label = priceNode.getComponent(Label);
|
|
|
+ if (label) {
|
|
|
+ // 尝试解析价格
|
|
|
+ const price = parseInt(label.string);
|
|
|
+ if (!isNaN(price)) {
|
|
|
+ return price;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 默认价格
|
|
|
+ return 50;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 隐藏价格标签
|
|
|
+ hidePriceLabel(block: Node) {
|
|
|
+ const priceNode = this.blockPriceMap.get(block);
|
|
|
+ if (priceNode) {
|
|
|
+ priceNode.active = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 显示价格标签
|
|
|
+ showPriceLabel(block: Node) {
|
|
|
+ const priceNode = this.blockPriceMap.get(block);
|
|
|
+ if (priceNode) {
|
|
|
+ priceNode.active = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 扣除玩家金币
|
|
|
+ deductPlayerCoins(amount: number): boolean {
|
|
|
+ if (this.playerCoins >= amount) {
|
|
|
+ this.playerCoins -= amount;
|
|
|
+ this.updateCoinDisplay();
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
setupDragEvents(block: Node) {
|
|
|
// 添加触摸开始事件
|
|
|
block.on(Node.EventType.TOUCH_START, (event: EventTouch) => {
|
|
|
@@ -184,17 +339,73 @@ export class BlockManager extends Component {
|
|
|
// 添加触摸结束事件
|
|
|
block.on(Node.EventType.TOUCH_END, (event: EventTouch) => {
|
|
|
if (this.currentDragBlock) {
|
|
|
- // 尝试将方块放置到网格中
|
|
|
- if (!this.tryPlaceBlockToGrid(this.currentDragBlock)) {
|
|
|
+ // 获取当前触摸位置
|
|
|
+ const touchPos = event.getUILocation();
|
|
|
+
|
|
|
+ // 检查是否拖到了kuang区域
|
|
|
+ if (this.isInKuangArea(touchPos)) {
|
|
|
+ // 如果拖回kuang区域,恢复到原始位置
|
|
|
+ const originalPos = this.originalPositions.get(this.currentDragBlock);
|
|
|
+ if (originalPos) {
|
|
|
+ this.currentDragBlock.position = originalPos.clone();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 恢复方块原来的占用状态(如果有)
|
|
|
+ this.restoreBlockOccupiedGrids(this.currentDragBlock);
|
|
|
+
|
|
|
+ // 更新方块位置标记
|
|
|
+ this.blockLocations.set(this.currentDragBlock, 'kuang');
|
|
|
+
|
|
|
+ // 确保价格标签显示
|
|
|
+ this.showPriceLabel(this.currentDragBlock);
|
|
|
+ } else if (this.tryPlaceBlockToGrid(this.currentDragBlock)) {
|
|
|
+ // 获取方块价格
|
|
|
+ const price = this.getBlockPrice(this.currentDragBlock);
|
|
|
+
|
|
|
+ // 尝试扣除金币
|
|
|
+ if (this.deductPlayerCoins(price)) {
|
|
|
+ // 扣除成功,清除临时保存的占用状态
|
|
|
+ this.clearTempStoredOccupiedGrids(this.currentDragBlock);
|
|
|
+
|
|
|
+ // 更新方块位置标记
|
|
|
+ this.blockLocations.set(this.currentDragBlock, 'grid');
|
|
|
+
|
|
|
+ // 隐藏价格标签
|
|
|
+ this.hidePriceLabel(this.currentDragBlock);
|
|
|
+ } else {
|
|
|
+ // 金币不足,放置失败,返回原位
|
|
|
+ const originalPos = this.originalPositions.get(this.currentDragBlock);
|
|
|
+ if (originalPos) {
|
|
|
+ this.currentDragBlock.position = originalPos.clone();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 恢复方块原来的占用状态
|
|
|
+ this.restoreBlockOccupiedGrids(this.currentDragBlock);
|
|
|
+
|
|
|
+ // 确保价格标签显示
|
|
|
+ this.showPriceLabel(this.currentDragBlock);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
// 放置失败,返回原位
|
|
|
- this.currentDragBlock.position = this.blockStartPos.clone();
|
|
|
+ const currentLocation = this.blockLocations.get(this.currentDragBlock);
|
|
|
+ if (currentLocation === 'kuang') {
|
|
|
+ // 如果之前在kuang中,返回kuang中的位置
|
|
|
+ const originalPos = this.originalPositions.get(this.currentDragBlock);
|
|
|
+ if (originalPos) {
|
|
|
+ this.currentDragBlock.position = originalPos.clone();
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 否则返回拖拽开始的位置
|
|
|
+ this.currentDragBlock.position = this.blockStartPos.clone();
|
|
|
+ }
|
|
|
|
|
|
// 恢复方块原来的占用状态
|
|
|
this.restoreBlockOccupiedGrids(this.currentDragBlock);
|
|
|
- } else {
|
|
|
- // 放置成功,清除临时保存的占用状态
|
|
|
- this.clearTempStoredOccupiedGrids(this.currentDragBlock);
|
|
|
+
|
|
|
+ // 确保价格标签显示
|
|
|
+ this.showPriceLabel(this.currentDragBlock);
|
|
|
}
|
|
|
+
|
|
|
this.currentDragBlock = null;
|
|
|
}
|
|
|
}, this);
|
|
|
@@ -208,11 +419,34 @@ export class BlockManager extends Component {
|
|
|
// 恢复方块原来的占用状态
|
|
|
this.restoreBlockOccupiedGrids(this.currentDragBlock);
|
|
|
|
|
|
+ // 确保价格标签显示
|
|
|
+ this.showPriceLabel(this.currentDragBlock);
|
|
|
+
|
|
|
this.currentDragBlock = null;
|
|
|
}
|
|
|
}, this);
|
|
|
}
|
|
|
|
|
|
+ // 检查是否在kuang区域内
|
|
|
+ isInKuangArea(touchPos: Vec2): boolean {
|
|
|
+ if (!this.kuangContainer) return false;
|
|
|
+
|
|
|
+ // 获取kuang的世界矩形
|
|
|
+ const kuangTransform = this.kuangContainer.getComponent(UITransform);
|
|
|
+ if (!kuangTransform) return false;
|
|
|
+
|
|
|
+ // 计算kuang的世界边界
|
|
|
+ const kuangBoundingBox = new Rect(
|
|
|
+ this.kuangContainer.worldPosition.x - kuangTransform.width * kuangTransform.anchorX,
|
|
|
+ this.kuangContainer.worldPosition.y - kuangTransform.height * kuangTransform.anchorY,
|
|
|
+ kuangTransform.width,
|
|
|
+ kuangTransform.height
|
|
|
+ );
|
|
|
+
|
|
|
+ // 检查触摸点是否在kuang矩形内
|
|
|
+ return kuangBoundingBox.contains(new Vec2(touchPos.x, touchPos.y));
|
|
|
+ }
|
|
|
+
|
|
|
// 临时保存方块占用的网格
|
|
|
tempStoreBlockOccupiedGrids(block: Node) {
|
|
|
// 获取方块占用的网格
|
|
|
@@ -567,6 +801,15 @@ export class BlockManager extends Component {
|
|
|
}
|
|
|
this.blocks = [];
|
|
|
|
|
|
+ // 清空原始位置记录
|
|
|
+ this.originalPositions.clear();
|
|
|
+
|
|
|
+ // 清空位置标记
|
|
|
+ this.blockLocations.clear();
|
|
|
+
|
|
|
+ // 清空价格标签映射
|
|
|
+ this.blockPriceMap.clear();
|
|
|
+
|
|
|
// 重置网格占用情况
|
|
|
this.initGridOccupationMap();
|
|
|
}
|