def __init__(self): self.world = self.create_world() self.added_contacts = [] self.contact_listener = VoidContactListener(self) self.world.SetContactListener(self.contact_listener) self.hub = Hub(self.world) self.ship = Ship(self.world)
class Game(object): def __init__(self): self.world = self.create_world() self.added_contacts = [] self.contact_listener = VoidContactListener(self) self.world.SetContactListener(self.contact_listener) self.hub = Hub(self.world) self.ship = Ship(self.world) def step(self, dt): maybe_dead = set() if random.random() <= dt: Asteroid(self.world, self.ship) self.ship.step(dt) self.step_laser(dt, maybe_dead) self.world.Step(dt, 10, 8) for agent_1, agent_2 in self.added_contacts: maybe_dead.add(agent_1) maybe_dead.add(agent_2) agent_1.collide(agent_2) agent_2.collide(agent_1) for agent in maybe_dead: if not agent.alive: if type(agent) is Asteroid: agent.split() self.world.DestroyBody(agent.body) del self.added_contacts[:] def step_laser(self, dt, maybe_dead): if self.ship.firing: angle = self.ship.body.GetAngle() unit = box2d.b2Vec2(-math.sin(angle), math.cos(angle)) segment = box2d.b2Segment() segment.p1 = self.ship.body.GetPosition() segment.p2 = segment.p1 + unit * 10.0 fraction, normal, shape = self.world.RaycastOne(segment, False, None) if shape is not None: agent = shape.GetBody().GetUserData() if type(agent) is Asteroid: maybe_dead.add(agent) agent.power -= self.ship.damage * dt * fraction def on_draw(self): glScaled(15.0, 15.0, 15.0) position = self.ship.body.GetPosition() glTranslated(-position.x, -position.y, 0.0) self.draw_lifeline() self.draw_towline() self.draw_laser() for agent in self.query_draw(): agent.draw() def query_draw(self): position = self.ship.body.GetPosition() aabb = box2d.b2AABB() aabb.lowerBound.Set(position.x - 40.0, position.y - 25.0) aabb.upperBound.Set(position.x + 40.0, position.y + 25.0) max_count = 100 (count, shapes) = self.world.Query(aabb, max_count) agents = set(shape.GetBody().GetUserData() for shape in shapes) agents = sorted(agents, key=id) return agents def draw_lifeline(self): position = self.ship.body.GetPosition() distance = math.sqrt(position.x ** 2 + position.y ** 2) fraction = distance / self.ship.max_lifeline_range if fraction <= 0.5: red = fraction * 2.0 green = 1.0 else: red = 1.0 green = 1.0 - (fraction - 0.5) * 2.0 alpha = 0.5 + 0.5 * fraction glBegin(GL_LINES) glColor4d(red, green, 0.0, alpha) glVertex2d(0.0, 0.0) glVertex2d(position.x, position.y) glEnd() def draw_towline(self): joint_edge = self.ship.body.GetJointList() if joint_edge is not None: joint = joint_edge.joint anchor_1 = joint.GetAnchor1() anchor_2 = joint.GetAnchor2() glBegin(GL_LINES) glColor3d(1.0, 0.0, 1.0) glVertex2d(anchor_1.x, anchor_1.y) glVertex2d(anchor_2.x, anchor_2.y) glEnd() def draw_laser(self): if self.ship.firing: position = self.ship.body.GetPosition() angle = self.ship.body.GetAngle() unit = box2d.b2Vec2(-math.sin(angle), math.cos(angle)) endpoint = position + unit * 10.0 glBegin(GL_LINES) glColor4d(1.0, 0.0, 0.0, 1.0) glVertex2d(position.x, position.y) glColor4d(1.0, 0.0, 0.0, 0.0) glVertex2d(endpoint.x, endpoint.y) glEnd() def create_world(self): world_aabb = box2d.b2AABB() world_aabb.lowerBound.Set(-400.0, -400.0) world_aabb.upperBound.Set(400.0, 400.0) gravity = box2d.b2Vec2(0.0, 0.0) return box2d.b2World(world_aabb, gravity, False) def add_contact(self, point): agent_1 = point.shape1.GetBody().GetUserData() agent_2 = point.shape2.GetBody().GetUserData() self.added_contacts.append((agent_1, agent_2)) def persist_contact(self, point): pass def remove_contact(self, point): pass def contact_result(self, point): pass