地块的鼠标事件处理
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 { 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 },
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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