/** * 跳判断相关脚本代码 */ let assign = function (target, ...varArgs) { if (target == null) { throw new TypeError('Cannot convert undefined or null to object'); } if (!varArgs || varArgs.length <= 0) { return target; } // 深度合并对象 function deepAssign(obj1, obj2) { for (let key in obj2) { obj1[key] = obj1[key] && obj1[key].toString() === "[object Object]" ? deepAssign(obj1[key], obj2[key]) : obj1[key] = obj2[key]; } return obj1; } varArgs.forEach(val => { target = deepAssign(target, val); }); return target; }; function Event() { this.events = {}; } Event.prototype.addEventListener = function (type, listener) { this.events[type] = this.events[type] || []; this.events[type].push(listener); }; Event.prototype.trigger = function () { for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } var type = args[0]; var params = args.slice(1); if (!!this.events[type]) { // console.log("type:",type); this.events[type].forEach(function (listener) { try { listener.apply(null, params); } catch (e) { console.error(e); } }); } }; var ActionJump = function ActionJump() { let jumpOpts = { //是否上升的标志位 isDirectionUp: false, //持续上升次数 continueUpCount: 0, //上一点的持续上升的次数,为了记录波峰的上升次数 continueUpFormerCount: 0, continueDownCount: 0, continueDownFormerCount: 0, //上一点的状态,上升还是下降 lastStatus: false, //波峰值 peakOfWave: 0, //波谷值 valleyOfWave: 0, //检测到极快的波动的次数 timeOfPeakCount: 0, //停止跳 bStopJump: false, //上次传感器的值 gravityOld: 0, bUpState: false, } this.jumpOpts = jumpOpts; //其他波峰波谷参数相关数组记录 this.peakOfWaveArray = []; this.peakOfWaveMaxValue = 0; this.valleyOfWaveArray = []; this.valleyOfWaveMinValue = 0; this.highestCount = 0; //陀螺仪 this.oriGyroYArray = []; this.event = new Event(); } ActionJump.prototype.addEventListener = function (type, listener) { this.event.addEventListener(type, listener); }; ActionJump.prototype.updateJump = function () { let data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; //使用三个轴的数据,计算重力轴的加速度。最后减去重力的加速度值 //********加速计******** let { lAccX, lAccY, lAccZ } = data.linearAcc; let { oAccX, oAccY, oAccZ } = data.oriAcc; let { oGyroX, oGyroY, oGyroZ } = data.oriGyro; this.detectorNewStep(data.resultant, lAccX, lAccY, lAccZ, oAccX, oAccY, oAccZ, data.runIndex, oGyroY); }; /* * 检测步子,并开始计步 * 1.传入数据 * 2.如果检测到了波峰,并且符合时间差以及阈值的条件,则判定为1步 * 3.符合时间差条件,波峰波谷差值大于initialValue,则将该差值纳入阈值的计算中 * */ ActionJump.prototype.detectorNewStep = function (resultant, linearX, linearY, linearZ, oriX, oriY, oriZ, _runIndex, _oGyroY) { let bUpdate = true; let _judgmentValue = oriZ; if (this.jumpOpts.gravityOld == 0) { this.jumpOpts.gravityOld = _judgmentValue; } else { if (!this.jumpOpts.bStopJump) { let { bState, bType, value } = this.detectorPeakOfWaveAndValleyOfWave(_judgmentValue, this.jumpOpts.gravityOld); if (bState) { this.jumpOpts.bUpState = true; let _temp = { type: bType, oldValue: value, value: resultant, lastIndex: _runIndex - 1 }; this.event.trigger('resultant', _temp); bUpdate = false; //记录最高点和最低点数组 if (bType == 'peakOfWave') { this.peakOfWaveArray.push(_temp); if (value > this.peakOfWaveMaxValue) this.peakOfWaveMaxValue = value; } else if (bType == 'valleyOfWave') { this.valleyOfWaveArray.push(_temp); if (value < this.valleyOfWaveMinValue) this.valleyOfWaveMinValue = value; } this.highestCount = 0; //陀螺仪部分 this.oriGyroYArray = []; } if (this.jumpOpts.bUpState) { this.oriGyroYArray.push(_oGyroY); //出现极值后 if (Math.abs(linearZ) < 4 && Math.abs(resultant) < 6) { this.highestCount++; if (this.highestCount >= 2) { //达到最高点, this.jumpOpts.bStopJump = true; let _currentMaxValue = 0; if (Math.abs(this.peakOfWaveMaxValue) > Math.abs(this.valleyOfWaveMinValue)) { _currentMaxValue = this.peakOfWaveMaxValue; } else { _currentMaxValue = this.valleyOfWaveMinValue; } let allOGyroValue = 0; for (let i = 0; i < this.oriGyroYArray.length; i++) { allOGyroValue += this.oriGyroYArray[i]; } allOGyroValue /= this.oriGyroYArray.length; //目前测试预大于100 为旋转跳动 // if (allOGyroValue > 0) { // console.log('right:', allOGyroValue); // } else { // console.log('left:', allOGyroValue); // } this.event.trigger('resultant', { type: "jump", acc: _currentMaxValue, value: resultant }); this.event.trigger('resultant', { type: "curAngle", value: _currentMaxValue, resultant: resultant }); this.event.trigger('resultant', { type: "rotate", value: allOGyroValue, resultant: resultant }); //如果_currentMaxValue小于30判断原地跳 // console.log("_currentMaxValue:", _currentMaxValue,allOGyroValue); //后面通用使用这个类型传输数据 this.event.trigger('resultant', { type: "stateDataOfJump", currentMaxValue: _currentMaxValue, oGyroValue: allOGyroValue, resultant: resultant }); // bUpdate = false; this.jumpOpts.bUpState = false; this.resetAll(); } } } } else { this.jumpOpts.timeOfPeakCount++; if (this.jumpOpts.timeOfPeakCount >= 30) { this.jumpOpts.timeOfPeakCount = 0; this.jumpOpts.bStopJump = false; this.event.trigger('resultant', { type: "stop" }); this.resetAll(); } } // let result = Math.atan2(averX, averZ) * 180 / (Math.PI); // result = Math.round(result); // let curAngle = result > 0 ? result : (360 + result); // console.log("curAngle:", curAngle); this.event.trigger('resultant', { type: "bUpdateDraw", linearX: linearX, linearZ: linearZ, linearY: linearY, oriX: oriX, oriY: oriY, oriZ: oriZ }); this.jumpOpts.gravityOld = _judgmentValue; } } ActionJump.prototype.detectorPeakOfWaveAndValleyOfWave = function (newValue, oldValue) { this.jumpOpts.lastStatus = this.jumpOpts.isDirectionUp; if (newValue >= oldValue) { this.jumpOpts.continueDownFormerCount = this.jumpOpts.continueDownCount; this.jumpOpts.continueDownCount = 0; this.jumpOpts.isDirectionUp = true; this.jumpOpts.continueUpCount++; } else { this.jumpOpts.continueUpFormerCount = this.jumpOpts.continueUpCount; this.jumpOpts.continueUpCount = 0; this.jumpOpts.isDirectionUp = false; this.jumpOpts.continueDownCount++; } if (!this.jumpOpts.isDirectionUp && this.jumpOpts.lastStatus && this.jumpOpts.continueUpFormerCount >= 2 && Math.abs(oldValue) >= 5) { this.jumpOpts.peakOfWave = oldValue; return { value: oldValue, bType: 'peakOfWave', bState: true }; } else if (!this.jumpOpts.lastStatus && this.jumpOpts.isDirectionUp && this.jumpOpts.continueDownFormerCount >= 2 && Math.abs(oldValue) >= 5) { this.jumpOpts.valleyOfWave = oldValue; return { value: oldValue, bType: 'valleyOfWave', bState: true }; } else { return { value: oldValue, bType: 'None', bState: false }; } } //重置对应的参数 ActionJump.prototype.resetAll = function () { this.peakOfWaveArray = []; this.peakOfWaveMaxValue = 0; this.valleyOfWaveArray = []; this.valleyOfWaveMinValue = 0; this.highestCount = 0; this.jumpOpts.continueDownFormerCount = 0; this.jumpOpts.continueDownCount = 0; this.jumpOpts.continueUpFormerCount = 0; this.jumpOpts.continueUpCount = 0; } if (typeof module === "object" && typeof module.exports === "object") { module.exports = ActionJump; }