|
|
@@ -0,0 +1,288 @@
|
|
|
+/**
|
|
|
+ * 跳判断相关脚本代码
|
|
|
+ */
|
|
|
+
|
|
|
+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;
|
|
|
+}
|