adds raw power metric and memory cleanup in games
This commit is contained in:
parent
63216b1159
commit
cb4b2d831f
|
|
@ -41,6 +41,7 @@ export function createRowingGames (canvasElement, clientWidth, clientHeight) {
|
|||
// todo: check if there is some kaboomish way to get the active scene
|
||||
let activeScene
|
||||
k.scene('strokeFighterBattle', () => { activeScene = StrokeFighterBattleScene(k) })
|
||||
k.scene('disposed', () => { })
|
||||
|
||||
k.go('strokeFighterBattle')
|
||||
|
||||
|
|
@ -50,8 +51,15 @@ export function createRowingGames (canvasElement, clientWidth, clientHeight) {
|
|||
}
|
||||
}
|
||||
|
||||
// todo: currently we move to an empty scene to dispose the game as there does not seem to be
|
||||
// a mechanism in kaboom to dispose the instance.
|
||||
function dispose () {
|
||||
k.go('disposed')
|
||||
}
|
||||
|
||||
return {
|
||||
k,
|
||||
dispose,
|
||||
appState
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -182,17 +182,34 @@ export default function StrokeFighterBattleScene (k) {
|
|||
})
|
||||
|
||||
const timer = k.add([
|
||||
k.text('0'),
|
||||
k.text('00:00'),
|
||||
k.scale(0.8),
|
||||
k.pos(12, 32),
|
||||
k.fixed(),
|
||||
k.layer('ui')
|
||||
])
|
||||
|
||||
let trainingTimeRounded = 0
|
||||
timer.onUpdate(() => {
|
||||
trainingTime += k.dt()
|
||||
timer.text = trainingTime.toFixed(2)
|
||||
const newTrainingTimeRounded = Math.round(trainingTime)
|
||||
if (trainingTimeRounded !== newTrainingTimeRounded) {
|
||||
timer.text = `${secondsToTimeString(newTrainingTimeRounded)} / ${k.debug.fps()}fps`
|
||||
trainingTimeRounded = newTrainingTimeRounded
|
||||
}
|
||||
})
|
||||
|
||||
// converts a timestamp in seconds to a human readable hh:mm:ss format
|
||||
function secondsToTimeString (secondsTimeStamp) {
|
||||
if (secondsTimeStamp === Infinity) return '∞'
|
||||
const hours = Math.floor(secondsTimeStamp / 60 / 60)
|
||||
const minutes = Math.floor(secondsTimeStamp / 60) - (hours * 60)
|
||||
const seconds = Math.floor(secondsTimeStamp % 60)
|
||||
let timeString = hours > 0 ? ` ${hours.toString().padStart(2, '0')}:` : ''
|
||||
timeString += `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`
|
||||
return timeString
|
||||
}
|
||||
|
||||
k.onCollide('bullet', 'enemy', (bullet, enemy) => {
|
||||
k.destroy(bullet)
|
||||
enemy.hurt(1)
|
||||
|
|
@ -218,9 +235,9 @@ export default function StrokeFighterBattleScene (k) {
|
|||
}
|
||||
|
||||
function driveFinished (metrics) {
|
||||
if (metrics.power < THRESHOLD_POWER * 0.75) {
|
||||
if (metrics.powerRaw < THRESHOLD_POWER * 0.75) {
|
||||
fireWeapons(1)
|
||||
} else if (metrics.power < THRESHOLD_POWER) {
|
||||
} else if (metrics.powerRaw < THRESHOLD_POWER) {
|
||||
fireWeapons(2)
|
||||
} else {
|
||||
fireWeapons(3)
|
||||
|
|
|
|||
|
|
@ -92,4 +92,10 @@ export class GameComponent extends AppElement {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
disconnectedCallback () {
|
||||
if (this.rowingGames !== undefined) {
|
||||
this.rowingGames.dispose()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,9 +8,6 @@
|
|||
import NoSleep from 'nosleep.js'
|
||||
import { filterObjectByKeys } from './helper.js'
|
||||
|
||||
const rowingMetricsFields = ['strokesTotal', 'distanceTotal', 'caloriesTotal', 'power', 'heartrate',
|
||||
'heartrateBatteryLevel', 'splitFormatted', 'strokesPerMinute', 'durationTotalFormatted', 'strokeState']
|
||||
|
||||
export function createApp (app) {
|
||||
const urlParameters = new URLSearchParams(window.location.search)
|
||||
const mode = urlParameters.get('mode')
|
||||
|
|
@ -74,13 +71,9 @@ export function createApp (app) {
|
|||
break
|
||||
}
|
||||
case 'metrics': {
|
||||
let activeFields = rowingMetricsFields
|
||||
const resetStateFields = ['heartrate', 'heartrateBatteryLevel']
|
||||
// if we are in reset state only update heart rate
|
||||
if (data.strokesTotal === 0) {
|
||||
activeFields = ['heartrate', 'heartrateBatteryLevel']
|
||||
}
|
||||
|
||||
const filteredData = filterObjectByKeys(data, activeFields)
|
||||
const filteredData = (data.strokesTotal === 0) ? filterObjectByKeys(data, resetStateFields) : data
|
||||
app.updateState({ ...app.getState(), metrics: filteredData })
|
||||
break
|
||||
}
|
||||
|
|
|
|||
|
|
@ -158,6 +158,7 @@ function createRowingStatistics (config) {
|
|||
strokeTime: lastStrokeDuration, // seconds
|
||||
distance: lastStrokeDistance > 0 && lastStrokeSpeed > 0 && sessionState === 'rowing' ? lastStrokeDistance : 0, // meters
|
||||
power: powerAverager.getAverage() > 0 && lastStrokeSpeed > 0 && sessionState === 'rowing' ? powerAverager.getAverage() : 0, // watts
|
||||
powerRaw: powerAverager.getLastPushedValue() > 0 && lastStrokeSpeed > 0 && sessionState === 'rowing' ? powerAverager.getLastPushedValue() : 0, // watts
|
||||
split: splitTime, // seconds/500m
|
||||
splitFormatted: secondsToTimeString(splitTime),
|
||||
powerRatio: powerRatioAverager.getAverage() > 0 && lastStrokeSpeed > 0 && sessionState === 'rowing' ? powerRatioAverager.getAverage() : 0,
|
||||
|
|
|
|||
|
|
@ -29,6 +29,10 @@ function createWeightedAverager (maxNumOfDataPoints) {
|
|||
}
|
||||
}
|
||||
|
||||
function getLastPushedValue () {
|
||||
return dataPoints[0]
|
||||
}
|
||||
|
||||
function reset () {
|
||||
dataPoints = []
|
||||
}
|
||||
|
|
@ -36,6 +40,7 @@ function createWeightedAverager (maxNumOfDataPoints) {
|
|||
return {
|
||||
pushValue,
|
||||
getAverage,
|
||||
getLastPushedValue,
|
||||
reset
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,22 @@ test('average of a and b is (2*b + a) / 3', () => {
|
|||
assert.is(weightedAverager.getAverage(), 3)
|
||||
})
|
||||
|
||||
test('average of a, b and c is (2*c + b) / 3 if maxNumOfDataPoints is 2', () => {
|
||||
const weightedAverager = createWeightedAverager(2)
|
||||
weightedAverager.pushValue(5) // a
|
||||
weightedAverager.pushValue(2) // b
|
||||
weightedAverager.pushValue(17) // c
|
||||
assert.is(weightedAverager.getAverage(), 12)
|
||||
})
|
||||
|
||||
test('lastPushedValue of a, b and c is c', () => {
|
||||
const weightedAverager = createWeightedAverager(10)
|
||||
weightedAverager.pushValue(5) // a
|
||||
weightedAverager.pushValue(2) // b
|
||||
weightedAverager.pushValue(17) // c
|
||||
assert.is(weightedAverager.getLastPushedValue(), 17)
|
||||
})
|
||||
|
||||
test('average should be 0 after reset', () => {
|
||||
const weightedAverager = createWeightedAverager(10)
|
||||
weightedAverager.pushValue(5)
|
||||
|
|
|
|||
|
|
@ -37,14 +37,13 @@ export default {
|
|||
terser({
|
||||
ecma: 2020,
|
||||
module: true,
|
||||
warnings: true,
|
||||
mangle: {
|
||||
properties: {
|
||||
regex: /^__/
|
||||
}
|
||||
}
|
||||
}),
|
||||
summary()
|
||||
summary({})
|
||||
],
|
||||
output:
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue