diff options
Diffstat (limited to 'html/rogue/js/renderer.js')
-rw-r--r-- | html/rogue/js/renderer.js | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/html/rogue/js/renderer.js b/html/rogue/js/renderer.js new file mode 100644 index 0000000..e0fd489 --- /dev/null +++ b/html/rogue/js/renderer.js @@ -0,0 +1,93 @@ +// Rendering constants +const RENDER_CONSTANTS = { + VIEWPORT_BUFFER: 100, + SKY_COLORS: { + TOP: '#1a1a2e', + UPPER_MID: '#2d1b3d', + LOWER_MID: '#462639', + BOTTOM: '#1f1f2f' + }, + GROUND_COLOR: '#4a4', + DEBUG_FONT: '14px monospace', + DEBUG_COLOR: '#ffffff' +}; + +// Helper functions for rendering +const createSkyGradient = (ctx, groundY) => { + const gradient = ctx.createLinearGradient(0, 0, 0, groundY); + gradient.addColorStop(0, RENDER_CONSTANTS.SKY_COLORS.TOP); + gradient.addColorStop(0.4, RENDER_CONSTANTS.SKY_COLORS.UPPER_MID); + gradient.addColorStop(0.7, RENDER_CONSTANTS.SKY_COLORS.LOWER_MID); + gradient.addColorStop(1, RENDER_CONSTANTS.SKY_COLORS.BOTTOM); + return gradient; +}; + +const getViewBounds = (camera) => ({ + left: camera.x - RENDER_CONSTANTS.VIEWPORT_BUFFER, + right: camera.x + camera.width + RENDER_CONSTANTS.VIEWPORT_BUFFER, + top: camera.y - RENDER_CONSTANTS.VIEWPORT_BUFFER, + bottom: camera.y + camera.height + RENDER_CONSTANTS.VIEWPORT_BUFFER +}); + +const isInView = (x, viewBounds) => + x > viewBounds.left && x < viewBounds.right; + +// Layer rendering functions +const renderBackground = (ctx, state, groundY, viewBounds) => { + // Save the current transform + ctx.save(); + + // Reset transform for viewport-fixed sky + ctx.setTransform(1, 0, 0, 1, 0, 0); + + // Sky (fixed to viewport) + ctx.fillStyle = state.cachedGradient; + ctx.fillRect(0, 0, ctx.canvas.width, groundY); + + // Restore transform for underground + ctx.restore(); + + // Underground (follows camera) + ctx.fillStyle = '#000000'; + ctx.fillRect( + viewBounds.left, + groundY, + viewBounds.right - viewBounds.left, + ctx.canvas.height + ); +}; + +const renderBackgroundObjects = (ctx, state, groundY, viewBounds) => { + state.world.backgroundTrees + .filter(tree => isInView(tree.x, viewBounds)) + .forEach(tree => renderTree(ctx, tree, groundY)); + + state.world.backgroundRocks + .filter(rock => isInView(rock.x, viewBounds)) + .forEach(rock => renderRock(ctx, rock, groundY)); + + state.world.backgroundGrass + .filter(grass => isInView(grass.x, viewBounds)) + .forEach(grass => renderGrass(ctx, grass, groundY, state.time)); +}; + +const renderForegroundObjects = (ctx, state, groundY, viewBounds) => { + state.world.foregroundTrees + .filter(tree => isInView(tree.x, viewBounds)) + .forEach(tree => renderTree(ctx, tree, groundY)); + + state.world.foregroundRocks + .filter(rock => isInView(rock.x, viewBounds)) + .forEach(rock => renderRock(ctx, rock, groundY)); + + state.world.foregroundGrass + .filter(grass => isInView(grass.x, viewBounds)) + .forEach(grass => renderGrass(ctx, grass, groundY, state.time)); +}; + +const renderDebugInfo = (ctx, state) => { + ctx.fillStyle = RENDER_CONSTANTS.DEBUG_COLOR; + ctx.font = RENDER_CONSTANTS.DEBUG_FONT; + const text = `x: ${Math.round(state.debug.mouseX)}, y: ${Math.round(state.debug.mouseY)}`; + ctx.fillText(text, 10, ctx.canvas.height - 20); +}; \ No newline at end of file |