diff --git a/docs/assets/js/UI/ui.js b/docs/assets/js/UI/ui.js new file mode 100644 index 0000000..a2dfd21 --- /dev/null +++ b/docs/assets/js/UI/ui.js @@ -0,0 +1,58 @@ +// UI for title screen +function drawTitleScreenUI() {}; + +// UI for level transition +function drawLevelTransitionUI() {}; + +// UI for playing +function drawPlayingUI() {}; + +//UI for pause screen +function drawPausedUI() {}; + +//UI for game end +function drawEndUI() {}; + +// Construct a rectangular UI +function rectUI() {}; + +//Heart rate monitor history +var heartBeatHistory = [].fill(0,0, constants.ui.heartRate.history_length); + +//Shift accumulation +var shiftAccum = 0; + +//Beat progression +var beatTimeElapsed = 0; + +// Draw heartbeat UI +function heartBeatUI(x, y, width, height){ + + shiftAccum += constants.ui.heartRate.scroll_speed; + if(shiftAccum>=1){ + shiftAccum%=1; + heartBeatHistory.shift(); + pushNextBeatValue(); + } + + if(timeSinceLastBeat===0){ + beatTimeElapsed = 0; + } + + for (let index = 0; index < heartBeatHistory.length; index++) { + const qrsValueAtPosition = heartBeatHistory[index]; + line(x+index, y+(2*height/3), x+index, y+(2*height/3)+qrsValueAtPosition); + } +} + +function pushNextBeatValue(){ + var nextBeatValue; + + beatTimeElapsed %= constants.ui.heartRate.complex_width; + if(beatTimeElapsed<=constants.ui.heartRate.pr_width){ + nextBeatValue = -0.25((x - 1.5)**2) + 0.5625; + } else if (beatTimeElapsed >= constants.ui.heartRate.pr_width + 1 && beatTimeElapsed <= constants.ui.heartRate.pr_width + 1 + constants.ui.heartRate.qrs_width/4) { + } + + heartBeatHistory.push(nextBeatValue); +} diff --git a/docs/assets/js/constants.js b/docs/assets/js/constants.js index 71638b2..4570ac8 100644 --- a/docs/assets/js/constants.js +++ b/docs/assets/js/constants.js @@ -19,6 +19,24 @@ var constants = { game: { } + }, + + // Heart rate monitor UI constants + heartRate: { + history_length: 100, + + //300 squares/min + scroll_speed: 0.13333, + pr_width: 0.16, + qrs_width: 0.1, + qt_width: 0.39, + complex_width: 0.65 + } + }, + legs:{ + size:{ + maximumMovement: 30 } } + }; \ No newline at end of file diff --git a/docs/assets/js/game.js b/docs/assets/js/game.js index dcd3fee..dbbfc67 100644 --- a/docs/assets/js/game.js +++ b/docs/assets/js/game.js @@ -348,6 +348,13 @@ function circle(x,y,r,color) { curCtx.fill(); } +function line(x1, y1, x2, y2, color) { + curCtx.beginPath(); + curCtx.style = color; + curCtx.moveTo(x1 + camera.x + difx, y1 + camera.y + dify); + curCtx.lineTo(x2 + camera.x + difx, y2 + camera.y + dify); +} + function shape(x,y,relitivePoints,color) { x+=camera.x+difx; y+=camera.y+dify; diff --git a/docs/assets/js/index.js b/docs/assets/js/index.js index b85d54e..df0eaaa 100644 --- a/docs/assets/js/index.js +++ b/docs/assets/js/index.js @@ -11,27 +11,28 @@ audio = [ ]; var globalStates = { - titleScreen:0, - starting:1, - playing:2, - paused:3, - end:4 + titleScreen: 0, + levelTransition: 1, + playing: 2, + paused: 3, + end: 4, + building: 5 }; -var globalState = globalStates.titleScreen; +var globalState = globalStates.playing; function update() { - switch(globalState) { + switch (globalState) { // title screen case globalStates.titleScreen: break; - // starting - case globalStates.starting: + // level transition + case globalStates.levelTransition: break; // playing case globalStates.playing: - + handlePlaying(); break; // paused case globalStates.paused: @@ -40,20 +41,66 @@ function update() { // end case globalStates.end: + break; + //building - to be used only in development + case globalStates.building: + buildUpdate(); break; } } -function input() { - -} - function draw() { + switch (globalState) { + // title screen + case globalStates.titleScreen: + break; + // level transition + case globalStates.levelTransition: + + break; + // playing + case globalStates.playing: + drawWorldBlocks(); + break; + // paused + case globalStates.paused: + + break; + // end + case globalStates.end: + + break; + //building - to be used only in development + case globalStates.building: + buildDraw(); + break; + } } function absoluteDraw() { - + switch (globalState) { + // title screen + case globalStates.titleScreen: + drawTitleScreenUI(); + break; + // level transition + case globalStates.levelTransition: + drawLevelTransitionUI(); + break; + // playing + case globalStates.playing: + drawPlayingUI(); + break; + // paused + case globalStates.paused: + drawPausedUI(); + break; + // end + case globalStates.end: + drawEndUI(); + break; + } } function onAssetsLoaded() { diff --git a/docs/assets/js/player/leg.js b/docs/assets/js/player/leg.js new file mode 100644 index 0000000..0ca436f --- /dev/null +++ b/docs/assets/js/player/leg.js @@ -0,0 +1,56 @@ + + +// a Class for legs +class Leg{ + + + Leg(thighX, thighY, kneeX, kneeY, footX, footY){ + + // Thigh X,Y + this.thighX = thighX; + this.thighY = thighY; + + // Knee X,Y + this.kneeX = kneeX; + this.kneeY = kneeY; + + // Foot X,Y + this.footX = footX; + this.footY = footY + + // Calculates distances + this.thighToKnee = abs(math.hypot(thighX - kneeX, thighY - kneeY)); + this.kneeToFoot = abs(math.hypot(kneeX - footX, kneeY - footX)); + + } + + setThigh(newX, newY){ + this.thighX = newX; + this.thighY = newY; + + // Recalculates distances + this.thighToKnee = abs(math.hypot(newX - this.kneeX, newY - this.kneeY)); + } + + setKnee(newX, newY){ + this.kneeX = newX; + this.kneeY = newY; + + // Recalculates distances + this.thighToKnee = abs(math.hypot(this.thighX - newX, this.thighY - newY)); + this.kneeToFoot = abs(math.hypot(newX - this.footX, newY - this.footY)); + } + + setFoot(newX, newY){ + this.footX = newX; + this.footY = newY; + + // Recalculates distances + this.kneeToFoot = abs(math.hypot(this.kneeX - newX, this.kneeY - newY)); + } + + + +}; + + diff --git a/docs/assets/js/player/lifeFunctions.js b/docs/assets/js/player/lifeFunctions.js new file mode 100644 index 0000000..deb1cd0 --- /dev/null +++ b/docs/assets/js/player/lifeFunctions.js @@ -0,0 +1,44 @@ + +var breath = 180; +var fullBreathTimer = 0; +var heartRate = 60; + +var timeSinceLastBeat = 0; + + +function updateLife() { + + if(keyDown[k.Z]) { + breathe(); + } else { + breath--; + } + + if(keyPress[k.X]) { + heartbeat(); + } else { + timeSinceLastBeat++; + } + +}; + +function breathe() { + + breath += 5; + if(breath >= 200) { + breath = 200; + fullBreathTimer++; + if(fullBreathTimer >= 60) { + //cough and lose breath or something + } + } else { + fullBreathTimer = 0; + } + +}; + +function heartbeat() { + + timeSinceLastBeat = 0; + +}; \ No newline at end of file diff --git a/docs/assets/js/player/player.js b/docs/assets/js/player/player.js new file mode 100644 index 0000000..69fb573 --- /dev/null +++ b/docs/assets/js/player/player.js @@ -0,0 +1,133 @@ +class Player { + + constructor(x, y){ + this.x = x; + this.y = y; + this.hipL = {x:x-5,y:y}; + this.hipR = {x:x+5,y:y}; + this.footL = {x:x-5,y:y+10}; + this.footR = {x:x+5,y:y+10}; + this.kneeL= {x:x-5,y:y+5}; + this.kneeR = {x:x+5,y:y+5}; + this.legSelected = "l"; + this.shouldMoveLeg = false; + } + + getLeg(){ + if(this.legSelected === "l"){ + return [this.footL, this.kneeL, this.thighL]; + } + return [this.footR, this.kneeR, this.thighR]; + + } + +} + + + +// leg has been selected, move leg towards mouse +Player.prototype.moveLeg = function(){ + + + if(!this.shouldMoveLeg){ + return + } + + var target = mousePosition(); + + //TODO set a proper constant + if(Math.hypot(this.x - target.x, this.y - target.y) < constants.legs.size.maximumMovement){ + + // Points to move towards + var ix = target.x; + var iy = target.y; + var leg = this.getLeg() + + // Check collision psuedo code need to figure out actual collison + if(ix.collide()){ + ix = leg[0].x; + } + + // Check collision psuedo code need to figure out actual collison + if(iy.collide()){ + iy = leg[0].y; + } + + + // total distances as a square + var targetSqrDistance = ix * ix + iy * iy; + + // gets lengths may need to be tweaked + var thighKneeLength = abs(Math.hypot(leg[2].x - leg[1].x, leg[2].y - leg[1].y) * 2) + var kneeFootLength = abs(Math.hypot(leg[1].x - leg[0].x, leg[1].y - leg[0].y) * 2) + + + var thighKneeAngle = Math.max(-1, Math.min(1, (targetSqrDistance + thighKneeLength - kneeFootLength) + / (2 * (thighKneeLength / 2) * Math.sqrt(targetSqrDistance) + ))); + + + + + } + + + + + /* + + if target within range of leg + ik towards target in x + if colliding undo move + ik towards target in y + if colliding undo move + if out of target + ik towards target in x + if colliding undo move + ik towards target in y + if colliding undo move + slowly move torso towards mouse + planted leg ik towards torso + if torso outside the planted leg range + move torso back + */ + + + // Finds the distance between the old hip position and the future one + requiredLegDistance = Math.hypot(currentHip.x - futureFoot.x, currentHip.y - futureFoot.y); + + newFootX = futureFoot.x; + newFootY = futureFoot.y; + + + + // TODO implement collision checking + + + + newHipX = currentHip.x + futureFoot.x - currentFoot.x; + newHipY = currentHip.y + futureFoot.y - currentFoot.y; + + // newKneeX = + + + + + // returns new leg positions + return [{x:newHipX, y:newHipY}, {x:newKneeX, y:newKneeY}, {x:newFootX, y:newFootY}]; + + + + +} + + + + +Player.prototype.draw = function() { + +} + +Player.prototype.update = function() { + +} \ No newline at end of file diff --git a/docs/assets/js/playing/playing.js b/docs/assets/js/playing/playing.js new file mode 100644 index 0000000..995b15f --- /dev/null +++ b/docs/assets/js/playing/playing.js @@ -0,0 +1,6 @@ +function handlePlaying() { + // enter build mode + if(keyPress[k.BACKSLASH]) { + globalState = globalStates.building; + } +} \ No newline at end of file diff --git a/docs/assets/js/titleScreen/titleScreen.js b/docs/assets/js/titleScreen/titleScreen.js new file mode 100644 index 0000000..e69de29 diff --git a/docs/assets/js/world/build.js b/docs/assets/js/world/build.js new file mode 100644 index 0000000..d74e94e --- /dev/null +++ b/docs/assets/js/world/build.js @@ -0,0 +1,74 @@ +// build +// contains updating during build mode. Used to make levels +/*------------------------------------------------------------------------------------- + How to Use +to enter press \ +keys +arrow keys - move camera +rmb - place block +scroll - size block ++z - size horizontally ++x - size faster +c - delete last block +v - print block dimension list +-------------------------------------------------------------------------------------*/ + +// current block being added +var buildBlock = { x: 0, y: 0, w: 10, h: 10, type: 0 }; +var buildBlocks = []; + +function buildDraw() { + for (var i = 0; i < buildBlocks.length; i++) { + buildBlocks[i].draw(); + } + rect(buildBlock.x,buildBlock.y,buildBlock.w,buildBlock.h,"green"); +} + +// should only be called while in build mode +function buildUpdate() { + + // panning + if (keyDown[k.LEFT]) { moveCamera(-2, 0); } + if (keyDown[k.RIGHT]) { moveCamera(2, 0); } + if (keyDown[k.UP]) { moveCamera(0, -2); } + if (keyDown[k.DOWN]) { moveCamera(0, 2); } + + // move block to mouse + var mp = mousePosition(); + buildBlock.x = mp.x; + buildBlock.y = mp.y; + + // print list of block dimensions to be used in levels array + if (keyPress[k.v]) { + var world = buildBlocks; + var finalString = ""; + for (var i = 0; i < world.length; i++) { + finalString += `${Math.round(world[i].x)},${Math.round(world[i].y)},${Math.round(world[i].w)},${Math.round(world[i].h)},`; + } + console.log(finalString); + } + + // place block + if (mousePress[2]) { + buildBlocks.push(new block(buildBlock.x, buildBlock.y, buildBlock.w, buildBlock.h)); + collisionRects.push(buildBlock.x); + collisionRects.push(buildBlock.y); + collisionRects.push(buildBlock.w); + collisionRects.push(buildBlock.h); + } + + // scroll to increase size + // hold z to change dimension being scaled + // hold x to scale faster + if (keyDown[k.z]) { + buildBlock.w += keyDown[k.x] ? scroll * 20 : scroll; + } else { + buildBlock.h += keyDown[k.x] ? scroll * 20 : scroll; + } + + // delete newest block + if (keyPress[k.c]) { + buildBlocks.splice(buildBlocks.length - 1, 1); + collisionRects.splice(collisionRects.length - 4, 4); + } +} \ No newline at end of file diff --git a/docs/assets/js/world/level.js b/docs/assets/js/world/level.js new file mode 100644 index 0000000..6e2af18 --- /dev/null +++ b/docs/assets/js/world/level.js @@ -0,0 +1,33 @@ +var collisionRects = []; +class block { + constructor(x, y, w, h) { + this.x = x; + this.y = y; + this.w = w; + this.h = h; + } + draw() { + rect(this.x, this.y, this.w, this.h, "blue"); + } +} + +// create blocks +var blockData = [631,407,590,461,316,427,40,420,277,447,40,380,238,466,40,340,199,486,40,300,161,507,40,260,121,527,40,220,82,545,40,180,-407,561,1300,150,-1000,350,120,570,-281,483,120,70,-191,481,35,35,878,145,95,776,734,172,195,76]; +for (let i = 0, l = blockData.length; i < l; i += 4) { + collisionRects.push(new block(blockData[i], blockData[i + 1], blockData[i + 2], blockData[i + 3])); +} + +function drawWorldBlocks() { + for (var i = 0; i < collisionRects.length; i++) { + collisionRects[i].draw(); + } +} + +function collidingWithWorld(objectWithXYWH) { + for (let i = 0, l = collisionRects.length; i < l; i++) { + if (rectrect(collisionRects[i], objectWithXYWH)) { + return i; + } + } + return false; +} \ No newline at end of file diff --git a/docs/index.html b/docs/index.html index 08c34f0..c34c8df 100644 --- a/docs/index.html +++ b/docs/index.html @@ -19,7 +19,7 @@ - + @@ -28,6 +28,19 @@ + + + + + + + + + +