import Key from "./Key.js"; import MrCroc from "./MrCroc.js"; import RetroArchitecture from "./retro/RetroArchitecture.js"; import FileLoader from "./FileLoader.js"; import Camera from "./Camera.js"; class ImageLoader { images = []; numberImagesLoaded = 0; update() { this.numberImagesLoaded++; if (this.numberImagesLoaded === this.images.length) { window.dispatchEvent(new Event('imagesloaded')); } } getCurrentProgress() { return this.numberImagesLoaded / this.images.length; } addImage(image) { image.addEventListener( 'load', () => { this.update(); } ); this.images.push(image); } } function MainLoop(timestamp) { if (lastRendered === undefined && lastTimestamp === undefined) { lastRendered = timestamp; lastTimestamp = timestamp; } let delta = (timestamp - lastTimestamp) / (10 / GAME_SPEED); let ceilingHeight = Math.max( architecture.getCeilingHeight(mrCroc.getPositionHeadLeft()), architecture.getCeilingHeight(mrCroc.getPositionHeadRight()), ); let groundHeight = Math.min( architecture.getGroundHeight(mrCroc.getPositionFootLeft()), architecture.getGroundHeight(mrCroc.getPositionFootRight()) ); /* Handle falling */ mrCroc.position.y += mrCroc.fallSpeed; mrCroc.fallSpeed += GRAVITY * delta; /* Handle ground collision */ if (mrCroc.position.y > groundHeight && mrCroc.fallSpeed > 0) { mrCroc.position.y = groundHeight; mrCroc.fallSpeed = 0; } /* Handle ceiling collision */ if (mrCroc.position.y - mrCroc.getHeight() <= ceilingHeight) { mrCroc.fallSpeed = 0; mrCroc.position.y = ceilingHeight + mrCroc.getHeight() + 1; } /* Handle jumping */ if (!mrCroc.isJumping && mrCroc.fallSpeed === 0 && mrCroc.position.y === groundHeight && KeyJump.isPressed()) { mrCroc.jump(); } else if (!KeyJump.isPressed()) { mrCroc.isJumping = false; } /* Movement left and right */ if (KeyLeft.isPressed()) { let lastWallLeft = Math.min( architecture.getWallLeft(mrCroc.getPositionHeadLeft()), architecture.getWallLeft(mrCroc.getPositionFootLeft()) ); mrCroc.moveLeft(timestamp, delta); if (mrCroc.position.x <= lastWallLeft + mrCroc.getWidth() * 0.5) { mrCroc.position.x = lastWallLeft + mrCroc.getWidth() * 0.5 + 1; } } else if (KeyRight.isPressed()) { let lastWallRight = Math.max( architecture.getWallRight(mrCroc.getPositionHeadRight()), architecture.getWallRight(mrCroc.getPositionFootRight()) ); mrCroc.moveRight(timestamp, delta); if (mrCroc.position.x >= lastWallRight - mrCroc.getWidth() * 0.5) { mrCroc.position.x = lastWallRight - mrCroc.getWidth() * 0.5 - 1; } } /* 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); architecture.draw(context, camera); mrCroc.draw(context, camera); /* context.fillRect(0, ceilingHeight, window.innerWidth, 1); context.fillRect(0, groundHeight, 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; } lastTimestamp = timestamp; window.requestAnimationFrame(MainLoop); } const FPS = 60; const FRAME_DURATION = 1000 / FPS; const GAME_SPEED = 1; const GRAVITY = 2; let levelJson = new FileLoader('levels/level01.json'); const LEVEL = JSON.parse(levelJson.getContent()); let lastRendered = undefined; let lastTimestamp = undefined; let context; let mrCroc, architecture; let camera = new Camera(); let KeyLeft = new Key('ArrowLeft'); let KeyRight = new Key('ArrowRight'); let KeyJump = new Key('Space'); let loader = new ImageLoader(); let imgAnimation = new Image(); imgAnimation.src = 'graphics/mr-croc-walk-right.png'; loader.addImage(imgAnimation); let imgAnimationB = new Image(); imgAnimationB.src = 'graphics/mr-croc-walk-left.png'; loader.addImage(imgAnimationB); let imgArch = new Image(); imgArch.src = 'graphics/tileset-landscape01.jpg'; loader.addImage(imgArch); window.addEventListener( 'imagesloaded', () => { let canvas = document.getElementById('canvas'); 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.createFromData(LEVEL); camera.borderRight = architecture.columns * architecture.tileWidth; camera.borderBottom = architecture.rows * architecture.tileHeight; mrCroc = new MrCroc(); mrCroc.position.x = architecture.tileWidth * LEVEL.startX + architecture.tileWidth * 0.5; mrCroc.position.y = architecture.tileHeight * LEVEL.startY; window.requestAnimationFrame(MainLoop); } );