From 2d78f1c6801e757e5bc747854426be89c8fcf84d Mon Sep 17 00:00:00 2001
From: luxiaotao1123 <t1341870251@163.com>
Date: 星期三, 09 十月 2024 14:06:25 +0800
Subject: [PATCH] #

---
 zy-acs-flow/src/map/tool.js     |   74 ++++++++++++++++++
 zy-acs-flow/src/map/player.js   |  139 ++++++++++++++++++++++++++++++++++
 zy-acs-flow/src/map/MapPage.jsx |   15 +++
 3 files changed, 228 insertions(+), 0 deletions(-)

diff --git a/zy-acs-flow/src/map/MapPage.jsx b/zy-acs-flow/src/map/MapPage.jsx
index e7dd074..a668653 100644
--- a/zy-acs-flow/src/map/MapPage.jsx
+++ b/zy-acs-flow/src/map/MapPage.jsx
@@ -77,13 +77,28 @@
             case MapMode.OBSERVER_MODE:
                 setDeviceVisible(false);
                 player.hideGridLines();
+
+                player.activateMapMultiSelect((selectedSprites, resetFn) => {
+                    console.log(selectedSprites);
+                });
+
                 break
             case MapMode.MOVABLE_MODE:
                 player.showGridLines();
+
+                player.activateMapMultiSelect((selectedSprites, resetFn) => {
+                    Tool.spriteListBeMovable(selectedSprites, () => {
+                        // resetFn();
+                    });
+                });
                 break
             case MapMode.SETTINGS_MODE:
                 player.hideGridLines();
                 setDeviceVisible(false);
+
+                player.activateMapMultiSelect((selectedSprites, resetFn) => {
+                    console.log(selectedSprites);
+                });
                 break
             default:
                 break
diff --git a/zy-acs-flow/src/map/player.js b/zy-acs-flow/src/map/player.js
index 5a1112d..2dfc06d 100644
--- a/zy-acs-flow/src/map/player.js
+++ b/zy-acs-flow/src/map/player.js
@@ -1,5 +1,6 @@
 import * as PIXI from 'pixi.js';
 import * as TWEEDLE from 'tweedle.js';
+import * as Tool from './tool';
 
 export default class Player {
 
@@ -27,6 +28,99 @@
             bunny.rotation += 0.1 * delta;
         });
 
+    }
+
+    activateMapMultiSelect = (fn) => {
+        const mapMultiSelectHandle = (event) => {
+            console.log(123);
+            
+            if (event.button !== 0) {
+                return;
+            }
+
+            let isSelecting = false;
+            if (!this.selectionBox) {
+                this.selectionBox = new PIXI.Graphics();
+                this.app.stage.addChild(this.selectionBox);
+            }
+
+            // select start pos
+            const startPoint = new PIXI.Point();
+            this.app.renderer.events.mapPositionToPoint(startPoint, event.clientX, event.clientY);
+            let selectionStart = { x: startPoint.x, y: startPoint.y };
+
+            // avoid trigger sprite event
+            let hasHitSprite = false;
+            for (let child of this.mapContainer.children) {
+                if (child.data?.uuid) {
+                    if (child.getBounds().contains(selectionStart.x, selectionStart.y)) {
+                        hasHitSprite = true; break;
+                    }
+                }
+            }
+
+            if (!hasHitSprite) {
+                isSelecting = true;
+            }
+
+            const handleMouseMove = (event) => {
+                if (isSelecting) {
+                    // select end pos
+                    const endPoint = new PIXI.Point();
+                    this.app.renderer.events.mapPositionToPoint(endPoint, event.clientX, event.clientY);
+                    const selectionEnd = { x: endPoint.x, y: endPoint.y }
+
+                    const width = Math.abs(selectionEnd.x - selectionStart.x);
+                    const height = Math.abs(selectionEnd.y - selectionStart.y);
+
+                    this.selectionBox.clear();
+                    this.selectionBox.lineStyle(2, 0xCCCCCC, 1);
+                    this.selectionBox.beginFill(0xCCCCCC, 0.2);
+                    this.selectionBox.drawRect(Math.min(selectionStart.x, selectionEnd.x), Math.min(selectionStart.y, selectionEnd.y), width, height);
+                    this.selectionBox.endFill();
+                }
+            }
+
+            this.mapContainer.parent.on('mousemove', handleMouseMove);
+
+            this.mapContainer.parent.on('mouseup', (event) => {
+                if (isSelecting) {
+                    this.clearSelectedSprites();
+
+                    // sprite show style which be selected
+                    this.mapContainer.children.forEach(child => {
+                        if (Tool.isSpriteInSelectionBox(child, this.selectionBox)) {
+                            this.selectedSprites.push(child);
+                            Tool.markSprite(child);
+                        }
+                    })
+                    isSelecting = false;
+                    this.selectionBox.clear();
+
+                    // complete
+                    if (fn) {
+                        fn(this.selectedSprites, () => {
+                            // trigger at end of selectionBox when fn happen mouseup
+                            this.selectedSprites = [];
+                        });
+                    }
+
+                }
+
+                this.mapContainer.parent.off('mousemove', handleMouseMove);
+            });
+        }
+
+        this.mapContainer.parent.on('mousedown', mapMultiSelectHandle)
+    }
+
+    clearSelectedSprites = () => {
+        if (this.selectedSprites && this.selectedSprites.length > 0) {
+            this.selectedSprites.forEach(child => {
+                Tool.unMarkSprite(child);
+            })
+        }
+        this.selectedSprites = [];
     }
 
     activateMapScale = () => {
@@ -87,6 +181,51 @@
         this.app.view.addEventListener('mousedown', mapPanHandle);
     }
 
