220 lines
7.9 KiB
JavaScript
220 lines
7.9 KiB
JavaScript
// UI for title screen
|
|
function drawTitleScreenUI() {
|
|
}
|
|
|
|
|
|
var playingUIOffsets = {
|
|
heart: 100,
|
|
breath: 100,
|
|
blink: 100
|
|
};
|
|
|
|
// UI for playing
|
|
function drawPlayingUI() {
|
|
|
|
// cartesianRect(0,ch/3*2, cw, ch/3, "#333333")
|
|
|
|
//Heart Rate Monitor
|
|
heartBeatUI(cw / 4 * 3 - 8, ch / 8 * 7 - 8 + playingUIOffsets.heart, cw / 4, ch / 8);
|
|
|
|
//Respiration Monitor
|
|
respiratoryUI(cw / 8 * 5, ch / 8 * 7 - 8 + playingUIOffsets.breath, cw / 16, ch / 8);
|
|
|
|
//Blink eye
|
|
blinkUI();
|
|
|
|
|
|
switch(tutState) {
|
|
case tutorialStates.getCereal:
|
|
text("Objective: eat breakfast",10,ch-30,"black",2);
|
|
break;
|
|
case tutorialStates.getMail:
|
|
text("Objective: bring in the mail",10,ch-30,"black",2);
|
|
break;
|
|
case tutorialStates.goToBed:
|
|
text("Objective: go back to bed",10,ch-30,"black",2);
|
|
break;
|
|
}
|
|
|
|
var alpha;
|
|
// dry overlay
|
|
if (eyeDryness > constants.lifeFuncs.blink.dryTime) {
|
|
alpha = (eyeDryness - constants.lifeFuncs.blink.dryTime) / 350;
|
|
curCtx.globalAlpha = alpha;
|
|
img(sprites.blinkOverlay, cw / 2, ch / 2);
|
|
}
|
|
|
|
// blue overlay
|
|
switch (currentBreathMode) {
|
|
case breathMode.inhale:
|
|
if (fullBreathTimer >= 200) {
|
|
alpha = (fullBreathTimer-200) / 200;
|
|
curCtx.globalAlpha = clamp(alpha,0,1);
|
|
img(sprites.breathOverlay, cw / 2, ch / 2);
|
|
}
|
|
break;
|
|
case breathMode.exhale:
|
|
if (noBreathTimer >= 200) {
|
|
alpha = (noBreathTimer-200) / 200;
|
|
curCtx.globalAlpha = clamp(alpha,0,1);
|
|
img(sprites.breathOverlay, cw / 2, ch / 2);
|
|
}
|
|
break;
|
|
}
|
|
|
|
if(pressure > 80) {
|
|
alpha = (pressure-80) / 20;
|
|
curCtx.globalAlpha = clamp(alpha,0,1);
|
|
img(sprites.beatOverlay, cw / 2, ch / 2);
|
|
}
|
|
|
|
if( pressure < 25 ) {
|
|
alpha = (25-pressure) / 25;
|
|
curCtx.globalAlpha = clamp(alpha,0,1);
|
|
img(sprites.beatOverlay, cw / 2, ch / 2);
|
|
}
|
|
curCtx.globalAlpha = 1;
|
|
}
|
|
|
|
//UI for pause screen
|
|
function drawPausedUI() {
|
|
}
|
|
|
|
//UI for game end
|
|
function drawEndUI() {
|
|
}
|
|
|
|
|
|
/***
|
|
*
|
|
* RESPIRATORY UI
|
|
*
|
|
*/
|
|
|
|
function respiratoryUI(x, y, width, height) {
|
|
// cartesianRect(x, y, width, height, "rgb(" + noBreathTimer / 180 * 255 + "," + 0 + "," + 0 + ")");
|
|
// cartesianRect(x, y + (height - breath / constants.lifeFuncs.breath.fullBreath * height), width, breath / constants.lifeFuncs.breath.fullBreath * height, "rgb(" + 255 + "," + (255 - fullBreathTimer / 180 * 255) + "," + (255 - fullBreathTimer / 180 * 255) + ")");
|
|
|
|
var color = currentBreathMode === breathMode.inhale ? "rgb(" + fullBreathTimer + ",0,0)" : "rgb(" + noBreathTimer + ",0,0)";
|
|
rect(cw - 275, ch - 46 + playingUIOffsets.breath,70,70,color);
|
|
|
|
img(sprites.lungBack,cw - 275, ch - 46 + playingUIOffsets.breath);
|
|
|
|
img(sprites.lungCover,cw - 275, ch - 46 + playingUIOffsets.breath);
|
|
|
|
img(sprites.lungs,cw - 275, ch - 46 + playingUIOffsets.breath, 0, 1.5 + breath / 400, 1.5 + breath / 300 );
|
|
}
|
|
|
|
/***
|
|
*
|
|
* HEART RATE MONITOR UI
|
|
*
|
|
*/
|
|
|
|
//Heart rate monitor history
|
|
let heartBeatHistory = [];
|
|
heartBeatHistory.length = constants.ui.heartRate.history_length;
|
|
heartBeatHistory.fill(0);
|
|
|
|
//Shift accumulation
|
|
let shiftAccum = 0;
|
|
|
|
//Beat progression
|
|
let beatTimeElapsed = Infinity;
|
|
|
|
// Draw heartbeat UI
|
|
function heartBeatUI(x, y, width, height) {
|
|
|
|
//Shift monitor over once a full scrolling unit is accumulated
|
|
shiftAccum += constants.ui.heartRate.scroll_speed;
|
|
if (shiftAccum >= 1) {
|
|
shiftAccum %= 1;
|
|
beatTimeElapsed += 0.04;
|
|
|
|
//Remove oldest value
|
|
heartBeatHistory.shift();
|
|
|
|
//Append new value
|
|
pushNextBeatValue();
|
|
}
|
|
|
|
//If heart is beaten, reset beat timer.
|
|
if (heartBeat) {
|
|
beatTimeElapsed = 0;
|
|
heartBeat = false;
|
|
}
|
|
|
|
//Backdrop
|
|
var BackdropColor;
|
|
if (pressure > 42 && pressure < 60) {
|
|
BackdropColor = "#0c2605";
|
|
} else if (pressure > 28 && pressure < 75) {
|
|
BackdropColor = "#2b2b06";
|
|
} else {
|
|
BackdropColor = "#260505";
|
|
}
|
|
rect(x + width / 2, y + height / 2, width, height, BackdropColor);
|
|
img(sprites.heartBack, cw - 107, ch - 46 + playingUIOffsets.heart);
|
|
|
|
//Pressure Meter
|
|
rect(x + width - 8, y + height / 2, 16, height, "red");
|
|
rect(x + width - 8, y + height / 2, 16, height / 2, "yellow");
|
|
rect(x + width - 8, y + height / 2, 16, height / 6, "green");
|
|
let pressureHeight = Math.max(Math.min(y + height - (pressure / constants.lifeFuncs.cardio.optimalPressure * height / 2), y + height), y);
|
|
line(x + width - 16, pressureHeight, x + width, pressureHeight, 2, "black")
|
|
|
|
//Graph
|
|
for (let index = 0; index < heartBeatHistory.length; index++) {
|
|
const qrsValueAtPosition = heartBeatHistory[index];
|
|
const qrsValueAtNextPosition = heartBeatHistory[index + 1];
|
|
line(x + (index * (width - 16) / heartBeatHistory.length), y + (2 * height / 3) + (qrsValueAtPosition * (width - 16) / heartBeatHistory.length), x + ((index + 1) * (width - 16) / heartBeatHistory.length), y + (2 * height / 3) + (qrsValueAtNextPosition * (width - 16) / heartBeatHistory.length), Math.min(3, Math.max(3 / beatTimeElapsed, 1)), "red");
|
|
}
|
|
|
|
// cover
|
|
img(sprites.heartCover, cw - 107, ch - 46 + playingUIOffsets.heart);
|
|
}
|
|
|
|
//Determine next value to be added to the graph
|
|
function pushNextBeatValue() {
|
|
let nextBeatValue = 0;
|
|
|
|
//Timespan of one "square" on the EKG
|
|
const squareSize = constants.ui.heartRate.square_size;
|
|
//Length of full complex
|
|
const complexTime = constants.ui.heartRate.complex_width * squareSize;
|
|
//Length of PR segment of complex
|
|
const prTime = constants.ui.heartRate.pr_width * squareSize;
|
|
//Length of QRS component of complex
|
|
const qrsTime = constants.ui.heartRate.qrs_width * squareSize;
|
|
//Length of QT component of complex
|
|
const qtTime = constants.ui.heartRate.qt_width * squareSize;
|
|
|
|
if (beatTimeElapsed <= complexTime) {
|
|
//PR Segment
|
|
if (beatTimeElapsed <= prTime) {
|
|
nextBeatValue = 0.5 * (Math.pow((beatTimeElapsed / squareSize - (prTime / 2 / squareSize)), 2)) - 2;
|
|
} else if (beatTimeElapsed > prTime + squareSize && beatTimeElapsed <= prTime + squareSize + (qrsTime / 4)) { //QRS Segment pt. 1
|
|
nextBeatValue = -4 + beatTimeElapsed / squareSize;
|
|
} else if (beatTimeElapsed > prTime + squareSize + qrsTime / 4 && beatTimeElapsed <= prTime + squareSize + qrsTime / 2) { //QRS Segment pt. 2
|
|
nextBeatValue = -14 * (beatTimeElapsed / squareSize - 4.5) - 0.5;
|
|
} else if (beatTimeElapsed > prTime + squareSize + qrsTime / 2 && beatTimeElapsed <= prTime + squareSize + (3 * qrsTime / 4)) { //QRS Segment pt. 3
|
|
nextBeatValue = 7 * (beatTimeElapsed / squareSize - 5) - 6.5;
|
|
} else if (beatTimeElapsed > prTime + squareSize + (3 * qrsTime / 4) && beatTimeElapsed <= prTime + squareSize + qrsTime) { //QRS Segment pt. 4
|
|
nextBeatValue = 2 * (beatTimeElapsed / squareSize - 6);
|
|
} else if (beatTimeElapsed > prTime + squareSize * 2 + qrsTime && beatTimeElapsed <= prTime + squareSize * 2 + qrsTime + qtTime) { //PT Segment
|
|
nextBeatValue = 0.5 * Math.pow((beatTimeElapsed / squareSize - (prTime + squareSize * 2 + qrsTime + qtTime / 2) / squareSize), 2) - 3;
|
|
}
|
|
}
|
|
|
|
heartBeatHistory.push(nextBeatValue);
|
|
}
|
|
|
|
|
|
function blinkUI() {
|
|
// eye
|
|
img(sprites.eye, cw - 350, ch - 40 + playingUIOffsets.blink, 0, 2, 2);
|
|
var alpha = clamp(eyeDryness / constants.lifeFuncs.blink.dryTime, 0, 1);
|
|
curCtx.globalAlpha = alpha;
|
|
img(sprites.eyeDry, cw - 350, ch - 40 + playingUIOffsets.blink, 0, 2, 2);
|
|
curCtx.globalAlpha = 1;
|
|
} |