def __init__(self, x, y, batch): self.position = euclid.Point2(x, y) self.velocity = euclid.Point2(0, 0) self.angle = math.pi/2 self.batch = batch self.lines = batch.add(6, GL_LINES, primitives.SmoothLineGroup(), ('v2f', (0, 0) * 6), ('c4B', (255, 255, 255, 255) * 6)) self.ball_position = euclid.Point2(window.width/2, window.height/4) self.ball_velocity = euclid.Point2(0, 0) self.ball_lines = primitives.add_circle(batch, 0, 0, 20, (255, 255, 255, 255), 20) self._ball_verts = list(self.ball_lines.vertices) self._update_ball_verts() self.join_active = False self.join_line = None self.joined = False
def update(self, dt): self.angle += (keyboard[key.LEFT] - keyboard[key.RIGHT]) * math.pi * dt r = euclid.Matrix3.new_rotate(self.angle) if keyboard[key.UP]: thrust = r * euclid.Vector2(600, 0) else: thrust = euclid.Vector2(0, 0) # attempt join on spacebar press s_b = self.position - self.ball_position if keyboard[key.SPACE] and abs(s_b) < 100: self.join_active = True if not self.joined: # simulation is just the ship # apply thrust to the ship directly thrust.y += GRAVITY # now figure my new velocity self.velocity += thrust * dt # calculate new line endpoints self.position += self.velocity * dt else: # simulation is of a rod with ship and one end and ball at other n_v = s_b.normalized() n_t = thrust.normalized() # figure the linear acceleration, velocity & move d = abs(n_v.dot(n_t)) lin = thrust * d lin.y += GRAVITY self.velocity += lin * dt self.cog += self.velocity * dt # now the angular acceleration r90 = euclid.Matrix3.new_rotate(math.pi/2) r_n_t = r90 * n_t rd = n_v.dot(r_n_t) self.ang_velocity -= abs(abs(thrust)) * rd * 0.0001 self.join_angle += self.ang_velocity * dt # vector from center of gravity our to either end ar = euclid.Matrix3.new_rotate(self.join_angle) a_r = ar * euclid.Vector2(self.join_length/2, 0) # set the ship & ball positions self.position = self.cog + a_r self.ball_position = self.cog - a_r self._update_ball_verts() if self.join_active: if abs(s_b) >= 100 and not self.joined: self.joined = True h_s_b = s_b / 2 self.cog = self.position - h_s_b self.join_angle = math.atan2(s_b.y, s_b.x) self.join_length = abs(s_b) # mass just doubled, so slow linear velocity down self.velocity /= 2 # XXX and generate some initial angular velocity based on # XXX ship current velocity self.ang_velocity = 0 # render the join line l = [ self.position.x, self.position.y, self.ball_position.x, self.ball_position.y ] if self.join_line: self.join_line.vertices[:] = l else: self.join_line = self.batch.add(2, GL_LINES, primitives.SmoothLineGroup(), ('v2f', l), ('c4B', (255, 255, 255, 255) * 2)) # update the ship verts bl = r * euclid.Point2(-25, 25) t = r * euclid.Point2(25, 0) br = r * euclid.Point2(-25, -25) x, y = self.position self.lines.vertices[:] = [ x+bl.x, y+bl.y, x+t.x, y+t.y, x+t.x, y+t.y, x+br.x, y+br.y, x+br.x, y+br.y, x+bl.x, y+bl.y, ]