Clouds

Time to add one of the most satisfying platform mechanics in gaming - cloud platforms! These one-way surfaces let you jump up through them and move through them from the sides, but when you’re falling down, you land on top. Think Mario’s cloud platforms or Mega Man’s jump-through floors - they make platforming feel incredibly smooth and natural!

Controls: Arrow Keys to move, Spacebar to jump
Try this: Jump up through the blue cloud platforms, then fall back down onto them!

Understanding Cloud Platforms: The Magic of One-Way Surfaces

See the difference? Let’s break down what makes cloud platforms so special:

🧱 Solid walls = Completely impassable from ALL directions

☁️ Cloud platforms = Selectively solid based on direction

Why cloud platforms rock:

Normal solid wall blocks hero from all directions

VS.

Cloud platform allows entry from sides/below, stops from above

Setting Up Cloud Tiles: Modern Tile Types

Let’s create our cloud platform tile type using modern JavaScript patterns:

// Define tile types as constants
const TILE_TYPES = {
    EMPTY: 0,
    SOLID: 1, 
    CLOUD: 2
};

// Tile properties - much cleaner than ActionScript prototypes!
const tileProperties = {
    [TILE_TYPES.EMPTY]: {
        walkable: true,
        solid: false,
        cloud: false
    },
    [TILE_TYPES.SOLID]: {
        walkable: false,
        solid: true,
        cloud: false  
    },
    [TILE_TYPES.CLOUD]: {
        walkable: true,    // Can move through from sides
        solid: false,      // Not solid like normal walls
        cloud: true        // Special cloud behavior
    }
};

// Helper functions for tile checking
function getTileType(x, y) {
    const col = Math.floor(x / TILE_SIZE);
    const row = Math.floor(y / TILE_SIZE);
    
    if (row < 0 || row >= map.length || col < 0 || col >= map[0].length) {
        return TILE_TYPES.EMPTY;
    }
    
    return map[row][col];
}

function isCloudTile(x, y) {
    return getTileType(x, y) === TILE_TYPES.CLOUD;
}

function isSolidTile(x, y) {
    return getTileType(x, y) === TILE_TYPES.SOLID;
}

Why this approach rocks:

Cloud Platform Collision Logic: The Smart Part!

Here’s where the magic happens - making platforms solid only when falling onto them from above:

function canLandOnCloudPlatform(player) {
    // Only check when player is falling down
    if (player.velocityY <= 0) {
        return null; // Not falling, can't land
    }
    
    // Check both feet positions
    const leftFootX = player.x + 5;  // Slight inset from edge
    const rightFootX = player.x + player.width - 5;
    const feetY = player.y + player.height + 1; // Just below player
    
    // Are either feet touching cloud platforms?
    const leftOnCloud = isCloudTile(leftFootX, feetY);
    const rightOnCloud = isCloudTile(rightFootX, feetY);
    
    if (leftOnCloud || rightOnCloud) {
        // Calculate exact platform surface
        const platformRow = Math.floor(feetY / TILE_SIZE);
        const platformY = platformRow * TILE_SIZE;
        
        // Only land if falling onto platform from above
        if (player.y + player.height <= platformY + 5) {
            return platformY; // Return platform surface Y position
        }
    }
    
    return null; // No valid cloud platform landing
}

The key insight: Cloud platforms are only “solid” when:

  1. Player is moving downward (velocityY > 0)
  2. Player’s feet are touching the platform
  3. Player is above the platform (not inside it)

Why check both feet? This handles edge cases where your hero is partially over the platform. Much more reliable than single-point collision!

Integrating Cloud Collision

Now we modify our main collision system:

function checkCollisions() {
    // Normal solid tile collision first
    if (player.velocityY > 0) { // Falling
        const solidGroundHit = checkSolidGroundCollision();
        if (solidGroundHit) {
            landOnSurface(solidGroundHit);
            return;
        }
        
        // Check cloud platform collision
        const cloudLanding = canLandOnCloudPlatform(player);
        if (cloudLanding) {
            landOnSurface(cloudLanding);
            return;
        }
    }
    
    // Ceiling collision (clouds don't block upward movement!)
    if (player.velocityY < 0) {
        const ceilingHit = checkCeilingCollision(); // Only solid tiles
        if (ceilingHit) {
            hitCeiling(ceilingHit);
        }
    }
}

function landOnSurface(surfaceY) {
    player.y = surfaceY - player.height;
    player.velocityY = 0;
    player.onGround = true;
}

Putting It All Together: Cloud Platform Movement

Now we need to update our movement and falling logic to handle cloud platforms correctly:

// In your main game loop
function updateMovementAndCollision() {
    handleInput();        // Process player controls
    updatePhysics();      // Apply gravity and velocity
    checkCollisions();    // Handle all collision types
    checkStillOnGround(); // See if player walked off platform
}

function checkStillOnGround() {
    if (!player.onGround) return; // Already falling
    
    // Check if still standing on solid ground OR cloud platform
    const leftFoot = player.x + 5;
    const rightFoot = player.x + player.width - 5;
    const groundLevel = player.y + player.height + 1;
    
    const onSolid = isSolidTile(leftFoot, groundLevel) || 
                   isSolidTile(rightFoot, groundLevel);
    
    const onCloud = isCloudTile(leftFoot, groundLevel) || 
                   isCloudTile(rightFoot, groundLevel);
    
    // If not on any platform, start falling
    if (!onSolid && !onCloud) {
        player.onGround = false;
        // Gravity will take over next frame
    }
}

Critical detail: When checking if we’re still on a platform (for edge detection), we check both solid tiles AND cloud platforms. This prevents the hero from floating in mid-air after walking off any platform type.

The flow works like this:

  1. Player walks left/right → checkStillOnGround() sees they’re over empty space
  2. player.onGround = false → gravity starts pulling them down
  3. While falling → cloud platforms are checked for landing
  4. When landing on cloud → player.onGround = true → can jump again!

🎉 Congratulations! You now have silky-smooth cloud platforms just like the pros use! Players can flow through your levels naturally, jumping up through platforms and landing on them from above.

Try different feels: Experiment with the +5 inset values for feet detection, or add different cloud types with different behaviors. The foundation you’ve built makes these variations super easy to implement!

Next up: Ladders that let players climb up and down at will - another classic platformer mechanic that combines perfectly with your jumping and cloud platform systems!