diff options
author | elioat <elioat@tilde.institute> | 2024-12-24 14:36:12 -0500 |
---|---|---|
committer | elioat <elioat@tilde.institute> | 2024-12-24 14:36:12 -0500 |
commit | 1bbd9f9fe02e388f135f07d3cf9e66a5dcbbadfb (patch) | |
tree | 76656e73d8c7748a934f27abf908d282fa8bad51 /html/rogue/js/world.js | |
parent | 23a9df9793a3f1cc0dbdfc677254df56c33501f4 (diff) | |
download | tour-1bbd9f9fe02e388f135f07d3cf9e66a5dcbbadfb.tar.gz |
*
Diffstat (limited to 'html/rogue/js/world.js')
-rw-r--r-- | html/rogue/js/world.js | 236 |
1 files changed, 236 insertions, 0 deletions
diff --git a/html/rogue/js/world.js b/html/rogue/js/world.js index e69de29..b20aa54 100644 --- a/html/rogue/js/world.js +++ b/html/rogue/js/world.js @@ -0,0 +1,236 @@ +// Define world object types +const WORLD_OBJECTS = { + PLATFORM: 'platform', + TREE_BACKGROUND: 'tree_background', + TREE_FOREGROUND: 'tree_foreground', + ROCK_BACKGROUND: 'rock_background', + ROCK_FOREGROUND: 'rock_foreground' +}; + +// Tree configurations +const TREE_TYPES = { + SMALL: { + width: 80, + height: 120, + canopyOffset: 40, // Distance from bottom where canopy starts + canopyColor: '#2a4', + trunkColor: '#531' + }, + LARGE: { + width: 120, + height: 200, + canopyOffset: 60, + canopyColor: '#1a4', + trunkColor: '#420' + } +}; + +// Rock configurations +const ROCK_TYPES = { + SMALL: { + width: 40, + height: 30, + color: '#666', + highlights: '#888' + }, + MEDIUM: { + width: 70, + height: 45, + color: '#555', + highlights: '#777' + }, + LARGE: { + width: 100, + height: 60, + color: '#444', + highlights: '#666' + } +}; + +// Create a world with platforms, trees, and rocks +const createWorld = () => ({ + groundHeight: 12, + // Separate arrays for different layers + backgroundTrees: [ + { + type: WORLD_OBJECTS.TREE_BACKGROUND, + x: 50, + config: TREE_TYPES.LARGE + }, + { + type: WORLD_OBJECTS.TREE_BACKGROUND, + x: 500, + config: TREE_TYPES.SMALL + } + ], + backgroundRocks: [ + { + type: WORLD_OBJECTS.ROCK_BACKGROUND, + x: 150, + config: ROCK_TYPES.LARGE + }, + { + type: WORLD_OBJECTS.ROCK_BACKGROUND, + x: 400, + config: ROCK_TYPES.SMALL + } + ], + platforms: [ + { + type: WORLD_OBJECTS.PLATFORM, + x: 300, + y: 300, + width: 200, + height: 20, + color: '#484' + }, + { + type: WORLD_OBJECTS.PLATFORM, + x: 600, + y: 200, + width: 200, + height: 20, + color: '#484' + }, + { + type: WORLD_OBJECTS.PLATFORM, + x: -200, + y: 250, + width: 200, + height: 20, + color: '#484' + } + ], + foregroundTrees: [ + { + type: WORLD_OBJECTS.TREE_FOREGROUND, + x: 200, + config: TREE_TYPES.SMALL + }, + { + type: WORLD_OBJECTS.TREE_FOREGROUND, + x: 800, + config: TREE_TYPES.LARGE + } + ], + foregroundRocks: [ + { + type: WORLD_OBJECTS.ROCK_FOREGROUND, + x: 300, + config: ROCK_TYPES.MEDIUM + }, + { + type: WORLD_OBJECTS.ROCK_FOREGROUND, + x: 700, + config: ROCK_TYPES.SMALL + } + ] +}); + +const renderTree = (ctx, tree, groundY) => { + const { x, config } = tree; + const { width, height, canopyOffset, trunkColor, canopyColor } = config; + + // Draw trunk + ctx.fillStyle = trunkColor; + ctx.fillRect( + x - width/6, + groundY - height, + width/3, + height + ); + + // Draw canopy (triangular shape) + ctx.fillStyle = canopyColor; + ctx.beginPath(); + ctx.moveTo(x - width/2, groundY - canopyOffset); + ctx.lineTo(x + width/2, groundY - canopyOffset); + ctx.lineTo(x, groundY - height); + ctx.closePath(); + ctx.fill(); +}; + +const renderRock = (ctx, rock, groundY) => { + const { x, config } = rock; + const { width, height, color, highlights } = config; + + // Draw main rock shape (slightly irregular pentagon) + ctx.fillStyle = color; + ctx.beginPath(); + ctx.moveTo(x - width/2, groundY); + ctx.lineTo(x - width/2 + width/6, groundY - height); + ctx.lineTo(x + width/3, groundY - height); + ctx.lineTo(x + width/2, groundY - height/2); + ctx.lineTo(x + width/2, groundY); + ctx.closePath(); + ctx.fill(); + + // Add highlights + ctx.fillStyle = highlights; + ctx.beginPath(); + ctx.moveTo(x - width/4, groundY - height); + ctx.lineTo(x, groundY - height); + ctx.lineTo(x + width/6, groundY - height/2); + ctx.lineTo(x - width/6, groundY - height/2); + ctx.closePath(); + ctx.fill(); +}; + +// Collision detection helper +const checkCollision = (player, platform) => { + return player.x < platform.x + platform.width && + player.x + player.width > platform.x && + player.y < platform.y + platform.height && + player.y + player.height > platform.y; +}; + +// World physics helper +const handleWorldCollisions = (player, world) => { + let onGround = false; + + // Check ground collision first + const groundY = window.innerHeight - world.groundHeight; + if (player.y + player.height > groundY) { + player.y = groundY - player.height; + player.velocityY = 0; + onGround = true; + } + + // Then check platform collisions + for (const platform of world.platforms) { + if (checkCollision(player, platform)) { + // Calculate overlap on each axis + const overlapX = Math.min( + player.x + player.width - platform.x, + platform.x + platform.width - player.x + ); + const overlapY = Math.min( + player.y + player.height - platform.y, + platform.y + platform.height - player.y + ); + + // Resolve collision on the axis with smallest overlap + if (overlapX < overlapY) { + // Horizontal collision + if (player.x < platform.x) { + player.x = platform.x - player.width; + } else { + player.x = platform.x + platform.width; + } + player.velocityX = 0; + } else { + // Vertical collision + if (player.y < platform.y) { + player.y = platform.y - player.height; + player.velocityY = 0; + onGround = true; + } else { + player.y = platform.y + platform.height; + player.velocityY = 0; + } + } + } + } + + return { ...player, jumping: !onGround }; +}; |