import { _decorator, Color, Component, instantiate, Label, Node, Prefab, Sprite } from 'cc'; import * as cc from 'cc'; import RAPIER, { IntegrationParameters } from '@dimforge/rapier2d-compat'; import { RAPIER_PTM_RATIO, RapierDebugRenderer } from './RapierDebugRenderer'; import { logger } from './Clogger'; const { ccclass, property } = _decorator; @ccclass('SceneRapier2d') export class SceneRapier2d extends Component { @property(Node) node_fps:Node|null = null; @property(Node) node_counts:Node|null = null; @property(Prefab) prefab_item:Prefab|null = null; @property(Node) container_balls:Node|null = null; @property(cc.Node) node_switch:cc.Node|null = null; @property(cc.Node) node_switchscene:cc.Node|null = null; private _timeAccumulator: any; private _countAcc: any; private world: RAPIER.World; private gravity = new RAPIER.Vector2(0, -10); private _initComplete: boolean = false; private _rigidBody: RAPIER.RigidBody; private _debugRenderer: RapierDebugRenderer; //将一个node和一个RigidBody绑定 private _mapNodeBalls: Map = new Map(); protected async onLoad(): Promise { logger.log('dballs onLoad'); RAPIER.init().then(() => { logger.log('RAPIER.init success'); this._initComplete = true; // 创建物理世界 this.world = new RAPIER.World(this.gravity); this.fillWorld(); this._debugRenderer = this.getComponent(RapierDebugRenderer)!; this._debugRenderer.setWorld(this.world); this.afterInit(); }); } afterInit() { this.node_switch.children[0]!.getComponent(Label).string = this._debugRenderer.onoff ? 'debug:ON' : 'debug:OFF'; this.node_switch.on('click', (b:cc.Button) => { this._debugRenderer.onoff = !this._debugRenderer.onoff; this._debugRenderer.clear(); b!.node.children[0]!.getComponent(Label).string = this._debugRenderer.onoff ? 'debug:ON' : 'debug:OFF'; }); } start() { logger.log('dballs start'); this.node_switchscene.on('click', (b:cc.Button) => { cc.director.loadScene('scene_box2d'); }); // this.schedule((dt:number)=>{ // if(!this._initComplete){ // return; // } // this.world.step(); // this._mapNodeBalls.forEach((rigidBody, node)=>{ // let position = rigidBody.translation(); // node.setPosition(position.x*RAPIER_PTM_RATIO, position.y*RAPIER_PTM_RATIO); // node.active = true; // }); // }, 1/60, cc.macro.REPEAT_FOREVER, 0); } fillWorld(){ let world = this.world; let viewSize = cc.view.getVisibleSize(); let groundRigidBody = world.createRigidBody(new RAPIER.RigidBodyDesc(RAPIER.RigidBodyType.Fixed)); world.createCollider(RAPIER.ColliderDesc.cuboid(viewSize.width/2, 0.5).setTranslation(0,-viewSize.height/(2*RAPIER_PTM_RATIO)).setRestitution(1).setFriction(0.0), groundRigidBody); let groundRigidBody1 = world.createRigidBody(new RAPIER.RigidBodyDesc(RAPIER.RigidBodyType.Fixed)); world.createCollider(RAPIER.ColliderDesc.cuboid(0.5,viewSize.height/2 ).setTranslation(-viewSize.width/(2*RAPIER_PTM_RATIO),0).setRestitution(1).setFriction(0.0), groundRigidBody1); let groundRigidBody2 = world.createRigidBody(new RAPIER.RigidBodyDesc(RAPIER.RigidBodyType.Fixed)); world.createCollider(RAPIER.ColliderDesc.cuboid(0.5,viewSize.height/2 ).setTranslation(viewSize.width/(2*RAPIER_PTM_RATIO),0).setRestitution(1).setFriction(0.0), groundRigidBody2); // let rigidBody = world.createRigidBody(new RAPIER.RigidBodyDesc(RAPIER.RigidBodyType.Dynamic).setTranslation(0.0, 5.0).setLinearDamping(0).setAngularDamping(0)); // let collider = world.createCollider(RAPIER.ColliderDesc.ball(0.5).setDensity(1.0).setRestitution(1).setFriction(0.0), rigidBody); // this._rigidBody = rigidBody; } update(dt: number) { if (!this._timeAccumulator) { this._timeAccumulator = 0; } this._timeAccumulator += dt; // if (this._timeAccumulator >= 0.1) { this.node_fps.getComponent(Label)!.string = `FPS: ${Math.floor(1 / dt)}`; // this._timeAccumulator = 0; // } if(Math.floor(1 / dt) < 30){ return; } if (!this._countAcc) { this._countAcc = 0; } //物理系统同步 if(!this._initComplete){ return; } this.world.step(); this._mapNodeBalls.forEach((rigidBody, node)=>{ let position = rigidBody.translation(); node.setPosition(position.x*RAPIER_PTM_RATIO, position.y*RAPIER_PTM_RATIO); node.active = true; }); // this._countAcc += 1; // if (this._countAcc >= 60/60) { for (let i = 0; i < 4; i++) { let node = instantiate(this.prefab_item); node.getComponent(Sprite).color = new Color(Math.random()*255, Math.random()*255, Math.random()*255); node.active = false; this.container_balls.addChild(node); let x = (Math.random()*2-1)*cc.view.getVisibleSize().width/2; let y = 400; let r = (node.getComponent(cc.UITransform).width-2)/2 ; let rigidBody = this.world.createRigidBody(new RAPIER.RigidBodyDesc(RAPIER.RigidBodyType.Dynamic).setTranslation(x/RAPIER_PTM_RATIO, y/RAPIER_PTM_RATIO).setLinearDamping(0).setAngularDamping(0).setCanSleep(false)); this.world.createCollider(RAPIER.ColliderDesc.ball(r/RAPIER_PTM_RATIO).setDensity(1.0).setRestitution(0.5).setFriction(0.0), rigidBody); this._mapNodeBalls.set(node, rigidBody); // node.setPosition(x, 400); // this._listBalls.push(node); } this.node_counts.getComponent(Label)!.string = `BALLS: ${this.container_balls.children.length}`; // this._countAcc = 0; // } } }