def __init__(self): self.pos = Point(0.0, 0.0) self.vel = Point(0.0, 0.0) self.theta = 0.0 self.theta_vel = 0.0 self.radius = 0.0 self.orig = [] self.pts = [] self.alive = True self.wrap = Point(True, True)
def __init__(self, sprite): self.color = [255, 255, 255] self.fade = 15 self.alive = True self.sides = [] for start, end in zip(sprite.orig[1:], sprite.orig[:-1]): side = Sprite() side.orig = [start, end] side.pos = Point(sprite.pos.x, sprite.pos.y) side.vel = Point((random() * 4) - 2, (random() * 4) - 2) side.theta = sprite.theta self.sides.append(side)
def init_edge(self): side = randint(0, 3) if side == 0: self.pos = Point(25, random() * ScreenSize.height) elif side == 1: self.pos = Point(ScreenSize.width - 25, random() * ScreenSize.height) elif side == 2: self.pos = Point(random() * ScreenSize.width, 25) else: self.pos = Point(random() * ScreenSize.width, ScreenSize.height - 25)
def __init__(self): Sprite.__init__(self) self.speed = 0.27 self.decay = 0.98 self.pos = Point(350, 200) self.time_to_respawn = 0 self.init_shape()
def set_points(self, xpts, ypts, connect=False): self.orig = [Point(x, y) for x, y in zip(xpts, ypts)] if connect: self.orig.append(self.orig[0]) # Calculate bounding circle radius for pt in self.orig: dist = math.sqrt((pt.x**2) + (pt.y**2)) if dist > self.radius: self.radius = dist
def contains(self, pt): # Even # of edge crossings = outside polygon # Odd # of edge crossing = inside polygon n = len(self.pts) inside = False p1 = Point(self.pts[0].x, self.pts[0].y) # Count edge crossings by casting a ray from inside the polygon for i in range(n + 1): p2 = self.pts[i % n] if pt.y > min(p1.y, p2.y) and pt.y <= max(p1.y, p2.y) and pt.x <= max(p1.x, p2.x): if p1.y != p2.y: xinters = (pt.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x if p1.x == p2.x or pt.x <= xinters: inside = not inside p1.x, p1.y = p2.x, p2.y return inside
def fire_bullet(self, pt): self.time_to_fire = 30 # Fire bullet toward specific point if self.size == Saucer.Small: # Add a little bit of error dest = Point(pt.x, pt.y) dest.x += randint(-20, 20) dest.y += randint(-20, 20) # Calculate theta and velocity toward point theta = math.atan2(dest.x - self.pos.x, self.pos.y - dest.y) vel = Point(math.sin(theta) * 5.0, -math.cos(theta) * 5.0) return Bullet(self.pos.x + vel.x, self.pos.y + vel.y, theta) # Fire bullet in random direction else: theta = random() * (2.0 * math.pi) vel = Point(math.sin(theta) * 10.0, -math.cos(theta) * 10.0) return Bullet(self.pos.x + vel.x, self.pos.y + vel.y, theta)
def contains(self, pt): # Even # of edge crossings = outside polygon # Odd # of edge crossing = inside polygon n = len(self.pts) inside = False p1 = Point(self.pts[0].x, self.pts[0].y) # Count edge crossings by casting a ray from inside the polygon for i in range(n + 1): p2 = self.pts[i % n] if pt.y > min(p1.y, p2.y) and pt.y <= max( p1.y, p2.y) and pt.x <= max(p1.x, p2.x): if p1.y != p2.y: xinters = (pt.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x if p1.x == p2.x or pt.x <= xinters: inside = not inside p1.x, p1.y = p2.x, p2.y return inside
def update(self): # Update position based on velocity self.pos.x += self.vel.x self.pos.y += self.vel.y # Update angle based on velocity self.rotate(self.theta_vel) # Wrap position within screen bounds if self.wrap.x: self.pos.x = wrap_x(self) if self.wrap.y: self.pos.y = wrap_y(self) # Update vertices based on pos and angle self.pts = [] for pt in self.orig: newx = (pt.x * math.cos(self.theta)) - ( pt.y * math.sin(self.theta)) + self.pos.x newy = (pt.x * math.sin(self.theta)) + ( pt.y * math.cos(self.theta)) + self.pos.y self.pts.append(Point(newx, newy))
def vapor_bounds_range(self): bounds = [] size = int(abs(self.vel.x) + abs(self.vel.y)) if size < 6: size = 6 for dy in range(size): pts = [] gap = 3 y = self.orig[1].y + dy for x in range(int(self.orig[1].x + gap), int(self.orig[2].x - gap), 1): newx = (x * math.cos(self.theta)) - ( y * math.sin(self.theta)) + self.pos.x newy = (x * math.sin(self.theta)) + ( y * math.cos(self.theta)) + self.pos.y pts.append(Point(newx, newy)) bounds.append(pts) return bounds
class Sprite(object): def __init__(self): self.pos = Point(0.0, 0.0) self.vel = Point(0.0, 0.0) self.theta = 0.0 self.theta_vel = 0.0 self.radius = 0.0 self.orig = [] self.pts = [] self.alive = True self.wrap = Point(True, True) # Set points and calculate radius def set_points(self, xpts, ypts, connect=False): self.orig = [Point(x, y) for x, y in zip(xpts, ypts)] if connect: self.orig.append(self.orig[0]) # Calculate bounding circle radius for pt in self.orig: dist = math.sqrt((pt.x**2) + (pt.y**2)) if dist > self.radius: self.radius = dist # Move to location x,y def move(self, x, y): self.pos.move(x, y) # Move location by dx,dy def translate(self, dx, dy): self.pos.translate(dx, dy) # Scale points to a size [0.0 - 1.0] def scale(self, ratio): xpts = [pt.x * ratio for pt in self.orig] ypts = [pt.y * ratio for pt in self.orig] self.set_points(xpts, ypts) # Rotate angle by dt def rotate(self, dt): self.theta += dt if self.theta < 0: self.theta += 2.0 * math.pi if self.theta > (2.0 * math.pi): self.theta -= 2.0 * math.pi # Return if vertices create a closed polygon def is_polygon(self): if len(self.pts) > 1: return self.pts[0].x == self.pts[-1].x and self.pts[ 0].y == self.pts[-1].y else: return False # Use ray casting from inside the polygon to determine containment. def contains(self, pt): # Even # of edge crossings = outside polygon # Odd # of edge crossing = inside polygon n = len(self.pts) inside = False p1 = Point(self.pts[0].x, self.pts[0].y) # Count edge crossings by casting a ray from inside the polygon for i in range(n + 1): p2 = self.pts[i % n] if pt.y > min(p1.y, p2.y) and pt.y <= max( p1.y, p2.y) and pt.x <= max(p1.x, p2.x): if p1.y != p2.y: xinters = (pt.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x if p1.x == p2.x or pt.x <= xinters: inside = not inside p1.x, p1.y = p2.x, p2.y return inside # Checks if the polygon contains any sprite vertices def collision(self, sprite): # Only polygons can collide if not self.is_polygon() or not sprite.is_polygon(): return False # Only check if in close proximity if not self.proximity(sprite): return False # First check if this polygon contains any vertex for pt in sprite.pts: if self.contains(pt): return True # Next check sprite polygon against current vertices for pt in self.pts: if sprite.contains(pt): return True return False # Use pythagorean theorem to check proximmity distance def proximity(self, s, dist=55): a2 = (s.pos.x - self.pos.x)**2 b2 = (s.pos.y - self.pos.y)**2 return math.sqrt(a2 + b2) < dist # Update all coordinate values def update(self): # Update position based on velocity self.pos.x += self.vel.x self.pos.y += self.vel.y # Update angle based on velocity self.rotate(self.theta_vel) # Wrap position within screen bounds if self.wrap.x: self.pos.x = wrap_x(self) if self.wrap.y: self.pos.y = wrap_y(self) # Update vertices based on pos and angle self.pts = [] for pt in self.orig: newx = (pt.x * math.cos(self.theta)) - ( pt.y * math.sin(self.theta)) + self.pos.x newy = (pt.x * math.sin(self.theta)) + ( pt.y * math.cos(self.theta)) + self.pos.y self.pts.append(Point(newx, newy)) # Draw to the display def render(self, gfx, color=[255, 255, 255]): for start, end in zip(self.pts[:-1], self.pts[1:]): pygame.draw.aaline(gfx, color, (start.x, start.y), (end.x, end.y), 1)
class Sprite(object): def __init__(self): self.pos = Point(0.0, 0.0) self.vel = Point(0.0, 0.0) self.theta = 0.0 self.theta_vel = 0.0 self.radius = 0.0 self.orig = [] self.pts = [] self.alive = True self.wrap = Point(True, True) # Set points and calculate radius def set_points(self, xpts, ypts, connect=False): self.orig = [Point(x, y) for x, y in zip(xpts, ypts)] if connect: self.orig.append(self.orig[0]) # Calculate bounding circle radius for pt in self.orig: dist = math.sqrt((pt.x ** 2) + (pt.y ** 2)) if dist > self.radius: self.radius = dist # Move to location x,y def move(self, x, y): self.pos.move(x, y) # Move location by dx,dy def translate(self, dx, dy): self.pos.translate(dx, dy) # Scale points to a size [0.0 - 1.0] def scale(self, ratio): xpts = [pt.x * ratio for pt in self.orig] ypts = [pt.y * ratio for pt in self.orig] self.set_points(xpts, ypts) # Rotate angle by dt def rotate(self, dt): self.theta += dt if self.theta < 0: self.theta += 2.0 * math.pi if self.theta > (2.0 * math.pi): self.theta -= 2.0 * math.pi # Return if vertices create a closed polygon def is_polygon(self): if len(self.pts) > 1: return self.pts[0].x == self.pts[-1].x and self.pts[0].y == self.pts[-1].y else: return False # Use ray casting from inside the polygon to determine containment. def contains(self, pt): # Even # of edge crossings = outside polygon # Odd # of edge crossing = inside polygon n = len(self.pts) inside = False p1 = Point(self.pts[0].x, self.pts[0].y) # Count edge crossings by casting a ray from inside the polygon for i in range(n + 1): p2 = self.pts[i % n] if pt.y > min(p1.y, p2.y) and pt.y <= max(p1.y, p2.y) and pt.x <= max(p1.x, p2.x): if p1.y != p2.y: xinters = (pt.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x if p1.x == p2.x or pt.x <= xinters: inside = not inside p1.x, p1.y = p2.x, p2.y return inside # Checks if the polygon contains any sprite vertices def collision(self, sprite): # Only polygons can collide if not self.is_polygon() or not sprite.is_polygon(): return False # Only check if in close proximity if not self.proximity(sprite): return False # First check if this polygon contains any vertex for pt in sprite.pts: if self.contains(pt): return True # Next check sprite polygon against current vertices for pt in self.pts: if sprite.contains(pt): return True return False # Use pythagorean theorem to check proximmity distance def proximity(self, s, dist=55): a2 = (s.pos.x - self.pos.x) ** 2 b2 = (s.pos.y - self.pos.y) ** 2 return math.sqrt(a2 + b2) < dist # Update all coordinate values def update(self): # Update position based on velocity self.pos.x += self.vel.x self.pos.y += self.vel.y # Update angle based on velocity self.rotate(self.theta_vel) # Wrap position within screen bounds if self.wrap.x: self.pos.x = wrap_x(self) if self.wrap.y: self.pos.y = wrap_y(self) # Update vertices based on pos and angle self.pts = [] for pt in self.orig: newx = (pt.x * math.cos(self.theta)) - (pt.y * math.sin(self.theta)) + self.pos.x newy = (pt.x * math.sin(self.theta)) + (pt.y * math.cos(self.theta)) + self.pos.y self.pts.append(Point(newx, newy)) # Draw to the display def render(self, gfx, color=[255, 255, 255]): for start, end in zip(self.pts[:-1], self.pts[1:]): pygame.draw.aaline(gfx, color, (start.x, start.y), (end.x, end.y), 1)
def respawn(self): self.time_to_respawn = 100 self.pos = Point(350, 200) self.vel = Point(0, 0)