physics_group.dart 2.45 KB
Newer Older
1 2
part of flutter_sprites;

3 4 5 6 7 8 9
/// A [Node] that acts as a middle layer between a [PhysicsWorld] and a node
/// with an assigned [PhysicsBody]. The group's transformations are limited to
/// [position], [rotation], and uniform [scale].
///
///     PhysicsGroup group = new PhysicsGroup();
///     myWorld.addChild(group);
///     group.addChild(myNode);
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
class PhysicsGroup extends Node {

  set scaleX(double scaleX) {
    assert(false);
  }

  set scaleY(double scaleX) {
    assert(false);
  }

  set skewX(double scaleX) {
    assert(false);
  }

  set skewY(double scaleX) {
    assert(false);
  }

  set physicsBody(PhysicsBody body) {
    assert(false);
  }

  set position(Point position) {
    super.position = position;
    _invalidatePhysicsBodies(this);
  }

  set rotation(double rotation) {
    super.rotation = rotation;
    _invalidatePhysicsBodies(this);
  }

  set scale(double scale) {
    super.scale = scale;
    _invalidatePhysicsBodies(this);
  }

  void _invalidatePhysicsBodies(Node node) {
    if (_world == null) return;

    if (node.physicsBody != null) {
      // TODO: Add to list
      _world._bodiesScheduledForUpdate.add(node.physicsBody);
    }

    for (Node child in node.children) {
      _invalidatePhysicsBodies(child);
    }
  }

  void addChild(Node node) {
    super.addChild(node);

    PhysicsWorld world = _world;
    if (node.physicsBody != null && world != null) {
      node.physicsBody._attach(world, node);
    }

    if (node is PhysicsGroup) {
      _attachGroup(this, world);
    }
  }

  void _attachGroup(PhysicsGroup group, PhysicsWorld world) {
    for (Node child in group.children) {
      if (child is PhysicsGroup) {
        _attachGroup(child, world);
      } else if (child.physicsBody != null) {
        child.physicsBody._attach(world, child);
      }
    }
  }

  void removeChild(Node node) {
    super.removeChild(node);

    if (node.physicsBody != null) {
      node.physicsBody._detach();
    }

    if (node is PhysicsGroup) {
      _detachGroup(this);
    }
  }

  void _detachGroup(PhysicsGroup group) {
    for (Node child in group.children) {
      if (child is PhysicsGroup) {
        _detachGroup(child);
      } else if (child.physicsBody != null) {
        child.physicsBody._detach();
      }
    }
  }

  PhysicsWorld get _world {
    if (this.parent is PhysicsWorld)
      return this.parent;
    if (this.parent is PhysicsGroup) {
      PhysicsGroup group = this.parent;
      return group._world;
    }
    return null;
  }
}