def __init__(self): self.inplay = False self.radius = 20 self.position = Point(0, 0) self.angle = 0 self.remote_player_region = None self.remotely_controlled = False
def _get_central_extremes(self, x_center_bar_edge, y_center_bar_edge, angle, dimension): ext1 = Point(x_center_bar_edge - dimension / 2 * sin(angle), y_center_bar_edge + dimension / 2 * sin(pi / 2 - angle)) ext2 = Point(x_center_bar_edge + dimension / 2 * sin(angle), y_center_bar_edge - dimension / 2 * sin(pi / 2 - angle)) return [ext1, ext2]
class Ball(): def __init__(self): self.inplay = False self.radius = 20 self.position = Point(0, 0) self.angle = 0 self.remote_player_region = None self.remotely_controlled = False def get_size(self): return self.radius def get_position(self): return self.position def set_position(self, xpos, ypos): self.position = Point(float(xpos), float(ypos)) def get_angle(self): return self.angle def set_angle(self, angle): self.angle = angle def set_remote_player_region(self, region): self.remote_player_region = region def is_remotely_controlled(self): return self.remote_player_region != None and self.remote_player_region.contains( self.position) def set_outofbound(self): self.inplay = False def is_inplay(self): return self.inplay def get_delta_future_position(self, speed): ball_speed = 12 * speed delta_x = ball_speed * cos(self.angle) delta_y = ball_speed * sin(self.angle) return delta_x, delta_y def move(self, speed, angle=None): if self.inplay: if angle != None: self.angle = angle (delta_x, delta_y) = self.get_delta_future_position(speed) self.position.move(delta_x, delta_y) def bounce(self, new_angle, speed): self.move(speed, new_angle) def kickoff(self, point): # don't put another ball in play if self.inplay: return self.inplay = True self.position = point.copy()
def get_bouncing_angle(self, ball, game_speed): crossed_half_planes = [] ball_size = ball.get_size() ball_angle = ball.get_angle() ball_position = ball.get_position() bouncing_planes_containing_ball = self.get_bouncing_half_planes( ball_position) print("get_bouncing_angle, half planes ball is in: {}".format( bouncing_planes_containing_ball)) # if the ball is inside the bar (e.g., because the bar moved), # bring the ball back outside while len(bouncing_planes_containing_ball) == 0: ball.move(game_speed, ball_angle - pi) ball_position = ball.get_position() bouncing_planes_containing_ball = self.get_bouncing_half_planes( ball_position) # if the ball faces only one bouncing half plane from this bar, # it should NOT bounce if it is getting farther away. # The ball should instead bounce if either: # (1) the ball would cross the bar's edge / half plane; OR # (2) the distance of the ball to the bar's edge is lower than # the ball size (e.g., because the bar moved) if len(bouncing_planes_containing_ball) == 1: [bhf] = bouncing_planes_containing_ball line = bhf.get_line() distance_ball_bhf = line.get_min_distance_to_point(ball_position) (delta_x, delta_y) = ball.get_delta_future_position(game_speed) ball_future_position = Point(ball_position.X + delta_x, ball_position.Y + delta_y) future_distance_ball_bhf = line.get_min_distance_to_point( ball_future_position) if (bhf.contains(ball_position) and not bhf.contains(ball_future_position)) or ( distance_ball_bhf <= ball.get_size()): crossed_half_planes = [bhf] # move the ball fully outside the bar self._move_ball_outside_bar(ball, line, game_speed) # if the ball is inside more than one bouncing half planes, # it means it is closer to a bar's corner rather than to any # bar's edge. So, we check that the distance of the ball # center to all bar's corner is smaller than the ball's size elif len(bouncing_planes_containing_ball) == 2: [bp1, bp2] = bouncing_planes_containing_ball corner = bp1.get_line_intersection(bp2) if corner.distance(ball_position) < ball.get_size(): crossed_half_planes = bouncing_planes_containing_ball # it shouldn't be possible for the ball to face more than # two bar's edges else: raise RuntimeError( "Ball ({},{}) facing an unexpected number of edges in Bar {}: {}" .format(ball.get_position(), ball.get_angle(), self.get_id(), bouncing_planes_containing_ball)) # return the bouncing angle print( "\nFound intersected bar's edges: {}".format(crossed_half_planes)) return self._get_new_angle(crossed_half_planes, ball_angle)
def init_game_objects(self, number_players): # Ball (initially placed in the middle of the screen) self.ball = Ball() self.ball_starting_point = Point(self.canvas_width / 2, self.distance_bar_bound * 8) self.ball.set_position(self.ball_starting_point.X, self.ball_starting_point.Y) self.controller.register_ball(self.ball) # Walls self.walls = [ Wall(self.canvas_width / 2, 0, self.canvas_width), Wall(self.canvas_width / 2, self.canvas_height, self.canvas_width) ] for wall in self.walls: self.controller.register_wall(wall) # Nets self.nets = [ Net(0, self.canvas_width / 2, self.canvas_width - self.walls[0].get_thickness() * 2, net_id=1), Net(self.canvas_width, self.canvas_height / 2, self.canvas_height - self.walls[0].get_thickness() * 2, net_id=2) ] for net in self.nets: self.controller.register_net(net) # Players' bars self.bars = [] for i in range(1, number_players + 1): bar = Bar(i, self.bar_move_unit) self.bars.append(bar) self.controller.register_bar(bar) self._set_initial_bar_positions() # Players (initially empty, must be filled with set_players_info) self.bots = dict() self.local_players = dict() self.remote_players = dict()
def get_central_point(self): return Point(self.get_xpos(), self.get_ypos())
def set_position(self, xpos, ypos): self.position = Point(float(xpos), float(ypos))
def _compute_initial_bar_positions(self): return [ Point(self.distance_bar_bound, self.canvas_height / 2), Point(self.canvas_width - self.distance_bar_bound, self.canvas_height / 2) ]