From b7f669224d02b6d79dc67533efc5f3ee8f451bac Mon Sep 17 00:00:00 2001 From: Mal Date: Sat, 25 Jan 2020 23:30:36 +0100 Subject: [PATCH] Terrain collision. --- js/Movable.js | 28 ++++++++- js/module.js | 108 ++++++++++++++++++++++------------ js/retro/RetroArchitecture.js | 54 +++++++++++++++-- 3 files changed, 146 insertions(+), 44 deletions(-) diff --git a/js/Movable.js b/js/Movable.js index fa518e2..a145219 100644 --- a/js/Movable.js +++ b/js/Movable.js @@ -40,6 +40,16 @@ export default class Movable return this.animations[this.currentAnimation].getRect(); } + getWidth() + { + return this.getRect().width; + } + + getHeight() + { + return this.getRect().height; + } + getPositionFootLeft() { return new GeometryPoint( @@ -50,7 +60,23 @@ export default class Movable getPositionFootRight() { return new GeometryPoint( - this.position.x + this.animations[this.currentAnimation].getWidth() * 0.5, this.position.y + this.position.x + this.getWidth() * 0.5, this.position.y + ); + } + + getPositionHeadLeft() + { + return new GeometryPoint( + this.position.x - this.animations[this.currentAnimation].getWidth() * 0.5, + this.position.y - this.animations[this.currentAnimation].getHeight() + ); + } + + getPositionHeadRight() + { + return new GeometryPoint( + this.position.x + this.getWidth() * 0.5, + this.position.y - this.animations[this.currentAnimation].getHeight() ); } diff --git a/js/module.js b/js/module.js index 2b8295e..7074b16 100644 --- a/js/module.js +++ b/js/module.js @@ -2,7 +2,6 @@ import Key from "./Key.js"; import MrCroc from "./MrCroc.js"; import RetroArchitecture from "./retro/RetroArchitecture.js"; import FileLoader from "./FileLoader.js"; -import GeometryPoint from "./geometry/GeometryPoint.js"; class ImageLoader { @@ -44,11 +43,10 @@ function MainLoop(timestamp) let delta = (timestamp - lastTimestamp) / (10 / GAME_SPEED); - if (KeyLeft.isPressed()) { - mrCroc.moveLeft(timestamp, delta); - } else if (KeyRight.isPressed()) { - mrCroc.moveRight(timestamp, delta); - } + let lastCeilingHeight = Math.max( + architecture.getCeilingHeight(mrCroc.getPositionHeadLeft()), + architecture.getCeilingHeight(mrCroc.getPositionHeadRight()), + ); lastGroundHeight = Math.min( architecture.getGroundHeight(mrCroc.getPositionFootLeft()), @@ -62,40 +60,55 @@ function MainLoop(timestamp) architecture.getGroundHeight(mrCroc.getPositionFootRight()) ); - if (mrCroc.position.y < lastGroundHeight) { - mrCroc.fallSpeed += GRAVITY * delta; + mrCroc.fallSpeed += GRAVITY * delta; + + if (mrCroc.position.y >= lastGroundHeight) { + mrCroc.position.y = lastGroundHeight; + mrCroc.fallSpeed = 0; } - /* - if (architecture.hasRectCollision(mrCroc.getRect())) { - mrCroc.position.x = lastPosition.x; + if (mrCroc.position.y - mrCroc.getHeight() <= lastCeilingHeight) { + mrCroc.fallSpeed = 0; + mrCroc.position.y = lastCeilingHeight + mrCroc.getHeight() + 1; } - let archIntersections = architecture.getCollisionRects(mrCroc.getRect()); - let width = archIntersections.getUniqueWidth(); + if (!mrCroc.isJumping && mrCroc.fallSpeed === 0 && mrCroc.position.y === groundHeight && KeyJump.isPressed()) { + mrCroc.jump(); + } else if (!KeyJump.isPressed()) { + mrCroc.isJumping = false; + } - if (width !== null) { - if (width.x === mrCroc.position.x) { - mrCroc.position.x += width.width; - } else { - mrCroc.position.x = width.x - mrCroc.getRect().width; + let lastWallRight = Math.min( + architecture.getWallRight(mrCroc.getPositionHeadRight()), + architecture.getWallRight(mrCroc.getPositionFootRight()) + ); + + let lastWallLeft = Math.max( + architecture.getWallLeft(mrCroc.getPositionHeadLeft()), + architecture.getWallLeft(mrCroc.getPositionFootLeft()) + ); + + if (KeyLeft.isPressed()) { + mrCroc.moveLeft(timestamp, delta); + + let wallLeft = Math.max( + architecture.getWallLeft(mrCroc.getPositionHeadLeft()), + architecture.getWallLeft(mrCroc.getPositionFootLeft()) + ); + + if (wallLeft < lastWallLeft) { + mrCroc.position.x = lastWallLeft + 1; } - } + } else if (KeyRight.isPressed()) { + mrCroc.moveRight(timestamp, delta); - */ + let wallRight = Math.min( + architecture.getWallRight(mrCroc.getPositionHeadRight()), + architecture.getWallRight(mrCroc.getPositionFootRight()) + ); - if (mrCroc.position.y !== lastGroundHeight) { - if (lastGroundHeight < groundHeight) { - mrCroc.position.y = lastGroundHeight; - mrCroc.fallSpeed = 0; - } else { - mrCroc.fallSpeed += GRAVITY * delta; - } - } else { - if (!mrCroc.isJumping && mrCroc.fallSpeed === 0 && KeyJump.isPressed()) { - mrCroc.jump(); - } else if (!KeyJump.isPressed()) { - mrCroc.isJumping = false; + if (wallRight > lastWallRight) { + mrCroc.position.x = lastWallRight - 1; } } @@ -103,6 +116,20 @@ function MainLoop(timestamp) context.clearRect(0, 0, window.innerWidth, window.innerHeight); architecture.draw(context); mrCroc.draw(context); + + /* + context.fillRect(0, lastCeilingHeight, window.innerWidth, 1); + context.fillRect(0, lastGroundHeight, window.innerWidth, 1); + context.fillStyle = 'black'; + context.fillRect(lastWallRight, 0, 1, window.innerHeight); + context.fillStyle = 'red'; + context.fillRect(lastWallLeft, 0, 1, window.innerHeight); + mrCroc.getPositionHeadRight().draw(context); + mrCroc.getPositionFootRight().draw(context); + mrCroc.getPositionHeadLeft().draw(context); + mrCroc.getPositionFootLeft().draw(context); + */ + lastRendered = timestamp; } @@ -114,13 +141,11 @@ function MainLoop(timestamp) const FPS = 60; const FRAME_DURATION = 1000 / FPS; const GAME_SPEED = 1; -const GRAVITY = 1; +const GRAVITY = 2; let levelJson = new FileLoader('levels/test.json'); const LEVEL = levelJson.getContent(); -console.log(LEVEL); - let lastRendered = undefined; let lastTimestamp = undefined; let groundHeight = undefined; @@ -151,7 +176,7 @@ imgBackground.src = 'graphics/ground.jpg'; loader.addImage(imgBackground); let imgArch = new Image(); -imgArch.src = 'graphics/maria-world.jpg'; +imgArch.src = 'graphics/tileset-landscape01.jpg'; loader.addImage(imgArch); window.addEventListener( @@ -161,6 +186,14 @@ window.addEventListener( canvas.width = window.innerWidth; canvas.height = window.innerHeight; + window.addEventListener( + 'resize', + function () { + canvas.width = window.innerWidth; + canvas.height = window.innerHeight; + } + ); + context = canvas.getContext('2d'); architecture = RetroArchitecture.createFromJson(LEVEL); @@ -169,9 +202,6 @@ window.addEventListener( mrCroc.position.x = 300; mrCroc.position.y = 100; - architecture.draw(context); - mrCroc.draw(context); - window.requestAnimationFrame(MainLoop); } ); diff --git a/js/retro/RetroArchitecture.js b/js/retro/RetroArchitecture.js index 750531c..a64691d 100644 --- a/js/retro/RetroArchitecture.js +++ b/js/retro/RetroArchitecture.js @@ -1,6 +1,7 @@ import RetroSprite from "./RetroSprite.js"; import RetroArchitectureTile from "./RetroArchitectureTile.js"; import GeometryRectCollection from "../geometry/GeometryRectCollection.js"; +import GeometryPoint from "../geometry/GeometryPoint.js"; export default class RetroArchitecture { @@ -67,10 +68,10 @@ export default class RetroArchitecture return false; } - getTileForPosition(position) + getTileForPosition(position, offsetX = 0, offsetY = 0) { - let x = parseInt(position.x / this.tileWidth); - let y = parseInt(position.y / this.tileHeight); + let x = parseInt(position.x / this.tileWidth) + offsetX; + let y = parseInt(position.y / this.tileHeight) + offsetY; if (x < 0 || x >= this.columns || y < 0 || y >= this.rows) { return null; @@ -79,13 +80,28 @@ export default class RetroArchitecture return {x: x, y: y}; } + getCeilingHeight(position) + { + let tilePosition = this.getTileForPosition(position, 0); + + while (tilePosition !== null && tilePosition.y > 0) { + if (this.matrix[tilePosition.y][tilePosition.x] !== null) { + return tilePosition.y * this.tileHeight + this.tileHeight; + } + + tilePosition.y--; + } + + return 0; + } + getGroundHeight(position) { let tilePosition = this.getTileForPosition(position); while (tilePosition !== null && tilePosition.y < this.rows) { if (this.matrix[tilePosition.y][tilePosition.x] !== null) { - return tilePosition.y * this.tileHeight + return tilePosition.y * this.tileHeight; } tilePosition.y++; @@ -94,6 +110,36 @@ export default class RetroArchitecture return this.tileHeight * this.rows; } + getWallRight(position) + { + let tilePosition = this.getTileForPosition(new GeometryPoint(position.x, position.y), 1, -1); + + while (tilePosition !== null && tilePosition.x < this.columns) { + if (this.matrix[tilePosition.y][tilePosition.x] !== null) { + return tilePosition.x * this.tileWidth - this.tileWidth * 0.5; + } + + tilePosition.x++; + } + + return this.tileWidth * this.columns; + } + + getWallLeft(position) + { + let tilePosition = this.getTileForPosition(new GeometryPoint(position.x, position.y), -1,-1); + + while (tilePosition !== null && tilePosition.x > 0) { + if (this.matrix[tilePosition.y][tilePosition.x] !== null) { + return tilePosition.x * this.tileWidth + this.tileWidth * 1.5; + } + + tilePosition.x--; + } + + return 0; + } + draw(context) { for (let y = 0; y < this.rows; y++) {