protected void driveMoveFrame(float delay) { DriveLogic drive = _drive; _tempPos.clear(); DriveData dData = _d.driveData; float speedAbs = Math.Abs(drive.driveCurrentMoveSpeedM); if (speedAbs == 0 && dData.forward == 0) { if (dData.turn == 0 || !drive.canDriveTurnAtPivot) { return; } } //本次移动距离 float dis; //不启用加速度 if (drive.driveAccelerateSpeedM == 0) { dis = _useMoveSpeedM * delay * dData.forward; } else { //滑行 if (dData.forward == 0) { //需要的减速时间 float nTime = speedAbs / drive.driveGroundFrictionM; float useA = drive.driveCurrentMoveSpeedM > 0 ? -drive.driveGroundFrictionM : drive.driveGroundFrictionM; if (delay <= nTime) { float d = useA * delay; dis = drive.driveCurrentMoveSpeedM * delay + d * delay / 2; drive.driveCurrentMoveSpeedM += d; } //减到0 else { dis = drive.driveCurrentMoveSpeedM * nTime / 2; //vt/2 drive.driveCurrentMoveSpeedM = 0; } } else { float useA = drive.driveAccelerateSpeedM * dData.forward; bool sameSymbol = MathUtils.sameSymbol(useA, drive.driveCurrentMoveSpeedM); //符号相同,并且已经是最高速度 if (sameSymbol && speedAbs >= _useMoveSpeedM) { dis = drive.driveCurrentMoveSpeedM * delay; } else { //需要加速的时间 float nTime = (_useMoveSpeedM - (sameSymbol ? speedAbs : -speedAbs)) / drive.driveAccelerateSpeedM; //匀加速 if (delay <= nTime) { float d = useA * delay; dis = drive.driveCurrentMoveSpeedM * delay + d * delay / 2; drive.driveCurrentMoveSpeedM += d; } //到max else { dis = drive.driveCurrentMoveSpeedM * nTime + useA * nTime * nTime / 2; //到达最大速度 drive.driveCurrentMoveSpeedM = useA > 0 ? _useMoveSpeedM : -_useMoveSpeedM; //剩余时间用新速度 dis += (drive.driveCurrentMoveSpeedM * (delay - nTime)); } } } } bool hasPos = false; bool hasDir = false; if (dData.turn == 0) { if (dis != 0) { _scenePosLogic.calculateVectorByDir(_tempPos, _dir, dis); _scenePosLogic.addPos(_tempPos, _pos); hasPos = true; } else { return; } } else { if (dis != 0) { float angle; float radius; if (drive.canDriveTurnAtPivot) { angle = drive.driveDirectionSpeed * delay; radius = dis / angle; } else { radius = drive.driveTurnRadius; angle = dis / radius; } //正方向 float forward = (float)(radius * Math.Sin(angle)); //两侧 float side = (float)(radius * (1 - Math.Cos(angle))); _tempPos.x = forward; _tempPos.z = dData.turn * side; _tempPos.y = 0; //朝向向量 _scenePosLogic.rotatePosByDir2D(_tempPos, _dir); _scenePosLogic.addPos(_tempPos, _pos); //朝向修改 _dir.direction = MathUtils.directionCut(_dir.direction - (angle * dData.turn)); hasDir = true; hasPos = true; } else { if (drive.canDriveTurnAtPivot) { float angle = drive.driveDirectionSpeed * delay; _dir.direction = MathUtils.directionCut(_dir.direction - (angle * dData.turn)); hasDir = true; } else { return; } } } BaseGameUtils.makeTerrainPos(_tempPos); if (hasDir) { _unit.pos.onSetDir(); } if (hasPos) { if (_scenePosLogic.isPosEnabled(_moveType, _tempPos)) { _pos.copyPos(_tempPos); _unit.pos.onSetPos(); } else { // Ctrl.print("撞墙",_tempPos.toDataString()); } } if (drive.driveAccelerateSpeedM != 0 && drive.driveCurrentMoveSpeedM == 0f && dData.forward == 0 && _currentMoveIsInitiative) { if (!drive.canDriveTurnAtPivot || dData.turn == 0) { stopMove(); } } }
public override void init() { base.init(); _scenePosLogic = _scene.pos; _d = _data.move; _pos = _data.pos.pos; _dir = _data.pos.dir; //有战斗数据 if (_data.fight != null) { FightUnitConfig fightUnitConfig = _data.getFightIdentity().getFightUnitConfig(); _moveType = fightUnitConfig.mapMoveType; _walkSpeedRatio = fightUnitConfig.walkSpeedRatio; if (fightUnitConfig.needDrive) { if (_drive == null) { _drive = new DriveLogic(); } DriveLogic drive = _drive; drive.needDrive = true; drive.needDrive = fightUnitConfig.needDrive; drive.canDriveTurnAtPivot = fightUnitConfig.canDriveTurnAtPivot; drive.driveDirectionSpeed = fightUnitConfig.driveDirectionSpeedT; drive.driveTurnRadius = fightUnitConfig.driveTurnRadius; if (fightUnitConfig.driveAccelerateSpeed == 0) { drive.driveAccelerateSpeedM = 0f; drive.driveGroundFrictionM = 0f; } else { drive.driveAccelerateSpeedM = fightUnitConfig.driveAccelerateSpeed * Global.useMoveSpeedRatio / 1000000f; //先暂时取陆地的 drive.driveGroundFrictionM = MapBlockTypeConfig.get(MapBlockType.Land).groundFriction *Global.useMoveSpeedRatio / 1000000f; } } else { if (_drive != null) { _drive.needDrive = false; } } calculateUseMoveSpeed(); } else { if (_drive != null) { _drive.needDrive = false; } } }