地块的鼠标事件处理

This commit is contained in:
DESKTOP-J7I1C4E\a9350 2024-03-18 15:43:54 +08:00
parent 5634aec7a9
commit 3b41a3fcd0
3 changed files with 208 additions and 91 deletions

View File

@ -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 },
];
}
}
}

View File

@ -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);
}
}

View File

@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "fe6e16c8-0a04-45bb-b297-1cadc596dd64",
"files": [],
"subMetas": {},
"userData": {}
}