Object Lifecycle

How game objects are created, updated, and removed via the Decor pool.

Creation

Objects are placed by calling Decor::PlaceObject(type, pos, posEnd, speed). This finds the first inactive slot in the 100-slot pool (obj.active == false) and initialises it:

PlaceObject(ObjectType type, Vector3 pos, Vector3 posEnd, float speed):
  for i in [0, kMaxObjects):
      if !objects_[i].active:
          obj = &objects_[i]
          obj->type      = type
          obj->posStart  = pos
          obj->posEnd    = posEnd
          obj->pos       = pos
          obj->speed     = speed
          obj->direction = +1
          obj->animPhase = 0
          obj->active    = true
          obj->node      = make_unique<ObjectNode>(ctx, scene_, elementMat_)
          return
  // pool full — object silently dropped

Per-Frame Update

Decor::Update(dt, blupiPos):
  platformDelta_ = Vector3::ZERO
  for each active object obj:
      StepMovement(obj, dt)
      obj.animPhase++
      icon = GetIcon(obj)
      obj.node->SetIcon(icon)
      obj.node->SetPosition(obj.pos)
      CheckContact(obj, blupiPos)

StepMovement

Linear patrol between posStart and posEnd. When the object reaches an endpoint, direction reverses:

StepMovement(obj, dt):
  if posStart == posEnd: return   // stationary
  obj.pos += direction * normalize(posEnd - posStart) * speed * dt
  if distance(obj.pos, posEnd) < 0.05f:
      obj.direction = -1; obj.pos = posEnd
  elif distance(obj.pos, posStart) < 0.05f:
      obj.direction = +1; obj.pos = posStart

Platform Carry

For ObjectType1 (moving platform): if Blupi is within the carry radius, the per-frame XZ displacement is accumulated in platformDelta_ and applied to Blupi via blupi_->ApplyExternalDelta(platformDelta_) in GalaxyEggbertGame::UpdatePlay().

Contact Detection

CheckContact(obj, blupiPos):
  dist = distance(obj.pos, blupiPos)
  if dist < 0.85f:
      switch(obj.type):
          case ExitDoor:  exitReached_ = true
          case EnemyA:    blupiHit_    = true
          case Shield:    shieldCollected_ = true; deactivate(obj)
          case Key1..3:   keysCollected_++; deactivate(obj)
          case Treasure:  collected_++; deactivate(obj)
          ...

Removal

deactivate(obj) sets obj.active = false and calls obj.node->Remove(), which removes the scene node. The pool slot becomes available for reuse by the next PlaceObject() call. Removed objects do not respawn unless the level is fully reloaded.

Event Consumption

// In GalaxyEggbertGame::UpdatePlay():
if (decor_->WasBlupiHit())        { /* lose life */ }
if (decor_->WasExitReached())     { EnterPhase(Win); }
if (decor_->WasShieldCollected()) { shieldTimer_ = 5.0f; blupi_->StartFlash(5.0f); }
decor_->ClearEvents();            // reset all flags after reading