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 zcmV;)1UCDLP)EX>4Tx04R}tkv&MmKpe$iQ>9WWf_4yb$WWauh)U5-t5Adrp;l;lcSTOiK+|nA zm57U(?5Y@eg@7RXF@u=QEMrcRlIS?T?&0I>U6f~aKKJM7RdW^td?N8IGfbO!gE+Qn z8=Uuv!>lN)#OK6gCS8#Dk?V@bZ=4G*3p_Jyrc?98VPdh+#!4HrqNx#25l2)_r+gvf zvC4UivsSLM<~{ifLpgnAnd>x%k-#FBAVGwJDoQBBMwC{a6bmWZk9Y77xqgXU3b{&P z#tGnm2Cnp$zfuRLKS{5( zw8#V$mfCgGy0}1FmMY5*Sy}E`#607($rP*1~@nb zMhld^-r?On?Y;ebrrF;Q$^LT63!6h200006VoOIv09F7100lmJb(;VH010qNS#tmY z3ljhU3ljkVnw%H_000McNlirueSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00N;&L_t(&-o;rvZsR}_5c2p|`GgIvHhQ$%BPsG(*gakK;mkP*fFy?Oi?ppHBM0E_cty@-xVS$-g* z+jHOd-nx>?nTVv<`g7F?aN>KpM9;y=00aQwL0L8A|MB3N2RxY(;o1gp@Hlv#@SbZJ zzyQEfaZ27^Z6mgVkU!r6emv%1{P+j({Bx=kJ;E;Y&&&W9oWlsNO#!Q8hy5vyx$*tz zk4>qklG*Ma^;6JYaQXe6Q=U>RrSJQq`);M-uz=l?LPYZZ&&r>_3$J0$`=#>h_cjn# zktUa4kI3N3zA;T{3a-~H9FIqjI#G-Plo42?98ZyATuXes_K1dL9R^m?H7~(PjXsT; z?@lA)te&RE)oR=J|3)BDC9C&@rc)yx7LstNT#7f>JaAC8p<^z=OH6PY7M6qOZyJs+m$76BC%5edJ^ z$jUVj0PT5-i5xYrVm$4ADk9-o6Vvw5ERpNf^$R%Zx-MIySMmKV&m;Xt-V5=j<|wSe zm|&QuWktOQ0@!S!aM)8myNVo2Y@)js>LoL`knk_a0Pj@`TGfKZt zD{htJ>MdFD8WE#%EI^5M4H)c=h}8#F*%1XCNG9BE9FxUq&++WL+Qs#L*YWILa#bnL z^#JG%K;4+`4#Lv4t$PF#-^(TX&`Y_T3+Jk%cQKm$mJptGV`8oDHe(<)7cSWoZmx!N n-Oe5cV6IEb8Cq>mSgPv_6eB}_WrX2O00000NkvXXu0mjf37;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);