Merge pull request #4 from rsninja722/heartbeat-ui

Heartrate monitor
This commit is contained in:
rsninja722 2020-04-18 13:09:29 -04:00 committed by GitHub
commit 7b2fc5fd3f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 121 additions and 44 deletions

3
.gitignore vendored
View File

@ -3,3 +3,6 @@ docs/_site/*
docs/.sass-cache/* docs/.sass-cache/*
docs/.jekyll-cache/* docs/.jekyll-cache/*
docs/node_modules docs/node_modules
# idea
.idea

View File

@ -1,57 +1,121 @@
// UI for title screen // UI for title screen
function drawTitleScreenUI() {}; function drawTitleScreenUI() {
}
// UI for level transition // UI for level transition
function drawLevelTransitionUI() {}; function drawLevelTransitionUI() {
}
// UI for playing // UI for playing
function drawPlayingUI() {}; function drawPlayingUI() {
//Heart Rate Monitor
heartBeatUI(cw/4*3-8,ch/8*7-8,cw/4,ch/8);
//Respiration Monitor
respiratoryUI(cw/8*5,ch/8*7-8, cw/16, ch/8);
}
//UI for pause screen //UI for pause screen
function drawPausedUI() {}; function drawPausedUI() {
}
//UI for game end //UI for game end
function drawEndUI() {}; function drawEndUI() {
}
// Construct a rectangular UI
function rectUI() {}; /***
*
* RESPIRATORY UI
*
*/
function respiratoryUI(x, y, width, height){
cartesianRect(x,y,width,height, "black");
cartesianRect(x,y+(height-breath/constants.lifeFuncs.breath.fullBreath*height), width, breath/constants.lifeFuncs.breath.fullBreath*height, "teal");
}
/***
*
* HEART RATE MONITOR UI
*
*/
//Heart rate monitor history //Heart rate monitor history
var heartBeatHistory = [].fill(0,0, constants.ui.heartRate.history_length); let heartBeatHistory = [];
heartBeatHistory.length = constants.ui.heartRate.history_length;
heartBeatHistory.fill(0);
//Shift accumulation //Shift accumulation
var shiftAccum = 0; let shiftAccum = 0;
//Beat progression //Beat progression
var beatTimeElapsed = 0; let beatTimeElapsed = Infinity;
// Draw heartbeat UI // Draw heartbeat UI
function heartBeatUI(x, y, width, height){ function heartBeatUI(x, y, width, height){
//Shift monitor over once a full scrolling unit is accumulated
shiftAccum += constants.ui.heartRate.scroll_speed; shiftAccum += constants.ui.heartRate.scroll_speed;
if(shiftAccum>=1){ if(shiftAccum>=1){
shiftAccum%=1; shiftAccum%=1;
beatTimeElapsed += 0.04;
//Remove oldest value
heartBeatHistory.shift(); heartBeatHistory.shift();
//Append new value
pushNextBeatValue(); pushNextBeatValue();
} }
if(timeSinceLastBeat===0){ //If heart is beaten, reset beat timer.
if(heartBeat){
beatTimeElapsed = 0; beatTimeElapsed = 0;
heartBeat = false;
} }
//Backdrop
rect(x+width/2,y+height/2,width,height,"black");
//Graph
for (let index = 0; index < heartBeatHistory.length; index++) { for (let index = 0; index < heartBeatHistory.length; index++) {
const qrsValueAtPosition = heartBeatHistory[index]; const qrsValueAtPosition = heartBeatHistory[index];
line(x+index, y+(2*height/3), x+index, y+(2*height/3)+qrsValueAtPosition); const qrsValueAtNextPosition = heartBeatHistory[index+1];
line(x+(index*width/heartBeatHistory.length), y+(2*height/3)+(qrsValueAtPosition*width/heartBeatHistory.length), x+((index+1)*width/heartBeatHistory.length), y+(2*height/3)+(qrsValueAtNextPosition*width/heartBeatHistory.length),Math.min(3,Math.max(3/beatTimeElapsed,1)), "red");
} }
} }
//Determine next value to be added to the graph
function pushNextBeatValue(){ function pushNextBeatValue(){
var nextBeatValue; let nextBeatValue = 0;
beatTimeElapsed %= constants.ui.heartRate.complex_width; //Timespan of one "square" on the EKG
if(beatTimeElapsed<=constants.ui.heartRate.pr_width){ const squareSize = constants.ui.heartRate.square_size;
nextBeatValue = -0.25((x - 1.5)**2) + 0.5625; //Length of full complex
} else if (beatTimeElapsed >= constants.ui.heartRate.pr_width + 1 && beatTimeElapsed <= constants.ui.heartRate.pr_width + 1 + constants.ui.heartRate.qrs_width/4) { 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); heartBeatHistory.push(nextBeatValue);

View File

@ -26,11 +26,17 @@ var constants = {
history_length: 100, history_length: 100,
//300 squares/min //300 squares/min
scroll_speed: 0.13333, scroll_speed: 0.8,
pr_width: 0.16, square_size: 0.08,
qrs_width: 0.1, pr_width: 4,
qt_width: 0.39, qrs_width: 2,
complex_width: 0.65 qt_width: 5,
complex_width: 18
}
},
lifeFuncs:{
breath:{
fullBreath: 200
} }
}, },
legs:{ legs:{

View File

@ -341,6 +341,11 @@ function rect(x,y,w,h,color) {
curCtx.fillRect(x-(w/2)+camera.x+difx,y-(h/2)+camera.y+dify,w,h); curCtx.fillRect(x-(w/2)+camera.x+difx,y-(h/2)+camera.y+dify,w,h);
} }
function cartesianRect(x,y,w,h,color) {
curCtx.fillStyle = color;
curCtx.fillRect(x+camera.x+difx,y+camera.y+dify,w,h);
}
function circle(x,y,r,color) { function circle(x,y,r,color) {
curCtx.beginPath(); curCtx.beginPath();
curCtx.arc(x+camera.x+difx, y+camera.y+dify, r, 0, 2 * Math.PI, false); curCtx.arc(x+camera.x+difx, y+camera.y+dify, r, 0, 2 * Math.PI, false);
@ -348,11 +353,13 @@ function circle(x,y,r,color) {
curCtx.fill(); curCtx.fill();
} }
function line(x1, y1, x2, y2, color) { function line(x1, y1, x2, y2, weight, color) {
curCtx.beginPath(); curCtx.beginPath();
curCtx.style = color; curCtx.strokeStyle = color;
curCtx.lineWidth = weight;
curCtx.moveTo(x1 + camera.x + difx, y1 + camera.y + dify); curCtx.moveTo(x1 + camera.x + difx, y1 + camera.y + dify);
curCtx.lineTo(x2 + camera.x + difx , y2 + camera.y + dify); curCtx.lineTo(x2 + camera.x + difx , y2 + camera.y + dify);
curCtx.stroke();
} }
function shape(x,y,relitivePoints,color) { function shape(x,y,relitivePoints,color) {

View File

@ -1,32 +1,29 @@
var breath = 180; let breath = 180;
var fullBreathTimer = 0; let fullBreathTimer = 0;
var heartRate = 60; let heartRate = 60;
var timeSinceLastBeat = 0; let heartBeat = false;
function updateLife() { function updateLife() {
if(keyDown[k.Z]) { if(keyDown[k.z]) {
breathe(); breathe();
} else { } else {
breath--; breath--;
} }
if(keyPress[k.X]) { if(keyPress[k.x]) {
heartbeat(); heartbeat();
} else {
timeSinceLastBeat++;
} }
}; };
function breathe() { function breathe() {
breath += 5; breath += 5;
if(breath >= 200) { if(breath >= constants.lifeFuncs.breath.fullBreath) {
breath = 200; breath = constants.lifeFuncs.breath.fullBreath;
fullBreathTimer++; fullBreathTimer++;
if(fullBreathTimer >= 60) { if(fullBreathTimer >= 60) {
//cough and lose breath or something //cough and lose breath or something
@ -38,7 +35,5 @@ function breathe() {
}; };
function heartbeat() { function heartbeat() {
heartBeat = true;
timeSinceLastBeat = 0;
}; };

View File

@ -3,4 +3,6 @@ function handlePlaying() {
if(keyPress[k.BACKSLASH]) { if(keyPress[k.BACKSLASH]) {
globalState = globalStates.building; globalState = globalStates.building;
} }
updateLife();
} }

View File

@ -33,13 +33,13 @@
<script src="assets/js/world/level.js"></script> <script src="assets/js/world/level.js"></script>
<!-- <script src="assets/js/player/player.js"></script> <!-- <script src="assets/js/player/player.js"></script>
<script src="assets/js/player/leg.js"></script> <script src="assets/js/player/leg.js"></script> -->
<script src="assets/js/player/lifeFunctions.js"></script> --> <script src="assets/js/player/lifeFunctions.js"></script>
<script src="assets/js/playing/playing.js"></script> <script src="assets/js/playing/playing.js"></script>
<!-- <script src="assets/js/titleScreen/titleScreen.js"></script> <!-- <script src="assets/js/titleScreen/titleScreen.js"></script> -->
<script src="assets/js/UI/ui.js"></script> --> <script src="assets/js/UI/ui.js"></script>
<!-- Webpage --> <!-- Webpage -->
<script src="assets/js/injection/cssinjector.js"></script> <script src="assets/js/injection/cssinjector.js"></script>