123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316 |
- import {
- _decorator,
- AssetManager,
- assetManager,
- color,
- Color,
- Component,
- instantiate,
- Label,
- Node,
- Prefab,
- RichText,
- Sprite,
- SpriteFrame,
- tween,
- v3,
- Vec2,
- Vec3,
- Widget,
- } from "cc";
- import { GameAudioMgr } from "./GameAudioMgr";
- import { PlayerMovement2D } from "./PlayerMovement2D";
- import { IGamePlayer } from "../../module_basic/shared/protocols/public/game/GameTypeDef";
- import { CellBullet } from "./CellBullet";
- import { GameMgr } from "../../module_basic/scripts/GameMgr";
- import { CellMgr } from "./CellMgr";
- import { UserMgr } from "../../module_basic/scripts/UserMgr";
- import { TEAM_ID_MAP } from "../../module_basic/shared/types/TeamInfo";
- import { ModuleDef } from "../../scripts/ModuleDef";
- import { RoomMgr } from "../../module_basic/scripts/RoomMgr";
- import { GameResMgr } from "./GameResMgr";
- import { GenderIcon } from "../../module_basic/scripts/GenderIcon";
- import { ExtraNode, NodeUtils } from "../../module_basic/scripts/NodeUtils";
- import { SpriteUtils } from "../../module_basic/scripts/SpriteUtils";
- import { utils } from "cc";
- const { ccclass, property } = _decorator;
- const tempV2 = new Vec2();
- const tempV3 = new Vec3();
- const tempColor = new Color();
- @ccclass("Cell")
- export class Cell extends Component {
- @property(Node) visualRoot: Node;
- @property(Node) body: Node;
- @property(Node) firePoint: Node;
- @property(Node) dir: Node;
- @property(Sprite) sprIcon: Sprite;
- @property(Sprite) sprEfx: Sprite;
- @property(Label) lblName: Label;
- @property(Label) lblTeam: Label;
- @property(Label) lblLocation: Label;
- @property(GenderIcon) genderIcon: GenderIcon;
- @property(Label) lblPos: Label;
- public player: IGamePlayer;
- public movement: PlayerMovement2D;
- private _transformsCache: number[][] = [];
- start() {
- this.movement = this.node.getComponent(PlayerMovement2D);
- CellMgr.inst.addCell(this);
- }
- setPlayer(player: IGamePlayer) {
- this.player = player;
- this.dir.active = player.uid == UserMgr.inst.uid;
- this.setRadius(player.radius);
- this.lblName.string = player.roleName;
- let teamName = TEAM_ID_MAP[player.teamId].name;
- this.lblTeam.string = `[${teamName}]`;
- if (GameMgr.inst.selfPlayer.teamId == player.teamId) {
- tempColor.fromHEX("#00EF00");
- this.lblTeam.color = tempColor;
- tempColor.fromHEX("#000000");
- this.lblTeam.outlineColor = tempColor;
- } else {
- tempColor.fromHEX("#FF0000");
- this.lblTeam.color = tempColor;
- tempColor.fromHEX("#FFFFFF");
- this.lblTeam.outlineColor = tempColor;
- }
- this.setColor(player.color);
- this.setState("normal");
- this.lblLocation.string = player.location || "保密";
- this.lblLocation.updateRenderData(true);
- this.genderIcon.setGender(RoomMgr.inst.getUser(player.uid)?.gender);
- this.lblLocation.node.children.forEach((v) => {
- v.getComponent(Widget).updateAlignment();
- });
- SpriteUtils.setTeamSkin(this.sprIcon, player.teamId);
- this.setColor(0xffffffff);
- }
- setState(state: "normal" | "destroyed") {
- if (state == "normal") {
- this.visualRoot.active = true;
- } else if (state == "destroyed") {
- this.visualRoot.active = false;
- }
- }
- displayPos() {
- let scale = this.body.scale.x;
- this.lblPos.string = `${this.node.worldPosition.x.toFixed(
- 0
- )},${this.node.worldPosition.y.toFixed(0)}\n
- scale:${scale.toFixed(1)}
- radius:${this.player.radius.toFixed(0)}
- `;
- }
- private _scaleAnimDoing = false;
- setRadius(radius: number) {
- if (radius > 2000) {
- return;
- }
- this.player.radius = radius;
- let self = this;
- if (this._scaleAnimDoing) {
- return;
- }
- this._scaleAnimDoing = true;
- let scale = (radius * 2) / 150;
- // this.body.setScale(scale, scale, 1.0);
- this.lblLocation.node.active = radius > 75;
- tween(this.body)
- // .to(0.1, { scale: new Vec3(scale * 1.05, scale * 1.05, 1.0) })
- .to(
- 0.2,
- { scale: new Vec3(scale, scale, 1.0) },
- {
- onComplete: () => {
- (self.node as ExtraNode).__radius__ = radius;
- self._scaleAnimDoing = false;
- },
- }
- )
- .start();
- }
- setColor(colorVal: number) {
- Color.fromUint32(tempColor, colorVal | 0xff000000);
- this.sprIcon.color = tempColor;
- }
- protected onDestroy(): void {
- CellMgr.inst.removeCell(this);
- }
- shootAnim(cb?: Function) {
- let t = GameMgr.inst.selfPlayer.transform;
- tempV3.set(t[0], t[1], t[2]);
- let volume = GameAudioMgr.getVolumeByDist(this.node.worldPosition, tempV3);
- GameAudioMgr.playOneShot("sounds/sfx_shoot", volume);
- //animation
- }
- fireBullet(
- pos: { x: number; y: number; z: number },
- rotationDegrees: number
- ) {
- let bullet = instantiate(GameResMgr.inst.bulletPrefab);
- this.node.parent.addChild(bullet);
- bullet.setWorldPosition(pos.x, pos.y, pos.z);
- bullet.setRotationFromEuler(0, 0, rotationDegrees);
- let rotationAngle = (rotationDegrees / 180) * Math.PI;
- let dir = tempV2.set(Math.cos(rotationAngle), Math.sin(rotationAngle));
- bullet.getComponent(CellBullet).moveDir = dir;
- return bullet;
- }
- private computeTargetDist(x1: number, y1: number, x2: number, y2: number) {
- let dx = x1 - x2;
- let dy = y1 - y2;
- let dist = Math.sqrt(dx * dx + dy * dy);
- return dist;
- }
- syncTransform(trans: number[], forceSync: boolean) {
- if (forceSync) {
- this._transformsCache = [];
- this.node.setWorldPosition(trans[0], trans[1], trans[2]);
- if (this.movement) {
- this.movement.onMovement(trans[3], 1.0);
- }
- } else {
- this._transformsCache.push(trans);
- let dist = 0;
- let pos = this.node.worldPosition;
- let lastX = pos.x;
- let lastY = pos.y;
- this._transformsCache.forEach((v) => {
- dist += this.computeTargetDist(lastX, lastY, v[0], v[1]);
- lastX = v[0];
- lastY = v[1];
- });
- //distance is too far
- if (dist >= this.player.speed) {
- this._transformsCache = [];
- this.node.setWorldPosition(trans[0], trans[1], trans[2]);
- console.log("distance is too far,force sync transform");
- }
- }
- }
- protected update(dt: number): void {
- if (this.player.protectedTime > 0) {
- this.sprEfx.node.active = true;
- tempColor.set(this.sprEfx.color);
- //clamp to 0.2 ~ 0.8
- tempColor.a = 255 * (Math.sin(Date.now() / 50 / Math.PI) * 0.6 + 0.2);
- this.sprEfx.color = tempColor;
- } else {
- this.sprEfx.node.active = false;
- }
- }
- private _lastRotation = NaN;
- private _lastSyncTime = 0;
- protected lateUpdate(dt: number): void {
- if (GameMgr.inst.gameData && GameMgr.inst.gameData.gameState != "playing") {
- return;
- }
- if (this.player.playerId == GameMgr.inst.selfPlayer.playerId) {
- this.lateUpdate_SelfPlayer(dt);
- } else {
- this.lateUpdate_OtherPlayers(dt);
- }
- this.displayPos();
- }
- lateUpdate_SelfPlayer(dt: number) {
- if (this.movement?.getRealSpeed() > 0) {
- let pos = this.node.worldPosition;
- this.dir.setWorldRotationFromEuler(0, 0, this.movement.realDegree);
- let rotation = this.movement.rotDegree;
- if (
- rotation != this._lastRotation ||
- Date.now() - this._lastSyncTime > 2000
- ) {
- this._lastRotation = rotation;
- this._lastSyncTime = Date.now();
- //console.log(rotation);
- GameMgr.inst.sendMsg_CellDataChange(pos.x, pos.y, pos.z, rotation);
- }
- }
- }
- lateUpdate_OtherPlayers(dt: number) {
- if (this.player.state != "moving") {
- return;
- }
- if (this._transformsCache.length == 0) {
- let rotation = (this.player.transform[3] / 180) * Math.PI;
- let dirX = Math.cos(rotation);
- let dirY = Math.sin(rotation);
- let len = Math.sqrt(dirX * dirX + dirY * dirY);
- if (len > 0) {
- dirX /= len;
- dirY /= len;
- }
- let pos = this.node.worldPosition;
- let targetX = pos.x + dirX * this.player.speed * dt;
- let targetY = pos.y + dirY * this.player.speed * dt;
- this.node.setWorldPosition(targetX, targetY, pos.z);
- } else {
- //加速处理
- let speed = this._transformsCache.length * this.player.speed;
- let movement = speed * dt;
- while (movement > 0 && this._transformsCache.length > 0) {
- let pos = this.node.worldPosition;
- let target = this._transformsCache[0];
- let dist = this.computeTargetDist(pos.x, pos.y, target[0], target[1]);
- if (dist > movement) {
- let factor = movement / dist;
- let targetX = pos.x * (1 - factor) + target[0] * factor;
- let targetY = pos.y * (1 - factor) + target[1] * factor;
- this.node.setWorldPosition(targetX, targetY, pos.z);
- movement = 0;
- } else {
- movement -= dist;
- this.node.setWorldPosition(target[0], target[1], pos.z);
- this._transformsCache.shift();
- }
- }
- }
- NodeUtils.clampInMapBoundary(this.node as ExtraNode);
- }
- }
|