def avoidMouse(self, boid): #Boids try to avoid/flee mouse position mousePos = m.Vector2(pygame.mouse.get_pos()) if not boid.circle.containsPt(Point(mousePos.x, mousePos.y)): return m.Vector2(0, 0) atVel = boid.pos + boid.velocity acc = atVel - mousePos if acc.dot(boid.velocity) < 0: bx = boid.velocity.x ax = acc.x sign = lambda a: math.copysign(1, a) if not sign(bx) == sign(ax): acc.x = 0 else: acc.y = 0 distTo = boid.pos.distance_to(mousePos) if distTo > 0: acc *= distTo**-1 else: acc *= 100 return acc
def __init__(self, scene): self.scene = scene # Player status self.isDead = False # Media for player self.image = 'media/player.png' self.image_dead = 'media/player_dead.png' # Player dimensions self.dwidth = 100 self.dheight = 75 # Player direction self.direct_x = 0 self.direct_y = 0 # Pygame code generation self.rect = Rect(0, 0, self.dwidth, self.dheight) self.sprite = GameSprite(self.image) self.sprite_surface = self.sprite.getImage() # get player sprite surface # Player position self.pwidth = 660 self.pheight = 660 # Init player position self.pos = pymath.Vector2(self.pwidth / 2, self.pheight / 2) self.draw_pos = pymath.Vector2(self.pos.x, self.pos.y) # game window icon = self.sprite_surface pygame.display.set_icon(self.sprite_surface)
def __initPosition(self, windowSize: tuple, playerId: int) -> math.Vector2: rect = Rect(0, 0, windowSize[0] / 2, windowSize[1] / 2) if (0 == playerId): return math.Vector2(rect.center) else: rect.move_ip(windowSize[0] / 2, windowSize[1] / 2) return math.Vector2(rect.center)
def __init__(self, point1, point2, width=5, *groups): super().__init__() self.dirty = 2 self._layer = constants.LAYER_WALL self.add(*groups) self.points = [point1, point2] self.width = width # This sprite's origin on the application's screen. # Necessary to draw the sprite correctly, as well as to calculate # collision rectangles correctly. self.origin = Point(min(point1.x, point2.x), min(point1.y, point2.y)) self.point1 = point1 - self.origin self.point2 = point2 - self.origin v = math.Vector2(*(point2 - point1).as_2d_tuple()) self.reflect_vector = math.Vector2(-1 * v.y, v.x) self.image = Surface(( abs(point2.x - point1.x) + self.width, abs(point2.y - point1.y) + self.width )) self.image.set_colorkey(colors.BLACK) self.rect = self.image.get_rect() self.rect.x = self.origin.x self.rect.y = self.origin.y self.update() self.mask = mask.from_surface(self.image)
def __updateTankSurface(self, surface: Surface, color: Color, direction: math.Vector2): surface.fill((0, 0, 0, 0)) # rect inside surface surfaceSize = surface.get_size() surfaceRect = Rect(0, 0, surfaceSize[0], surfaceSize[1]) tankRect = Rect(0, 0, self.size[0], self.size[1]) diff = math.Vector2(surfaceRect.center) - math.Vector2(tankRect.center) tankRect.move_ip(diff) temp = surface.copy() draw.rect(temp, color, tankRect) # apply tank direction to surface degree = -math.Vector2(0, 1).angle_to(direction) temp = transform.rotate(temp, degree) # temp was enlarged by rotate (wtf): # calculate diff so that temp surface is positioned outside # of the destination surface below tempRectSize = temp.get_size() diff = math.Vector2(tempRectSize) - math.Vector2(surfaceSize) # copy back wanted portion from rotation surface.blit(temp, -diff / 2)
def __init__(self, pos, mass, size_X, size_Y): self.pos = pos self.vel = math.Vector2(0, 0) self.acc = math.Vector2(0, 0) self.mass = mass self.size_X = size_X self.size_Y = size_Y
def _postInit(self, client=False, *args, **kwargs): self.color = kwargs['color'] self.updateable = True # любой игрок должен обновляться постоянно self.client = client # является ли игрок нами self.active = None # текущее оружие в руках self.rect.center = pmath.Vector2(self.rect.center) self.velocity = pmath.Vector2( 0, 0) # скорость представляем в виде вектора для удобства self.keydir = pmath.Vector2(0, 0) # как и нажатые клавиши self.lifes = 10 self.dir = (0, 0) self.onGround = False self.second_jump = True # доступен ли прыжок в воздухе self.collideable = False # игроки не сталкиваются self.count = 0 # очки self.hook = GrapplingHook(owner=self) self.weapons = dict( map( lambda x: (x.__name__, x(owner=self, hidden=True) ), # здесь валяется всё оружие игрока [Hammer, Pistol, Shotgun, GrenadeLauncher, Ninja])) self.wpnswitcher = { getattr(pygame, 'K_%s' % (i + 1)): v for i, v in enumerate(self.weapons) } self.switch_weapon('Hammer') self.respawn()
def ball_overlap(self, popped_list): ''' Check if any balls replaced on table overlap balls already on table Goes through all the balls and checks if they overlap. Not very efficient. Not fully Tested. Works in trivial cases. ''' add_to_rerack = [] for new_ball in popped_list: ball_center = pm.Vector2(new_ball.x + new_ball.radius, new_ball.y + new_ball.radius) for existing_ball in self.balls: existing_center = pm.Vector2( existing_ball.x + existing_ball.radius, existing_ball.y + existing_ball.radius) collision_vector = ball_center - existing_center #If the balls are pretty close, add the existing ball to the list to be reracked if collision_vector.length() < 2 * new_ball.radius: self.balls.remove(existing_ball) existing_ball.vel = pm.Vector2(0, 0) add_to_rerack.append(existing_ball) #If the balls are still overlapped but not by a lot, simply move the existing one out of the way. #Will cause a mess if many balls in same place, but that generally will not happen. #elif collision_vector.length() < 2 * new_ball.radius: # collision_vector.scale_to_length(2 * new_ball.radius) # existing_ball.x = new_ball.x - collision_vector.x # existing_ball.y = new_ball.y - collision_vector.y return add_to_rerack
def create_character_input(json, index): cinput = CharacterInput(index) cinput.look_direction = gmath.Vector2(json["lookx"], json["looky"]) cinput.movement = gmath.Vector2(json["dx"], json["dy"]) cinput.shooting = json["shooting"] return cinput
def coord_canvas2coord_screen(self, canvas_pos=(0, 0)): """Transformo una posición de coordenadas CANVAS en una posicion de coordenadas SCREEN""" canvas_pos = pm.Vector2(canvas_pos) screen_pos = canvas_pos * self.global_zoom_factor + self.global_pos screen_pos = pm.Vector2(int(round(screen_pos.x)), -int(round(screen_pos.y))) return screen_pos
def draw_item(item, image_name): image = resources[image_name] rotated_image = pygame.transform.rotate(image, item.rotation) rotated_rect = rotated_image.get_rect() height, width = rotated_rect.height, rotated_rect.width screen.blit( rotated_image, gmath.Vector2(item.x, item.y) - gmath.Vector2(width / 2, height / 2))
def render(direction: math.Vector2, window_size: tuple, surface: Surface) -> None: start_pos = math.Vector2 (window_size[0]/2, window_size[1]/2) if direction is None or direction.length() < 0.05: draw.circle(surface, (255, 0, 0), start_pos, 5, 1) else: # copy, no reference vector = math.Vector2(direction) length = vector.length() vector.scale_to_length(length * 100) draw.aaline(surface, (0, 255, 0), start_pos, start_pos + vector)
def on_collision(self, ball): ''' Calculate new velocities of self and the ball self collided with ''' center_self = pygame.math.Vector2(self.rect.center) center_ball = pygame.math.Vector2(ball.rect.center) center_vector = center_self - center_ball if center_vector.length( ) == 0: #Prevent divide by zero when normalizing. Only time it should be zero is when reracking goes wrong. return pm.Vector2(0, 0), pm.Vector2(0, 0) center_vector = pygame.math.Vector2.normalize(center_vector) #Returns true if this collision has already been calculated if center_vector in self.prev_collisions or -1 * center_vector in self.prev_collisions: return self.vel, ball.vel if center_vector in ball.prev_collisions or -1 * center_vector in ball.prev_collisions: return self.vel, ball.vel self.prev_collisions.append(center_vector) ball.prev_collisions.append(center_vector) #Phi is angle between ball centers, relative to standard x axis phi = math.radians( (center_self - center_ball).angle_to(pygame.math.Vector2(1, 0))) #Theta1 and 2 and angle of ball's velocities, relative to standard x axis theta1 = math.radians(self.vel.angle_to(pygame.math.Vector2(1, 0))) theta2 = math.radians(ball.vel.angle_to(pygame.math.Vector2(1, 0))) #Change initial velocities into different coordinate space v_xp1 = self.vel.length() * math.cos(theta1 - phi) v_yp1 = self.vel.length() * math.sin(theta1 - phi) v_xp2 = ball.vel.length() * math.cos(theta2 - phi) v_yp2 = ball.vel.length() * math.sin(theta2 - phi) #Calculate final velocities in the different coordinate space u_xp1 = v_xp2 u_xp2 = v_xp1 u_yp1 = v_yp1 u_yp2 = v_yp2 #Go back to original coordinates u_x1 = u_xp1 * math.cos(phi) - u_yp1 * math.sin(phi) u_y1 = -1 * (u_xp1 * math.sin(phi) + u_yp1 * math.cos(phi)) u_x2 = u_xp2 * math.cos(phi) - u_yp2 * math.sin(phi) u_y2 = -1 * (u_xp2 * math.sin(phi) + u_yp2 * math.cos(phi)) return pygame.math.Vector2(u_x1, u_y1), pygame.math.Vector2(u_x2, u_y2)
def retrieve_corners(self): """Retorna la lista de puntos que rodean a la linea.""" (x_min, x_max), (y_min,y_max) = self.return_box() points_list_v = [pm.Vector2(x_min, y_min), pm.Vector2(x_min, y_max), pm.Vector2(x_max, y_max), pm.Vector2(x_max, y_min)] return points_list_v
def alignment(self, boid, neighbors): #Rule 3: Boids try to match velocity with nearby boids. if len(neighbors) == 0: return m.Vector2(0, 0) v = m.Vector2(0, 0) for neighbor in neighbors: v += neighbor.velocity v /= len(neighbors) acc = v - boid.velocity return acc
def __init__(self, pos, direction): self.pos = math.Vector2(pos) self.dir = direction self.vel = math.Vector2() self.a_vel = 0 self.acc = math.Vector2() self.a_acc = 0 self.prev_pos = math.Vector2(pos) self.prev_dir = direction
def fx(self, surf): # рисуем звенья цепи link_width = self.chain.get_rect().width - 3 link_pos = pmath.Vector2(self.rect.center) link_delta = pmath.Vector2(self.rect.center) angle = utils.u_degrees(-self.angle) link_delta.from_polar((link_width, angle)) links_cnt = int(self.dist // link_width) self.chain = pygame.transform.rotate(self.chain_orig, angle) self.chain = pygame.transform.flip(self.chain, False, True) for _ in range(links_cnt): link_pos += link_delta surf.blit(self.chain, link_pos)
def cohesion(self, boid, neighbors): #Rule 1: Boids try to fly towards the center of mass of neighbouring boids. if len(neighbors) == 0: return m.Vector2(0, 0) centerOfPos = m.Vector2(0, 0) for neighbor in neighbors: centerOfPos += neighbor.pos centerOfPos /= len(neighbors) acc = centerOfPos - boid.pos return acc
def update_fins(self): vec = pgmath.Vector2( *math_tools.cartesian_from_polar(10.0 + self.power, 180 + self.direction)) self.back = self.position + vec vec = pgmath.Vector2( *math_tools.cartesian_from_polar(5.0, 90 + self.direction)) self.port_corner = self.back + vec self.starboard_corner = self.back - vec self.collidables[1] = collidables.Collision_segment( self.position, self.port_corner) self.collidables[2] = collidables.Collision_segment( self.position, self.starboard_corner)
def __init__(self, pos=m.Vector2(0, 0), vel=m.Vector2(0, 0)): self.pos = pos self.x = pos.x self.y = pos.y self.velocity = vel self.s = int(random.uniform(1, 5)) r = int(random.gauss(30, 20)) self.neighborRadius = r if self.s * 10 < r else self.s * 10 self.circle = Circle(self.x, self.y, self.neighborRadius) self.maxSpeed = abs(random.gauss(6, 1)) self.color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
def update_movement(character_input, event): directions = { 119: gmath.Vector2(0, -1), 115: gmath.Vector2(0, 1), 100: gmath.Vector2(1, 0), 97: gmath.Vector2(-1, 0) } direction = directions.get(event.key) if direction == None: return direction *= 1 if event.type == pygame.KEYDOWN else -1 character_input.movement += direction
def __init__(self, dna=None): self.img = image.load('props/rocket.png') self.rect = self.img.get_rect() self.rect.center = (WIDTH / 2, HEIGHT / 2) self.rect.bottom = HEIGHT - 50 self.vel = math.Vector2(0, -1) self.acc = math.Vector2() self.fitness = 0 self.hit = False self.hitTime = 0 self.crashed = False if dna: self.dna = dna else: self.dna = Dna()
def insertBoid(self, pos=None): vel = m.Vector2(random.uniform(-10, 10), random.uniform(-10, 10)) if pos is not None: if type(pos) == tuple: boid = Boid(m.Vector2(pos[0], pos[1]), vel) elif type(pos) == m.Vector2: boid = Boid(pos, vel) else: x, y = pygame.display.get_surface().get_size() x = random.randint(0, x) y = random.randint(0, y) boid = Boid(m.Vector2(x, y), vel) self.flock.append(boid) return
def seperation(self, boid, neighbors): #Rule 2: Boids try to keep a small distance away from other objects (including other boids). if len(neighbors) == 0: return m.Vector2(0, 0) acc = m.Vector2(0, 0) for neighbor in neighbors: if boid.pos.distance_to(neighbor.pos) < boid.neighborRadius: v = (boid.pos - neighbor.pos) r, phi = v.as_polar() if r > 0: r = r**-1 v.from_polar((r, phi)) acc += v return acc
def __init__(self, position=(0, 0), direction=0, bounds=[0, 0, 0, 0], power=1, a=0, b=0): Base_spell.__init__(self, power, a, b, types[2]['missile'], position) self.direction = direction self.min_x = bounds[0] self.min_y = bounds[1] self.max_x = bounds[2] self.max_y = bounds[3] self.port_corner = None self.starboard_corner = None self.back = self.position + pgmath.Vector2( *math_tools.cartesian_from_polar(10.0 + self.power, 180 + self.direction)) self.previous_position = self.back self.collidables = [ collidables.Collision_segment(self.previous_position, self.position), None, None ] self.update_fins() self.velocity = pgmath.Vector2 self.update_velocity()
def __init__(self, pos, angle, color): self.pos = pos self.dir = math.Vector2(1, 0) self.initangle = angle self.angle = 0 self.dir = self.dir.rotate(angle) self.color = color
def update(self, dt: int, windowSize: tuple) -> None: # TANK stickDirection = math.Vector2(self.joystick.get_axis(0), self.joystick.get_axis(1)) if stickDirection.length() < 0.08: return # MOVEMENT # force from stick force = stickDirection.length() # add some damping force *= 0.8 directionNormalized = stickDirection.normalize() # forward 0 - 1 (self.tankDirection is also normalized) forward = self.tankDirection.dot(directionNormalized) # we do not have dpi here: use window size as speed orientation speed = sqrt(windowSize[0] * windowSize[1]) self.position += directionNormalized * forward * force * speed * (dt / 1000) # ROTATION rotationDirection = directionNormalized - self.tankDirection self.tankDirection += rotationDirection * dt self.tankDirection.normalize_ip() self.__updateTankSurface(self.tankSurface, self.color, stickDirection)
def drag_view(self): """Desplazo la vista en la pantalla""" self.global_pos += pm.Vector2(self.screen_mouse_dx, -self.screen_mouse_dy) self.update_is_in_window() return None
def projection(a, b): """a projected onto b""" if a.length() == 0 or b.length() == 0: return pgmath.Vector2(0, 0) else: return b * (b.dot(a)) / (b.length()**2)
def draw(self, screen, draw_subpath=True): """Draw the flight (and optinally its path). Arguments: screen {Surface} -- Surface to draw on. Keyword Arguments: draw_subpath {bool} -- Whether to draw the path of the flight. (default: {True}) """ pgdraw.circle(screen, (0, 0, 0), vec2int(self.get_pos()), self.ICON_SIZE, 0) dir_vect = pgmath.Vector2( 0, 1).rotate(-self.direction) * Flight.ICON_SIZE * 2 vect_point = dir_vect + self.get_pos() new_x = int(vect_point[0]) new_y = int(vect_point[1]) pgdraw.line(screen, ( 0, 0, 0, ), (self.x, self.y), (new_x, new_y)) if (self.path is not None and self.is_landing()) and draw_subpath: self.path.draw_subpath(screen, self.path_pos)