The Clay Physics plugin provides physics simulation components built on top of the Box2D physics engine. It offers easy-to-use QML components for creating physics-enabled game objects with proper world unit integration and collision detection capabilities.

Getting Started

To use the Clay Physics plugin in your QML files:

import Clayground.Physics
import Box2D

Core Components

  • PhysicsItem - Base component for physics-enabled items with world unit support
  • RectBoxBody - Rectangle-shaped physics body with visual representation
  • ImageBoxBody - Image-based physics body with box collision
  • VisualizedPolyBody - Polygon physics body integrated with Canvas visualization
  • CollisionTracker - Tracks entities colliding with a fixture
  • PhysicsUtils - Singleton with collision connection helpers

Usage Examples

Basic Physics Object

import QtQuick
import Box2D
import Clayground.Physics

World {
    id: physicsWorld
    gravity: Qt.point(0, -10)

    RectBoxBody {
        xWu: 5
        yWu: 10
        widthWu: 2
        heightWu: 1
        color: "blue"

        bodyType: Body.Dynamic
        density: 1
        friction: 0.3
        restitution: 0.5
    }
}

Platform Game Character

RectBoxBody {
    id: player
    widthWu: 1
    heightWu: 2
    color: "orange"

    bodyType: Body.Dynamic
    fixedRotation: true
    bullet: true

    categories: Box.Category1
    collidesWith: Box.Category2 | Box.Category3

    // Jump logic
    function jump() {
        if (onGround) {
            linearVelocity.y = 10
        }
    }

    // Ground detection
    property bool onGround: false
    CollisionTracker {
        fixture: player.fixture
        debug: true
        onBeginContact: (entity) => {
            if (entity.objectName === "ground") {
                player.onGround = true
            }
        }
        onEndContact: (entity) => {
            if (entity.objectName === "ground") {
                player.onGround = false
            }
        }
    }
}

Collectible Items

ImageBoxBody {
    source: "coin.png"
    xWu: 10
    yWu: 5
    widthWu: 0.5
    heightWu: 0.5

    bodyType: Body.Static
    sensor: true

    categories: Box.Category4
    collidesWith: Box.Category1  // Player category

    Component.onCompleted: {
        PhysicsUtils.connectOnEntered(fixture, (entity) => {
            if (entity.objectName === "player") {
                // Award points
                destroy()
            }
        })
    }
}

Moving Platform

RectBoxBody {
    id: platform
    widthWu: 4
    heightWu: 0.5
    color: "gray"

    bodyType: Body.Kinematic

    SequentialAnimation on xWu {
        loops: Animation.Infinite
        NumberAnimation { to: 10; duration: 3000 }
        NumberAnimation { to: 5; duration: 3000 }
    }
}

Complex Polygon Shape

VisualizedPolyBody {
    canvas: myCanvas
    vertices: [
        {x: 0, y: 0},
        {x: 2, y: 0},
        {x: 2, y: 1},
        {x: 1, y: 2},
        {x: 0, y: 1}
    ]
    fillColor: "green"
    strokeColor: "darkgreen"

    bodyType: Body.Dynamic
    density: 2
}

Trigger Zones

RectBoxBody {
    id: triggerZone
    xWu: 15
    yWu: 10
    widthWu: 5
    heightWu: 5
    color: "yellow"
    opacity: 0.3

    bodyType: Body.Static
    sensor: true

    CollisionTracker {
        fixture: triggerZone.fixture
        onBeginContact: (entity) => {
            console.log("Entity entered zone:", entity)
            // Trigger game event
        }
        onEndContact: (entity) => {
            console.log("Entity left zone:", entity)
        }
    }
}

Best Practices

  1. World Units: Always use world units (Wu) for consistency across different screen sizes.

  2. Collision Categories: Use Box2D categories and masks for efficient collision filtering.

  3. Body Types:
    • Static: Non-moving obstacles
    • Kinematic: Moving platforms (animated)
    • Dynamic: Physics-controlled objects
  4. Performance: Use sensors for triggers to avoid physical collision responses.

  5. Continuous Collision: Enable bullet property for fast-moving objects to prevent tunneling.

Technical Implementation

The Clay Physics plugin:

  • Box2D Integration: Wraps QML Box2D with world unit support
  • Coordinate System: Automatic conversion between screen pixels and world units
  • Collision Management: Simplified collision detection with signal-based API
  • Visual Integration: Seamless integration with visual components
  • Memory Management: Automatic cleanup of collision tracking when objects are destroyed

The plugin handles the complexity of coordinate transformations and provides a clean API for common game physics scenarios.