地块的鼠标事件处理
This commit is contained in:
		
							parent
							
								
									5634aec7a9
								
							
						
					
					
						commit
						3b41a3fcd0
					
				|  | @ -1,104 +1,172 @@ | ||||||
| import { _decorator, Color, Component, EventMouse, Node, Sprite, UITransform, v2 } from 'cc'; | import { | ||||||
| import { NpkImage } from '../Tool/NPKImage'; |   _decorator, | ||||||
| import { MapTileDirection } from './MapTileData'; |   Color, | ||||||
| import { BaseSprite } from '../GlobalScript/CommonComponent/BaseSprite'; |   Component, | ||||||
| const { ccclass, property } = _decorator; |   EventMouse, | ||||||
|  |   Node, | ||||||
|  |   Sprite, | ||||||
|  |   UITransform, | ||||||
|  |   v2, | ||||||
|  |   v3, | ||||||
|  |   Vec3, | ||||||
|  | } from "cc"; | ||||||
|  | import { NpkImage } from "../Tool/NPKImage"; | ||||||
|  | import { MapTileDirection } from "./MapTileData"; | ||||||
|  | import { BaseSprite } from "../GlobalScript/CommonComponent/BaseSprite"; | ||||||
|  | import { DiamondCheck, Point } from "./common/InDiamondCheck"; | ||||||
|  | const { ccclass } = _decorator; | ||||||
| 
 | 
 | ||||||
