123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342 |
- import { _decorator, Component, Node } from "cc";
- import { GameCamera } from "./GameCamera";
- import { Material } from "cc";
- import { GameEvent, GameMgr } from "../../module_basic/scripts/GameMgr";
- import { UITransform } from "cc";
- import { size } from "cc";
- import { Sprite } from "cc";
- import { Vec2 } from "cc";
- import { renderer } from "cc";
- import {
- IFood,
- IGameData,
- IGamePlayer,
- } from "../../module_basic/shared/protocols/public/game/GameTypeDef";
- import { instantiate } from "cc";
- import { GameResMgr } from "./GameResMgr";
- import { Cell } from "./Cell";
- import { UserMgr } from "../../module_basic/scripts/UserMgr";
- import { PlayerMovement2D } from "./PlayerMovement2D";
- import { PlayerController } from "./PlayerController";
- import { UIGameJoystick } from "../ui_game_joystick/UIGameJoystick";
- import { UIGameHUD } from "../ui_game_hud/UIGameHUD";
- import { UIGameRank } from "../ui_game_rank/UIGameRank";
- import { RoomMgr } from "../../module_basic/scripts/RoomMgr";
- import { IRoomData, IUserData } from "../../module_basic/shared/types/RoomData";
- import { UserInfo } from "../../module_basic/shared/types/UserInfo";
- import { color } from "cc";
- import { GameLocalData } from "./GameLocalData";
- import { director } from "cc";
- import { SceneUtil } from "../../core_tgx/base/SceneUtils";
- import { ModuleDef } from "../../scripts/ModuleDef";
- import { SceneDef } from "../../scripts/SceneDef";
- import { GameSceneUtil } from "../../module_basic/scripts/GameSceneUtil";
- import { UIGameResult } from "../../module_ball/ui_game/UIGameResult";
- const { ccclass, property } = _decorator;
- @ccclass("GameLocalScene")
- export class GameLocalScene extends Component {
- @property(Node) mapRoot: Node;
- @property(Node) background: Node;
- @property(Node) objectsRoot: Node;
- @property(GameCamera) gameCamera: GameCamera;
- @property(Material) mapMaterial: Material;
- public static MAP_WIDTH = 10000;
- public static MAP_HEIGHT = 10000;
- // private _cellMap: { [key: number]: Cell } = {};
- private _foodMap: { [key: number]: Node } = {};
- private _foodInfoMap: { [key: number]: IFood } = {};
- private _foodPool: Node[] = [];
- private _backgroundPass: renderer.Pass;
- private _handleEdgeFactor: number;
- private _selfPlayers: Cell[] = [];
- start() {
- let localUser: UserInfo = {
- uid: "local-me-uid-xxx-001",
- };
- UserMgr.inst.setUserInfo(localUser);
- let roomData: IRoomData = GameLocalData.ins.createLocalRoomData(
- localUser.uid
- );
- RoomMgr.inst.onNet_RoomDataSyncPush({
- data: roomData,
- });
- tgx.UIMgr.inst.showUI(UIGameJoystick);
- tgx.UIMgr.inst.showUI(UIGameHUD);
- // tgx.UIMgr.inst.showUI(UIGameRank);
- let selfPlayerInfo = GameLocalData.ins.mockIGamePlayer();
- let gameData = GameLocalData.ins.createLocalGameData(selfPlayerInfo);
- GameMgr.inst.localMode(gameData);
- GameMgr.inst.onNet_PlayerComesPush({
- player: selfPlayerInfo,
- });
- this.initBackground();
- this.createCell(selfPlayerInfo);
- let self = this;
- let intIn = setInterval(() => {
- if (
- !GameMgr.inst.gameData ||
- GameMgr.inst.gameData.gameState == "gameover"
- ) {
- clearInterval(intIn);
- return;
- }
- self.createFoods();
- }, 1000);
- director.on(GameEvent.GAME_EXIT, this.onGameExit, this);
- director.on(GameEvent.LOCAL_PLAYER_SPAWN, this.onLocalPlayerSpawn, this);
- }
- private _lastSpawnTime = 0;
- private onLocalPlayerSpawn() {
- if (Date.now() - this._lastSpawnTime < 500) {
- return;
- }
- this._lastSpawnTime = Date.now();
- let waitCreateData = [];
- for (let i = 0; i < this._selfPlayers.length; i++) {
- console.log(">>>> i", i, this._selfPlayers.length);
- let oneSelfCell = this._selfPlayers[i];
- if (oneSelfCell.player.radius > 50) {
- oneSelfCell.player.radius = Math.floor(oneSelfCell.player.radius / 2);
- oneSelfCell.setRadius(oneSelfCell.player.radius);
- let newInfo = JSON.parse(JSON.stringify(oneSelfCell.player));
- newInfo.state = "moving";
- let moveDistance = oneSelfCell.player.radius * 3;
- let move2D = oneSelfCell.getComponent(PlayerMovement2D);
- let moveDir = move2D.moveDir;
- let newPos = new Vec2(
- oneSelfCell.node.getWorldPosition().x + moveDistance * moveDir.x,
- oneSelfCell.node.getWorldPosition().y + moveDistance * moveDir.y
- );
- newInfo.transform[0] = newPos.x;
- newInfo.transform[1] = newPos.y;
- newInfo.transform[3] = move2D.rotDegree;
- waitCreateData.push(newInfo);
- }
- }
- for (let i = 0; i < waitCreateData.length; i++) {
- this.createCell(waitCreateData[i]);
- }
- }
- onGameExit() {
- tgx.UIMgr.inst.closeAll();
- GameMgr.inst.localGameOver();
- UIGameResult.show();
- }
- protected onDestroy(): void {
- director.off(GameEvent.GAME_EXIT, this.onGameExit, this);
- }
- initBackground() {
- const extBorder = 4000;
- let gameData = GameMgr.inst.gameData;
- const realWidth = gameData.mapWidth + extBorder;
- const realHeight = gameData.mapHeight + extBorder;
- this.background.getComponent(UITransform).contentSize = size(
- realWidth,
- realHeight
- );
- //@en initialize the material parameters of the background.
- //@zh 初始化地图背景材质
- const halfWidth = gameData.mapWidth / 2;
- const halfHeight = gameData.mapHeight / 2;
- let spriteFrame = this.background.getComponent(Sprite).spriteFrame;
- let uvScale = new Vec2();
- let scaler = 0.6;
- //@en use uv scale to adapt the map size
- //@zh 使用uv缩放来适配地图大小
- uvScale.x = (realWidth / spriteFrame.width) * scaler;
- uvScale.y = (realHeight / spriteFrame.height) * scaler;
- this.mapMaterial.setProperty("uvScale", uvScale);
- this.mapMaterial.setProperty(
- "halfMapSize",
- new Vec2(halfWidth, halfHeight)
- );
- //this.mapMaterial.setProperty('edgeColor', new Vec4(1.0,0.0,0.0,1.0));
- //this.mapMaterial.setProperty('fadeOutRange', 1000.0);
- //@en save the material parameter handle for efficient setting of material parameters in update
- //@zh 保存材质参数相关句柄,方便在update中高效率地设置材质参数
- this._backgroundPass = this.mapMaterial.passes[0];
- this._handleEdgeFactor = this._backgroundPass.getHandle("edgeFactor");
- }
- tmpColor = color();
- createFoods() {
- let createCount = 1000 - Object.keys(this._foodMap).length;
- if (createCount <= 0) {
- return;
- }
- if (createCount > 100) {
- createCount = 100;
- }
- for (let i = 0; i < createCount; i++) {
- this.createFood(GameLocalData.ins.newFoodData());
- }
- }
- protected update(dt: number): void {
- let value = Math.sin(Date.now() / 50 / Math.PI);
- value = value * 0.5 + 0.5;
- this._backgroundPass.setUniform(this._handleEdgeFactor, value);
- this.checkFoodAndEat();
- this.mergeLogic();
- }
- mergeLogic() {
- let mergeInfo = this.checkCanMerge();
- if (mergeInfo) {
- let left = mergeInfo.left;
- let right = mergeInfo.right;
- left.setRadius(left.player.radius + right.player.radius);
- let index = this._selfPlayers.indexOf(right);
- if (this.gameCamera.target === right) {
- this.gameCamera.target = left;
- }
- right.node.destroy();
- this._selfPlayers.splice(index, 1);
- }
- }
- checkCanMerge(): {
- left: Cell;
- right: Cell;
- } {
- let m1 = null;
- let m2 = null;
- for (let i = 0; i < this._selfPlayers.length; i++) {
- let left = this._selfPlayers[i];
- for (let j = i + 1; j < this._selfPlayers.length; j++) {
- let right = this._selfPlayers[j];
- if (left === right) {
- continue;
- }
- let distance = Vec2.distance(
- left.node.getWorldPosition(),
- right.node.getWorldPosition()
- );
- let ddd = left.player.radius + right.player.radius;
- if (distance < ddd) {
- m1 = left;
- m2 = right;
- if (m1.player.radius > m2.player.radius) {
- m1 = right;
- m2 = left;
- }
- return {
- left: m1,
- right: m2,
- };
- }
- }
- }
- }
- async createCell(player: IGamePlayer) {
- let newCell = instantiate(GameResMgr.inst.cellPrefab);
- this.objectsRoot.addChild(newCell);
- newCell.setWorldPosition(
- player.transform[0],
- player.transform[1],
- player.transform[2]
- );
- let cellComp = newCell.getComponent(Cell);
- cellComp.setPlayer(player);
- // this._cellMap[player.playerId] = cellComp;
- if (player.uid == UserMgr.inst.uid) {
- this._selfPlayers.push(cellComp);
- let mv2d = newCell.addComponent(PlayerMovement2D);
- mv2d.needRotation = false;
- mv2d.moveSpeed = player.speed;
- mv2d.setPrecision(10);
- if (this._selfPlayers.length == 1) {
- this.gameCamera.target = cellComp;
- }
- newCell.addComponent(PlayerController);
- if (player.state == "moving") {
- mv2d.onMovement(player.transform[3], 1.0);
- }
- }
- }
- async createFood(fd: IFood) {
- // console.log("createFood", fd);
- let newFood = this._foodPool.pop();
- if (!newFood) {
- newFood = new Node();
- newFood.addComponent(Sprite);
- }
- this._foodInfoMap[fd.id] = fd;
- this.mapRoot.addChild(newFood);
- newFood.name = "food_" + fd.id;
- this._foodMap[fd.id] = newFood;
- let foodSprites = GameResMgr.inst.foodSprites;
- let sprf = foodSprites[fd.type % foodSprites.length];
- let spr = newFood.getComponent(Sprite);
- spr.spriteFrame = sprf;
- this.tmpColor.fromHEX(fd.color.toString(16));
- spr.color = this.tmpColor;
- let scale = (fd.radius * 2) / sprf.rect.width;
- newFood.setScale(scale, scale, 1.0);
- newFood.setRotationFromEuler(0, 0, Math.random() * 360);
- newFood.setWorldPosition(fd.x, fd.y, 0);
- }
- checkFoodAndEat() {
- if (this._selfPlayers.length == 0) {
- return;
- }
- for (let foodId in this._foodMap) {
- let foodNode = this._foodMap[foodId];
- let foodPos = foodNode.getWorldPosition();
- for (let i = 0; i < this._selfPlayers.length; i++) {
- let oneSelfCell = this._selfPlayers[i];
- let playerPos = oneSelfCell.node.getWorldPosition();
- let distance = Vec2.distance(foodPos, playerPos);
- let ddd = oneSelfCell.player.radius / 1.5;
- let foodInfo = this._foodInfoMap[foodId];
- if (foodInfo && distance < ddd) {
- delete this._foodMap[foodId];
- delete this._foodInfoMap[foodId];
- foodNode.removeFromParent();
- this._foodPool.push(foodNode);
- let oneAdd = foodInfo.radius / 10;
- oneSelfCell.setRadius(oneSelfCell.player.radius + oneAdd);
- }
- }
- }
- }
- }
|