This commit is contained in:
devil
2023-05-21 15:53:32 +08:00
parent 7bff1c70f1
commit e199970fb5
169 changed files with 11582 additions and 0 deletions

View File

@@ -0,0 +1,211 @@
import { instantiate, Intersection2D, Node, NodePool, Prefab, Rect, resources, UITransform, Vec3, view } from "cc";
import ArrayUtil from "../core/utils/ArrayUtil";
import { monsterCtl } from "./monsterCtl";
import Game from "./Test2";
interface MonsterPool {
name: string;
pool: NodePool;
}
export default class MonsterFactory {
private static instance: MonsterFactory = null;
public static get Instance(): MonsterFactory {
if (this.instance == null)
this.instance = new MonsterFactory();
return this.instance;
}
MonsterPoolList: Array<MonsterPool> = new Array<MonsterPool>();
monsterParent: Node;
monsterDataCountList = {}; //每种怪物的数量数据
monsterAllList: Array<monsterCtl> = new Array<monsterCtl>(); //所有的怪物;
screenMonsterAllList: Array<monsterCtl> = new Array<monsterCtl>(); //屏幕里面的怪物;
arrayMonsterList: Array<Array<monsterCtl>> = new Array<Array<monsterCtl>>();
currenTime = -30;
currentIndex = 0;//当前刷新到了第几次
weekCount = 0; //第几次循环
constructor() {
// this.monsterParent = find("Canvas/Game/monsterCtl");
this.monsterParent = Game.Instance.monsterRootNode
}
getMonsterCountByName(name) {
let index = 0;
for (let i = 0; i < this.monsterAllList.length; i++) {
if (this.monsterAllList[i].node.name == name) {
index++;
}
}
return index;
}
clear() {
this.currenTime = -30;
this.currentIndex = 0;
this.weekCount = 0;
for (let i = 0; i < this.monsterAllList.length; i++) {
let monsterCtl = this.monsterAllList[i];
this.recoverNode(monsterCtl.node);
i--;
}
this.monsterDataCountList = {};
this.monsterAllList = new Array<monsterCtl>();
this.arrayMonsterList = new Array<Array<monsterCtl>>();
this.screenMonsterAllList = new Array<monsterCtl>()
}
update(dt) {
}
creatorMonsterByName(name, pos: Vec3, call?) {
let pool: NodePool = this.getEfPoolByName(name);
let node: Node = pool.get();
if (this.monsterDataCountList[name] == null) {
this.monsterDataCountList[name] = 0;
}
this.monsterDataCountList[name]++;
let resetNode = (ef: Node) => {
ef.parent = this.monsterParent;
ef.active = true;
ef.setPosition(pos.x, pos.y);
call && call(ef);
let mstCtl = ef.getComponent(monsterCtl)
if (mstCtl) {
mstCtl.reuse()
this.monsterAllList.push(mstCtl);
} else {
console.error("monster has none monster ctl...")
}
};
if (node == null) {
resources.load("prefab/monster/" + name, Prefab, (err, resPrefab) => {
node = instantiate(resPrefab)
resetNode(node)
})
}
else {
// console.log("从缓存池创建...")
resetNode(node);
}
}
getEfPoolByName(name) {
let efPool: NodePool = null;
for (let i = 0; i < this.MonsterPoolList.length; i++) {
if (name == this.MonsterPoolList[i].name) {
efPool = this.MonsterPoolList[i].pool;
break
}
}
if (efPool == null) {
efPool = new NodePool();
this.MonsterPoolList.push({
name: name,
pool: efPool
})
}
return efPool;
}
/**
* 回收
* @param node
*/
recoverNode(node) {
let name = node.name;
if (this.monsterDataCountList[node.name]) {
this.monsterDataCountList[node.name]--;
}
for (let i = 0; i < this.MonsterPoolList.length; i++) {
if (name == this.MonsterPoolList[i].name) {
node.active = false;
this.MonsterPoolList[i].pool.put(node);
let com = node.getComponent(monsterCtl);
let index = this.monsterAllList.indexOf(com);
if (index != -1) {
ArrayUtil.fastRemoveAt(this.monsterAllList, index)
// this.monsterAllList.splice(index, 1);
}
break;
}
}
}
/**
* 获取当前在屏幕内的怪物
* @param node
*/
getInViewMonster(node: Node = null) {
let tNode = node ? node : Game.Instance.Player.node
this.screenMonsterAllList = [];
this.arrayMonsterList = new Array<Array<monsterCtl>>();
let pos = tNode.getComponent(UITransform).convertToWorldSpaceAR(new Vec3());
let v2 = view.getViewportRect();
let realView = new Vec3(v2.width, v2.height, 0);
let allRect = new Rect(pos.x - realView.x / 2, pos.y - realView.y / 2, realView.x, realView.y);
let cutRectMonterList = new Array<monsterCtl>();
this.arrayMonsterList.push(cutRectMonterList);
for (let j = 0; j < this.monsterAllList.length; j++) {
let monsterCtl = this.monsterAllList[j];
let monsterRect = monsterCtl.getCircle(true);
//顺便获取屏幕里面的怪
if (Intersection2D.rectCircle(allRect, monsterRect.pos, monsterRect.radius)) {
this.screenMonsterAllList.push(monsterCtl);
}
}
}
cutRectCount = 2;
getCutRectList(node) {
this.screenMonsterAllList = [];
this.arrayMonsterList = new Array<Array<monsterCtl>>();
let pos = node.getComponent(UITransform).convertToWorldSpaceAR(new Vec3());
let v2 = view.getViewportRect();
let realView = new Vec3(v2.width, v2.height, 0);
let allRect = new Rect(pos.x - realView.x / 2, pos.y - realView.y / 2, realView.x, realView.y);
let rect1 = new Rect(pos.x - realView.x, pos.y, realView.x, realView.y);
let rect2 = new Rect(pos.x, pos.y, realView.x, realView.y);
let rect3 = new Rect(pos.x - realView.x, pos.y - realView.y, realView.x, realView.y);
let rect4 = new Rect(pos.x, pos.y - realView.y, realView.x, realView.y);
let rectList = [rect1, rect2, rect3, rect4];
for (let i = 0; i < rectList.length; i++) {
let rect = rectList[i];
let cutRectMonterList = new Array<monsterCtl>();
this.arrayMonsterList.push(cutRectMonterList);
for (let j = 0; j < this.monsterAllList.length; j++) {
let monsterCtl = this.monsterAllList[j];
let monsterRect = monsterCtl.getCircle();
// let result = rect.intersects(monsterRect);
// rect.polygonCircle
let result = Intersection2D.rectCircle(rect, monsterRect.pos, monsterRect.radius)
//改为矩形圆形判断
if (result) {
cutRectMonterList.push(monsterCtl);
monsterCtl.cutRectMonterList = cutRectMonterList;
}
//顺便获取屏幕里面的怪
if (i == 0) {
if (Intersection2D.rectCircle(allRect, monsterRect.pos, monsterRect.radius)) {
this.screenMonsterAllList.push(monsterCtl);
}
}
}
}
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "411ec7f5-0831-42e0-92ab-00f47d9173c5",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,90 @@
import { Camera, Component, dynamicAtlasManager, Node, _decorator } from 'cc';
import WaveMng from '../logics/mng/WaveMng';
import { player } from '../rolectl/player';
import { Vector2 } from '../RVO/Common';
import { Simulator } from '../RVO/Simulator';
import { monsterCtl } from './monsterCtl';
const { ccclass, property } = _decorator;
// 关闭web的动态合图
// dynamicAtlasManager.enabled = false
export default class Game {
public limitMonst: number = 400
private static instance: Game = null;
public static get Instance(): Game {
if (this.instance == null)
this.instance = new Game();
return this.instance;
}
private _Player: player;
public get Player(): player {
return this._Player;
}
public set Player(value: player) {
this._Player = value;
}
private _monsterRootNode: Node;
public get monsterRootNode(): Node {
return this._monsterRootNode;
}
public set monsterRootNode(value: Node) {
this._monsterRootNode = value;
}
private _camera: Camera;
public get camera(): Camera {
return this._camera;
}
public set camera(value: Camera) {
this._camera = value;
}
}
@ccclass('Test2')
export class Test2 extends Component {
@property(Camera)
camera: Camera;
@property(Node)
avatarLayer: Node;
@property(player)
player: player
onEnable() {
Game.Instance.Player = this.player
Game.Instance.monsterRootNode = this.avatarLayer
Game.Instance.camera = this.camera// this.node.getComponent(this.camera)
}
onDisable() {
}
_bigRedBall: Node
start() {
// let simulator = Simulator.instance;
Simulator.instance.setAgentDefaults(60, 3, 1, 0.1, 14, 80, new Vector2(0, 0));
}
_framTimes = 0
_dt: number = 0
update(dt: number) {
//测试怪物生成RVO
this._dt += dt
if (this._dt > 0.5) {
this._dt = 0
this.getComponent(WaveMng).createMonster()
}
// 更新逻辑坐标
Simulator.instance.run(dt);
this._framTimes = 0
for (let index = 0; index < Game.Instance.Player.monsterList.length; index++) {
const monster = Game.Instance.Player.monsterList[index];
monster.getComponent(monsterCtl).moveByRvo()
}
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "1928e6fa-5abf-447e-9276-7b784ea79f1d",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,206 @@
import { Component, Vec2, Vec3, _decorator, v2, v3 } from 'cc';
import { RVOMath } from '../RVO/Common';
import { Simulator } from '../RVO/Simulator';
import Util from '../core/utils/Util';
import MonsterFactory from './MonsterFactory';
import Game from './Test2';
import { monsterEffectCtl } from './monsterEffectCtl';
const { ccclass, property } = _decorator;
@ccclass('monsterCtl')
export class monsterCtl extends Component {
private _hp: number = 5;
public get hp(): number {
return this._hp;
}
public set hp(value: number) {
this._hp = value;
}
// private state : number =
//测试受击
// hurtCoolTime = 0.15;
// hurtTime = 0.2;
hurtCoolTime = 0.15;
hurtTime = 0.2;
private _hit: boolean = false
private _hitPow: number = 3 //受击系数 系数越高 反弹力度越大
private orScale: Vec3 = v3(1, 1, 1)
public cutRectMonterList = []
private _agentHandleId: number = -1; //RVOid
public get agentHandleId(): number {
return this._agentHandleId;
}
public set agentHandleId(value: number) {
this._agentHandleId = value;
}
start() {
this.orScale = this.node.scale
this._effectCtl = this.node.getComponent(monsterEffectCtl)
}
_effectCtl: monsterEffectCtl
reuse() {
this._hit = false
this.hurtTime = 0
this._effectCtl = this.node.getComponent(monsterEffectCtl)
if (this._effectCtl)
this._effectCtl.reuse()
}
/**
* 改为圆形判断
*/
getRect() {
let agent = Simulator.instance.getAgentByAid(this.agentHandleId)
if (agent) {
return agent.radius_
}
}
_tmpV2: Vec2 = new Vec2()
getCircle(world: boolean = false) {
let agent = Simulator.instance.getAgentByAid(this.agentHandleId)
if (agent) {
if (world) {
return { pos: Util.v3t2(this.node.worldPosition, this._tmpV2), radius: agent.radius_ }
} else {
return { pos: Util.v3t2(this.node.position, this._tmpV2), radius: agent.radius_ }
}
} else {
console.error("monster Circle error...")
return null
}
}
_frames: number = 0
update(deltaTime: number) {
this.hurtTime -= deltaTime
if (this._hit) {//设置 反向并且衰减的 线速度
this.setPreferredVelocities(this._hitPow)//this._hitPow * this.hurtTime / this.hurtCoolTime
if (this.hurtTime <= 0) {
this._hit = false
}
} else {
if (this._frames++ > 8) {
this._frames = 0
this.setPreferredVelocities()//设置追踪主角的线速度
//确定朝向
}
}
}
/**
* 设置追踪主角的线速度方向和大小
*/
_tmpScale: Vec3 = new Vec3()
setPreferredVelocities(hitPow: number = null) {
if (this.agentHandleId < 0) {
return
}
this._tmpScale = this.node.getScale()
let agentAid = this.agentHandleId
let agent = Simulator.instance.getAgentByAid(agentAid)
let agentPos = Simulator.instance.getAgentPosition(agentAid)
let moveTarget: Vec2 = v2(Game.Instance.Player.node.getPosition().x, Game.Instance.Player.node.getPosition().y)
//受击状态的线速度处理
if (hitPow) {
if (agent && agentPos) {
let goalVector: Vec2 = moveTarget.subtract2f(agentPos.x, agentPos.y)// this.goals[i].minus(Simulator.instance.getAgentPosition(agentAid));
goalVector = goalVector.normalize().multiplyScalar(agent.maxSpeed_ * -hitPow);
Simulator.instance.setAgentPrefVelocity(agentAid, goalVector);
}
return
}
if (agent && agentPos) {
let goalVector: Vec2 = moveTarget.subtract2f(agentPos.x, agentPos.y)// this.goals[i].minus(Simulator.instance.getAgentPosition(agentAid));
if (goalVector.lengthSqr() > 1.0) {
goalVector = goalVector.normalize().multiplyScalar(agent.maxSpeed_);
}
if (goalVector.lengthSqr() < RVOMath.RVO_EPSILON) {
Simulator.instance.setAgentPrefVelocity(agentAid, Vec2.ZERO);
}
else {
Simulator.instance.setAgentPrefVelocity(agentAid, goalVector);
//这个会导致抖动呀 宝贝...
// let angle = Math.random() * 2.0 * Math.PI;
// let dist = Math.random() * 0.0001;
// Simulator.instance.setAgentPrefVelocity(i,
// Simulator.instance.getAgentPrefVelocity(i).plus(new Vector2(Math.cos(angle), Math.sin(angle)).scale(dist)));
}
if (goalVector.x > 0) {
this.node.setScale(this._tmpScale.set(Math.abs(this._tmpScale.x), this._tmpScale.y, this._tmpScale.z))
} else {
this.node.setScale(this._tmpScale.set(-Math.abs(this._tmpScale.x), this._tmpScale.y, this._tmpScale.z))
}
} else {
console.error("RVO异常::", agent, agentPos, agentAid)
}
// }
}
/**
* 在此之前 请确保Simulator run执行完毕
*/
moveByRvo() {
// console.log("p::", p, Simulator.instance.getAgentPosition(this.agentHandleId))
let p = Simulator.instance.getAgentPosition(this.agentHandleId);
this.node.setPosition(p.x, p.y)
}
/**
* 测试效果 闪白 蓝光...
*/
hurtAction() {
let randEfIdx = Math.random()
let mstEffectCtl = this.node.getComponent(monsterEffectCtl)
if (mstEffectCtl) {
if (randEfIdx > 0.5) {
mstEffectCtl.playHit()
} else {
mstEffectCtl.playFroze()
}
}
}
hurt(): boolean {
// if (!this.)
if (this.hurtTime > 0) { //受击冷却中
return
}
this.hurtTime = this.hurtCoolTime
this._hp--
if (this._hp <= 0) {
this.rmMonster()
return true
} else {
this.hurtAction()
this._hit = true
return false
}
}
rmMonster() {
this._effectCtl.disove(() => {
if (this.agentHandleId >= 0) {
Simulator.instance.removeAgent(this.agentHandleId)
// console.log("移除RVO对象::", this.agentHandleId)
}
MonsterFactory.Instance.recoverNode(this.node)
})
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "cc093bda-87cd-4315-9b9e-178cd9fe6791",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,136 @@
import { Component, Material, Sprite, UIOpacity, Vec4, _decorator, color, math, tween } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('monsterEffectCtl')
export class monsterEffectCtl extends Component {
_mt: Material = null
_spCmp: Sprite = null
private _hited: boolean;
private _froze: boolean;
private _optCmp: UIOpacity = null;
start() {
this._spCmp = this.node.getComponent(Sprite)
// this._optCmp = this.node.addComponent(UIOpacity)
// this._mt = this.node.getComponent(Sprite).getMaterialInstance(0)//这个打断合批...
}
reuse() {
this.start()
// this._hited = this._froze = false
// this._frozeDt = this._hitDt = 0
// this._mt = this.node.getComponent(Sprite).getMaterialInstance(0)
//关闭蓝色内发光 关闭闪白
this._spCmp.color = color(255, 255, 255, 1)
}
/**
* 闪白
*/
_showHitTotalTime: number = 0.15
playHit() {
//方式一 setProperty 打断合批
//需要放开 start()中的 this._mt = this.node.getComponent(Sprite).getMaterialInstance(0)
// tween(this._mt).to(this._showHitTotalTime, {}, {
// onUpdate(target: Material, ratio) {
// target.setProperty("hitwhit", ratio)
// },
// }).call(() => {
// this._mt.setProperty("hitwhit", 0.0)
// }).start()
//方式二 占用alpha通道
let tSpCmp = this._spCmp // this.node.getComponent(Sprite)
tSpCmp.color = color(255, 255, 255, 1)
let tmpColor: math.Color = color(255, 255, 255, 244)
tween(tSpCmp).to(this._showHitTotalTime, {}, {
onUpdate(target: Sprite, ratio) {
tmpColor = color(255, 255, 255, 255 * ratio)
target.color = tmpColor
},
}).call(() => {
tmpColor = color(255, 255, 255, 1)
tSpCmp.color = tmpColor
}).start()
}
/**
* 减速(视觉效果)
*/
frozeColor: Vec4 = Vec4.ZERO;
_showFrozeTime: number = 10
_frozeDt: number = 0
playFroze() {
//占用r通道 r在0~25.5之间 开启蓝色内光
let tSpCmp = this._spCmp
let tmpColor: math.Color = null
tSpCmp.color = color(1, tSpCmp.color.g, tSpCmp.color.b, tSpCmp.color.a)
tween(tSpCmp).to(this._showFrozeTime, {}, {}).call(() => {
tmpColor = color(255, 255, 255, tSpCmp.color.a)
tSpCmp.color = tmpColor
}).start()
}
/**
* 测试消融
*/
_disoveTime: number = 1
disove(cb?: Function) {
//占用g通道
let tSpCmp = this._spCmp
tSpCmp.color = color(this._spCmp.color.r, 1, this._spCmp.color.b, this._spCmp.color.a)
let tmpColor: math.Color = null
tween(tSpCmp).to(this._disoveTime, {}, {
onUpdate(target: Sprite, ratio) {
tmpColor = color(255, 254 * ratio, 255, 255)
target.color = tmpColor
},
}).call(() => {
if (cb) {
cb()
}
// tmpColor = color(255, 255, 255, 1)
// tSpCmp.color = tmpColor
}).start()
}
/**
* 仅用于测试显示效果
* 游戏类的冰冻减速
* 中毒燃烧掉血等逻辑 应该由逻辑层实现
*/
_hitDt: number
update(dt: number) {
// this._mt = this.node.getComponent(Sprite).getMaterial(0)
// if (this._hited) {
// this._hitDt += dt
// let percent = this._hitDt / this._showHitTotalTime
// percent = Math.min(Math.max(percent, 0.), 1.)
// this._mt.setProperty("hitwhit", percent)
// if (percent >= 1) {
// this._hitDt = 0
// this._hited = false
// this._mt.setProperty("hitwhit", 0.0)
// }
// }
// if (this._froze) {
// this._frozeDt += dt
// this._mt.setProperty("glowColor", this.frozeColor)
// if (this._frozeDt > this._showFrozeTime) {
// this._frozeDt = 0
// this._mt.setProperty("glowColor", Vec4.ZERO)
// this._froze = false
// }
// }
// console.log("this.mt::" , this._mt)
// this.node.getComponent(Sprite).setMaterial(this._mt,0)
}
}

View File

@@ -0,0 +1 @@
{"ver":"4.0.23","importer":"typescript","imported":true,"uuid":"eb420a22-bf96-4b6c-b2d9-8bab34bd9a58","files":[],"subMetas":{},"userData":{}}