添加游戏特效管理

This commit is contained in:
dgflash
2022-04-14 19:14:33 +08:00
parent aa5a4d8215
commit dce258ef91
27 changed files with 342 additions and 71 deletions

View File

@@ -1,11 +0,0 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "16f74800-b991-41f0-9345-1e8ef3d4c7b1",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -1,5 +1,11 @@
/*
* @Author: dgflash
* @Date: 2022-04-14 17:08:01
* @LastEditors: dgflash
* @LastEditTime: 2022-04-14 19:07:39
*/
import { Component, _decorator } from "cc";
import { EventDispatcher } from "../event/EventDispatcher";
import { EventDispatcher } from "../common/event/EventDispatcher";
const { ccclass } = _decorator;
@@ -79,4 +85,4 @@ export class GameComponent extends Component {
this._eventDispatcher = null;
}
}
}
}

View File

@@ -2,7 +2,7 @@
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "ac536f92-9564-4e5d-bcf0-cc66fb91e8aa",
"uuid": "9e3f843c-2206-43f5-9b19-27b3ab93159d",
"files": [],
"subMetas": {},
"userData": {}

View File

@@ -9,7 +9,7 @@
* 6、只支持PC上使用
*/
import { CCFloat, Component, EventTouch, game, KeyCode, macro, math, systemEvent, SystemEvent, _decorator } from 'cc';
import { CCFloat, Component, EventKeyboard, EventMouse, EventTouch, game, Input, input, KeyCode, math, _decorator } from 'cc';
const { ccclass, property, menu } = _decorator;
const { Vec2, Vec3, Quat } = math;
@@ -25,11 +25,11 @@ const KEYCODE = {
D: 'D'.charCodeAt(0),
Q: 'Q'.charCodeAt(0),
E: 'E'.charCodeAt(0),
SHIFT: KeyCode.SHIFT_LEFT,
SHIFT: KeyCode.SHIFT_LEFT
};
@ccclass("FreeFlightCamera")
@menu('game/camera/FreeFlightCamera')
@menu('oops/camera/FreeFlightCamera')
export class FreeFlightCamera extends Component {
@property({
type: CCFloat,
@@ -63,27 +63,27 @@ export class FreeFlightCamera extends Component {
public _speedScale = 1;
public onLoad() {
systemEvent.on(SystemEvent.EventType.MOUSE_WHEEL, this.onMouseWheel, this);
systemEvent.on(SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);
systemEvent.on(SystemEvent.EventType.KEY_UP, this.onKeyUp, this);
systemEvent.on(SystemEvent.EventType.TOUCH_START, this.onTouchStart, this);
systemEvent.on(SystemEvent.EventType.TOUCH_MOVE, this.onTouchMove, this);
systemEvent.on(SystemEvent.EventType.TOUCH_END, this.onTouchEnd, this);
input.on(Input.EventType.MOUSE_WHEEL, this.onMouseWheel, this);
input.on(Input.EventType.KEY_DOWN, this.onKeyDown, this);
input.on(Input.EventType.KEY_UP, this.onKeyUp, this);
input.on(Input.EventType.TOUCH_START, this.onTouchStart, this);
input.on(Input.EventType.TOUCH_MOVE, this.onTouchMove, this);
input.on(Input.EventType.TOUCH_END, this.onTouchEnd, this);
Vec3.copy(this._euler, this.node.eulerAngles);
Vec3.copy(this._position, this.node.position);
}
public onDestroy() {
systemEvent.off(SystemEvent.EventType.MOUSE_WHEEL, this.onMouseWheel, this);
systemEvent.off(SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);
systemEvent.off(SystemEvent.EventType.KEY_UP, this.onKeyUp, this);
systemEvent.off(SystemEvent.EventType.TOUCH_START, this.onTouchStart, this);
systemEvent.off(SystemEvent.EventType.TOUCH_MOVE, this.onTouchMove, this);
systemEvent.off(SystemEvent.EventType.TOUCH_END, this.onTouchEnd, this);
input.off(Input.EventType.MOUSE_WHEEL, this.onMouseWheel, this);
input.off(Input.EventType.KEY_DOWN, this.onKeyDown, this);
input.off(Input.EventType.KEY_UP, this.onKeyUp, this);
input.off(Input.EventType.TOUCH_START, this.onTouchStart, this);
input.off(Input.EventType.TOUCH_MOVE, this.onTouchMove, this);
input.off(Input.EventType.TOUCH_END, this.onTouchEnd, this);
}
public update(dt) {
public update(dt: number) {
// position
Vec3.transformQuat(v3_1, this._velocity, this.node.rotation);
Vec3.scaleAndAdd(this._position, this._position, v3_1, this.moveSpeed * this._speedScale);
@@ -96,41 +96,41 @@ export class FreeFlightCamera extends Component {
this.node.setRotation(qt_1);
}
public onMouseWheel(e) {
const delta = -e.getScrollY() * this.moveSpeed * 0.1; // 向下滚动时增量为正
public onMouseWheel(event: EventMouse) {
const delta = -event.getScrollY() * this.moveSpeed * 0.1; // 向下滚动时增量为正
Vec3.transformQuat(v3_1, Vec3.UNIT_Z, this.node.rotation);
Vec3.scaleAndAdd(this._position, this.node.position, v3_1, delta);
}
public onKeyDown(e) {
public onKeyDown(event: EventKeyboard) {
const v = this._velocity;
if (e.keyCode === KEYCODE.SHIFT) { this._speedScale = this.moveSpeedShiftScale; }
else if (e.keyCode === KEYCODE.W) { if (v.z === 0) { v.z = -1; } }
else if (e.keyCode === KEYCODE.S) { if (v.z === 0) { v.z = 1; } }
else if (e.keyCode === KEYCODE.A) { if (v.x === 0) { v.x = -1; } }
else if (e.keyCode === KEYCODE.D) { if (v.x === 0) { v.x = 1; } }
else if (e.keyCode === KEYCODE.Q) { if (v.y === 0) { v.y = -1; } }
else if (e.keyCode === KEYCODE.E) { if (v.y === 0) { v.y = 1; } }
if (event.keyCode === KEYCODE.SHIFT) { this._speedScale = this.moveSpeedShiftScale; }
else if (event.keyCode === KEYCODE.W) { if (v.z === 0) { v.z = -1; } }
else if (event.keyCode === KEYCODE.S) { if (v.z === 0) { v.z = 1; } }
else if (event.keyCode === KEYCODE.A) { if (v.x === 0) { v.x = -1; } }
else if (event.keyCode === KEYCODE.D) { if (v.x === 0) { v.x = 1; } }
else if (event.keyCode === KEYCODE.Q) { if (v.y === 0) { v.y = -1; } }
else if (event.keyCode === KEYCODE.E) { if (v.y === 0) { v.y = 1; } }
}
public onKeyUp(e) {
public onKeyUp(event: EventKeyboard) {
const v = this._velocity;
if (e.keyCode === KEYCODE.SHIFT) { this._speedScale = 1; }
else if (e.keyCode === KEYCODE.W) { if (v.z < 0) { v.z = 0; } }
else if (e.keyCode === KEYCODE.S) { if (v.z > 0) { v.z = 0; } }
else if (e.keyCode === KEYCODE.A) { if (v.x < 0) { v.x = 0; } }
else if (e.keyCode === KEYCODE.D) { if (v.x > 0) { v.x = 0; } }
else if (e.keyCode === KEYCODE.Q) { if (v.y < 0) { v.y = 0; } }
else if (e.keyCode === KEYCODE.E) { if (v.y > 0) { v.y = 0; } }
if (event.keyCode === KEYCODE.SHIFT) { this._speedScale = 1; }
else if (event.keyCode === KEYCODE.W) { if (v.z < 0) { v.z = 0; } }
else if (event.keyCode === KEYCODE.S) { if (v.z > 0) { v.z = 0; } }
else if (event.keyCode === KEYCODE.A) { if (v.x < 0) { v.x = 0; } }
else if (event.keyCode === KEYCODE.D) { if (v.x > 0) { v.x = 0; } }
else if (event.keyCode === KEYCODE.Q) { if (v.y < 0) { v.y = 0; } }
else if (event.keyCode === KEYCODE.E) { if (v.y > 0) { v.y = 0; } }
}
private onTouchStart(e: EventTouch) {
if (game.canvas.requestPointerLock) { game.canvas.requestPointerLock(); }
game.canvas!.requestPointerLock();
}
private onTouchMove(e: EventTouch) {
e.getStartLocation(v2_1);
if (v2_1.x > game.canvas.width * 0.4) { // rotation
if (v2_1.x > game.canvas!.width * 0.4) { // rotation
e.getDelta(v2_2);
this._euler.y -= v2_2.x * this.rotateSpeed * 0.1; // 上下旋转
this._euler.x += v2_2.y * this.rotateSpeed * 0.1; // 左右旋转
@@ -149,9 +149,9 @@ export class FreeFlightCamera extends Component {
}
e.getStartLocation(v2_1);
if (v2_1.x < game.canvas.width * 0.4) { // position
if (v2_1.x < game.canvas!.width * 0.4) { // position
this._velocity.x = 0;
this._velocity.z = 0;
}
}
}
}

View File

@@ -2,7 +2,7 @@
"ver": "1.1.0",
"importer": "directory",
"imported": true,
"uuid": "811237dc-e1bd-43e9-8289-793efadcea2c",
"uuid": "686a8dbc-4c23-4370-a0df-420b6cc7bf38",
"files": [],
"subMetas": {},
"userData": {

View File

@@ -2,7 +2,7 @@
"ver": "1.1.0",
"importer": "directory",
"imported": true,
"uuid": "cc263b2f-8b27-4e4e-bad4-3860c593e0b3",
"uuid": "0ac8e8a4-4b4d-40f4-a03d-bd8ff1975fbd",
"files": [],
"subMetas": {},
"userData": {

View File

@@ -2,7 +2,7 @@
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "9a795af4-dca5-4f2c-a806-1512a89a7705",
"uuid": "a9730721-9420-4d2f-b869-f0b053e57b91",
"files": [],
"subMetas": {},
"userData": {}

View File

@@ -2,10 +2,8 @@
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "539c144b-519d-477d-84a0-4551eeacbfd9",
"uuid": "636cfc58-d237-4467-bf4c-700fa4962be6",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
"userData": {}
}

View File

@@ -2,10 +2,8 @@
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "dce50f6b-61e2-42d0-8729-b8c9dd8f9e8e",
"uuid": "186cb183-5126-4e4c-9c3e-59f7039f522c",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
"userData": {}
}

View File

@@ -0,0 +1,54 @@
/*
* @Author: dgflash
* @Date: 2021-10-12 14:11:04
* @LastEditors: dgflash
* @LastEditTime: 2022-04-08 15:42:16
*/
import { Component, sp, _decorator } from 'cc';
import { resLoader } from '../../../common/loader/ResLoader';
const { ccclass, property } = _decorator;
/** 动画播放完隐藏特效 */
@ccclass('SpineFinishedRelease')
export class SpineFinishedRelease extends Component {
@property
isDestroy: boolean = true;
private spine!: sp.Skeleton;
private resPath: string = null!;
/** 设置路径 */
setResPath(path: string) {
this.resPath = path;
}
onLoad() {
this.spine = this.getComponent(sp.Skeleton)!;
this.spine.setCompleteListener(this.onSpineComplete.bind(this));
if (this.resPath) {
resLoader.load(this.resPath, sp.SkeletonData, (err: Error | null, sd: sp.SkeletonData) => {
if (err) {
console.error(`加载【${this.resPath}】的 SPINE 资源不存在`);
return;
}
this.spine.skeletonData = sd;
this.spine.setAnimation(0, "animation", false);
});
}
else {
this.spine.setAnimation(0, "animation", false);
}
}
private onSpineComplete() {
if (this.isDestroy) {
this.node.destroy();
}
else {
this.node.removeFromParent();
}
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "64c1985f-3821-4347-b64f-f591eb63af6e",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,12 @@
{
"ver": "1.1.0",
"importer": "directory",
"imported": true,
"uuid": "54a3c2f0-f61b-4364-8793-152253b88559",
"files": [],
"subMetas": {},
"userData": {
"compressionType": {},
"isRemoteBundle": {}
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "41dced17-0943-4823-be09-d3349e68351f",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -2,7 +2,7 @@
"ver": "1.1.0",
"importer": "directory",
"imported": true,
"uuid": "fd6e96ff-96ce-44f0-8eda-24aaf8c2e936",
"uuid": "6295772d-e72e-4ed2-bb3b-5aa3c1132f3a",
"files": [],
"subMetas": {},
"userData": {

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "dd1877ff-a74c-498e-9b20-9cea493beb55",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -1,12 +1,16 @@
/*
* @Author: dgflash
* @Date: 2022-02-10 09:50:41
* @LastEditors: dgflash
* @LastEditTime: 2022-04-08 17:22:27
*/
import { Component, gfx, macro, Material, MeshRenderer, utils, Vec3, _decorator } from 'cc';
const { ccclass, property } = _decorator;
/** 绘制扇形网格 */
@ccclass('DrawSectorMesh')
/**
*
*/
export class DrawSectorMesh extends Component {
export class DrawMeshSector extends Component {
@property({ type: Material })
public mat: Material | null = null;

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "69692e04-9c37-40ed-829a-f5561307eff2",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,29 @@
/*
* @Author: dgflash
* @Date: 2021-08-11 16:41:12
* @LastEditors: dgflash
* @LastEditTime: 2022-04-07 17:25:04
*/
import { Component, _decorator } from 'cc';
import { EffectSingleCase } from './EffectSingleCase';
const { ccclass, property } = _decorator;
/**
* 延时释放特效
* 注:场景中频繁有特效添加和释放时,可考虑使用对象池优化创建对象的性能开销
*/
@ccclass('EffectDelayRelease')
export class EffectDelayRelease extends Component {
/** 延时释放时间(单位秒) */
@property
public delay: number = 1;
start() {
this.scheduleOnce(this.onDelay, this.delay);
}
private onDelay() {
EffectSingleCase.instance.put(this.node);
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "ecbbfcee-05da-40a9-8e09-a2975452d147",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,30 @@
/*
* @Author: dgflash
* @Date: 2021-12-30 19:16:47
* @LastEditors: dgflash
* @LastEditTime: 2022-04-07 17:08:44
*/
import { Animation, Component, _decorator } from 'cc';
import { EffectSingleCase } from './EffectSingleCase';
const { ccclass, property } = _decorator;
@ccclass('EffectFinishedRelease')
/** 动画播放完释放特效 */
export class EffectFinishedRelease extends Component {
@property({ type: Animation, tooltip: '资源对象池类型名' })
anim: Animation = null!;
onLoad() {
this.anim.on(Animation.EventType.FINISHED, this.onFinished, this);
this.anim.on(Animation.EventType.LASTFRAME, this.onFinished, this);
}
start() {
this.anim.play();
}
private onFinished() {
EffectSingleCase.instance.put(this.node);
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "39094659-91ac-44a2-9237-f917fd069ca4",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,83 @@
/*
* @Author: dgflash
* @Date: 2021-10-12 14:00:43
* @LastEditors: dgflash
* @LastEditTime: 2022-04-14 19:06:51
*/
import { Component, Node, NodePool, Vec3 } from 'cc';
import { ViewUtil } from '../../utils/ViewUtil';
class EffectData extends Component {
type: string = null!;
}
/** 全局单例特效 */
export class EffectSingleCase {
private static _instance: EffectSingleCase;
public static get instance(): EffectSingleCase {
if (this._instance == null) {
this._instance = new EffectSingleCase();
}
return this._instance;
}
private effects: Map<string, NodePool> = new Map();
/**
* 显示预制对象
* @param name 预制对象名称
* @param parent 父节点
* @param pos 位置
*/
show(name: string, parent: Node, pos?: Vec3): Node {
var np = this.effects.get(name);
if (np == null) {
np = new NodePool();
this.effects.set(name, np);
}
var node: Node;
if (np.size() == 0) {
node = ViewUtil.createPrefabNode(name);
node.addComponent(EffectData).type = name;
}
else {
node = np.get()!;
}
node.parent = parent;
if (pos) node.position = pos;
return node;
}
/**
* 回收对象
* @param name 预制对象名称
* @param node 节点
*/
put(node: Node) {
var name = node.getComponent(EffectData)!.type;
var np = this.effects.get(name);
if (np) {
np.put(node);
}
}
/**
* 清除对象池数据
* @param name 参数为空时,清除所有对象池数据;指定名时,清楚指定数据
*/
clear(name?: string) {
if (name) {
var np = this.effects.get(name)!;
np.clear();
}
else {
this.effects.forEach(np => {
np.clear();
});
this.effects.clear();
}
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "b6288c35-d337-4566-8bf7-3f0b60980c1f",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -1,11 +1,16 @@
import { Animation, Label, _decorator } from "cc";
import { GameComponent } from "../../common/component/GameComponent";
/*
* @Author: dgflash
* @Date: 2022-04-14 17:08:01
* @LastEditors: dgflash
* @LastEditTime: 2022-04-14 19:06:34
*/
import { Animation, Component, Label, _decorator } from "cc";
import { LanguageLabel } from "../language/LanguageLabel";
const { ccclass, property } = _decorator;
@ccclass('NotifyComponent')
export class NotifyComponent extends GameComponent {
export class NotifyComponent extends Component {
@property(Label)
private lab_content: Label | null = null;