Update Method¶
Intent: Simulate a collection of independent objects by telling each to process one frame of behavior at a time.
Acron Mapping¶
Pattern role |
Acron equivalent |
|---|---|
|
Task function registered with |
Entity collection |
Each entity owns its own task or a manager task iterates a list |
Delta time |
|
Entity activation |
|
Entity deactivation |
|
Two approaches: (a) each entity has its own task — simple, but many tasks have overhead; (b) one manager task iterates a Python list of entities — efficient for hundreds of objects.
How to Implement (manager approach, recommended for many entities)¶
Create an
EntityManagerwith a list and a single task.Each entity class has an
update(dt)method — no Acron imports needed in the entity.EntityManagercallsentity.update(dt)for each live entity per frame.Mark entities for removal with a
deadflag; purge at end of frame.
Code Sketch (Python)¶
class Enemy:
def __init__(self, node):
self.node = node
self.dead = False
self._dir = 1
def update(self, dt: float):
self.node.setX(self.node, self._dir * 4 * dt)
if abs(self.node.getX()) > 10:
self._dir *= -1
def destroy(self):
self.node.removeNode()
class EntityManager:
def __init__(self):
self._entities = []
taskMgr.add(self._update_all, 'entityUpdate', sort=10)
def add(self, entity):
self._entities.append(entity)
def _update_all(self, task):
dt = globalClock.getDt()
for e in self._entities:
if not e.dead:
e.update(dt)
# Purge dead entities at end of frame
dead = [e for e in self._entities if e.dead]
for e in dead:
e.destroy()
self._entities.remove(e)
return task.cont
def destroy(self):
taskMgr.remove('entityUpdate')
for e in self._entities:
e.destroy()
self._entities.clear()
Pitfalls¶
Update order is not simultaneous: entities update one at a time, in list order. When entity A updates, it sees B’s state from the previous frame; when B updates next, it already sees A’s new state. This asymmetry can cause subtle bugs when entities interact. The book flags this explicitly: if order matters, either enforce a fixed canonical order or double-buffer state (see Double Buffer).
Modifying the list during iteration: marking
entity.dead = Trueduringupdate()is safe; removing fromself._entitieswhile iterating is not. Always purge after the loop (shown above).Per-entity tasks for many objects: registering 500 separate tasks via
taskMgr.add()adds overhead. Use the manager/list approach for large entity counts.Task sort order: the entity update task must run after input processing but before rendering. Use
sort=10; Acron’s render task runs atsort=50by default.