From 3b41a3fcd050eeeb91f3ea920dc2e2f1c7bbc5f0 Mon Sep 17 00:00:00 2001 From: "DESKTOP-J7I1C4E\\a9350" Date: Mon, 18 Mar 2024 15:43:54 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9C=B0=E5=9D=97=E7=9A=84=E9=BC=A0=E6=A0=87?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/Script/MapTileButtonComponent.ts | 250 +++++++++++++------- assets/Script/common/InDiamondCheck.ts | 40 ++++ assets/Script/common/InDiamondCheck.ts.meta | 9 + 3 files changed, 208 insertions(+), 91 deletions(-) create mode 100644 assets/Script/common/InDiamondCheck.ts create mode 100644 assets/Script/common/InDiamondCheck.ts.meta diff --git a/assets/Script/MapTileButtonComponent.ts b/assets/Script/MapTileButtonComponent.ts index ec9284a..7ae34a9 100644 --- a/assets/Script/MapTileButtonComponent.ts +++ b/assets/Script/MapTileButtonComponent.ts @@ -1,104 +1,172 @@ -import { _decorator, Color, Component, EventMouse, Node, Sprite, UITransform, v2 } from 'cc'; -import { NpkImage } from '../Tool/NPKImage'; -import { MapTileDirection } from './MapTileData'; -import { BaseSprite } from '../GlobalScript/CommonComponent/BaseSprite'; -const { ccclass, property } = _decorator; +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, +enum buttonState { + // 普通 + Normal, + // 悬停 + Hover, + // // 按下 + // Down, } - -@ccclass('MapTileButtonComponent') +@ccclass("MapTileButtonComponent") export class MapTileButtonComponent extends Component { + direction: MapTileDirection; - direction: MapTileDirection; - - /// 状态 - 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); + 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; + } + } - update(deltaTime: number) { - if (this.SpriteObj){ - switch (this.state) { - case buttonState.Normal: - this.SpriteObj.color = Color.WHITE; - break; - case buttonState.Hover: - this.SpriteObj.color = Color.YELLOW; - break; - } - } - } + //精灵对象 + private SpriteObj: Sprite; - OnHover(event: EventMouse) { - this.state = buttonState.Normal; - } - 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); - } + start() { + this.position = this.node.getPosition(); - OnUp(event: EventMouse) { - //必须是鼠标左键 - if (event.getButton() != EventMouse.BUTTON_LEFT) return; - this.state = buttonState.Normal; - const np = this.node.position; - this.node.setPosition(np.x,np.y +1); + 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 }, + ]; + } + } } - - diff --git a/assets/Script/common/InDiamondCheck.ts b/assets/Script/common/InDiamondCheck.ts new file mode 100644 index 0000000..57b035b --- /dev/null +++ b/assets/Script/common/InDiamondCheck.ts @@ -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); + } +} diff --git a/assets/Script/common/InDiamondCheck.ts.meta b/assets/Script/common/InDiamondCheck.ts.meta new file mode 100644 index 0000000..fe496bb --- /dev/null +++ b/assets/Script/common/InDiamondCheck.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.23", + "importer": "typescript", + "imported": true, + "uuid": "fe6e16c8-0a04-45bb-b297-1cadc596dd64", + "files": [], + "subMetas": {}, + "userData": {} +}