mirror of
https://gitee.com/dgflash/oops-framework.git
synced 2026-06-18 19:52:10 +08:00
添加游戏特效管理
This commit is contained in:
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"ver": "1.1.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "cc263b2f-8b27-4e4e-bad4-3860c593e0b3",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"compressionType": {},
|
||||
"isRemoteBundle": {}
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
import { Component, _decorator } from "cc";
|
||||
import { EventDispatcher } from "../event/EventDispatcher";
|
||||
|
||||
const { ccclass } = _decorator;
|
||||
|
||||
@ccclass("GameComponent")
|
||||
export class GameComponent extends Component {
|
||||
private _eventDispatcher: EventDispatcher | null = null;
|
||||
|
||||
public get eventDispatcher(): EventDispatcher {
|
||||
if (!this._eventDispatcher) {
|
||||
this._eventDispatcher = new EventDispatcher();
|
||||
}
|
||||
return this._eventDispatcher;
|
||||
}
|
||||
|
||||
// 事件是否绑定node的active
|
||||
private _isBindMessageActive: boolean = false;
|
||||
|
||||
/** 绑定node active属性,即只有active为true才会响应事件 */
|
||||
public bindMessageActive() {
|
||||
this._isBindMessageActive = true;
|
||||
}
|
||||
|
||||
/** 解绑node active属性,无论node是否可见都会响应事件 */
|
||||
public unbindMessageActive() {
|
||||
this._isBindMessageActive = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册全局事件
|
||||
* @param event(string) 事件名
|
||||
* @param listener(function) 处理事件的侦听器函数
|
||||
* @param thisObj(object) 侦听函数绑定的this对象
|
||||
*/
|
||||
public on(event: string, listener: Function, thisObj: any) {
|
||||
this.eventDispatcher.on(event, (event, args) => {
|
||||
if (!this.isValid) {
|
||||
if (this._eventDispatcher) {
|
||||
this._eventDispatcher.destroy();
|
||||
this._eventDispatcher = null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._isBindMessageActive) {
|
||||
if (this.node.active) {
|
||||
listener.call(thisObj, event, args);
|
||||
}
|
||||
}
|
||||
else {
|
||||
listener.call(thisObj, event, args);
|
||||
}
|
||||
}, thisObj);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除全局事件
|
||||
* @param event(string) 事件名
|
||||
*/
|
||||
public off(event: string) {
|
||||
if (this._eventDispatcher) {
|
||||
this._eventDispatcher.off(event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 触发全局事件
|
||||
* @param event(string) 事件名
|
||||
* @param arg(Array) 事件参数
|
||||
*/
|
||||
public dispatchEvent(event: string, arg = null) {
|
||||
this.eventDispatcher.dispatchEvent(event, arg);
|
||||
}
|
||||
|
||||
onDestroy() {
|
||||
if (this._eventDispatcher) {
|
||||
this._eventDispatcher.destroy();
|
||||
this._eventDispatcher = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "ac536f92-9564-4e5d-bcf0-cc66fb91e8aa",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"ver": "1.1.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "811237dc-e1bd-43e9-8289-793efadcea2c",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"compressionType": {},
|
||||
"isRemoteBundle": {}
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
|
||||
import { CCInteger, Component, Material, Sprite, _decorator } from 'cc';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass('Ambilight')
|
||||
/** 流光效果 */
|
||||
export class Ambilight extends Component {
|
||||
@property
|
||||
_max: number = 1;
|
||||
@property(CCInteger)
|
||||
get max(): number {
|
||||
return this._max;
|
||||
}
|
||||
set max(value: number) {
|
||||
this._max = value;
|
||||
}
|
||||
|
||||
private _start = 0;
|
||||
_material !: Material;
|
||||
|
||||
update(dt: number) {
|
||||
this._material = this.node.getComponent(Sprite)!.getMaterial(0)!;
|
||||
|
||||
if (this.node.active && this._material) {
|
||||
this._setShaderTime(dt);
|
||||
}
|
||||
}
|
||||
|
||||
private _setShaderTime(dt: number) {
|
||||
let start = this._start;
|
||||
if (start > this.max) start = 0;
|
||||
start += 0.015;
|
||||
this._material.setProperty('speed', start);
|
||||
|
||||
this._start = start;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "9a795af4-dca5-4f2c-a806-1512a89a7705",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
import { Component, Material, sp, _decorator } from 'cc';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass('FlashSpine')
|
||||
export default class FlashSpine extends Component {
|
||||
duration: number = 0.5;
|
||||
_median: number = 0;
|
||||
_time: number = 0;
|
||||
|
||||
_material: Material = null!;
|
||||
_skeleton: sp.Skeleton = null!;
|
||||
|
||||
onLoad() {
|
||||
this._median = this.duration / 2;
|
||||
// 获取材质
|
||||
this._skeleton = this.node.getComponent(sp.Skeleton)!;
|
||||
this._material = this._skeleton.customMaterial!;
|
||||
// 设置材质对应的属性
|
||||
this._material.setProperty("u_rate", 1);
|
||||
}
|
||||
|
||||
update(dt: number) {
|
||||
if (this._time > 0) {
|
||||
this._time -= dt;
|
||||
|
||||
this._time = this._time < 0 ? 0 : this._time;
|
||||
let rate = Math.abs(this._time - this._median) * 2 / this.duration;
|
||||
|
||||
let mat = new Material();
|
||||
mat.copy(this._material);
|
||||
this._skeleton.customMaterial = mat;
|
||||
mat.setProperty("u_rate", rate);
|
||||
}
|
||||
}
|
||||
|
||||
clickFlash() {
|
||||
this._time = this.duration;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "539c144b-519d-477d-84a0-4551eeacbfd9",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"simulateGlobals": []
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
import { Component, Material, Sprite, _decorator } from 'cc';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass('FlashSprite')
|
||||
export default class FlashSprite extends Component {
|
||||
duration: number = 0.5;
|
||||
_median: number = 0;
|
||||
_time: number = 0;
|
||||
|
||||
_material: Material = null!;
|
||||
|
||||
onLoad() {
|
||||
this._median = this.duration / 2;
|
||||
// 获取材质
|
||||
this._material = this.node.getComponent(Sprite)!.getMaterial(0)!;
|
||||
// 设置材质对应的属性
|
||||
this._material.setProperty("u_rate", 1);
|
||||
}
|
||||
|
||||
update(dt: number) {
|
||||
if (this._time > 0) {
|
||||
this._time -= dt;
|
||||
|
||||
this._time = this._time < 0 ? 0 : this._time;
|
||||
let rate = Math.abs(this._time - this._median) * 2 / this.duration;
|
||||
this._material.setProperty("u_rate", rate);
|
||||
}
|
||||
}
|
||||
|
||||
clickFlash() {
|
||||
this._time = this.duration;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "dce50f6b-61e2-42d0-8729-b8c9dd8f9e8e",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"simulateGlobals": []
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"ver": "1.1.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "fd6e96ff-96ce-44f0-8eda-24aaf8c2e936",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"compressionType": {},
|
||||
"isRemoteBundle": {}
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
|
||||
import { Component, gfx, macro, Material, MeshRenderer, utils, Vec3, _decorator } from 'cc';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass('DrawSectorMesh')
|
||||
/**
|
||||
* 绘制扇形网格
|
||||
*/
|
||||
export class DrawSectorMesh extends Component {
|
||||
@property({ type: Material })
|
||||
public mat: Material | null = null;
|
||||
|
||||
@property({
|
||||
tooltip: "外圈半径"
|
||||
})
|
||||
public radius: number = 5;
|
||||
|
||||
@property({
|
||||
tooltip: "内圈半径"
|
||||
})
|
||||
public innerRadius: number = 1;
|
||||
|
||||
@property({
|
||||
tooltip: "扇形角度"
|
||||
})
|
||||
public angledegree: number = 60;
|
||||
|
||||
start() {
|
||||
this.createMesh()
|
||||
}
|
||||
|
||||
createMesh() {
|
||||
const model = this.addComponent(MeshRenderer)!;
|
||||
const segments: number = Math.floor(this.angledegree / 4) + 1; // 三角形个数(平滑度)
|
||||
|
||||
var positions: number[] = []; // 顶点位置数据
|
||||
|
||||
// 组装顶点数据
|
||||
var vertices_count: number = segments * 2 + 2; // vertices(顶点)的个数与triangles(索引三角形顶点数)匹配
|
||||
var vertices: Array<Vec3> = new Array<Vec3>(vertices_count);
|
||||
var angleRad: number = this.angledegree * macro.RAD; // 角度转弧度
|
||||
var angleCur: number = angleRad;
|
||||
var angledelta: number = angleRad / segments; // 每个三角形的弧度
|
||||
for (var i = 0; i < vertices_count; i += 2) { // 扇形每二个三角形之间共用2个顶点,所有生成时每次循环生成二个顶点
|
||||
var cosA: number = Math.cos(angleCur);
|
||||
var sinA: number = Math.sin(angleCur);
|
||||
|
||||
vertices[i] = new Vec3(this.radius * cosA, 0, this.radius * sinA); // 已知扇形外圈半径为斜边求x、z值,得到第一个顶点位置(外圈半径顶点)
|
||||
vertices[i + 1] = new Vec3(this.innerRadius * cosA, 0, this.innerRadius * sinA); // 已知扇形内圈半径为斜边求x、z值,得到第二个顶点位置(内圈半径顶点)
|
||||
angleCur -= angledelta;
|
||||
|
||||
positions.push(vertices[i].x);
|
||||
positions.push(vertices[i].y);
|
||||
positions.push(vertices[i].z);
|
||||
positions.push(vertices[i + 1].x);
|
||||
positions.push(vertices[i + 1].y);
|
||||
positions.push(vertices[i + 1].z);
|
||||
}
|
||||
|
||||
|
||||
// 组装三角形数据
|
||||
var indice_count: number = segments * 6; // 扇形外圈与扇形内圈会生成一个四边形,即二个三角形,6个顶点索引
|
||||
var indices: Array<number> = new Array<number>(indice_count);
|
||||
for (var i = 0, vi = 0; i < indice_count; i += 6, vi += 2) { // i为三角形顶点索引号,vi为顶点位置索引
|
||||
indices[i] = vi;
|
||||
indices[i + 1] = vi + 3;
|
||||
indices[i + 2] = vi + 1;
|
||||
indices[i + 3] = vi + 2;
|
||||
indices[i + 4] = vi + 3;
|
||||
indices[i + 5] = vi;
|
||||
}
|
||||
|
||||
// 组装UV数据
|
||||
var uvs: number[] = [];
|
||||
for (var i = 0; i < vertices_count; i++) {
|
||||
var u = vertices[i].x / this.radius / 2 + 0.5
|
||||
var v = vertices[i].z / this.radius / 2 + 0.5
|
||||
uvs.push(u, v);
|
||||
}
|
||||
|
||||
const primitiveMode = gfx.PrimitiveMode.TRIANGLE_FAN;
|
||||
const attributes: any[] = [{
|
||||
name: gfx.AttributeName.ATTR_NORMAL,
|
||||
format: gfx.Format.RGB32F,
|
||||
}];
|
||||
|
||||
var IGeometry = {
|
||||
positions: positions,
|
||||
indices: indices,
|
||||
uvs: uvs,
|
||||
primitiveMode: primitiveMode, // 默认值效果一样,需要研究作用
|
||||
attributes: attributes // 默认值效果一样,需要研究作用
|
||||
}
|
||||
|
||||
const mesh = utils.createMesh(IGeometry);
|
||||
model.mesh = mesh;
|
||||
model.material = this.mat;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "16f74800-b991-41f0-9345-1e8ef3d4c7b1",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"simulateGlobals": []
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user