173 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
			
		
		
	
	
			173 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
| import {
 | |
|   _decorator,
 | |
|   Color,
 | |
|   Component,
 | |
|   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 {
 | |
|   // 普通
 | |
|   Normal,
 | |
|   // 悬停
 | |
|   Hover,
 | |
|   // // 按下
 | |
|   // Down,
 | |
| }
 | |
| 
 | |
| @ccclass("MapTileButtonComponent")
 | |
| export class MapTileButtonComponent extends Component {
 | |
|   direction: MapTileDirection;
 | |
| 
 | |
|   private position: Vec3;
 | |
| 
 | |
|   /// 状态
 | |
|   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;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   //精灵对象
 | |
|   private SpriteObj: Sprite;
 | |
| 
 | |
|   start() {
 | |
|     this.position = this.node.getPosition();
 | |
| 
 | |
|     if (!this.node.getComponent(UITransform)) {
 | |
|       this.node.addComponent(UITransform);
 | |
|     }
 | |
|     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 },
 | |
|         ];
 | |
|     }
 | |
|   }
 | |
| }
 |