def test_non_statick_to_static_board(self): self.game.green.velocity = Vec2D(20, 40) self.game.if_statick_board() self.assertEqual(self.game.board_status, NON_STATICK) self.game.green.velocity = Vec2D(0, 0) self.game.if_statick_board() self.assertEqual(self.game.board_status, STATICK)
def test_correct_ball_pot(self): self.game.yellow.coords = Vec2D(UL_POCKET) self.game.yellow.velocity = Vec2D(10, 50) self.game.balls_handler() self.game.game_handler() self.assertEqual(self.game.turn.points, 2) self.assertEqual(self.game.first_player, self.game.turn) self.assertEqual(self.game.turn.target, RED_TARGET)
def test_no_free_color_ball_pos(self): self.game.black.coords = Vec2D(ML_POCKET) self.game.black.velocity = Vec2D(10, 50) self.game.redball5.coords = Vec2D(POS_BLACK) self.game.balls_handler() self.game.game_handler() self.assertEqual(self.game.black.coords.x, Vec2D(POS_BLACK).x + 16) self.assertEqual(self.game.black.coords.y, Vec2D(POS_BLACK).y)
def test_self_ball_pos_taken_free_other_color_pos(self): self.game.blue.coords = Vec2D(ML_POCKET) self.game.pink.coords = Vec2D(POS_GREEN) + 20 self.game.blue.velocity = Vec2D(10, 50) self.game.redball4.coords = Vec2D(POS_BLUE) self.game.balls_handler() self.game.game_handler() self.assertEqual(self.game.blue.coords, Vec2D(POS_PINK))
def test_moving_ball_to_statick_ball_collision(self): self.game.redball1.coords = Vec2D((550, 257)) self.game.white_ball.coords = Vec2D((650, 250)) self.game.white_ball.velocity = Vec2D((-140, 0)) while not self.game.hitted_balls: self.game.balls_handler() self.game.game_handler() self.assertGreater(self.game.redball1.velocity.y, 0) self.assertLess(self.game.white_ball.velocity.y, 0) self.assertIn(self.game.redball1, self.game.hitted_balls)
def test_moving_to_moving_ball_collision(self): self.game.redball1.coords = Vec2D((550, 257)) self.game.white_ball.coords = Vec2D((650, 250)) self.game.redball1.velocity = Vec2D((40, 0)) self.game.white_ball.velocity = Vec2D((-140, 0)) while self.game.redball1.velocity.y == 0: self.game.balls_handler() self.game.game_handler() self.assertGreater(self.game.redball1.velocity.y, 0) self.assertLess(self.game.white_ball.velocity.y, 0)
def test_low_color_hit_low_color_potted(self): self.game.hitted_balls.appendleft(self.game.green) self.game.brown.coords = Vec2D(MR_POCKET) self.game.brown.velocity = Vec2D(60, 40) self.game.balls_handler() self.game.game_handler() self.assertEqual(self.game.first_player.points, 0) self.assertEqual(self.game.turn.target, RED_TARGET) self.assertEqual(self.game.turn.points, FOUL_POINTS) self.assertEqual(self.game.brown.coords, Vec2D(POS_BROWN))
def test_lower_color_hit_higher_color_potted(self): self.game.hitted_balls.appendleft(self.game.green) self.game.black.coords = Vec2D(ML_POCKET) self.game.black.velocity = Vec2D(50, 40) self.game.balls_handler() self.game.game_handler() self.assertEqual(self.game.turn.target, RED_TARGET) self.assertEqual(self.game.first_player.points, 0) self.assertEqual(self.game.turn.points, 7) self.assertEqual(self.game.black.coords, Vec2D(POS_BLACK))
def test_color_hit_just_white_potted(self): self.game.hitted_balls.appendleft(self.game.blue) self.game.white_ball.coords = Vec2D(DR_POCKET) self.game.white_ball.velocity = Vec2D(30, 40) self.game.balls_handler() self.game.game_handler() self.assertEqual(self.game.turn.target, RED_TARGET) self.assertEqual(self.game.first_player.points, 0) self.assertEqual(self.game.turn.points, 5) self.assertEqual(self.game.white_ball.coords, Vec2D(POS_WHITE))
def test_correct_hit_and_pot(self): self.game.turn.change_target() self.game.hitted_balls.appendleft(self.game.yellow) self.game.yellow.coords = Vec2D(UL_POCKET) self.game.yellow.velocity = Vec2D(10, 50) self.game.balls_handler() self.game.game_handler() self.assertEqual(self.game.condition, RED_FREE) self.assertEqual(self.game.turn.points, 2) self.assertEqual(self.game.turn, self.game.first_player) self.assertEqual(self.game.second_player.points, 0) self.assertEqual(self.game.next_target_ball, 3) self.assertNotIn(self.game.yellow, self.game.all_balls)
def test_color_hit_red_potted(self): self.game.hitted_balls.appendleft(self.game.pink) self.game.redball2.coords = Vec2D(UL_POCKET) self.game.redball2.velocity = Vec2D(20, 40) self.game.balls_handler() self.assertTrue(self.game.redball2.is_potted) self.game.game_handler() self.assertEqual(self.game.turn.points, 6) self.assertEqual(self.game.turn.target, RED_TARGET) self.assertEqual(self.game.first_player.points, 0) self.assertEqual(self.game.second_player, self.game.turn) self.assertFalse(self.game.redball2.is_potted) self.assertNotIn(self.game.redball2, self.game.all_balls)
def test_red_hit_white_potted(self): self.game.white_ball.coords = Vec2D(UR_POCKET) self.game.white_ball.velocity = Vec2D(10, 50) self.assertFalse(self.game.white_ball.is_potted) self.game.balls_handler() self.assertTrue(self.game.white_ball.is_potted) self.game.game_handler() self.assertEqual(self.game.turn.points, FOUL_POINTS) self.assertEqual(self.game.turn.target, RED_TARGET) self.assertEqual(self.game.first_player.points, 0) self.assertEqual(self.game.second_player, self.game.turn) self.assertFalse(self.game.white_ball.is_potted) self.assertEqual(self.game.white_ball.coords, Vec2D(POS_WHITE))
def test_red_hit_color_potted(self): self.game.green.coords = Vec2D(DR_POCKET) self.game.green.velocity = Vec2D(10, 10) self.assertFalse(self.game.green.is_potted) self.game.balls_handler() self.assertTrue(self.game.green.is_potted) self.game.game_handler() self.assertEqual(self.game.turn.points, FOUL_POINTS) self.assertEqual(self.game.turn.target, RED_TARGET) self.assertEqual(self.game.first_player.points, 0) self.assertEqual(self.game.second_player, self.game.turn) self.assertFalse(self.game.green.is_potted) self.assertEqual(self.game.green.coords, Vec2D(POS_GREEN))
def test_correct_hit_wrong_ball_pot_low(self): self.game.turn.change_target() self.game.hitted_balls.appendleft(self.game.yellow) self.game.green.coords = Vec2D(UL_POCKET) self.game.green.velocity = Vec2D(10, 50) self.game.balls_handler() self.game.game_handler() self.assertEqual(self.game.condition, RED_FREE) self.assertEqual(self.game.turn.points, FOUL_POINTS) self.assertEqual(self.game.turn, self.game.second_player) self.assertEqual(self.game.first_player.points, 0) self.assertEqual(self.game.next_target_ball, 2) self.assertIn(self.game.yellow, self.game.all_balls) self.assertEqual(self.game.green.coords, Vec2D(POS_GREEN))
def test_wrong_hit_and_ball_pot_high(self): self.game.turn.change_target() self.game.hitted_balls.appendleft(self.game.blue) self.game.yellow.coords = Vec2D(UL_POCKET) self.game.yellow.velocity = Vec2D(10, 50) self.game.balls_handler() self.game.game_handler() self.assertEqual(self.game.condition, RED_FREE) self.assertEqual(self.game.turn.points, 5) self.assertEqual(self.game.turn, self.game.second_player) self.assertEqual(self.game.first_player.points, 0) self.assertEqual(self.game.next_target_ball, 2) self.assertIn(self.game.yellow, self.game.all_balls) self.assertEqual(self.game.yellow.coords, Vec2D(POS_YELLOW))
def parseNode(self, parent, node): position = node.get("position") radius = node.get("radius") speed = node.get("speed") color = node.get("color") mass = node.get("mass") if radius: radius = int(radius) else: radius = 10.0 if speed: speed = float(speed) else: speed = 1.0 if mass: mass = float(mass) else: mass = 1.0 if position: position = position.split(",") position = Vec2D(int(position[0]), int(position[1])) else: position = Vec2D(0, 0) if color: color = color.split(",") color = pg.Color(int(color[0]), int(color[1]), int(color[2]), int(color[3])) else: color = pg.Color(255,255,255,255) # Create the node body = LockedBody(position = position, radius = radius, color = color, mass = mass, speed = speed) if parent: body.parentBody = parent for child in node: body.addChild(self.parseNode(body, child)) return body
def test_game_finish_test(self): self.game.turn.change_target() self.game.all_balls = [self.game.black] self.game.hitted_balls.appendleft(self.game.black) self.game.black.coords = Vec2D(UL_POCKET) self.game.black.velocity = Vec2D(10, 50) while self.game.next_target_ball != 7: self.game.next_target_ball = next(self.game.colol_order) self.game.balls_handler() self.game.game_handler() self.assertEqual(self.game.condition, RED_FREE) self.assertEqual(self.game.turn.points, 7) self.assertEqual(self.game.turn, self.game.first_player) self.assertFalse(self.game.next_target_ball) self.assertEqual(self.game.all_balls, [])
def ball_return(self, potted_ball): potted_ball.vizibility = True returning_pos = Vec2D(potted_ball.pos) color_balls_pos = [ x.pos for x in self.all_balls if isinstance(x, balls.ColorBall) ] empty_place = False my_place_taken = self.chek_for_place(potted_ball) if my_place_taken is True: for position in color_balls_pos: empty_position = self.chek_for_place(potted_ball, pos=position) if empty_position is not True: empty_place = True returning_pos = position break if my_place_taken is True and empty_place is not True: found_place = False while found_place is not True: flag = self.chek_for_place(potted_ball, pos=returning_pos) if flag is not True: found_place = True break returning_pos.x += 1 potted_ball.coords = returning_pos else: potted_ball.coords = returning_pos
def step(self, dt): """ Computes one game step or tick, dt being the approx time elapsed since the previous tick """ black = (0, 0, 0) self.screen.fill(black) # Handle body drag creation self.input.update() if self.input.body: body = self.input.body clickP = self.input.clickPosition pg.draw.line(self.screen, pg.Color(255,255,255,255), (clickP.x, clickP.y), (body.position.x, body.position.y), 1) self.drawCircle(self.screen, self.screenToWorld(body.position), pg.Color(255,255,255,255), body.radius) lockedPhysicsList = [] # Used for dynamic calculations and collisions # Iterate over tree, update and draw for body in self.rootBody: body.update(dt) bodyPos = body.getWorldPosition() self.drawCircle(self.screen, bodyPos, body.color, body.radius) lockedPhysicsList.append(body) # Update and draw all dynamic bodies for index, body in enumerate(self.dynamicBodies): body.update(lockedPhysicsList, dt) self.drawCircle(self.screen, (body.position), pg.Color(255,255,255,255), body.radius) if Vec2D.magnitudeSquared(body.position) > 1000000 or body.hasCollided(): # Out of game area del self.dynamicBodies[index] pg.display.flip()
def update(self, lockedBodies, dt): """ Updates velocity and applies to position based on all the locked bodies in the system """ for body in lockedBodies: rawDisplace = body.getWorldPosition() - self.position direction = Vec2D.normalize(rawDisplace) displacementSquared = Vec2D.magnitudeSquared(rawDisplace) acceleration = dt * self.gConstant * body.mass / max( 10, displacementSquared ) # min radius 10 to prevent crazy acceleration self.velocity = self.velocity + Vec2D.scale( direction, acceleration) self.position = self.position + self.velocity # Have we collided if not self.collided: actualDisplacement = math.sqrt(displacementSquared) if actualDisplacement < (self.radius + body.radius): self.collided = True # Collision has occured
def cue_handler(self): start_pos, end_pos = self.cue.get_cue_pos(self.white_ball.coords) self.painter.cue_draw(self.cue, start_pos, end_pos) keys = pygame.key.get_pressed() if keys[pygame.K_KP_ENTER]: new_velocity = Vec2D.normalized(start_pos - end_pos) force = Vec2D(self.white_ball.coords - start_pos).length self.white_ball.velocity = new_velocity *\ force ** 2 / MIN_HITTING_FORCE self.hit = True
def test_color_hit_white_and_red_potted(self): self.game.hitted_balls.appendleft(self.game.black) self.game.white_ball.coords = Vec2D(DR_POCKET) self.game.redball4.coords = Vec2D(DL_POCKET) self.game.white_ball.velocity = Vec2D(70, 50) self.game.redball4.velocity = Vec2D(20, 70) self.game.redball8.is_potted = True self.assertFalse(self.game.white_ball.is_potted) self.game.balls_handler() self.assertTrue(self.game.white_ball.is_potted) self.assertTrue(self.game.redball4.is_potted) self.game.game_handler() self.assertEqual(self.game.turn.points, 7) self.assertEqual(self.game.turn.target, RED_TARGET) self.assertEqual(self.game.first_player.points, 0) self.assertEqual(self.game.second_player, self.game.turn) self.assertFalse(self.game.white_ball.is_potted) self.assertEqual(self.game.white_ball.coords, Vec2D(POS_WHITE)) self.assertNotIn(self.game.redball8, self.game.all_balls) self.assertNotIn(self.game.redball4, self.game.all_balls)
def white_ball_grab(self): mouse_pos = Vec2D(pygame.mouse.get_pos()) if self.white_ball.coords.x-8 < mouse_pos.x < \ self.white_ball.coords.x+8 and self.white_ball.coords.y-8\ < mouse_pos.y < self.white_ball.coords.y+8: for event in pygame.event.get(): (mouse1, mouse2, mouse3) = pygame.mouse.get_pressed() if mouse1: self.white_ball.grabed = True else: self.white_ball.grabed = False if self.white_ball.grabed: self.white_ball.coords = mouse_pos
def get_cue_pos(self, coords): start_pos = Vec2D(0, 0) end_pos = Vec2D(0, 0) r2 = self.r - self.length keys = pygame.key.get_pressed() if keys[pygame.K_LEFT]: self.angle -= 2 if keys[pygame.K_RIGHT]: self.angle += 2 if keys[pygame.K_UP]: self.r -= 1 if self.r < CUE_DEFAULT_R: self.r = CUE_DEFAULT_R if keys[pygame.K_DOWN]: self.r += 1 if self.r > CUE_DEFAULT_R + CUE_DEFAULT_R / 2: self.r = CUE_DEFAULT_R + CUE_DEFAULT_R / 2 end_pos.x = coords.x + math.cos(math.radians(self.angle)) * self.r end_pos.y = coords.y + math.sin(math.radians(self.angle)) * self.r start_pos.x = coords.x + math.cos(math.radians(self.angle)) * r2 start_pos.y = coords.y + math.sin(math.radians(self.angle)) * r2 return (start_pos, end_pos)
def test_more_then_one_potted_high(self): self.game.turn.change_target() self.game.hitted_balls.appendleft(self.game.yellow) self.game.yellow.coords = Vec2D(UL_POCKET) self.game.yellow.velocity = Vec2D(10, 50) self.game.blue.coords = Vec2D(DL_POCKET) self.game.blue.velocity = Vec2D(10, 50) self.game.black.coords = Vec2D(UR_POCKET) self.game.black.velocity = Vec2D(10, 50) self.game.balls_handler() self.game.game_handler() self.assertEqual(self.game.condition, RED_FREE) self.assertEqual(self.game.turn.points, 7) self.assertEqual(self.game.turn, self.game.second_player) self.assertEqual(self.game.first_player.points, 0) self.assertEqual(self.game.next_target_ball, 2) self.assertIn(self.game.yellow, self.game.all_balls) self.assertEqual(self.game.yellow.coords, Vec2D(POS_YELLOW)) self.assertEqual(self.game.blue.coords, Vec2D(POS_BLUE)) self.assertEqual(self.game.black.coords, Vec2D(POS_BLACK))
def __init__(self, position=Vec2D(0, 0), mass=1.0, speed=1, radius=10, color=pg.Color(255, 255, 255, 255), parent=None): self.position = position # Position is relative to parent if a parent exists self.speed = speed self.mass = mass self.radius = radius self.color = color self.parentBody = parent self.path = None self.children = []
def move(self, pockets): check = Vec2D(self.velocity) self.velocity -= Vec2D.normalized(self.velocity) * FRICTION * TIMER self.coords += self.velocity * TIMER if check.x * self.velocity.x < 0 or check.y * self.velocity.y < 0: self.velocity = Vec2D(0, 0) if int(self.coords.x) not in range(139, 534) and\ int(self.coords.x) not in range(564, 960)\ and int(self.coords.y) not in range(90, 484): """Ако някоя от топките е в обсега на някой от джобовете влизаме в този if и почваме да следим за сблъсък със стената на някой от джобовете или за попадение в джоба. """ for pocket in pockets: self.pocket_walls_collision(pockets[pocket][1], pockets[pocket][2]) self.pocket_walls_collision(pockets[pocket][3], pockets[pocket][4]) if (self.coords - pockets[pocket][0]).length <= POCKET_R: self.vizibility = False self.coords = Vec2D(1000, 1000) + self.pos self.velocity = Vec2D(0, 0) self.is_potted = True else: if self.coords.x < LEFT_BORDER or self.coords.x > RIGHT_BORDER: if self.coords.x < LEFT_BORDER: self.coords.x = LEFT_BORDER else: self.coords.x = RIGHT_BORDER self.velocity.x = -self.velocity.x elif self.coords.y < UP_BORDER or self.coords.y > DOWN_BORDER: if self.coords.y < UP_BORDER: self.coords.y = UP_BORDER else: self.coords.y = DOWN_BORDER self.velocity.y = -self.velocity.y
def test_wall_collision(self): self.game.redball1.coords = Vec2D(160, 100) self.game.redball2.coords = Vec2D(160, 300) self.game.redball3.coords = Vec2D(160, 470) self.game.redball4.coords = Vec2D(940, 300) self.game.redball1.velocity = Vec2D(0, -60) self.game.redball2.velocity = Vec2D(-60, 0) self.game.redball3.velocity = Vec2D(0, 60) self.game.redball4.velocity = Vec2D(60, 0) self.game.board_status = NON_STATICK while self.game.board_status == NON_STATICK: self.game.balls_handler() self.game.game_handler() self.assertGreater(self.game.redball1.coords.y, UP_BORDER) self.assertGreater(self.game.redball2.coords.x, LEFT_BORDER) self.assertLess(self.game.redball3.coords.y, DOWN_BORDER) self.assertLess(self.game.redball4.coords.x, RIGHT_BORDER)
def ball_collision(self, ball, next_ball): delta = next_ball.coords - ball.coords unit_delta = Vec2D(delta / delta.get_length()) unit_tangent = Vec2D(unit_delta.perpendicular()) velocity_1_n = unit_delta.dot(ball.velocity) velocity_1_t = unit_tangent.dot(ball.velocity) velocity_2_n = unit_delta.dot(next_ball.velocity) velocity_2_t = unit_tangent.dot(next_ball.velocity) new_velocity_1_t = velocity_1_t new_velocity_2_t = velocity_2_t new_velocity_1_n = velocity_2_n new_velocity_2_n = velocity_1_n new_velocity_1_n = Vec2D(new_velocity_1_n * unit_delta) new_velocity_2_n = Vec2D(new_velocity_2_n * unit_delta) new_velocity_1_t = Vec2D(new_velocity_1_t * unit_tangent) new_velocity_2_t = Vec2D(new_velocity_2_t * unit_tangent) new_velocity_1 = Vec2D(new_velocity_1_n + new_velocity_1_t) new_velocity_2 = Vec2D(new_velocity_2_n + new_velocity_2_t) ball.velocity = new_velocity_1 next_ball.velocity = new_velocity_2
def potted_ball_handler(self, potted, color_points=None): red_ball = 0 color_ball = 0 points = 0 if color_points is None: color_points = [0] else: color_points = color_points for ball in potted: if isinstance(ball, balls.WhiteBall): self.foul = True if isinstance(ball, balls.ColorBall): color_ball += 1 color_points.append(ball.points) if self.turn.target != COLOR_TARGET: self.foul = True if isinstance(ball, balls.RedBall): if self.turn.target != RED_TARGET: self.foul = True red_ball += 1 points += ball.points ball.velocity = Vec2D(0, 0) if isinstance(ball, balls.RedBall): self.all_balls.remove(ball) ball.is_potted = False else: self.ball_return(ball) ball.is_potted = False self.potted = [] if color_ball > 1 or (red_ball > 0 and color_ball > 0): self.foul = True if self.foul is True: # print("Foul wrong ball potted") self.change_turn() if max(color_points) > FOUL_POINTS: self.turn.points += max(color_points) else: self.turn.points += FOUL_POINTS else: if self.turn.target == RED_TARGET: self.turn.points += points else: self.turn.points += max(color_points) self.turn.change_target()