+    adaptScreen = () => {
+        if (!this.mapContainer || !this.app) {
+            return;
+        }
+
+        this.mapContainer.scale.set(1);
+        this.mapContainer.position.set(0, 0);
+        if (this.mapContainer.children.length === 0) {
+            return;
+        }
+
+        let minX, maxX, minY, maxY;
+        for (let sprite of this.mapContainer.children) {
+            if (sprite?.data?.uuid) {
+                let bounds = sprite.getBounds();
+                minX = minX !== undefined ? Math.min(minX, bounds.x) : bounds.x;
+                minY = minY !== undefined ? Math.min(minY, bounds.y) : bounds.y;
+                maxX = maxX !== undefined ? Math.max(maxX, bounds.x + bounds.width) : bounds.x + bounds.width;
+                maxY = maxY !== undefined ? Math.max(maxY, bounds.y + bounds.height) : bounds.y + bounds.height;
+            }
+        }
+
+        this.scale = Math.min(
+            this.app.renderer.width / (maxX - minX) * 0.8,
+            this.app.renderer.height / (maxY - minY) * 0.8
+        );
+
+        let centerPoint = {
+            x: (minX + maxX) / 2 * this.mapContainer.scale.x,
+            y: (minY + maxY) / 2 * this.mapContainer.scale.y
+        };
+
+        new TWEEDLE.Tween(this.mapContainer.scale).easing(TWEEDLE.Easing.Quadratic.Out)
+            .to({
+                x: this.scale,
+                y: this.scale
+            }, 200).start();
+
+        new TWEEDLE.Tween(this.mapContainer.position).easing(TWEEDLE.Easing.Quadratic.Out)
+            .to({
+                x: this.app.renderer.width / 2 - centerPoint.x * this.scale,
+                y: this.app.renderer.height / 2 - centerPoint.y * this.scale
+            }, 200).start();
+    }
+
     showGridLines = () => {
         this.hideGridLines();
         if (!this.gridLineContainer) {
diff --git a/zy-acs-flow/src/map/tool.js b/zy-acs-flow/src/map/tool.js
index 63bf3cd..d8ea096 100644
--- a/zy-acs-flow/src/map/tool.js
+++ b/zy-acs-flow/src/map/tool.js
@@ -72,6 +72,14 @@
     };
 }
 
+export const markSprite = (sprite) => {
+    sprite.alpha = 0.5;
+}
+
+export const unMarkSprite = (sprite) => {
+    sprite.alpha = 1;
+}
+
 export const beMovable = (sprite) => {
     sprite.off('pointerup');
     sprite.off('pointermove');
@@ -109,6 +117,72 @@
 
 }
 
+export const spriteListBeMovable = (selectedSprites, resetFn) => {
+    if (selectedSprites && selectedSprites.length > 0) {
+        let batchMove = false;
+        let batchMoveStartPos = null;
+
+        const batchMoving = (event) => {
+            const scale = mapContainer.scale.x;
+            if (batchMove && batchMoveStartPos) {
+                // offset move val
+                var mouseMovement = {
+                    x: (event.global.x - batchMoveStartPos.x) / scale,
+                    y: (event.global.y - batchMoveStartPos.y) / scale
+                };
+                for (let sprite of selectedSprites) {
+                    sprite.position.x = sprite.batchMoveStartPos.x + mouseMovement.x;
+                    sprite.position.y = sprite.batchMoveStartPos.y + mouseMovement.y;
+                }
+            }
+        }
+
+        const batchMoveEnd = (event) => {
+            batchMove = false;
+            batchMoveStartPos = null;
+            selectedSprites.forEach(child => {
+                unMarkSprite(child);
+            })
+            selectedSprites = [];
+            mapContainer.parent.off('mousedown');
+            mapContainer.parent.off('mousemove');
+            mapContainer.parent.off('mouseup');
+
+            if (resetFn) {
+                resetFn();
+            }
+        }
+
+        const batchMoveStart = (event) => {
+            batchMoveStartPos = { x: event.data.global.clone().x, y: event.data.global.clone().y };
+            selectedSprites.forEach(child => {
+                child.batchMoveStartPos = { x: child.position.x, y: child.position.y };
+            })
+
+            batchMove = true;
+            mapContainer.parent.off('mousemove');
+            mapContainer.parent.on('mousemove', batchMoving);
+
+            mapContainer.parent.off('mouseup');
+            mapContainer.parent.on('mouseup', batchMoveEnd);
+        }
+
+        mapContainer.parent.off('mousedown')
+        mapContainer.parent.on('mousedown', batchMoveStart);
+    }
+}
+
+export const isSpriteInSelectionBox = (sprite, selectionBox) => {
+    const spriteBounds = sprite.getBounds();
+    const boxBounds = selectionBox.getBounds();
+
+    return spriteBounds.x + spriteBounds.width > boxBounds.x
+        && spriteBounds.x < boxBounds.x + boxBounds.width
+        && spriteBounds.y + spriteBounds.height > boxBounds.y
+        && spriteBounds.y < boxBounds.y + boxBounds.height;
+}
+
+
 export const generateID = () => {
     return Date.now().toString(36) + Math.random().toString(36).substring(2);
 }

--
Gitblit v1.9.1