Skip to content

Transform Component

The Transform Component provides standardized spatial transformation properties for game objects. It handles position, scale, and rotation in 2D space, making it essential for object placement and movement.

Purpose

The Transform Component handles:

  • World position coordinates
  • Scaling for size modifications
  • Rotation for object orientation
  • Standardized spatial representation

Properties

Optional Properties (All have defaults)

PropertyTypeDefaultDescription
position{ x: number, y: number }{ x: 0, y: 0 }Position in world coordinates
scale{ x: number, y: number }{ x: 1, y: 1 }Scale multipliers for width/height
rotationnumber0Rotation in radians

Usage Examples

Basic Transform

typescript
const transformData: TransformComponentData = {};
// All properties use defaults: position (0,0), scale (1,1), rotation 0

Positioned Object

typescript
const transformData: TransformComponentData = {
  position: { x: 200, y: 150 }
};

Scaled and Rotated Object

typescript
const transformData: TransformComponentData = {
  position: { x: 300, y: 200 },
  scale: { x: 2, y: 1.5 }, // 2x width, 1.5x height
  rotation: Math.PI / 4 // 45 degrees
};

Flipped Object

typescript
const transformData: TransformComponentData = {
  position: { x: 400, y: 300 },
  scale: { x: -1, y: 1 }, // Horizontally flipped
  rotation: 0
};

Runtime Properties

The created component includes all properties as required (no optional properties in the final type):

  • position: { x: number; y: number }
  • scale: { x: number; y: number }
  • rotation: number

Property Descriptions

Position

  • World Coordinates: Absolute position in the game world
  • Origin: Top-left is typically (0, 0) in most 2D engines
  • Units: Pixels or world units depending on your game scale

Scale

  • Uniform Scaling: Use same value for x and y ({ x: 2, y: 2 })
  • Non-uniform Scaling: Different values for width/height ({ x: 1, y: 0.5 })
  • Negative Values: Flip objects ({ x: -1, y: 1 } flips horizontally)
  • Zero Values: Hide objects by scaling to zero

Rotation

  • Radians: All rotations use radians (not degrees)
  • Clockwise: Positive values rotate clockwise
  • Conversion: Use Math.PI / 180 * degrees to convert from degrees
  • Full Circle: 2 * Math.PI radians = 360 degrees

Common Usage Patterns

Object Movement

typescript
// Move object 10 pixels right
transform.position.x += 10;

// Move towards target
const target = { x: 500, y: 300 };
const direction = {
  x: target.x - transform.position.x,
  y: target.y - transform.position.y
};
const speed = 100; // pixels per second
transform.position.x += direction.x * speed * deltaTime;
transform.position.y += direction.y * speed * deltaTime;

Object Scaling

typescript
// Pulse effect
const pulseSpeed = 2;
const time = Date.now() / 1000;
const pulse = 1 + Math.sin(time * pulseSpeed) * 0.2;
transform.scale.x = pulse;
transform.scale.y = pulse;

// Grow object
transform.scale.x *= 1.1;
transform.scale.y *= 1.1;

Object Rotation

typescript
// Constant rotation
const rotationSpeed = Math.PI; // 180 degrees per second
transform.rotation += rotationSpeed * deltaTime;

// Look at target
const target = { x: 400, y: 300 };
const angle = Math.atan2(
  target.y - transform.position.y,
  target.x - transform.position.x
);
transform.rotation = angle;

Physics Integration

typescript
// Sync transform with physics body
transform.position.x = physicsBody.position.x;
transform.position.y = physicsBody.position.y;
transform.rotation = physicsBody.angle;

// Apply transform to sprite
sprite.position.x = transform.position.x;
sprite.position.y = transform.position.y;
sprite.scale.x = transform.scale.x;
sprite.scale.y = transform.scale.y;
sprite.rotation = transform.rotation;

Integration with Other Components

With Sprite Components

typescript
// System that syncs Transform with SpriteComponent
const entities = engine.EntityEngine.query<{
  TransformComponent: TransformComponent[];
  SpriteComponent: SpriteComponent[];
}>(["TransformComponent", "SpriteComponent"]);

for (const { components } of entities) {
  const transform = components.TransformComponent[0];
  const sprite = components.SpriteComponent[0];
  
  // Apply transform to sprite
  sprite.position = transform.position;
  sprite.scale = transform.scale;
  sprite.rotation = transform.rotation;
}

With Physics Components

typescript
// System that syncs Transform with RigidBody
const entities = engine.EntityEngine.query<{
  TransformComponent: TransformComponent[];
  RigidBodyRectangleComponent: RigidBodyRectangleComponent[];
}>(["TransformComponent", "RigidBodyRectangleComponent"]);

for (const { components } of entities) {
  const transform = components.TransformComponent[0];
  const rigidBody = components.RigidBodyRectangleComponent[0];
  
  // Sync physics body with transform
  transform.position.x = rigidBody._body.position.x;
  transform.position.y = rigidBody._body.position.y;
  transform.rotation = rigidBody._body.angle;
}

Scene Configuration

In JSON Scene Files

json
{
  "name": "Player",
  "components": [
    {
      "name": "TransformComponent",
      "data": {
        "position": { "x": 100, "y": 200 },
        "scale": { "x": 1, "y": 1 },
        "rotation": 0
      }
    }
  ]
}

In Blueprint Files

json
{
  "name": "MovableObject",
  "path": "MovableObject.blueprint.json",
  "components": [
    {
      "name": "TransformComponent",
      "data": {
        "position": { "x": 0, "y": 0 },
        "scale": { "x": 1, "y": 1 },
        "rotation": 0
      }
    }
  ]
}

Best Practices

Performance

  • Batch Updates: Update transforms in dedicated systems
  • Avoid Redundant Calculations: Cache frequently used values
  • Use Dirty Flags: Only update dependent components when transform changes

Architecture

  • Single Source of Truth: Use TransformComponent as the authoritative spatial data
  • System Separation: Keep transform logic separate from rendering/physics
  • Consistent Units: Use the same coordinate system throughout your game

Common Patterns

  • Transform Hierarchy: Parent-child relationships for complex objects
  • Interpolation: Smooth movement between positions
  • Constraints: Limit position, scale, or rotation values

Notes

  • TransformComponent is a built-in engine component and doesn't need registration
  • All rotation values are in radians, not degrees
  • Scale values can be negative for flipping objects
  • Position represents the center point or anchor point of objects
  • Compatible with all drawable and physics components
  • Essential for most game objects that have spatial properties

Released under the Academic License.