diff --git a/docs/assets/js/UI/ui.js b/docs/assets/js/UI/ui.js index f084c82..4f05905 100644 --- a/docs/assets/js/UI/ui.js +++ b/docs/assets/js/UI/ui.js @@ -9,7 +9,7 @@ function drawLevelTransitionUI() { // UI for playing function drawPlayingUI() { - cartesianRect(0,ch/3*2, cw, ch/3, "#333333") + // cartesianRect(0,ch/3*2, cw, ch/3, "#333333") //Heart Rate Monitor heartBeatUI(cw/4*3-8,ch/8*7-8,cw/4,ch/8); diff --git a/docs/assets/js/constants.js b/docs/assets/js/constants.js index 0adeac7..d9c73f2 100644 --- a/docs/assets/js/constants.js +++ b/docs/assets/js/constants.js @@ -42,9 +42,16 @@ var constants = { optimalPressure: 50 } }, - legs:{ - size:{ - maximumMovement: 30 + player:{ + leg_speed: 0.1, + movement_divider: 50, + max_movement_speed: 3, + width: 30, + height: 50, + select_range: 10, + hip: { + offset_x: 15, + offset_y: 25 } } diff --git a/docs/assets/js/index.js b/docs/assets/js/index.js index 23661b1..b288566 100644 --- a/docs/assets/js/index.js +++ b/docs/assets/js/index.js @@ -33,6 +33,7 @@ function update() { // playing case globalStates.playing: handlePlaying(); + player.update(); break; // paused case globalStates.paused: @@ -67,7 +68,9 @@ function draw() { break; // playing case globalStates.playing: + camera.zoom = 2; drawWorldBlocks(); + player.draw(); break; // paused case globalStates.paused: diff --git a/docs/assets/js/player/leg.js b/docs/assets/js/player/leg.js index 0ca436f..d8c74bc 100644 --- a/docs/assets/js/player/leg.js +++ b/docs/assets/js/player/leg.js @@ -1,56 +1,25 @@ - - // a Class for legs class Leg{ - Leg(thighX, thighY, kneeX, kneeY, footX, footY){ + constructor(x, y, len, angle) { - // Thigh X,Y - this.thighX = thighX; - this.thighY = thighY; + this.x = x; + this.y = y; - // Knee X,Y - this.kneeX = kneeX; - this.kneeY = kneeY; - // Foot X,Y - this.footX = footX; - this.footY = footY + this.len = len; + this.len2 = this.len * this.len; + this.angle = angle; - // 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)); + this.x2 = this.x + len * Math.cos(angle); + this.y2 = this.y + len * Math.sin(angle); } - + }; - +Leg.prototype.draw = function() { + line(this.x,this.y,this.x2,this.y2,"green"); +}; \ No newline at end of file diff --git a/docs/assets/js/player/player.js b/docs/assets/js/player/player.js index 69fb573..601cb43 100644 --- a/docs/assets/js/player/player.js +++ b/docs/assets/js/player/player.js @@ -1,133 +1,244 @@ class Player { - - constructor(x, y){ + 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.w = constants.player.width; + this.h = constants.player.height; + this.hipLeft = { x: this.x - constants.player.hip.offset_x, y: this.y + constants.player.hip.offset_y }; + this.hipRight = { x: this.x + constants.player.hip.offset_x, y: this.y + constants.player.hip.offset_y }; + this.leftLeg = new Leg(this.hipLeft.x, this.hipLeft.y, 50, -Math.PI / 4); + this.rightLeg = new Leg(this.hipRight.x, this.hipRight.y, 50, Math.PI / 2); + this.legSelected = "R"; this.shouldMoveLeg = false; + this.collided = false; + this.lastBodyX = x; + this.lastBodyY = y; + this.hover = { active: false, leg: "R" }; } - - getLeg(){ - if(this.legSelected === "l"){ - return [this.footL, this.kneeL, this.thighL]; - } - return [this.footR, this.kneeR, this.thighR]; - - } - } +Player.prototype.getActiveLeg = function(){ + if (this.legSelected === "L") { + return this.leftLeg; + } + return this.rightLeg; +} + +Player.prototype.getLockedLeg = function(){ + if (this.legSelected === "R") { + return this.leftLeg; + } + return this.rightLeg; +} + +Player.prototype.update = function() { + var curLeg = this.getActiveLeg(); + + // select + if (this.shouldMoveLeg) { + this.moveLeg(); + if(mousePress[0]) {// if (collidingWithWorld({ x: curLeg.x2, y: curLeg.y2, w: 4, h: 4 })) { + if (this.legSelected === "R") { + this.leftLeg.angle += pi; + } else { + this.rightLeg.angle += pi; + } + this.shouldMoveLeg = false; + } + // deselect + } else { + + var targetPos = mousePosition(); + var curLeg = this.getActiveLeg(); + this.hover.active = false; + //left + if (distanceToLineSegment(this.leftLeg.x, this.leftLeg.y, this.leftLeg.x2, this.leftLeg.y2, targetPos.x, targetPos.y) < constants.player.select_range) { + this.hover.active = true; + this.hover.leg = "L"; + if(mousePress[0]) { + this.shouldMoveLeg = true; + this.legSelected = "L"; + this.hover.active = false; + } + // right + } else if (distanceToLineSegment(this.rightLeg.x, this.rightLeg.y, this.rightLeg.x2, this.rightLeg.y2, targetPos.x, targetPos.y) < constants.player.select_range) { + this.hover.active = true; + this.hover.leg = "R"; + if(mousePress[0]) { + this.shouldMoveLeg = true; + this.legSelected = "R"; + this.hover.active = false; + } + } + } + + centerCameraOn(this.x,this.y); +} // leg has been selected, move leg towards mouse Player.prototype.moveLeg = function(){ + var targetPos = mousePosition(); + + // gets active leg & target + var curLeg = this.getActiveLeg(); + var target = targetPos; + + // Last leg position + var lastX = curLeg.x2; + var lastY = curLeg.y2; - if(!this.shouldMoveLeg){ - return + // move selected leg towards mouse + + // console.log(curLeg.angle.toPrecision(5),pointTo(curLeg,target).toPrecision(5)); + curLeg.angle = turn(curLeg.angle, pointTo(curLeg, target), constants.player.leg_speed); + // var angle = pointTo(curLeg,target); + curLeg.x2 = curLeg.x + curLeg.len * Math.cos(curLeg.angle); + curLeg.y2 = curLeg.y + curLeg.len * Math.sin(curLeg.angle); + + + // Collision + if(collidingWithWorld({x:curLeg.x2,y:curLeg.y2,w:4,h:4})){ + this.collided = true; + curLeg.x2 = lastX; + curLeg.y2 = lastY; + return 0; + } - 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(collidingWithWorld({x:this.x, y:this.y, w:this.w, h:this.h})){ + this.x = this.lastBodyX; + this.y = this.lastBodyY; } + if (dist(curLeg, target) > curLeg.len) { + // move towards mouse + this.x += Math.cos(pointTo(curLeg, target)) * clamp(dist(curLeg, target) / constants.player.movement_divider, 1, constants.player.max_movement_speed); + + this.y += Math.sin(pointTo(curLeg, target)) * clamp(dist(curLeg, target) / constants.player.movement_divider, 1, constants.player.max_movement_speed); + this.updateHips(); + } + + // if leg is right update it accordingly + if (this.legSelected === "R") { + // set angle to the locked foot to the locked hip + oppLeg = this.getLockedLeg(); + oppLeg.angle = pointTo({ x: oppLeg.x2, y: oppLeg.y2 }, this.hipRight); + + + // snap body to a position where the hip is attached to the leg + this.x = (oppLeg.x2 + oppLeg.len * Math.cos(oppLeg.angle)) - constants.player.hip.offset_x; + this.y = (oppLeg.y2 + oppLeg.len * Math.sin(oppLeg.angle)) - constants.player.hip.offset_y; + + this.updateHips(); + + // make sure each leg ends at the hips + oppLeg.x = this.hipRight.x; + oppLeg.y = this.hipRight.y; + + curLeg.x = this.hipLeft.x; + curLeg.y = this.hipLeft.y; + // if leg is left update it accordingly + } else { + // set angle to the locked foot to the locked hip + oppLeg = this.getLockedLeg(); + oppLeg.angle = pointTo({ x: oppLeg.x2, y: oppLeg.y2 }, this.hipLeft); - /* + // snap body to a position where the hip is attached to the leg + this.x = (oppLeg.x2 + oppLeg.len * Math.cos(oppLeg.angle)) + constants.player.hip.offset_x; + this.y = (oppLeg.y2 + oppLeg.len * Math.sin(oppLeg.angle)) - constants.player.hip.offset_y; - 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 - */ + this.updateHips(); + // make sure each leg ends at the hips + oppLeg.x = this.hipLeft.x; + oppLeg.y = this.hipLeft.y; - // 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 + curLeg.x = this.hipRight.x; + curLeg.y = this.hipRight.y; + } - 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}]; - - + this.lastBodyX = this.x; + this.lastBodyY = this.y; } - +Player.prototype.updateHips = function() { + this.hipLeft = { x: this.x - constants.player.hip.offset_x, y: this.y + constants.player.hip.offset_y }; + this.hipRight = { x: this.x + constants.player.hip.offset_x, y: this.y + constants.player.hip.offset_y }; +} Player.prototype.draw = function() { - + rect(this.x, this.y, this.w, this.h, "green"); + if(this.hover.active) { + if(this.hover.leg === "R") { + curCtx.shadowBlur = 10; + curCtx.shadowColor = "yellow"; + curCtx.lineWidth = 3; + this.rightLeg.draw(); + curCtx.lineWidth = 1; + curCtx.shadowBlur = 0; + curCtx.shadowColor = "black"; + this.leftLeg.draw(); + } else { + curCtx.shadowBlur = 10; + curCtx.shadowColor = "yellow"; + curCtx.lineWidth = 3; + this.leftLeg.draw(); + curCtx.lineWidth = 1; + curCtx.shadowBlur = 0; + curCtx.shadowColor = "black"; + this.rightLeg.draw(); + } + } else { + this.leftLeg.draw(); + this.rightLeg.draw(); + } } -Player.prototype.update = function() { - -} \ No newline at end of file +// https://github.com/scottglz/distance-to-line-segment/blob/master/index.js +function distanceSquaredToLineSegment2(lx1, ly1, ldx, ldy, lineLengthSquared, px, py) { + var t; // t===0 at line pt 1 and t ===1 at line pt 2 + if (!lineLengthSquared) { + // 0-length line segment. Any t will return same result + t = 0; + } + else { + t = ((px - lx1) * ldx + (py - ly1) * ldy) / lineLengthSquared; + + if (t < 0) + t = 0; + else if (t > 1) + t = 1; + } + + var lx = lx1 + t * ldx, + ly = ly1 + t * ldy, + dx = px - lx, + dy = py - ly; + return dx * dx + dy * dy; +} +function distanceSquaredToLineSegment(lx1, ly1, lx2, ly2, px, py) { + var ldx = lx2 - lx1, + ldy = ly2 - ly1, + lineLengthSquared = ldx * ldx + ldy * ldy; + return distanceSquaredToLineSegment2(lx1, ly1, ldx, ldy, lineLengthSquared, px, py); +} + +function distanceToLineSegment(lx1, ly1, lx2, ly2, px, py) { + return Math.sqrt(distanceSquaredToLineSegment(lx1, ly1, lx2, ly2, px, py)); +} + + + + +var player = new Player(500,100); + diff --git a/docs/assets/js/world/level.js b/docs/assets/js/world/level.js index 6e2af18..ae5e364 100644 --- a/docs/assets/js/world/level.js +++ b/docs/assets/js/world/level.js @@ -24,9 +24,9 @@ function drawWorldBlocks() { } function collidingWithWorld(objectWithXYWH) { - for (let i = 0, l = collisionRects.length; i < l; i++) { + for (var i = 0; i < collisionRects.length; i++) { if (rectrect(collisionRects[i], objectWithXYWH)) { - return i; + return true; } } return false; diff --git a/docs/index.html b/docs/index.html index ffbd496..3a817c4 100644 --- a/docs/index.html +++ b/docs/index.html @@ -39,8 +39,8 @@ - + +