From 46a64668afd62b98dfb0e0d7ba314bb0e8a0eb0d Mon Sep 17 00:00:00 2001 From: Mal Date: Tue, 11 Feb 2020 23:42:26 +0100 Subject: [PATCH] Camera momentum implemented. --- graphics/gisela-left.png | Bin 0 -> 1225 bytes graphics/gisela-right.png | Bin 0 -> 9936 bytes js/Camera.js | 85 +++++++++++++++++++++++++++++++------- js/module.js | 9 +++- 4 files changed, 79 insertions(+), 15 deletions(-) create mode 100644 graphics/gisela-left.png create mode 100644 graphics/gisela-right.png diff --git a/graphics/gisela-left.png b/graphics/gisela-left.png new file mode 100644 index 0000000000000000000000000000000000000000..4bf4a9c139052f9df577670de09b76293e295ea4 GIT binary patch literal 1225 zcmeAS@N?(olHy`uVBq!ia0y~yU{GLSU~u4IV_;yY?kio#z`)p&>FgZf>FlgfP?VpR znUl)EpfRy_qOHea2brVs!Apa*n#u$UPXx@>>F~PfyE>qSYhhT%)q_ti>1SM;uw;h? z*E&{qd$HAgdgpdo?ci#9z}_)=@#IC_Q-17UazW`@^W(ZbyT9+KX6N{7ba~CXLWj$_ z##1}GXTDh_QPJ9<@XN4y#u=Stze$r`SnPZE@bT-|De0wl-=Dt-Ef!<0QTnK3>@&Nf z*^3EAt_Zj0t^V>4 z{5$J9W4LyDB|M36V3kU_&i{{n|L(1yCJV;}Y4DZow>Wp4L*NFhl`$1ugf&%+BGr@`7#Ji=Tq8=H z^K)}k^GX<;i&7IyQd1PlGfOfQ+&z5*!W;R-85o!rdb&7YXm<51wRTVR+yeY5L^< z#|JanZDtBSyv0`V!J=aBhk4l&2N(_n6?)x^%T?aiG{OEpW1Y>j_&-0`Kl~|PC2V_0 z@ALUH4B~SRbFA}aT%FwhSF?BL$G9&EL$Hn^(d!mEA<9iq_i7FMBS=C@Lz*x&P#eQ>Oe3Z!5bxWlYy6*}SdQ zQhFFEeEHi&or$lneC4)yxl1p4QTWHdy62Vuy4~acxa^t6nu9YEW-Lo}JzK}-!4)QY z;SuxxXao11D`!rwn!vrhh+3s z%vPEp{j@1)@1c)(1ZTQ^oFM11{awc=F^zm@-5XZ3bj_Ij%WaMrd+qnv&YSx9m2Tt* zDZ#}>Iu4zsyb^DEJFc>a+!SP$@ld;yD>M0M=J}6rcHcVsweI@IH*rOwn&-YUyx?`X zJL4VSp-WrWRpqwuen8(o$FIu9{MmaFfe$!`njxgN@xNA37;vS literal 0 HcmV?d00001 diff --git a/graphics/gisela-right.png b/graphics/gisela-right.png new file mode 100644 index 0000000000000000000000000000000000000000..221de3b584ba3220951c42000bae55f952dbc382 GIT binary patch literal 9936 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 literal 0 HcmV?d00001 diff --git a/js/Camera.js b/js/Camera.js index fbe692d..a1ab763 100644 --- a/js/Camera.js +++ b/js/Camera.js @@ -13,6 +13,7 @@ export default class Camera this.borderRight = undefined; this.speedX = 0; this.speedY = 0; + this.speedMax = 12; } centerCamera(x, y) @@ -33,28 +34,84 @@ export default class Camera } } - facePosition(x, y, delta, reactionSpeed = 1) + centerCameraX(x) { - let positionX = x - this.width * 0.5; - let positionY = y - this.height * 0.5; + this.position.x = x - this.width * 0.5; - let distanceX = this.position.x - positionX; - let distanceY = this.position.y - positionY; + if (this.position.x < this.borderLeft) { + this.position.x = this.borderLeft; + } else if (this.borderRight !== undefined && this.position.x + this.width > this.borderRight) { + this.position.x = this.borderRight - this.width; + } + } - if (this.position.x !== positionX) { - this.position.x += distanceX * delta * reactionSpeed; + lockCameraIntoBorders() + { + this.lockCameraIntoHorizontalBorders(); + this.lockCameraIntoVerticalBorders(); + } + + lockCameraIntoHorizontalBorders() + { + let hasBeenLocked = false; + + if (this.position.x < this.borderLeft) { + this.position.x = this.borderLeft; + hasBeenLocked = true; + } else if (this.borderRight !== undefined && this.position.x + this.width > this.borderRight) { + this.position.x = this.borderRight - this.width; + hasBeenLocked = true; } - if (distanceX < 0.01) { - this.position.x = positionX; + return hasBeenLocked; + } + + lockCameraIntoVerticalBorders() + { + let hasBeenLocked = false; + + if (this.position.y < this.borderTop) { + this.position.y = this.borderTop; + hasBeenLocked = true; + } else if (this.borderBottom !== undefined && this.position.y + this.height > this.borderBottom) { + this.position.y = this.borderBottom - this.height; + hasBeenLocked = true; } - if (this.position.y !== positionY) { - this.position.y += distanceY * delta * reactionSpeed; - } + return hasBeenLocked; + } - if (distanceY < 0.01) { - this.position.y = positionY; + focusPosition(x, y, reactionLatency = 1) + { + this.focusPositionX(x, reactionLatency); + this.focusPositionY(y, reactionLatency); + } + + focusPositionX(x, reactionLatency = 1) + { + let centerX = this.position.x + this.width * 0.5; + let distanceX = x - centerX; + + if (!this.lockCameraIntoHorizontalBorders() && distanceX !== 0) { + if (Math.abs(distanceX) < 1) { + this.position.x = x - this.width * 0.5; + } else { + this.position.x += distanceX * (1 / reactionLatency); + } + } + } + + focusPositionY(y, reactionLatency = 1) + { + let centerY = this.position.y + this.height * 0.5; + let distanceY = y - centerY; + + if (distanceY !== 0) { + if (Math.abs(distanceY) < 1) { + this.position.y = y - this.height * 0.5; + } else { + this.position.y += distanceY * (1 / reactionLatency); + } } } } \ No newline at end of file diff --git a/js/module.js b/js/module.js index 939ba30..72697cf 100644 --- a/js/module.js +++ b/js/module.js @@ -128,11 +128,18 @@ function MainLoop(timestamp) ) } + camera.focusPosition( + mrCroc.position.x - mrCroc.getWidth() * 0.5, + mrCroc.position.y - mrCroc.getHeight() * 0.5, + 20 + ); + camera.lockCameraIntoBorders(); + /* Drawing */ if (timestamp - lastRendered >= FRAME_DURATION) { context.clearRect(0, 0, window.innerWidth, window.innerHeight); - camera.centerCamera(mrCroc.position.x - mrCroc.getWidth() * 0.5, mrCroc.position.y - mrCroc.getHeight() * 0.5); + // camera.centerCamera(mrCroc.position.x - mrCroc.getWidth() * 0.5, mrCroc.position.y - mrCroc.getHeight() * 0.5); architecture.draw(context, camera); mrCroc.draw(context, camera); gisela.draw(context, camera);