Physics Plugin
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
-
World Units: Always use world units (Wu) for consistency across different screen sizes.
-
Collision Categories: Use Box2D categories and masks for efficient collision filtering.
- Body Types:
- Static: Non-moving obstacles
- Kinematic: Moving platforms (animated)
- Dynamic: Physics-controlled objects
-
Performance: Use sensors for triggers to avoid physical collision responses.
- Continuous Collision: Enable
bulletproperty 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.