def update(self, position): self.length += mathfuncs.distance(self.positions[-1], position) self.positions.append(position) if self.length > self.max_length: self.length -= mathfuncs.distance(self.positions[0], self.positions[1]) self.positions = self.positions[1:] elif self.length > 0: self.widths = [1] width_delta = float(self.max_width / len(self.positions)) for i in range(len(self.positions)): self.widths.append(min(self.max_width, self.widths[i] * 1.5))
def update_point_damage(self): """updates the damage done by each attacking point""" current_point_positions_dictionary = self.get_player_point_positions() for point_name in self.point_name_to_point_damage.keys(): current_relative_position = \ self.get_point_relative_position( point_name, current_point_positions_dictionary ) previous_relative_position = \ self.get_point_relative_position( point_name, self.previous_point_positions ) additional_damage = \ min( self.get_max_attack_damage(), (mathfuncs.distance( current_relative_position, previous_relative_position ) + (.0 * self.get_extension_damage( point_name, current_point_positions_dictionary ))) * self.get_damage_growth_rate() ) self.point_name_to_point_damage[point_name] += additional_damage
def draw( self, surface, color=None, line_thickness=-1, pos_delta=None, frame_image_reference_pos=None, scale=1, radius=None, ): """draws a circle on a surface surface: the pygame surface to draw the circle on""" if color == None: color = self.color if radius == None: radius = 0.5 * mathfuncs.distance(self.endPoint1.pos, self.endPoint2.pos) pos = mathfuncs.midpoint(self.endPoint1.pos, self.endPoint2.pos) if frame_image_reference_pos != None: pos = scale_image_point(pos, frame_image_reference_pos, scale) radius = radius * scale if pos_delta != None: pos = move_image_point(pos, pos_delta) if line_thickness == -1: line_thickness = self.thickness if radius < line_thickness: line_thickness = radius pygame.draw.circle(surface, color, (int(pos[0]), int(pos[1])), int(radius)) # , \
def draw_frame(surface, frame, opacity=255): """draws all the points, lines and circles in a frame""" global LINE_COLORS frame_rect = frame.get_enclosing_rect(10, 16, 10) frame_surface = pygame.Surface((frame_rect.width, frame_rect.height)) pos_delta = (-frame_rect.left, -frame_rect.top) for line in frame.lines(): line.draw(frame_surface, (255,255,255), line_thickness = 20, pos_delta = pos_delta) for circle in frame.circles(): outer_radius = (.5 * mathfuncs.distance(circle.endPoint1.pos, \ circle.endPoint2.pos)) + 2 circle.draw(frame_surface, (255,255,255), pos_delta = pos_delta, radius = outer_radius) for point in frame.points(): point.draw(frame_surface, color=(255,255,255), radius=10, pos_delta = pos_delta) for line in frame.lines(): line.draw(frame_surface, LINE_COLORS[line.name], line_thickness = 16, pos_delta = pos_delta) for circle in frame.circles(): circle.draw(frame_surface, LINE_COLORS[circle.name], pos_delta = pos_delta) for point in frame.points(): point.draw(frame_surface, radius=8, pos_delta = pos_delta) frame_surface.set_colorkey((0,0,0)) frame_surface.set_alpha(opacity) surface.blit(frame_surface, (frame_rect.left, frame_rect.top))
def covers(self, pos): """indicates if a point covers a coordinate pos: The coordinates to test""" containsIndicator = False if mathfuncs.distance(self.pos, pos) <= self.radius: containsIndicator = True return containsIndicator
def draw_outer_circle(circle, color, surface): radius = (.5 * mathfuncs.distance(circle.endPoint1.pos, \ circle.endPoint2.pos)) pos = mathfuncs.midpoint(circle.endPoint1.pos, circle.endPoint2.pos) pygame.draw.circle(surface, \ color, \ (int(pos[0]), int(pos[1])), \ int(radius))
def sin(self, start_position, end_position): distance = mathfuncs.distance(start_position, end_position) y_delta = end_position[1] - start_position[1] sin = 0 if distance > 0: sin = float(y_delta) / distance return sin
def cos(self, start_position, end_position): distance = mathfuncs.distance(start_position, end_position) x_delta = end_position[0] - start_position[0] cos = 0 if distance > 0: cos = float(x_delta) / distance return cos
def get_line_length_change( self, point1_name, point2_name, current_point_positions ): point1_prev_position = self.previous_point_positions[point1_name] point2_prev_position = self.previous_point_positions[point2_name] prev_line_length = mathfuncs.distance( point1_prev_position, point2_prev_position ) point1_position = current_point_positions[point1_name] point2_position = current_point_positions[point2_name] current_line_length = mathfuncs.distance( point1_position, point2_position ) return abs(current_line_length - prev_line_length)
def get_max_distance(start_positions, end_positions): """returns key moves the furthest and the distance it travels""" max_distance = 0 max_distance_key = start_positions.keys()[0] for key, start_position in start_positions.iteritems(): distance = mathfuncs.distance(start_position, end_positions[key]) if distance > max_distance: max_distance = distance max_distance_key = key return max_distance_key, max_distance
def get_enclosing_rect(self, radius=None, point_radius=None, line_thickness=None): if line_thickness == None: line_thickness = self.thickness if radius == None: radius = 0.5 * mathfuncs.distance(self.endPoint1.pos, self.endPoint2.pos) enclosing_rect1 = pygame.Rect(*self.endPoint1.get_enclosing_rect(point_radius)) enclosing_rect2 = pygame.Rect(*self.endPoint2.get_enclosing_rect(point_radius)) pos = self.center() top_left = (int(pos[0] - radius - line_thickness), int(pos[1] - radius - line_thickness)) dimensions = (int(2 * (radius + line_thickness)), int(2 * (radius + line_thickness))) enclosing_circle_rect = pygame.Rect(top_left, dimensions) return enclosing_rect1.union(enclosing_rect2).union(enclosing_circle_rect)
def set_tile_acceleration(self, tile): x_acceleration = 0 y_acceleration = 0 for gravity_tile in self.gravity_tiles: length = distance(gravity_tile.position, tile.position) if length > 0: x_delta = tile.position[0] - gravity_tile.position[0] y_delta = tile.position[1] - gravity_tile.position[1] inverse_distance = -1/(length) x_acceleration += gravity_tile.gravity * x_delta/length * inverse_distance y_acceleration += gravity_tile.gravity * y_delta/length * inverse_distance tile.acceleration[0] = x_acceleration tile.acceleration[1] = y_acceleration
def allow_line_resize(self, line, end_point, new_pos): """checks if a line will exceed its max length if one of its endpoints moves to a new position line: the line to test end_point: the end point moving to a new position new_pos: the new position of the end_point""" indicator = True new_length = mathfuncs.distance(new_pos, \ line.other_end_point(end_point).pos) if new_length >= line.max_length: indicator = False return indicator
def get_top_left_and_bottom_right(self): position = mathfuncs.midpoint(self.endPoint1.pos, self.endPoint2.pos) position = (int(position[0]), int(position[1])) radius = int(mathfuncs.distance(self.endPoint1.pos, self.endPoint2.pos) / 2) point_radius = max(self.endPoint1.radius, self.endPoint2.radius) point1_top_left, point1_bottom_right = self.endPoint1.get_top_left_and_bottom_right() point2_top_left, point1_bottom_right = self.endPoint2.get_top_left_and_bottom_right() return ( ( position[0] - radius - self.thickness - point_radius, position[1] - radius - self.thickness - point_radius, ), ( position[0] + radius + self.thickness + point_radius, position[1] + radius + self.thickness + point_radius, ), )
def correct(self, slctd_point): """Changes the position of one endpoint based off the new position of the selected endpoint so that the line has a new slope and the max length. slctd_point: the point that has been moved""" pulled_point = self.endPoint1 if slctd_point.id == pulled_point.id: pulled_point = self.endPoint2 new_length = mathfuncs.distance(slctd_point.pos, pulled_point.pos) x_delta = slctd_point.pos[0] - pulled_point.pos[0] y_delta = slctd_point.pos[1] - pulled_point.pos[1] if new_length > self.max_length: pulled_point.pos = ( pulled_point.pos[0] + x_delta - ((x_delta / new_length) * self.max_length), pulled_point.pos[1] + y_delta - ((y_delta / new_length) * self.max_length), )
def get_line_positions(self, end_position_index): start_position = self.positions[end_position_index - 1] end_position = self.positions[end_position_index] l1 = mathfuncs.distance(end_position, start_position) if l1 > 0: #YAY FOR SIMILAR TRIANGLES! x1 = end_position[0] - start_position[0] y1 = end_position[1] - start_position[1] l2 = self.widths[end_position_index] / 2.0 position1 = ( end_position[0] + (y1 / l1 * l2), end_position[1] - (x1 / l1 * l2) ) position2 = ( end_position[0] - (y1 / l1 * l2), end_position[1] + (x1 / l1 * l2) ) return (position1, position2) else: return (end_position, end_position)
def set_max_length(self): """sets the maximum length of a line to the distance between its two endpoints""" self.max_length = mathfuncs.distance(self.endPoint1.pos, self.endPoint2.pos)
def contains(self, position): if distance(position, self.center) <= self.radius: return True else: return False
def get_top_right_reference_position(self): radius = 0.5 * mathfuncs.distance(self.endPoint1.pos, self.endPoint2.pos) pos = mathfuncs.midpoint(self.endPoint1.pos, self.endPoint2.pos) return (int(pos[0] + radius), int(pos[1] - radius))