| 
 | enum buttonState { | ||||||
| enum buttonState{ |   // 普通
 | ||||||
|     // 普通
 |   Normal, | ||||||
|     Normal, |   // 悬停
 | ||||||
|     // 悬停
 |   Hover, | ||||||
|     Hover, |   // // 按下
 | ||||||
|     // // 按下
 |   // Down,
 | ||||||
|     // Down,
 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | @ccclass("MapTileButtonComponent") | ||||||
| @ccclass('MapTileButtonComponent') |  | ||||||
| export class MapTileButtonComponent extends Component { | export class MapTileButtonComponent extends Component { | ||||||
|  |   direction: MapTileDirection; | ||||||
| 
 | 
 | ||||||
|     direction: MapTileDirection; |   private position: Vec3; | ||||||
| 
 |  | ||||||
|     /// 状态
 |  | ||||||
|     state: buttonState = buttonState.Normal; |  | ||||||
| 
 |  | ||||||
|     //精灵对象
 |  | ||||||
|     private SpriteObj: Sprite; |  | ||||||
| 
 |  | ||||||
|     start() { |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|         // //判断是否有精灵 如果没有 就给他搞一个
 |  | ||||||
|         // if (this.node.getComponent(Sprite))
 |  | ||||||
|         //     this.SpriteObj = this.node.getComponent(Sprite);
 |  | ||||||
|         // else
 |  | ||||||
|         //     this.SpriteObj = this.node.addComponent(Sprite);
 |  | ||||||
| 
 |  | ||||||
|         // //设置节点锚点为左上角
 |  | ||||||
|         // this.node.getComponent(UITransform).anchorPoint = v2(0, 1);
 |  | ||||||
|         // //设置类型
 |  | ||||||
|         // this.SpriteObj.sizeMode = Sprite.SizeMode.RAW;
 |  | ||||||
|         // //设置
 |  | ||||||
|         // this.SpriteObj.trim = false;
 |  | ||||||
| 
 |  | ||||||
|         const bs = this.node.addComponent( BaseSprite ); |  | ||||||
|         this.SpriteObj = bs.SpriteObj; |  | ||||||
| 
 |  | ||||||
|         let index = 24; |  | ||||||
|         switch (this.direction) { |  | ||||||
|             case MapTileDirection.horizontal: |  | ||||||
|                 index = 24; |  | ||||||
|             case MapTileDirection.vertical: |  | ||||||
|                 index = 25; |  | ||||||
|             case MapTileDirection.nook: |  | ||||||
|                 index = 26; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         bs.updateSpriteFrame(NpkImage.board,index); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|         this.node.on(Node.EventType.MOUSE_ENTER, this.OnHover, this); |  | ||||||
|         this.node.on(Node.EventType.MOUSE_LEAVE, this.OffHover, this); |  | ||||||
|         this.node.on(Node.EventType.MOUSE_DOWN, this.OnDown, this); |  | ||||||
|         // this.node.on(Node.EventType.MOUSE_UP, this.OnUp, this);
 |  | ||||||
| 
 | 
 | ||||||
|  |   /// 状态
 | ||||||
|  |   set state(newState: buttonState) { | ||||||
|  |     if (!this.SpriteObj) { | ||||||
|  |       this.SpriteObj = this.node.getComponent(Sprite); | ||||||
|     } |     } | ||||||
|  |     switch (newState) { | ||||||
|  |       case buttonState.Normal: | ||||||
|  |         this.SpriteObj.color = Color.WHITE; | ||||||
|  |         break; | ||||||
|  |       case buttonState.Hover: | ||||||
|  |         this.SpriteObj.color = Color.YELLOW; | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|     update(deltaTime: number) { |   //精灵对象
 | ||||||
|         if (this.SpriteObj){ |   private SpriteObj: Sprite; | ||||||
|             switch (this.state) { |  | ||||||
|                 case buttonState.Normal: |  | ||||||
|                     this.SpriteObj.color = Color.WHITE; |  | ||||||
|                     break; |  | ||||||
|                 case buttonState.Hover: |  | ||||||
|                     this.SpriteObj.color = Color.YELLOW; |  | ||||||
|                     break; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     OnHover(event: EventMouse) { |   start() { | ||||||
|         this.state = buttonState.Normal; |     this.position = this.node.getPosition(); | ||||||
|     } |  | ||||||
|     OffHover(event: EventMouse) { |  | ||||||
|         this.state = buttonState.Hover; |  | ||||||
|     } |  | ||||||
|     /// 按下就选择
 |  | ||||||
|     OnDown(event: EventMouse) { |  | ||||||
|         // if (event.getButton() != EventMouse.BUTTON_LEFT) return;
 |  | ||||||
|         // const np = this.node.position;
 |  | ||||||
|         // this.node.setPosition(np.x,np.y -1);
 |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     OnUp(event: EventMouse) { |     if (!this.node.getComponent(UITransform)) { | ||||||
|         //必须是鼠标左键
 |       this.node.addComponent(UITransform); | ||||||
|         if (event.getButton() != EventMouse.BUTTON_LEFT) return; |  | ||||||
|         this.state = buttonState.Normal; |  | ||||||
|         const np = this.node.position; |  | ||||||
|         this.node.setPosition(np.x,np.y +1); |  | ||||||
|     } |     } | ||||||
|  |     this.node.getComponent(UITransform).anchorPoint = v2(0, 0); | ||||||
| 
 | 
 | ||||||
|  |     const bs = this.node.addComponent(BaseSprite); | ||||||
|  |     bs.updateSpriteFrame(NpkImage.board, this.direction); | ||||||
|  | 
 | ||||||
|  |     // this.node.on(Node.EventType.MOUSE_ENTER, this.OnHover, this);
 | ||||||
|  |     this.node.on(Node.EventType.MOUSE_LEAVE, this.OffHover, this); | ||||||
|  |     this.node.on(Node.EventType.MOUSE_DOWN, this.onEvent, this); | ||||||
|  |     this.node.on(Node.EventType.MOUSE_UP, this.onEvent, this); | ||||||
|  |     this.node.on(Node.EventType.MOUSE_MOVE, this.onEvent, this); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   update(deltaTime: number) {} | ||||||
|  | 
 | ||||||
|  |   /// 事件的统一处理
 | ||||||
|  |   onEvent(event: EventMouse) { | ||||||
|  |     /// 判断是否在矩形范围内
 | ||||||
|  |     const inDiamond = this.getEventDiamond(event); | ||||||
|  |     if (inDiamond) { | ||||||
|  |       this.OnHover(); | ||||||
|  | 
 | ||||||
|  |       switch (event.type) { | ||||||
|  |         case Node.EventType.MOUSE_DOWN: | ||||||
|  |             this.OnDown(event); | ||||||
|  |           break; | ||||||
|  |         case Node.EventType.MOUSE_UP: | ||||||
|  |             this.OnUp(event); | ||||||
|  |           break; | ||||||
|  |       } | ||||||
|  |     } else { | ||||||
|  |       // 结束悬浮状态
 | ||||||
|  |       this.OffHover(); | ||||||
|  |       // 事件穿透
 | ||||||
|  |       event.preventSwallow = true; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   // 鼠标悬浮状态
 | ||||||
|  |   OnHover() { | ||||||
|  |     this.state = buttonState.Hover; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   // 鼠标悬浮状态结束
 | ||||||
|  |   OffHover() { | ||||||
|  |     this.state = buttonState.Normal; | ||||||
|  |     this.node.setPosition(this.position); | ||||||
|  |   } | ||||||
|  |   /// 按下
 | ||||||
|  |   OnDown(event: EventMouse) { | ||||||
|  |     if (event.getButton() != EventMouse.BUTTON_LEFT) return; | ||||||
|  |     const np = this.node.position; | ||||||
|  |     this.node.setPosition(np.x, np.y - 1); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   OnUp(event: EventMouse) { | ||||||
|  |     //必须是鼠标左键
 | ||||||
|  |     if (event.getButton() != EventMouse.BUTTON_LEFT) return; | ||||||
|  |     const np = this.node.position; | ||||||
|  |     this.node.setPosition(this.position); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   // 判断事件是否在矩形内
 | ||||||
|  |   getEventDiamond(event: EventMouse): boolean { | ||||||
|  |     const point = event.getLocation(); | ||||||
|  |     // 转换获取到 node 内的坐标
 | ||||||
|  |     const location = this.node | ||||||
|  |       .getComponent(UITransform) | ||||||
|  |       .convertToNodeSpaceAR(v3(point.x, point.y, 0)); | ||||||
|  |     // 是否在图片的菱形范围内
 | ||||||
|  |     const inDiamond = DiamondCheck.isPointInDiamond( | ||||||
|  |       { x: location.x, y: location.y }, | ||||||
|  |       this.getDiamond() | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     return inDiamond; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   // 判断坐标是否在矩形内部
 | ||||||
|  |   getDiamond(): [Point, Point, Point, Point] { | ||||||
|  |     let w = 58.5; | ||||||
|  |     let h = 37.5; | ||||||
|  |     let hc = 10; | ||||||
|  |     let wc = 17; | ||||||
|  | 
 | ||||||
|  |     switch (this.direction) { | ||||||
|  |       case MapTileDirection.nook: | ||||||
|  |         w = 58.5; | ||||||
|  |         h = 37.5; | ||||||
|  |         return [ | ||||||
|  |           { x: w, y: 0 }, | ||||||
|  |           { x: w + w, y: -h }, | ||||||
|  |           { x: w, y: -h - h }, | ||||||
|  |           { x: 0, y: -h }, | ||||||
|  |         ]; | ||||||
|  |       case MapTileDirection.horizontal: | ||||||
|  |         w = 42; | ||||||
|  |         h = 27; | ||||||
|  |         return [ | ||||||
|  |           { x: w + wc, y: 0 }, | ||||||
|  |           { x: w + w + wc, y: -h }, | ||||||
|  |           { x: w, y: -h - h - hc }, | ||||||
|  |           { x: 0, y: -h - hc }, | ||||||
|  |         ]; | ||||||
|  |       case MapTileDirection.vertical: | ||||||
|  |         w = 42; | ||||||
|  |         h = 27; | ||||||
|  |         return [ | ||||||
|  |           { x: w, y: 0 }, | ||||||
|  |           { x: w + w + wc, y: -h - hc }, | ||||||
|  |           { x: w + wc, y: -h - h - hc }, | ||||||
|  |           { x: 0, y: -h }, | ||||||
|  |         ]; | ||||||
|  |     } | ||||||
|  |   } | ||||||
| } | } | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|  |  | ||||||
|  | @ -0,0 +1,40 @@ | ||||||
|  | export type Point = { | ||||||
|  |   x: number; | ||||||
|  |   y: number; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export class DiamondCheck { | ||||||
|  |   // 计算两个向量的叉积的绝对值
 | ||||||
|  |   static crossProduct(a: Point, b: Point, p: Point): number { | ||||||
|  |     return (b.x - a.x) * (p.y - a.y) - (b.y - a.y) * (p.x - a.x); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   // 判断点p是否在由顶点a, b, c, d定义的多边形内部
 | ||||||
|  |   static isPointInDiamond( | ||||||
|  |     point: Point, | ||||||
|  |     diamondCoords: [Point,Point,Point,Point] | ||||||
|  |   ): boolean { | ||||||
|  | 
 | ||||||
|  |     const [a,b,c,d] = diamondCoords; | ||||||
|  | 
 | ||||||
|  |     // 计算多边形的边
 | ||||||
|  |     const ab = { x: b.x - a.x, y: b.y - a.y }; | ||||||
|  |     const bc = { x: c.x - b.x, y: c.y - b.y }; | ||||||
|  |     const cd = { x: d.x - c.x, y: d.y - c.y }; | ||||||
|  |     const da = { x: a.x - d.x, y: a.y - d.y }; | ||||||
|  | 
 | ||||||
|  |     // 计算点p与多边形每条边的叉积
 | ||||||
|  |     const abP = DiamondCheck.crossProduct(a, b, point); | ||||||
|  |     const bcP = DiamondCheck.crossProduct(b, c, point); | ||||||
|  |     const cdP = DiamondCheck.crossProduct(c, d, point); | ||||||
|  |     const daP = DiamondCheck.crossProduct(d, a, point); | ||||||
|  | 
 | ||||||
|  |     // 如果所有叉积的符号一致(即绝对值相同),点p在多边形内部
 | ||||||
|  |     const allSameSign = (a: number, b: number, c: number, d: number): boolean => | ||||||
|  |       Math.sign(a) === Math.sign(b) && | ||||||
|  |       Math.sign(b) === Math.sign(c) && | ||||||
|  |       Math.sign(c) === Math.sign(d); | ||||||
|  | 
 | ||||||
|  |     return allSameSign(abP, bcP, cdP, daP); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,9 @@ | ||||||
|  | { | ||||||
|  |   "ver": "4.0.23", | ||||||
|  |   "importer": "typescript", | ||||||
|  |   "imported": true, | ||||||
|  |   "uuid": "fe6e16c8-0a04-45bb-b297-1cadc596dd64", | ||||||
|  |   "files": [], | ||||||
|  |   "subMetas": {}, | ||||||
|  |   "userData": {} | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue