This guide shows the basic collision workflow in Sendama and how to swap collision strategies when you need different behavior.
- Add a collider component to the game object before you add it to a scene.
- Give the object a sprite, because collider bounds are derived from the sprite rectangle.
- Move the object with
CharacterControllerif you want movement to stop on solid collisions. - Handle collision callbacks in a behaviour.
<?php
use Sendama\Engine\Core\Behaviours\Behaviour;
use Sendama\Engine\Core\GameObject;
use Sendama\Engine\Core\Vector2;
use Sendama\Engine\Physics\CharacterController;
use Sendama\Engine\Physics\Interfaces\CollisionInterface;
final class PlayerCollisionHandler extends Behaviour
{
public function onCollisionEnter(CollisionInterface $collision): void
{
echo 'Hit ' . $collision->getGameObject()->getName();
}
}
$player = new GameObject('Player');
$player->setSpriteFromTexture('Textures/player.texture', Vector2::zero(), Vector2::one());
$player->addComponent(CharacterController::class);
$player->addComponent(PlayerCollisionHandler::class);AABBCollisionDetectionStrategy: compares bounding boxes. This is the default forCollider,CharacterController, andRigidbody.SimpleCollisionDetectionStrategy: currently uses the same bounding-box overlap check, but without the extra debug logging.BasicCollisionDetectionStrategy: only reports a hit when two colliders share the exact same position.SeparationBasedCollisionDetectionStrategy: reports a hit when the distance between colliders is less than1.
Use setCollisionDetectionStrategy() on the collider component instance itself. In practice that means a Collider, CharacterController, or Rigidbody, because those are the components that implement ColliderInterface.
<?php
use Sendama\Engine\Physics\CharacterController;
use Sendama\Engine\Physics\Strategies\BasicCollisionDetectionStrategy;
/** @var CharacterController $controller */
$controller = $player->addComponent(CharacterController::class);
$controller->setCollisionDetectionStrategy(
new BasicCollisionDetectionStrategy($controller)
);- Solid colliders block
CharacterController::move(). - Trigger colliders do not block movement.
- To make a pickup or checkpoint a trigger, call
setTrigger(true).
$coinCollider->setTrigger(true);At the moment, the CharacterController path dispatches onCollisionEnter() and onCollisionStay() for both solid and trigger contacts, so those are the safest callbacks to implement for gameplay reactions.
If you want to query collisions yourself:
<?php
use Sendama\Engine\Core\Vector2;
use Sendama\Engine\Physics\Physics;
$collisions = Physics::getInstance()->checkCollisions($playerCollider, new Vector2(1, 0));
if ($collisions !== []) {
// The move would overlap another collider.
}checkCollisions() tests the collider's projected bounds after applying the motion vector, which is useful for predicting whether a move will be blocked before translating the object.
- Colliders are registered with physics when the game object is added to the scene.
- If you add a collider after the object is already running, register it with
Physics::getInstance()->addCollider(...)yourself. - Collision bounds come from the game object's sprite rect, so a missing sprite means unreliable collision bounds.