def start_game(): global tk tk = Tk() tk.title("Bounce !!") tk.resizable(0, 0) tk.wm_attributes("-topmost", 1) canvas = Canvas(tk, width=500, height=500, bg="Black", highlightthickness=0) canvas.pack() tk.update() paddle = Paddle(canvas, "Blue") bricks = Bricks(canvas, "Green") ball = Ball(canvas, paddle, bricks, "red") while True: if ball.hit_bottom == False and len(bricks.recs) > 0: ball.draw() paddle.draw() elif len(bricks.recs) == 0: flag = 1 break elif ball.hit_bottom: flag = 2 break tk.update_idletasks() tk.update() time.sleep(0.05) return flag
class Board: def __init__(self): self.ball = Ball(400, 300, 3, 4, "random", 1) #self.ball.launch() self.paddle1 = Paddle(10, 250) self.paddle2 = Paddle(BOARD_LENGTH - 10 - PADDLE_LENGTH, 250) self.scoreboard = ScoreBoard() def move_paddle_1(self, speed): self.paddle1.move(speed) def move_paddle_2(self, speed): self.paddle2.move(speed) def move_ball(self): self.ball.move(self.scoreboard) return 1 def get_paddle_1(self): return self.paddle1 def get_paddle_2(self): return self.paddle2 def get_ball(self): return self.ball def get_scoreboard(self): return self.scoreboard def draw(self, display): self.paddle1.draw(display) self.paddle2.draw(display) self.scoreboard.update_board(display) self.ball.draw(display)
class Client: def __init__(self): port = int(input('Which port are you going to connect to? ')) self.name = input('What is your name? ') n = Network(port) x = n.get_xpos() player_count = n.get_player_count() self.player = Paddle(self.name, x, player_count) self.player2 = n.send_paddle(self.player) print('Connected to server.') self.main(n) def main(self, n): window = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT)) pygame.display.set_caption('You are ' + self.name + '!') while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() break ball = n.get_ball() self.player2 = n.send_paddle(self.player) self.update_window(window, ball) def update_window(self, win, ball): win.fill((0, 0, 0)) score1 = font.render(str(ball.score1), False, (255, 255, 255)) score2 = font.render(str(ball.score2), False, (255, 255, 255)) win.blit(score1, (WINDOW_WIDTH / 2 + 220, 20)) win.blit(score2, (WINDOW_WIDTH / 2 - 220, 20)) name1 = font.render(self.player.name, False, (255, 255, 255)) name2 = font.render(self.player2.name, False, (255, 255, 255)) if self.player.id == 1: win.blit(name1, (WINDOW_WIDTH - list(name1.get_rect())[2] - 100, 20)) win.blit(name2, (100, 20)) else: win.blit(name1, (100, 20)) win.blit(name2, (WINDOW_WIDTH - list(name2.get_rect())[2] - 100, 20)) if ball.score1 < 7 and ball.score2 < 7: ball.draw(win) self.player.move() self.player.draw(win) self.player2.draw(win) pygame.draw.rect(win, (255, 255, 255), (WINDOW_WIDTH / 2 - 5, 0, 10, WINDOW_HEIGHT)) else: if ball.winner.id == self.player.id: won = big_font.render('You won!', False, (0, 255, 0)) pos = (WINDOW_WIDTH / 2 - list(won.get_rect())[2] / 2, WINDOW_HEIGHT / 2 - list(won.get_rect())[3] / 2) win.blit(won, pos) else: lost = big_font.render('You lost!', False, (255, 0, 0)) pos = (WINDOW_WIDTH / 2 - list(lost.get_rect())[2] / 2, WINDOW_HEIGHT / 2 - list(lost.get_rect())[3] / 2) win.blit(lost, pos) pygame.display.update()
class PaddleTestCase(unittest.TestCase): def setUp(self): self.paddle = Paddle() self.paddle.rect.center = SCREEN_WIDTH // 2, SCREEN_HEIGHT - MARGIN def test_init(self): msg = "invalid paddle length" self.assertIn(self.paddle.len, range(-2, 4), msg=msg) msg = "paddle shouldn't start with balls attached" self.assertFalse(self.paddle.attached_balls, msg=msg) msg = "paddle shoudn't start with bonuses" self.assertFalse(self.paddle.is_confused, msg=msg) self.assertFalse(self.paddle.is_magnetic, msg=msg) def test_len(self): msg = "wrong paddle length" self.assertEqual(len(self.paddle), self.paddle.rect.width, msg=msg) def test_update(self): ball = Ball() ball.rect.center = self.paddle.rect.center self.paddle.attached_balls.add(ball) x1, x2 = self.paddle.rect.left, ball.rect.left dx = 10 self.paddle.update(dx=dx) msg = "wrong position after moving the paddle" self.assertEqual(self.paddle.rect.left, x1 + dx, msg=msg) msg = "attached ball didn't move along the paddle" self.assertEqual(ball.rect.left, x2 + dx, msg=msg) self.paddle.is_confused = True x0 = self.paddle.rect.left self.paddle.update(dx=dx) msg = "directions should be reversed" self.assertEqual(self.paddle.rect.left, x0 - dx, msg=msg) self.paddle.is_confused = False self.paddle.update(dx=SCREEN_WIDTH) msg = "paddle should stop moving at margins" self.assertEqual(self.paddle.rect.right, SCREEN_WIDTH - MARGIN, msg=msg) self.paddle.update(dx=-SCREEN_WIDTH) self.assertEqual(self.paddle.rect.left, MARGIN, msg=msg) def test_draw(self): surface = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT)) # pylint: disable=too-many-function-args self.paddle.draw(surface) msg = "paddle is not displayed" white = (255, 255, 255, 255) self.assertEqual(surface.get_at(self.paddle.rect.center), white, msg=msg)
class ScenePong(Scene): def __init__(self): Scene.__init__(self) def did_load(self, window, scene_director): self.window_width, self.window_height = window.get_size() self.scene_director = scene_director self.btnGoHome = UIButton() self.btnGoHome.fixture(color=(100, 100, 100), position=(20, 20)).foreground(text="HOME") # paddles self.player = Paddle(position=(20, window.get_rect().centery - 100)) self.player_ia = Paddle(position=(window.get_width() - 70, window.get_rect().centery - 100)) #ball center = (window.get_rect().centerx, window.get_rect().centery) self.ball = Ball(position=center, color=(20, 120, 125)) def listen_inputs(self, event, pressed_keys): # go home if pressed_keys[pygame.K_BACKSPACE]: self.scene_director.go_scene('home') if event.type == pygame.KEYDOWN: # step up if event.key == pygame.K_UP: self.player.step_up() # step down elif event.key == pygame.K_DOWN: self.player.step_down() elif event.type == pygame.KEYUP: if event.key == pygame.K_UP: self.player.stop() elif event.key == pygame.K_DOWN: self.player.stop() if pygame.mouse.get_pressed()[0]: mouse_position = pygame.mouse.get_pos() if self.btnGoHome.is_over(mouse_position): self.scene_director.go_scene('home') def update(self): self.player.update(self.window_height) self.ball.update(self.window_width, self.window_height) def render(self, window): Scene.render(self, window) window.fill((255, 255, 0)) self.player.draw(window) self.player_ia.draw(window) self.ball.draw(window) self.btnGoHome.draw(window)
def main(): pygame.init() clock = pygame.time.Clock() screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT), 0, 32) surface = pygame.Surface(screen.get_size()) surface = surface.convert() paddle = Paddle(0) ball = Ball(0) enemies = [] for i in range(NUMBER_OF_ENEMIES): enemy = Enemy(i) enemies.append(enemy) draw_grid(surface) myfont = pygame.font.SysFont("monospace", 16) score = 0 while True: clock.tick(FRAME_RATE) paddle.user_input() draw_grid(surface) paddle.move() ball.move() result = collision_detection(paddle, ball, enemies) if result == -1: score = 0 ball.reset() for enemy in enemies: enemy.reset() if result == 1: score += 1 paddle.draw(surface) ball.draw(surface) for enemy in enemies: enemy.draw(surface) screen.blit(surface, (0, 0)) text = None if score == NUMBER_OF_ENEMIES: text = myfont.render("WINNER", 50, WHITE) screen.blit(text, (SCREEN_WIDTH // 2 - 50, SCREEN_HEIGHT // 2)) ball.destroy() else: text = myfont.render(f"Score: {score}", 1, WHITE) screen.blit(text, (5, 10)) pygame.display.update()
class Game: def __init__(self): pygame.init() self._window = pygame.display.set_mode((800, 600)) pygame.display.set_caption("Pong") self.deltaTime = 0.0 self.player = Paddle() self.ball = Ball() def run(self): while True: start = time.time() self.handle_events() self.update() self.render() end = time.time() self.deltaTime = end - start def update(self): keys = pygame.key.get_pressed() if keys[pygame.K_LEFT]: self.player.move(-self.deltaTime * 250.0, 0.0) elif keys[pygame.K_RIGHT]: self.player.move(self.deltaTime * 250.0, 0.0) self.ball.update(self.deltaTime, self.player) def render(self): self._window.fill((0, 0, 0)) self.player.draw(self._window) self.ball.draw(self._window) pygame.display.update() def handle_events(self): for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit()
class PongGame: window_width = 650 window_height = 500 def __init__(self): self.ball = Ball(PongGame.window_width / 2, PongGame.window_height / 2) self.paddle1 = NNPaddle(PongGame.window_width - 50, PongGame.window_height / 2, self.ball, self) self.paddle2 = AIPaddle(50, PongGame.window_height / 2, self.ball, self) self.temp_paddle = None self.winner = None self.game_over = False self.speed = 1000 self.scores = [0, 0] self.timeout = 0 self.pause = False def start_game(self): pygame.init() clock = pygame.time.Clock() display = pygame.display.set_mode( (PongGame.window_width, PongGame.window_height)) pygame.display.set_caption('Neural Net Pong') while not self.game_over: delta = clock.tick(60) / self.speed display.fill((255, 255, 255)) # listen for events for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() self.handle_input(delta) self.game_over = self.handle_off_screen() if not self.game_over: self.handle_collisions() # super super advanced AI self.paddle1.follow_ball(delta) self.paddle2.follow_ball(delta) self.ball.move(delta) self.draw(display) if self.timeout < 100: self.timeout += 1 if self.pause: self.reset() pygame.display.flip() def draw(self, display): self.paddle1.draw(display) self.paddle2.draw(display) self.ball.draw(display) font = pygame.font.Font(None, 25) score = font.render( self.paddle2.name + ' | ' + str(self.scores[1]) + ' - ' + str(self.scores[0]) + ' | ' + self.paddle1.name, True, (0, 0, 0)) rect = score.get_rect(center=(325, 60)) display.blit(score, rect) def handle_input(self, delta): # listen for key presses keys = pygame.key.get_pressed() if keys[pygame.K_UP] and self.paddle2.bounds.y > 0: self.paddle2.move_up(delta) if keys[pygame. K_DOWN] and self.paddle2.bounds.y + self.paddle2.bounds.height < PongGame.window_height: self.paddle2.move_down(delta) if keys[pygame.K_RIGHT] and self.speed > 10: self.speed -= 10 if keys[pygame.K_LEFT] and self.speed < 1000000: self.speed += 10 if keys[pygame.K_r]: self.reset() if keys[pygame.K_SPACE] and self.timeout == 100: self.timeout = 0 if self.paddle2.name != 'Player': self.temp_paddle = self.paddle2 self.paddle2 = Paddle(50, PongGame.window_height / 2) self.paddle2.score = self.scores[0] else: self.paddle2 = self.temp_paddle if keys[pygame.K_p] and self.timeout == 100: if not self.pause: self.pause = True else: self.pause = False def handle_collisions(self): # collision with human paddle if self.ball.intersects_paddle(self.paddle2, self.paddle1): self.ball.vel_x = -self.ball.vel_x self.ball.vel_x *= 1.05 self.ball.vel_y *= 1.05 # collision with ceiling elif (self.ball.bounds.y <= 0 and self.ball.vel_y < 0) or ( self.ball.bounds.y + self.ball.bounds.height >= PongGame.window_height and self.ball.vel_y > 0): self.ball.vel_y = -self.ball.vel_y def handle_off_screen(self): if self.paddle1.score >= 3: self.winner = self.paddle1 return True elif self.paddle2.score >= 3: self.winner = self.paddle2 return True if self.ball.bounds.x + self.ball.bounds.width > PongGame.window_width or self.ball.bounds.x <= 0: if self.ball.bounds.x <= 0: self.paddle1.score += 1 self.paddle1.fitness += 10 self.scores[0] += 1 else: self.paddle2.score += 1 self.paddle2.fitness += 10 self.scores[1] += 1 self.ball = Ball(PongGame.window_width / 2, PongGame.window_height / 2) self.paddle1.reset(PongGame.window_width - 50, PongGame.window_height / 2, self.ball) self.paddle2.reset(50, PongGame.window_height / 2, self.ball) return False def reset(self): self.ball.reset() self.paddle1.reset(PongGame.window_width - 50, PongGame.window_height / 2, self.ball) self.paddle1.fitness = 0 self.paddle1.contacts_ball = 0 self.paddle1.score = 0 self.paddle2.reset(50, PongGame.window_height / 2, self.ball) self.paddle2.score = 0 self.scores = [0, 0]
class Board: def __init__(self, window, path="."): self.window = window self.h, self.w = window.getmaxyx() self.cells_x = self.w // Block.WIDTH self.cells_y = self.h // Block.HEIGHT self.field = [[None] * self.cells_x for i in range(self.cells_y)] self._gen_blocks(path) self.ball = Ball(self.h-2, self.w//2) self.paddle = Paddle(self.h-1, self.w//2) def draw(self): for row in self.field: for cell in row: if cell is not None: cell.draw(self.window) self.window.attron(curses.color_pair(1)) self.ball.draw(self.window) self.paddle.draw(self.window) def move(self, offset): self.paddle.move(offset, self.w) def animate(self): self.ball.animate(self.h, self.w) self._collide_endzone() self._collide_blocks() self._collide_paddle() def _collide_blocks(self): cell_x = self.ball.x // Block.WIDTH cell_y = self.ball.y // Block.HEIGHT if (cell_y >= self.cells_y) or (cell_x >= self.cells_x): return block = self.field[cell_y][cell_x] if block is not None: self.field[cell_y][cell_x] = None # destroy the block # deflect the ball if (self.ball.y == block.top()) or \ (self.ball.y == block.bottom()): self.ball.bounce_y() if (self.ball.x == block.left()) or \ (self.ball.x == block.right()): self.ball.bounce_x() if block.isdir: self._gen_blocks(block.f) else: pass #block.destroy() def _collide_endzone(self): if self.ball.y == self.h - 1: exit() def _collide_paddle(self): if self.paddle.contacts(self.ball): self.ball.bounce_y() def _add_block(self, f): for y, row in enumerate(self.field): for x, cell in enumerate(row): if cell is None: b = Block(f, y, x) self.field[y][x] = b return def _gen_blocks(self, path): for f in os.listdir(path): self._add_block(os.path.join(path, f))
class Level(object): """ Main Level class, handles most of the gameplay """ def __init__(self, screen, draw_offset, control_set, player_color, finish_game): """ Init with... way too many parameters :param screen: Main PyGame surface to draw the objects/UI on :param draw_offset: Drawing offset used in multiplayer :param control_set: Key-set used to control the Paddle :param player_color: Color of the player's Paddle :param finish_game: Function passed to the constructor, triggered on the game end :return: """ self.screen = screen self.draw_offset = draw_offset self.control_set = control_set self.prev_input_x = 0 self.level_number = 1 self.block_count = 0 self.player = Player("Derp") self.paddle = Paddle(LEVEL_WIDTH/2 - Paddle.WIDTH/2, LEVEL_HEIGHT - 40, player_color, parent=self, owner=self.player) self.ball = Ball(self.paddle.rect.x + Paddle.WIDTH/2 - Ball.RADIUS, self.paddle.rect.y - Ball.RADIUS * 2) self.items = None self.blocks = [] self.blocks_surface = None self.blocks_surface_dirty = True self.entities = [] self.font = Assets.font self.score_label = None self.lives_label = None self.level_label = None self.load_level(self.level_number) self.finish_game = finish_game def handle_input(self, events): """ Handles incoming input events :param events: input events from the main app :return: """ BONUS_SPAWN_X = 305 BONUS_SPAWN_Y = 200 for event in events: if event.type == KEYDOWN: if event.key == self.control_set[0]: if self.paddle.vx != 0: self.prev_input_x = 1 self.paddle.vx = -1 elif event.key == self.control_set[2]: if self.paddle.vx != 0: self.prev_input_x = -1 self.paddle.vx = 1 # elif event.key == K_SPACE: # self.paddle.change_size(self.paddle.rect.width+10) elif event.key == K_1: # self.add_entity(ItemExpand(BONUS_SPAWN_X, BONUS_SPAWN_Y)) self.spawn_item(BONUS_SPAWN_X, BONUS_SPAWN_Y, 1) elif event.key == K_2: # self.add_entity(ItemLaserGun(BONUS_SPAWN_X, BONUS_SPAWN_Y)) self.spawn_item(BONUS_SPAWN_X, BONUS_SPAWN_Y, 2) elif event.key == K_3: # self.add_entity(ItemShrink(BONUS_SPAWN_X, BONUS_SPAWN_Y)) self.spawn_item(BONUS_SPAWN_X, BONUS_SPAWN_Y, 3) elif event.key == K_4: # self.add_entity(ItemPaddleNano(BONUS_SPAWN_X, BONUS_SPAWN_Y)) self.spawn_item(BONUS_SPAWN_X, BONUS_SPAWN_Y, 4) elif event.key == K_5: # self.add_entity(ItemLife(BONUS_SPAWN_X, BONUS_SPAWN_Y)) self.spawn_item(BONUS_SPAWN_X, BONUS_SPAWN_Y, 5) elif event.key == K_6: # self.add_entity(ItemLife(BONUS_SPAWN_X, BONUS_SPAWN_Y)) self.spawn_item(BONUS_SPAWN_X, BONUS_SPAWN_Y, 6) elif event.type == KEYUP: if event.key == self.control_set[0]: if self.prev_input_x < 0: self.prev_input_x = 0 elif self.prev_input_x > 0: self.paddle.vx = 1 self.prev_input_x = 0 else: self.paddle.vx = 0 elif event.key == self.control_set[2]: if self.prev_input_x > 0: self.prev_input_x = 0 elif self.prev_input_x < 0: self.paddle.vx = -1 self.prev_input_x = 0 else: self.paddle.vx = 0 elif event.key == self.control_set[1]: if self.ball.docked: self.ball.docked = False self.ball.vx = 1 self.ball.vy = -1 else: self.paddle.use_attachment() elif event.key == K_EQUALS: self.start_level(self.level_number + 1) def start_level(self, new_level_num): """ Used to start level, checks the level bounds :param new_level_num: :return: """ self.ball.docked = True self.ball.dead = False if new_level_num > get_level_count(): self.finish_game() else: if self.level_number < new_level_num: self.player.score += self.player.lives * 500 else: self.player.score = 0 self.load_level(new_level_num) self.paddle.change_size(PADDLE_WIDTHS[PADDLE_DEFAULT_WIDTH_INDEX]) self.paddle.attachments = [] self.paddle.rect.x = LEVEL_WIDTH/2 - self.paddle.rect.width/2 self.paddle.rect.y = LEVEL_HEIGHT - 40 self.player.lives = 3 self.blocks_surface = Surface((LEVEL_WIDTH, LEVEL_HEIGHT)) self.blocks_surface_dirty = True def load_level(self, new_level_num): """ Parses level from the Character array that is provided by the LevelLoader class :param new_level_num: Number of the level, used to construct the filename, compute the next level number, and viewed on the UI :return: """ loaded_level = LevelLoader.load(LEVELDIR + str(new_level_num).zfill(2) + ".lvl") level = loaded_level[0] self.items = loaded_level[1] self.level_number = new_level_num self.blocks = [] self.entities = [] self.block_count = 0 for y in xrange(0, BLOCK_NUM_HEIGHT): self.blocks.append([None, ] * BLOCK_NUM_WIDTH) for x in xrange(0, BLOCK_NUM_WIDTH): if level[y][x] == 'i': self.blocks[y][x] = BlockIndestructible(PLAYFIELD_PADDING[0] + x * Block.WIDTH, PLAYFIELD_PADDING[1] + y * Block.HEIGHT) elif level[y][x] == 'm': self.blocks[y][x] = BlockMultiHit(PLAYFIELD_PADDING[0] + x * Block.WIDTH, PLAYFIELD_PADDING[1] + y * Block.HEIGHT) self.block_count += 1 elif level[y][x] == 'e': self.blocks[y][x] = BlockExplosive(PLAYFIELD_PADDING[0] + x * Block.WIDTH, PLAYFIELD_PADDING[1] + y * Block.HEIGHT) self.block_count += 1 elif level[y][x] != '0': self.blocks[y][x] = Block(PLAYFIELD_PADDING[0] + x * Block.WIDTH, PLAYFIELD_PADDING[1] + y * Block.HEIGHT, int(level[y][x]) - 1) self.block_count += 1 def add_entity(self, entity): """ Utility function to add new entities to the level. Later, might search for dead entities to replace them instead of expanding the list indefinitely :param entity: :return: """ self.entities.append(entity) def spawn_item(self, x, y, item): """ Function used to spawn items from blocks :param x: x coordinate of the play-field :param y: y coordinate of the play-field :param item: item to spawn, leave empty to make it randomly selected :return: """ if item == 1: self.add_entity(ItemLife(x, y)) elif item == 2: self.add_entity(ItemExpand(x, y)) elif item == 3: self.add_entity(ItemShrink(x, y)) elif item == 4: self.add_entity(ItemLaserGun(x, y)) elif item == 5: self.add_entity(ItemPaddleNano(x, y)) elif item == 6: pass elif randint(0, 35) == 0: item_type = randint(0, 4) if item_type == 0: dropped_item = ItemLife(x, y) elif item_type == 1: dropped_item = ItemExpand(x, y) elif item_type == 2: dropped_item = ItemShrink(x, y) elif item_type == 3: dropped_item = ItemLaserGun(x, y) else: dropped_item = ItemPaddleNano(x, y) self.add_entity(dropped_item) def block_destruction(self, block, item, func): """ Decides what to do with the block, based on the block type (sigh), and performs appropriate action :param block: Block to operate on :param item: If the block has a hard-assigned item in level, it will be spawned :param func: Function of the block that returns its points-value :return: """ return_v = func() if isinstance(block, BlockExplosive): rect = block.rect self.entities.append(Explosion(rect.x + rect.width/2 - Explosion.WIDTH/2, rect.y + rect.height/2 - Explosion.HEIGHT/2)) if block.dead: self.player.add_points(return_v) self.block_count -= 1 if not isinstance(block, BlockExplosive): self.spawn_item(block.rect.x, block.rect.y, item) self.blocks_surface_dirty = True def draw(self): """ Method called each frame to (re)draw the objects and UI :return: """ self.screen.blit(Assets.background, (self.draw_offset[0], self.draw_offset[1])) self.screen.blit(Assets.border, (self.draw_offset[0], self.draw_offset[1])) self.screen.blit(Assets.border, (self.draw_offset[0] + LEVEL_WIDTH - PLAYFIELD_PADDING[0], self.draw_offset[1])) if self.blocks_surface_dirty: self.blocks_surface = Surface((LEVEL_WIDTH, LEVEL_HEIGHT), SRCALPHA, 32) self.blocks_surface = self.blocks_surface.convert_alpha() self.blocks_surface_dirty = False for row in self.blocks: for block in row: if block is not None and not block.dead: block.draw(self.blocks_surface) self.screen.blit(self.blocks_surface, self.draw_offset) self.paddle.draw(self.screen, self.draw_offset) if not self.ball.dead: self.ball.draw(self.screen, self.draw_offset) # draw entities for entity in self.entities: if not entity.dead: entity.draw(self.screen, self.draw_offset) # draw upper bar draw.rect(self.screen, (0, 0, 0), (self.draw_offset[0] + PLAYFIELD_PADDING[0], self.draw_offset[1], LEVEL_WIDTH - PLAYFIELD_PADDING[0] * 2, PLAYFIELD_PADDING[1])) self.screen.blit(self.score_label, (self.draw_offset[0] + PLAYFIELD_PADDING[0] + 10, self.draw_offset[1])) self.screen.blit(self.lives_label, (self.draw_offset[0] + PLAYFIELD_PADDING[0] + 150, self.draw_offset[1])) self.screen.blit(self.level_label, (self.draw_offset[0] + LEVEL_WIDTH - 100, self.draw_offset[1])) def update(self): """ Method called each frame, to update the state of entities based on input events and previous state of the game :return: """ if self.block_count <= 0: self.start_level(self.level_number + 1) elif self.player.lives <= 0: self.start_level(self.level_number) self.paddle.update() if self.ball.docked and not self.ball.dead: self.ball.rect.x = self.paddle.rect.x + self.paddle.rect.width/2 - self.ball.radius self.ball.rect.y = self.paddle.rect.y - self.ball.radius * 2 elif self.player.lives > 0: self.ball.update() for entity in self.entities: if not entity.dead: entity.update() self.check_collision() self.score_label = self.font.render("SCORE: " + str(self.player.score), 1, (255, 255, 255)) self.lives_label = self.font.render("LIVES: " + str(self.player.lives), 1, (255, 255, 255)) self.level_label = self.font.render("LEVEL " + str(self.level_number), 1, (255, 255, 255)) def check_collision(self): """ Called after input handling and movement of the object, to check and solve collisions :return: """ # ball vs paddle if self.ball.rect.y < self.paddle.rect.y and \ sprite.collide_rect(self.paddle, self.ball): self.ball.vy = -1 # ball.vy # ball vs bottom if not self.ball.dead and self.ball.rect.y + self.ball.radius * 2 > LEVEL_HEIGHT: self.player.lives -= 1 if self.player.lives < 1: self.ball.dead = True else: self.ball.rect.x = self.paddle.rect.x + self.paddle.rect.width/2 - self.ball.radius self.ball.rect.y = self.paddle.rect.y - self.ball.radius * 2 self.ball.docked = True self.paddle.change_size(PADDLE_WIDTHS[PADDLE_DEFAULT_WIDTH_INDEX]) self.paddle.attachments = [] # ball vs blocks coll_num = [0, 0, 0] coll_num_val = (4, 2, 1) ball_grid_x = (self.ball.rect.x - PLAYFIELD_PADDING[0] + self.ball.radius) / Block.WIDTH ball_grid_y = (self.ball.rect.y - PLAYFIELD_PADDING[1] + self.ball.radius) / Block.HEIGHT for y in range(ball_grid_y - 1, ball_grid_y + 2): for x in range(ball_grid_x - 1, ball_grid_x + 2): if 0 <= x < BLOCK_NUM_WIDTH and 0 <= y < BLOCK_NUM_HEIGHT: if self.blocks[y][x] is not None and not self.blocks[y][x].dead and \ sprite.collide_rect(self.blocks[y][x], self.ball): self.block_destruction(self.blocks[y][x], self.items[y][x], self.blocks[y][x].on_collide) coll_num[y - ball_grid_y + 1] += coll_num_val[x - ball_grid_x + 1] self.ball.on_collide(coll_num) # entities for entity in self.entities: if not entity.dead: # paddle vs items if isinstance(entity, Item) and sprite.collide_rect(self.paddle, entity): entity.on_collect(self.paddle) entity.dead = True # self.player.lives += 1 # explosion vs blocks elif isinstance(entity, Explosion) and entity.state > 0: entity_block_x = (entity.rect.x - PLAYFIELD_PADDING[0] + Explosion.WIDTH/2) / Block.WIDTH entity_block_y = (entity.rect.y - PLAYFIELD_PADDING[1] + Explosion.HEIGHT/2) / Block.HEIGHT for y in xrange(entity_block_y - 1, entity_block_y + 2): for x in xrange(entity_block_x - 1, entity_block_x + 2): if 0 <= x < BLOCK_NUM_WIDTH and 0 <= y < BLOCK_NUM_HEIGHT: if self.blocks[y][x] is not None and not self.blocks[y][x].dead: self.block_destruction(self.blocks[y][x], self.items[y][x], self.blocks[y][x].kill) elif isinstance(entity, Projectile): entity_block_x = (entity.rect.x - PLAYFIELD_PADDING[0] + entity.rect.width/2) / Block.WIDTH entity_block_y = (entity.rect.y - PLAYFIELD_PADDING[1] + entity.rect.height/2) / Block.HEIGHT for y in xrange(entity_block_y - 1, entity_block_y + 2): for x in xrange(entity_block_x - 1, entity_block_x + 2): if 0 <= x < BLOCK_NUM_WIDTH and 0 <= y < BLOCK_NUM_HEIGHT: if self.blocks[y][x] is not None and not self.blocks[y][x].dead \ and sprite.collide_rect(self.blocks[y][x], entity): self.block_destruction(self.blocks[y][x], self.items[y][x], self.blocks[y][x].kill) entity.on_collide()
ball = Ball(canvas, paddle, score, 'red') balls.append(ball) def ball_destroyer(canvas, balls_list): if isinstance(balls_list, list): for ball in balls_list: if isinstance(ball, Ball): if ball.hit_bottom: balls_list.remove(ball) canvas.delete(ball.id) while len(balls) > 0: if paddle.started: ball_destroyer(canvas, balls) for ball in balls: ball.draw() if ball.hit_paddle(canvas.coords(ball.id)): balls.append(Ball(canvas, paddle, score, 'red')) paddle.draw() if len(balls) == 0: canvas.create_text(250, 120, text='ты хуй', font=('Courier', 110), fill='red') tk.update_idletasks() tk.update() time.sleep(0.01) time.sleep(3)
class Scene: def __init__(self): self.lblScore = pyglet.text.Label('Score: 0', font_name='Arial', font_size=12, x=15, y=5, anchor_x='left', anchor_y='bottom') self.lblLevel = pyglet.text.Label('Level: 1', font_name='Arial', font_size=12, x=game.window.width - 15, y=5, anchor_x='right', anchor_y='bottom') self.setup() def setup(self, score=0, level=1): # SETUP GAME OBEJCTS self.paddle = Paddle(game.keyboard, game.window.width / 2 - 50, 40, width=100, height=20, speed=400) self.ball = Ball(game.window.width / 2 - 8, 200, width=16, height=16, speed=200, direction=(0, -1)) self.wall_w = Wall(0, 0, width=10, height=game.window.height) self.wall_e = Wall(game.window.width - 10, 0, width=10, height=game.window.height) self.wall_n = Wall(0, game.window.height - 10, width=game.window.width, height=10) self.wall_s = Wall(0, 0, width=game.window.width, height=10) self.walls = [self.wall_w, self.wall_n, self.wall_e, self.wall_s] self.score = score self.lblScore.text = "Score: " + str(self.score) self.level = level self.lblLevel.text = "Level: " + str(self.level) # bricks setup BRICK_WIDTH = 60 BRICK_HEIGHT = 40 MARGIN = 10 self.bricks = [] brickX = MARGIN brickY = game.window.height - MARGIN - BRICK_HEIGHT while brickY > game.window.height / 2: while brickX + BRICK_WIDTH < game.window.width - MARGIN: self.bricks.append( Brick(brickX, brickY, BRICK_WIDTH, BRICK_HEIGHT)) brickX += BRICK_WIDTH + MARGIN brickX = MARGIN brickY -= MARGIN + BRICK_HEIGHT # appear #for brick in self.bricks: # brick.appear(0.25 + random.random() * 0.5) def draw(self): for brick in self.bricks: brick.draw() self.paddle.draw() self.ball.draw() self.wall_w.draw() self.wall_e.draw() self.wall_n.draw() self.lblScore.draw() self.lblLevel.draw() def tick(self, dt): # update tweens game.tween.tick(dt) # update game objects self.paddle.tick(dt) self.ball.tick(dt) # compute collisions and raise collision events game.physics.collide_prepare() game.physics.collide([self.ball], [self.paddle]) # collides ball against the paddle game.physics.collide([self.ball], self.walls) # collides ball against walls game.physics.collide([self.ball], self.bricks) # collides ball against bricks game.physics.collide_finish( ) # this raises collision events gathered during "physics.collide(...)" # remove dead bricks i = 0 while i < len(self.bricks): if not self.bricks[i].alive: self.bricks.pop(i) self.score += 1 self.lblScore.text = "Score: " + str(self.score) else: i += 1 # check ball off-screen if self.ball.x < -self.ball.width or self.ball.x > game.window.width + self.ball.width or self.ball.y > game.window.height + self.ball.height or self.ball.y < -self.ball.height: self.restart() # check all bricks down new_level = True for brick in self.bricks: if brick.destroyable and brick.alive: new_level = False break if new_level: self.next_level() def restart(self): self.setup() def next_level(self): self.setup(score=self.score, level=self.level + 1)
# use a try-block incase there are no bounding-boxes in the frame try: if hand_pos[1]: if hand_pos[1] >= 0 and hand_pos[1] <= SCREEN_WIDTH: #print("Center Y: %d" % hand_pos[1]) human_paddle.set_ypos(hand_pos[1]) except: print("Error, no hand in the frame!") # Update each game object ai_paddle.update(ball) human_paddle.update(ball) ball.move() # Draw each game object ai_paddle.draw(frame) human_paddle.draw(frame) ball.draw(frame) # Show the pong game cv.imshow('Pong', frame) key = cv.waitKey(1) & 0xff if key == ord('q'): break # Calibrate the skin detection module elif key == ord('s'): handDetect.calibrateSkinDetection(calibrate_frame) # Start the game elif key == ord('p'):
class Game: def __init__(self, paddle1computer=None, paddle2computer=None): self.paddle1computer = paddle1computer self.paddle2computer = paddle2computer self._setup() self._game_loop() def _setup(self): pygame.init() pygame.display.set_caption("pypong") self.screen = pygame.display.set_mode((800, 600)) self.clock = pygame.time.Clock() self.timer = 0 self.background = Background() self.paddle1 = Paddle() self.paddle2 = Paddle(760, 'player2.png') self.ball = Ball() self.paddle1_gui = PaddleGui(self.paddle1) self.paddle2_gui = PaddleGui(self.paddle2, 700) self.ball_gui = BallGui(self.ball) self.game_over = False self.running = True def _game_loop(self): while self.running: self.clock.tick(60) self.timer += self.clock.get_time() self.screen.fill((0, 0, 0)) self._handle_input() if not self.game_over: self._update_state() self._draw_objects() if self.paddle1.lives == 0: self._game_over('Player 2') if self.paddle2.lives == 0: self._game_over('Player 1') # refresh display pygame.display.flip() def _handle_input(self): for event in pygame.event.get(): if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: self.running = False if event.key == pygame.K_r: self._setup() if pygame.key.get_pressed()[pygame.K_w]: self.paddle1.move_up() if pygame.key.get_pressed()[pygame.K_s]: self.paddle1.move_down() if pygame.key.get_pressed()[pygame.K_UP]: self.paddle2.move_up() if pygame.key.get_pressed()[pygame.K_DOWN]: self.paddle2.move_down() # let computer move the paddles if activated if self.paddle1computer is not None: self.paddle1computer.move(self.paddle1, self.ball) if self.paddle2computer is not None: self.paddle2computer.move(self.paddle2, self.ball) def _update_state(self): if collision_screen_left(self.ball): self.paddle1.lives -= 1 self.ball.reset() self.background.flash() if collision_screen_right(self.ball): self.paddle2.lives -= 1 self.ball.reset() self.background.flash() if collision_screen_top(self.ball) or collision_screen_bottom( self.ball): self.ball.acceleration = np.multiply(self.ball.acceleration, np.array([1, -1])) self.ball.position += self.ball.acceleration self.ball.acceleration_multiply( np.array([1 + self.timer / 100000000, 1])) if collision(self.paddle1, self.ball): self.ball.accelerate(acc_factor(self.paddle1, self.ball)) self.background.flash((0, 255, 0), 100) if collision(self.paddle2, self.ball): self.ball.accelerate(acc_factor(self.paddle2, self.ball)) self.background.flash((0, 255, 0), 100) self.background.update() def _draw_objects(self): self.background.draw(self.screen) self.paddle1.draw(self.screen) self.paddle2.draw(self.screen) self.ball.draw(self.screen) self.paddle1_gui.draw(self.screen) self.paddle2_gui.draw(self.screen) self.ball_gui.draw(self.screen) def _game_over(self, winner): self.game_over = True surface_width = pygame.display.get_surface().get_width() surface_height = pygame.display.get_surface().get_height() font = pygame.font.Font('freesansbold.ttf', 18) text = font.render('GAME OVER', True, (255, 255, 255)) text_rect = text.get_rect(center=(surface_width / 2, surface_height / 2 - 40)) self.screen.blit(text, text_rect) text = font.render('WINNER: {}'.format(winner), True, (153, 255, 153)) text_rect = text.get_rect(center=(surface_width / 2, surface_height / 2)) self.screen.blit(text, text_rect) text = font.render('Press "r" to restart or "esc" to quit', True, (192, 192, 192)) text_rect = text.get_rect(center=(surface_width / 2, surface_height / 2 + 40)) self.screen.blit(text, text_rect)
class Board: def __init__(self, window, path="."): self.window = window self.h, self.w = window.getmaxyx() self.cells_x = self.w // Block.WIDTH self.cells_y = self.h // Block.HEIGHT self.field = [[None] * self.cells_x for i in range(self.cells_y)] self._gen_blocks(path) self.ball = Ball(self.h - 2, self.w // 2) self.paddle = Paddle(self.h - 1, self.w // 2) def draw(self): for row in self.field: for cell in row: if cell is not None: cell.draw(self.window) self.window.attron(curses.color_pair(1)) self.ball.draw(self.window) self.paddle.draw(self.window) def move(self, offset): self.paddle.move(offset, self.w) def animate(self): self.ball.animate(self.h, self.w) self._collide_endzone() self._collide_blocks() self._collide_paddle() def _collide_blocks(self): cell_x = self.ball.x // Block.WIDTH cell_y = self.ball.y // Block.HEIGHT if (cell_y >= self.cells_y) or (cell_x >= self.cells_x): return block = self.field[cell_y][cell_x] if block is not None: self.field[cell_y][cell_x] = None # destroy the block # deflect the ball if (self.ball.y == block.top()) or \ (self.ball.y == block.bottom()): self.ball.bounce_y() if (self.ball.x == block.left()) or \ (self.ball.x == block.right()): self.ball.bounce_x() if block.isdir: self._gen_blocks(block.f) else: block.destroy() def _collide_endzone(self): if self.ball.y == self.h - 1: exit() def _collide_paddle(self): if self.paddle.contacts(self.ball): self.ball.bounce_y() def _add_block(self, f): for y, row in enumerate(self.field): for x, cell in enumerate(row): if cell is None: b = Block(f, y, x) self.field[y][x] = b return def _gen_blocks(self, path): for f in os.listdir(path): self._add_block(os.path.join(path, f))
class Game: FPS = 60 WIDTH, HEIGHT = (gb.width, gb.height) WIN = pygame.display.set_mode( (0, 0), pygame.FULLSCREEN | pygame.DOUBLEBUF | pygame.HWSURFACE) pygame.display.set_caption("BREAKOUT") OFFSET_X = 600 OFFSET_Y = 200 def __init__(self): self.run = False self.menu = True self.rows = 3 self.columns = int((Game.WIDTH - Game.OFFSET_X) / Block.WIDTH) self.score = 0 self.lives = 5 self.level = 1 self.the_ball = Ball(Ball.START_POSITION[0], Ball.START_POSITION[1], 0, 0, white, Game.WIN) self.the_paddle = Paddle(Paddle.START_POSITION[0], Paddle.START_POSITION[1], Paddle.START_SIZE[0], Paddle.START_SIZE[1], white, Game.WIN) self.score_text = TextGUI(Game.WIDTH / 100 * 15, Game.HEIGHT // 60, Game.WIN, "SCORE: " + str(self.score), 50) self.lives_text = TextGUI(Game.WIDTH / 100 * 73, Game.HEIGHT - Game.HEIGHT // 12, Game.WIN, "LIVES: " + str(self.lives), 20) self.level_text = TextGUI(Game.WIDTH / 100 * 60, Game.HEIGHT // 60, Game.WIN, "LEVEL: " + str(self.level), 50) self.left_boundary = Boundary(0, 0 + Game.OFFSET_Y, Game.OFFSET_X // 2, Game.HEIGHT, gray, Game.WIN) self.right_boundary = Boundary(Game.WIDTH - Game.OFFSET_X // 2, 0 + Game.OFFSET_Y, Game.OFFSET_X // 2, Game.HEIGHT, gray, Game.WIN) self.top_boundary = Boundary(0, Game.OFFSET_Y // 2, Game.WIDTH, Game.OFFSET_Y // 2, gray, Game.WIN) def break_block(self, a_block): a_block.collide() self.the_ball.bounce_y() self.increase_score() def create_blocks(self): for c in range(1, self.columns + 1): for r in range(3, self.rows + 3): this_x = c * Block.WIDTH - (Block.WIDTH) + Game.OFFSET_X // 2 this_y = r * Block.HEIGHT + (Game.OFFSET_Y * 1.4) Block(this_x, this_y, 0, 0, random.choice(block_colors), Game.WIN) def increase_score(self): self.score += 10 self.score_text.create_text("SCORE: " + str(self.score)) def change_lives(self, amount): self.lives += amount self.lives_text.create_text("LIVES: " + str(self.lives)) def change_level(self, amount): self.level += amount self.level_text.create_text("LEVEL: " + str(self.level)) def increase_rows(self, amount): self.rows += amount def lost_level(self): pygame.time.delay(666) self.change_lives(-1) self.reset_level() def beat_level(self): pygame.time.delay(2000) self.change_level(1) self.change_lives(1) self.increase_rows(2) self.create_blocks() self.reset_level() def play_game(self): self.menu = False self.run = True self.main_game() def quit_game(self): quit() def redraw_window(self): Game.WIN.fill(black) for b in Block.blocks: b.draw() self.the_paddle.draw() self.the_ball.draw() self.left_boundary.draw() self.right_boundary.draw() self.top_boundary.draw() self.score_text.draw() self.lives_text.draw() self.level_text.draw() def reset_level(self): self.the_ball.reset_ball() self.the_paddle.x = Game.WIDTH / 2 - Game.WIDTH / 10 / 2 def reset_game(self): self.score = 11111 self.lives = 5 self.level = 9 self.level_text.create_text("LEVEL: " + str(self.level)) self.score_text.create_text("SCORE: " + str(self.score)) self.lives_text.create_text("LIVES: " + str(self.lives)) self.rows = 17 def lose(self): Game.WIN.fill(black) loser_text = TextGUI(Game.WIDTH // 4, Game.HEIGHT // 2, Game.WIN, random.choice(all_taunts), 50) loser_text.draw() self.reset_game() pygame.display.flip() pygame.time.delay(5000) self.main_menu() def win(self): loser_text = TextGUI(Game.WIDTH // 2 - Game.WIDTH // 4, Game.HEIGHT // 2, Game.WIN, "YOU WIN!!!", 100) loser_text.draw() self.reset_game() pygame.display.flip() pygame.time.delay(3000) self.main_menu() def main_game(self): self.reset_game() self.reset_level() self.create_blocks() clock = pygame.time.Clock() while self.run: clock.tick(Game.FPS) self.redraw_window() for event in pygame.event.get(): if event.type == pygame.QUIT: quit() keys = pygame.key.get_pressed() if keys[pygame.K_a] and self.the_paddle.x > 0 + Game.OFFSET_X // 2: self.the_paddle.move_left() if keys[pygame. K_d] and self.the_paddle.x < Game.WIDTH - self.the_paddle.w - Game.OFFSET_X // 2: self.the_paddle.move_right() if keys[pygame.K_SPACE]: quit() if self.the_ball.y - self.the_ball.radius < 0 + Game.OFFSET_Y: self.the_ball.bounce_y() if self.the_ball.x + self.the_ball.radius > Game.WIDTH - Game.OFFSET_X / 2 or self.the_ball.x - self.the_ball.radius < 0 + Game.OFFSET_X / 2: self.the_ball.bounce_x() if self.the_ball.y > Game.HEIGHT: self.lost_level() for block in Block.blocks: if self.the_ball.y + self.the_ball.radius > block.y and self.the_ball.y - self.the_ball.radius < block.y + block.h: if self.the_ball.x + self.the_ball.radius > block.x and self.the_ball.x - self.the_ball.radius < block.x + block.w: self.break_block(block) if self.the_ball.y + self.the_ball.radius > self.the_paddle.y and self.the_ball.y - self.the_ball.radius < self.the_paddle.y + self.the_paddle.h: if self.the_ball.x + self.the_ball.radius > self.the_paddle.x and self.the_ball.x - self.the_ball.radius < self.the_paddle.x + self.the_paddle.w: if self.the_ball.x < self.the_paddle.x + self.the_paddle.w / 2: normalized_ball_x = (self.the_ball.x - self.the_paddle.x) * -1 elif self.the_ball.x >= self.the_paddle.x + self.the_paddle.w / 2: normalized_ball_x = abs(self.the_ball.x - self.the_paddle.x - self.the_paddle.w) else: normalized_ball_x = (self.the_ball.x - self.the_paddle.x) * -1 contact_point_fraction = (normalized_ball_x / self.the_paddle.w) + .0001 regularized_fraction = int(1 / contact_point_fraction / 1.5) self.the_ball.x_velocity += regularized_fraction self.the_ball.bounce_y() if Block.blocks == []: if self.level == 10: self.run = False self.menu = True self.win() else: self.beat_level() if self.lives == 0: self.run = False self.menu = True self.lose() self.the_ball.move_ball() pygame.display.flip() def main_menu(self): button_width = int(Game.WIDTH / 6) button_height = int(Game.HEIGHT / 10) title = TextGUI(Game.WIDTH // 2 - Game.WIDTH // 10 * 2, Game.HEIGHT // 3, Game.WIN, "BREAKOUT", Game.WIDTH // 20) play_button = Button(int(Game.WIDTH / 6 * 2 - button_width / 2), int(Game.HEIGHT / 3 * 2 - button_height), button_width, button_height, random.choice([purple, orange]), Game.WIN, "PLAY", Game.WIDTH // 60, self.play_game) quit_button = Button(int(Game.WIDTH / 6 * 4 - button_width / 2), int(Game.HEIGHT / 3 * 2 - button_height), button_width, button_height, red, Game.WIN, "QUIT", Game.WIDTH // 60, self.quit_game) clock = pygame.time.Clock() while self.menu: clock.tick(Game.FPS) Game.WIN.fill(black) Mouse_x, Mouse_y = pygame.mouse.get_pos() title.draw() play_button.draw(Mouse_x, Mouse_y) play_button.button_text.draw() quit_button.draw(Mouse_x, Mouse_y) quit_button.button_text.draw() for event in pygame.event.get(): if event.type == pygame.QUIT: quit() pygame.display.flip()
class Pong(arcade.Window): """ This class handles all the game callbacks and interaction It assumes the following classes exist: Point Velocity Ball Paddle This class will then call the appropriate functions of each of the above classes. You are welcome to modify anything in this class, but should not have to if you don't want to. """ def __init__(self, width, height): """ Sets up the initial conditions of the game :param width: Screen width :param height: Screen height """ super().__init__(width, height) self.ball = Ball() self.paddle = Paddle() self.score = 0 # These are used to see if the user is # holding down the arrow keys self.holding_left = False self.holding_right = False arcade.set_background_color(arcade.color.WHITE) def on_draw(self): """ Called automatically by the arcade framework. Handles the responsiblity of drawing all elements. """ # clear the screen to begin drawing arcade.start_render() # draw each object self.ball.draw() self.paddle.draw() self.draw_score() def draw_score(self): """ Puts the current score on the screen """ score_text = "Score: {}".format(self.score) start_x = 10 start_y = SCREEN_HEIGHT - 20 arcade.draw_text(score_text, start_x=start_x, start_y=start_y, font_size=12, color=arcade.color.NAVY_BLUE) def update(self, delta_time): """ Update each object in the game. :param delta_time: tells us how much time has actually elapsed """ # Move the ball forward one element in time self.ball.advance() # Check to see if keys are being held, and then # take appropriate action self.check_keys() # check for ball at important places self.check_miss() self.check_hit() self.check_bounce() def check_hit(self): """ Checks to see if the ball has hit the paddle and if so, calls its bounce method. :return: """ too_close_x = (PADDLE_WIDTH / 2) + BALL_RADIUS too_close_y = (PADDLE_HEIGHT / 2) + BALL_RADIUS if (abs(self.ball.center.x - self.paddle.center.x) < too_close_x and abs(self.ball.center.y - self.paddle.center.y) < too_close_y and self.ball.velocity.dx > 0): # we are too close and moving right, this is a hit! self.ball.bounce_horizontal() self.score += SCORE_HIT def check_miss(self): """ Checks to see if the ball went past the paddle and if so, restarts it. """ if self.ball.center.x > SCREEN_WIDTH: # We missed! self.score -= SCORE_MISS self.ball.restart() def check_bounce(self): """ Checks to see if the ball has hit the borders of the screen and if so, calls its bounce methods. """ if self.ball.center.x < 0 and self.ball.velocity.dx < 0: self.ball.bounce_horizontal() if self.ball.center.y < 0 and self.ball.velocity.dy < 0: self.ball.bounce_vertical() if self.ball.center.y > SCREEN_HEIGHT and self.ball.velocity.dy > 0: self.ball.bounce_vertical() def check_keys(self): """ Checks to see if the user is holding down an arrow key, and if so, takes appropriate action. """ if self.holding_left: self.paddle.move_down() if self.holding_right: self.paddle.move_up() def on_key_press(self, key, key_modifiers): """ Called when a key is pressed. Sets the state of holding an arrow key. :param key: The key that was pressed :param key_modifiers: Things like shift, ctrl, etc """ if key == arcade.key.LEFT or key == arcade.key.DOWN: self.holding_left = True if key == arcade.key.RIGHT or key == arcade.key.UP: self.holding_right = True def on_key_release(self, key, key_modifiers): """ Called when a key is released. Sets the state of the arrow key as being not held anymore. :param key: The key that was pressed :param key_modifiers: Things like shift, ctrl, etc """ if key == arcade.key.LEFT or key == arcade.key.DOWN: self.holding_left = False if key == arcade.key.RIGHT or key == arcade.key.UP: self.holding_right = False
class Game(object): """Main program""" def __init__(self): #Initialize pygame and window pygame.init() self.screen_width, self.screen_height = 400, 600 self.screen = pygame.display.set_mode((self.screen_width, self.screen_height), 0, 32) self.screen.fill(blue) pygame.display.update() #Clock self.clock = pygame.time.Clock() #Bricks self.blocks = list() for w in range(1,self.screen_width,50): for h in range(23, 198, 22): self.blocks.append(Block(self.screen_width, self.screen_height, w, h, orange, blue_shadow)) #Paddle self.paddle = Paddle(self.screen_width, self.screen_height, purple, blue_shadow) #Ball self.ball = Ball(self.screen_width, self.screen_height, green, blue_shadow) def update(self): self.clock.tick(game_speed) self.paddle.update() self.ball.update(self.paddle) def draw(self): #Redraw Background self.screen.fill(blue) for block in self.blocks: block.draw_shadow(self.screen) self.ball.draw_shadow(self.screen) self.paddle.draw_shadow(self.screen) for block in self.blocks: block.draw(self.screen) self.ball.draw(self.screen) self.paddle.draw(self.screen) def new_game(self): self.game_over = False self.round = 0 self.play() def new_round(self): pass def play(self): while not self.game_over: for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() if event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: self.ball.serve() if event.key == pygame.K_LEFT: self.paddle.x_vel = -4 elif event.key == pygame.K_RIGHT: self.paddle.x_vel = 4 if event.type == pygame.KEYUP: if event.key == pygame.K_LEFT and self.paddle.x_vel < 0: self.paddle.x_vel = 0 if event.key == pygame.K_RIGHT and self.paddle.x_vel > 0: self.paddle.x_vel = 0 self.update() self.draw() pygame.display.update()
class PongGame: window_width = 650 window_height = 500 def __init__(self, four_player=False): self.ball = Ball(PongGame.window_width / 2, PongGame.window_height / 2) self.paddle1 = NNPaddle(PongGame.window_width - 50, PongGame.window_height / 2, self.ball, self) self.paddle2 = AIPaddle(50, PongGame.window_height / 2, self.ball, self) self.paddle3 = None self.paddle4 = None self.temp_paddle = None self.four_player = four_player self.winner = None self.game_over = False self.speed = 1000 self.scores = [0, 0] self.timeout = 0 self.pause = False if self.four_player: PongGame.window_width = 650 PongGame.window_height = 650 self.ball = Ball(PongGame.window_width / 2, PongGame.window_height / 2) self.scores = [0, 0, 0, 0] self.paddle1 = NNPaddle(PongGame.window_width - 50, PongGame.window_height / 2, self.ball, self, True) self.paddle2 = NNPaddle(50, PongGame.window_height / 2, self.ball, self, True) self.paddle3 = SidewaysNNPaddle(PongGame.window_width / 2, PongGame.window_height - 50, self.ball, self) self.paddle4 = SidewaysNNPaddle(PongGame.window_width / 2, 50, self.ball, self) def start_game(self): pygame.init() clock = pygame.time.Clock() display = pygame.display.set_mode( (PongGame.window_width, PongGame.window_height)) pygame.display.set_caption('Neural Net Pong') while not self.game_over: delta = clock.tick(60) / self.speed display.fill((255, 255, 255)) # listen for events for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() # check for user input self.handle_input(delta) if not self.four_player: self.game_over = self.handle_off_screen() else: self.game_over = self.handle_off_screen_four_player() if not self.game_over: self.handle_collisions() self.paddle1.follow_ball(delta) self.paddle2.follow_ball(delta) if self.paddle3 is not None and self.paddle4 is not None: self.paddle3.follow_ball(delta) self.paddle4.follow_ball(delta) self.ball.move(delta) self.draw(display) if self.timeout < 100: self.timeout += 1 if self.pause: self.reset() pygame.display.flip() def draw(self, display): self.paddle1.draw(display) self.paddle2.draw(display) if self.paddle3 is not None and self.paddle4 is not None: self.paddle3.draw(display) self.paddle4.draw(display) self.ball.draw(display) self.draw_scoreboard(display) def draw_scoreboard(self, display): font = pygame.font.Font(None, 25) if not self.four_player: score = font.render( self.paddle2.name + ' | ' + str(self.scores[1]) + ' - ' + str(self.scores[0]) + ' | ' + self.paddle1.name, True, (0, 0, 0)) info = font.render('Generation ' + str(self.paddle1.generation), True, (0, 0, 0)) rect = score.get_rect(center=(325, 60)) info_rect = info.get_rect(center=(325, 90)) display.blit(score, rect) display.blit(info, info_rect) else: score1 = font.render( self.paddle2.name + ' | ' + str(self.scores[1]) + ' - ' + str(self.scores[0]) + ' | ' + self.paddle1.name, True, (0, 0, 0)) score2 = font.render( self.paddle4.name + ' | ' + str(self.scores[3]) + ' - ' + str(self.scores[2]) + ' | ' + self.paddle3.name, True, (0, 0, 0)) rect1 = score1.get_rect(center=(325, 300)) rect2 = score2.get_rect(center=(325, 350)) display.blit(score1, rect1) display.blit(score2, rect2) def handle_input(self, delta): # listen for key presses keys = pygame.key.get_pressed() if keys[pygame.K_UP] and self.paddle2.bounds.y > 0: self.paddle2.move_up(delta) if keys[pygame. K_DOWN] and self.paddle2.bounds.y + self.paddle2.bounds.height < PongGame.window_height: self.paddle2.move_down(delta) if keys[pygame.K_RIGHT] and self.speed > 10: self.speed -= 10 if keys[pygame.K_LEFT] and self.speed < 1000000: self.speed += 10 if keys[pygame.K_r]: self.reset() if keys[pygame.K_SPACE] and self.timeout == 100: self.timeout = 0 if self.paddle2.name != 'Player': self.temp_paddle = self.paddle2 self.paddle2 = Paddle(50, PongGame.window_height / 2) self.paddle2.score = self.scores[0] else: self.paddle2 = self.temp_paddle if keys[pygame.K_p] and self.timeout == 100: if not self.pause: self.pause = True else: self.pause = False def handle_collisions(self): # collision with paddle if self.ball.intersects_paddle(self.paddle2, self.paddle1): self.ball.vel_x = -self.ball.vel_x self.ball.vel_x *= 1.05 self.ball.vel_y *= 1.05 elif self.four_player and self.ball.intersects_top_paddle( self.paddle4, self.paddle3): self.ball.vel_y = -self.ball.vel_y self.ball.vel_x *= 1.05 self.ball.vel_y *= 1.05 # collision with ceiling if not self.four_player: if (self.ball.bounds.y <= 0 and self.ball.vel_y < 0) or ( self.ball.bounds.y + self.ball.bounds.height >= PongGame.window_height and self.ball.vel_y > 0): self.ball.vel_y = -self.ball.vel_y def handle_off_screen_four_player(self): if self.paddle1.score >= 6: self.winner = self.paddle1 return True elif self.paddle2.score >= 6: self.winner = self.paddle2 return True elif self.paddle3.score >= 6: self.winner = self.paddle3 return True elif self.paddle4.score >= 6: self.winner = self.paddle4 return True if self.ball.bounds.x + self.ball.bounds.width > PongGame.window_width or self.ball.bounds.x <= 0: self.point_scored() elif self.ball.bounds.y + self.ball.bounds.height > PongGame.window_height or self.ball.bounds.y <= 0: self.point_scored() return False def point_scored(self): if self.ball.last_hit is not None: if self.ball.last_hit == self.paddle1: self.scores[0] += 1 self.paddle1.score += 1 elif self.ball.last_hit == self.paddle2: self.scores[1] += 1 self.paddle2.score += 1 elif self.ball.last_hit == self.paddle3: self.scores[2] += 1 self.paddle2.score += 1 elif self.ball.last_hit == self.paddle4: self.scores[3] += 1 self.paddle3.score += 1 self.ball = Ball(PongGame.window_width / 2, PongGame.window_height / 2) self.paddle1.reset(PongGame.window_width - 50, PongGame.window_height / 2, self.ball) self.paddle2.reset(50, PongGame.window_height / 2, self.ball) self.paddle3.reset(PongGame.window_width / 2, PongGame.window_height - 50, self.ball) self.paddle4.reset(PongGame.window_width / 2, 50, self.ball) def handle_off_screen(self): if self.paddle1.score >= 3: self.winner = self.paddle1 return True elif self.paddle2.score >= 3: self.winner = self.paddle2 return True if self.ball.bounds.x + self.ball.bounds.width > PongGame.window_width or self.ball.bounds.x <= 0: if self.ball.bounds.x <= 0: self.paddle1.score += 1 self.paddle1.fitness += 10 self.scores[0] += 1 else: self.paddle2.score += 1 self.paddle2.fitness += 10 self.scores[1] += 1 self.ball = Ball(PongGame.window_width / 2, PongGame.window_height / 2) self.paddle1.reset(PongGame.window_width - 50, PongGame.window_height / 2, self.ball) self.paddle2.reset(50, PongGame.window_height / 2, self.ball) return False def reset(self): self.ball.reset() self.paddle1.reset(PongGame.window_width - 50, PongGame.window_height / 2, self.ball) self.paddle1.fitness = 0 self.paddle1.contacts_ball = 0 self.paddle1.score = 0 self.paddle2.reset(50, PongGame.window_height / 2, self.ball) self.paddle2.score = 0 self.scores = [0, 0]
class Game(object): def __init__(self): self.ended = False self.paused = False self.keys = keyboard.Listener() self.player = Paddle() self.scores = Scoreboard((0, 20 * config.sprite_size), 57) border_graphics(graphic_group) demo_blocks(blocks.group) def draw(self, screen): screen.fill((0, 0, 0)) graphic_group.draw(screen) blocks.group.draw(screen) balls.group.draw(screen) self.scores.draw(screen) self.player.draw(screen) def update(self, time): self.keys.update() if self.paused: if self.keys[keyboard.M.SPC]: self.paused = False else: if self.keys[keyboard.M.SPC]: self.paused = True x_dir = self.keys[keyboard.M.RGT] x_dir -= self.keys[keyboard.M.LFT] self.player.update(time, x_dir, self.keys[keyboard.M.UP] - 0) balls.group.update(time, blocks.group) """ for key, value in block_collisions.iteritems(): if value == None: continue for block in value: # determine if ball bounces off vertically or horizontally d = vector.Vector2D(key.pos.x, key.pos.y) d.x -= block.rect.x d.y -= block.rect.y if d.x ** 2 < d.y ** 2: key.bounceX() else: key.bounceY() # destroy block del block config.sounds['beep.wav'].play() """ # update balls # update blocks self.scores.update() if self.keys[keyboard.M.ESC]: self.end() return self.ended def end(self): self.ended = True
from paddle import Paddle from inputs import handle_input TICK_RATE = 30 screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) pygame.display.set_caption("Pygame Pong Game") clock = pygame.time.Clock() done = [False] ball = Ball() left_paddle = Paddle() left_paddle.rect.x = left_paddle.rect.x + 20 right_paddle = Paddle() right_paddle.rect.x = SCREEN_WIDTH - right_paddle.rect.width while not done[0]: clock.tick(TICK_RATE) for event in pygame.event.get(): if event.type == pygame.QUIT: done = True handle_input(left_paddle, right_paddle) screen.fill(BLACK) ball.draw(screen) ball.update(left_paddle, right_paddle, done) left_paddle.draw(screen) right_paddle.draw(screen) pygame.display.flip() pygame.quit()
class PongGame: # Class Variables WIDTH = 1000 GAME_HEIGHT = 600 BORDER = 15 PADDLE_SPACING = 50 # Space between edge of paddle and end of screen FPS = 60 BOTTOM_HEIGHT = 100 GAME_TEXT_LOC = (WIDTH // 2 - 100, 25) SCORE_LOC = (30, GAME_HEIGHT + BORDER + 20) def __init__(self): self.screen = pygame.display.set_mode( (self.WIDTH, self.GAME_HEIGHT + self.BOTTOM_HEIGHT)) self.ball = Ball(self.screen, (self.WIDTH // 2, self.GAME_HEIGHT // 2)) right_paddle_pos = (self.WIDTH - (self.PADDLE_SPACING + Paddle.WIDTH), self.GAME_HEIGHT // 2 - Paddle.HEIGHT // 2) left_paddle_pos = (self.PADDLE_SPACING, self.GAME_HEIGHT // 2 - Paddle.HEIGHT // 2) self.right_paddle = Paddle(self.screen, right_paddle_pos, RIGHT_PADDLE_COLOR, RIGHT_PADDLE_SPEED) self.left_paddle = AIPaddle(self.screen, left_paddle_pos, LEFT_PADDLE_COLOR, LEFT_PADDLE_SPEED) self.score = 0 pygame.display.set_caption(f"Pong - Level {self.score + 1}") def draw_game(self): self.right_paddle.draw() self.left_paddle.draw() self.ball.draw() self.draw_border() self.display_score() def display_score(self): """ Updates score in bottom section. """ pygame.draw.rect(self.screen, BG_COLOR, (self.SCORE_LOC[0], self.SCORE_LOC[1], 200, 40)) pygame.font.init() font = pygame.font.SysFont('calibri', 30) score_text_surface = font.render(f"Score: {self.score}", 1, TEXT_COLOR) self.screen.blit(score_text_surface, self.SCORE_LOC) def draw_border(self): pygame.draw.rect(self.screen, BORDER_COLOR, (0, 0, self.WIDTH, self.BORDER)) pygame.draw.rect( self.screen, BORDER_COLOR, (0, self.GAME_HEIGHT - self.BORDER, self.WIDTH, self.BORDER)) def move_player(self, dir: str, dt: int): if dir == 'up': dir_vec = -1 elif dir == 'down': dir_vec = 1 else: dir_vec = 0 new_y = self.right_paddle.y + round( dir_vec * self.right_paddle.speed * dt) if new_y < self.BORDER: new_y = self.BORDER elif new_y > (self.GAME_HEIGHT - self.BORDER - Paddle.HEIGHT): new_y = self.GAME_HEIGHT - self.BORDER - Paddle.HEIGHT self.right_paddle.update(new_y) def move_ai(self, dt: int): self.left_paddle.check_fail() # If the AI is not failed, paddle moves towards ball if self.left_paddle.is_failed == False: # Move towards the ball if the ball y coordinate is outside the range of the paddle if 0 <= self.ball.x < round(self.WIDTH * (2 / 5)): if self.ball.y - (self.left_paddle.y + Paddle.HEIGHT // 2) < ( -1 * Paddle.HEIGHT // 2): dir_vec = -1 elif self.ball.y - (self.left_paddle.y + Paddle.HEIGHT // 2) > (Paddle.HEIGHT // 2): dir_vec = 1 else: dir_vec = 0 new_y = self.left_paddle.y + round( dir_vec * self.left_paddle.speed * dt) if new_y < self.BORDER: new_y = self.BORDER elif new_y > (self.GAME_HEIGHT - self.BORDER - Paddle.HEIGHT): new_y = self.GAME_HEIGHT - self.BORDER - Paddle.HEIGHT self.left_paddle.update(new_y) # Only move towards the ball if y coordinate is over threshold distance away from paddle center elif round(self.WIDTH * (2 / 5)) <= self.ball.x < self.WIDTH: threshold = 2 * Paddle.HEIGHT if self.ball.y - (self.left_paddle.y + Paddle.HEIGHT // 2) < ( -1 * threshold): dir_vec = -1 elif self.ball.y - (self.left_paddle.y + Paddle.HEIGHT // 2) > (threshold): dir_vec = 1 else: dir_vec = 0 new_y = self.left_paddle.y + round( dir_vec * self.left_paddle.speed * dt) if new_y < self.BORDER: new_y = self.BORDER elif new_y > (self.GAME_HEIGHT - self.BORDER - Paddle.HEIGHT): new_y = self.GAME_HEIGHT - self.BORDER - Paddle.HEIGHT self.left_paddle.update(new_y) def move_ball(self, dt: int): new_x = self.ball.x + round( self.ball.direction.value[0] * self.ball.speed * dt) new_y = self.ball.y + round( self.ball.direction.value[1] * self.ball.speed * dt) if new_y <= (self.BORDER + Ball.RADIUS): new_y = self.BORDER + Ball.RADIUS self.ball_collide('top') elif new_y >= (self.GAME_HEIGHT - self.BORDER - Ball.RADIUS): new_y = self.GAME_HEIGHT - self.BORDER - Ball.RADIUS self.ball_collide('bottom') elif (self.right_paddle.x - Ball.RADIUS) <= new_x < ( self.right_paddle.x + Paddle.WIDTH + Ball.RADIUS): if self.right_paddle.y - Ball.RADIUS <= new_y <= self.right_paddle.y + Paddle.HEIGHT + Ball.RADIUS: new_x = self.right_paddle.x - Ball.RADIUS self.ball_collide('right') elif (self.left_paddle.x - Ball.RADIUS) <= new_x < ( self.left_paddle.x + Paddle.WIDTH + Ball.RADIUS): if self.left_paddle.y - Ball.RADIUS <= new_y <= self.left_paddle.y + Paddle.HEIGHT + Ball.RADIUS: new_x = self.left_paddle.x + Paddle.WIDTH + Ball.RADIUS self.ball_collide('left') self.ball.update((new_x, new_y)) def ball_collide(self, collision_loc: str): """ """ if collision_loc == 'top': if self.ball.direction == Directions.UP_LEFT: self.ball.change_direction(Directions.DOWN_LEFT) elif self.ball.direction == Directions.UP_RIGHT: self.ball.change_direction(Directions.DOWN_RIGHT) elif collision_loc == 'bottom': if self.ball.direction == Directions.DOWN_LEFT: self.ball.change_direction(Directions.UP_LEFT) elif self.ball.direction == Directions.DOWN_RIGHT: self.ball.change_direction(Directions.UP_RIGHT) elif collision_loc == 'right': if self.ball.direction == Directions.DOWN_RIGHT: self.ball.change_direction(Directions.DOWN_LEFT) elif self.ball.direction == Directions.UP_RIGHT: self.ball.change_direction(Directions.UP_LEFT) elif collision_loc == 'left': if self.ball.direction == Directions.DOWN_LEFT: self.ball.change_direction(Directions.DOWN_RIGHT) elif self.ball.direction == Directions.UP_LEFT: self.ball.change_direction(Directions.UP_RIGHT) else: raise ValueError(f"Invalid direction: {collision_loc}") def score_goal(self): """ Updates the score and resets the ball and paddles to the middle. """ self.score += 1 self.left_paddle.update_prob(self.score) # Display Score pygame.font.init() font = pygame.font.SysFont('calibri', 50) score_text_surface = font.render(f"Score: {self.score}", 1, TEXT_COLOR) self.screen.blit(score_text_surface, self.GAME_TEXT_LOC) self.display_score() self.ball.update((self.WIDTH // 2, self.GAME_HEIGHT // 2)) self.ball.change_direction(random.choice(list(Directions))) self.left_paddle.update(self.GAME_HEIGHT // 2 - self.left_paddle.HEIGHT // 2) self.right_paddle.update(self.GAME_HEIGHT // 2 - self.right_paddle.HEIGHT // 2) def lose(self): """ Displays 'You Lose' and freezes the game. """ paused = True # Display "You Lose!" pygame.font.init() font = pygame.font.SysFont('calibri', 50) lose_text_surface = font.render("You Lose!", 1, TEXT_COLOR) score_text_surface = font.render(f"Score: {self.score}", 1, TEXT_COLOR) self.screen.blit(lose_text_surface, self.GAME_TEXT_LOC) x, y = self.GAME_TEXT_LOC self.screen.blit(score_text_surface, (x + 15, y + 60)) pygame.display.update() while paused: for event in pygame.event.get(): if event.type == pygame.QUIT: paused = False #TODO: ask to start new game return False def run(self): clock = pygame.time.Clock() running = True frozen = False frames_frozen = 0 freeze_length = self.FPS * 4 # frames in 4 seconds while running: dt = clock.tick(self.FPS) for event in pygame.event.get(): if event.type == pygame.QUIT: running = False if not frozen: keys = pygame.key.get_pressed() if keys[pygame.K_UP]: self.move_player('up', dt) elif keys[pygame.K_DOWN]: self.move_player('down', dt) self.move_ball(dt) self.move_ai(dt) if self.ball.x <= 0: frozen = True self.score_goal() elif self.ball.x >= self.WIDTH: running = self.lose() else: frames_frozen += 1 if frames_frozen == freeze_length: frozen = False frames_frozen = 0 pygame.draw.rect(self.screen, BG_COLOR, (self.GAME_TEXT_LOC[0], self.GAME_TEXT_LOC[1], 200, 50)) pygame.display.update() pygame.quit()
class Level: # pylint: disable=too-many-instance-attributes """ Class representing a level. It keeps track of all sprites: balls, the paddle, tiles, explosions and bonuses. """ sounds = { "death": pygame.mixer.Sound(os.path.join("sounds", "death.wav")), "next_level": pygame.mixer.Sound(os.path.join("sounds", "next_level.wav")), } def __init__(self, n): self.paddle = Paddle() self.balls = pygame.sprite.Group() ball = Ball() self.balls.add(ball) self.paddle.attached_balls.add(ball) self.tile_matrix = [[None for _ in range(16)] for _ in range(16)] self.tiles = pygame.sprite.Group() if n != 0: # case n = 0 is used for testing with open(os.path.join("levels", f"{n}.pkl"), "rb") as file: file = pickle.load(file) for line in file.split("\n"): try: j, i, alias = line.split() if alias not in Tile.types: raise RuntimeError(f"invalid tile type: {alias}") i, j = int(i), int(j) tile = Tile.types[alias](MARGIN + 60 * i, 3 * MARGIN + 30 * j) self.tile_matrix[i][j] = tile self.tiles.add(tile) except (TypeError, ValueError): pass self.bonuses = pygame.sprite.Group() self.explosions = pygame.sprite.Group() self.n = n self.finished = False self.paused = False Ball.reset_state() def draw(self, surface): # draw all sprites self.explosions.draw(surface) self.paddle.draw(surface) self.balls.draw(surface) self.tiles.draw(surface) self.bonuses.draw(surface) # conditional text if self.finished: message = "Level Cleared!" text = message_font.render(message, True, pygame.Color("white")) w, h = text.get_size() x, y = (SCREEN_WIDTH - w) // 2, (SCREEN_HEIGHT - h) // 2 surface.blit(text, (x, y)) elif self.paused: text = message_font.render("Pause", True, pygame.Color("white")) w, h = text.get_size() x, y = (SCREEN_WIDTH - w) // 2, (SCREEN_HEIGHT - h) // 2 surface.blit(text, (x, y)) def update(self): """ Updates the postions of all sprites. """ self.paddle.update(paused=self.finished or self.paused) if not (self.finished or self.paused): self.balls.update() self.bonuses.update() if not self.balls: pygame.event.post(pygame.event.Event(events.DEATH)) elif all(isinstance(tile, Brick) for tile in self.tiles): self.finished = True self.sounds["next_level"].play() else: self.detect_collisions() self.explosions.update() def detect_collisions(self): """ Detects sprite collisions. """ # paddle vs. balls for ball in pygame.sprite.spritecollide(self.paddle, self.balls, False): ball.on_hit(self.paddle) # paddle vs. bonuses for bonus in pygame.sprite.spritecollide(self.paddle, self.bonuses, True): bonus.on_collect() # balls vs. tiles for ball in self.balls: for tile in pygame.sprite.spritecollide(ball, self.tiles, False): ball.hit(tile) break def explosion(self, x, y): """ Trigerred when an explosion occurs. Destoys all tiles around the explosion center. """ i, j = (x - MARGIN) // 60, (y - 3 * MARGIN) // 30 for k in range(-1, 2): for l in range(-1, 2): try: tile = self.tile_matrix[i + k][j + l] x, y = MARGIN + 60 * (i + k) + 30, 3 * MARGIN + 30 * ( j + l) + 15 if MARGIN < x <= SCREEN_WIDTH - MARGIN: mute = not (k == 0 and l == 0) self.explosions.add(Explosion(x, y, mute=mute)) if tile.alive(): tile.kill() except (AttributeError, IndexError): pass def on_death(self): """ Triggered when player loses all balls. """ if self.n != 0: self.sounds["death"].play() time.sleep(1) Ball.reset_state() # refresh paddle, ball, delete bonuses self.bonuses.empty() self.paddle = Paddle() self.balls.empty() ball = Ball() self.balls.add(ball) self.paddle.attached_balls.add(ball)
class Breakout(object): def __init__(self): # Initilaize pygame and the display/window pygame.init() self.screen_width, self.screen_height = 600, 800 self.screen = pygame.display.set_mode((self.screen_width, self.screen_height)) # , pygame.FULLSCREEN) pygame.display.set_caption('Breakout') # Create the game objects self.paddle = Paddle(self.screen_width, self.screen_height) self.ball = Ball(self.screen_width, self.screen_height) self.bricks = list() for i in range(0,600,60): for j in range(42, 211, 42): self.bricks.append(Brick(self.screen_width, self.screen_height, i, j)) # Let's control the frame rate self.clock = pygame.time.Clock() def new_game(self): """Start a new game of Breakout. Resets all game-level parameters, and starts a new round. """ self.game_over = False self.round = 0 self.paddle.reset() self.new_round() def new_round(self): """Start a new round in a Breakout game. Resets all round-level parameters, increments the round counter, and puts the ball on the paddle. """ self.round += 1 self.ball.reset(self.paddle) def play(self): """Start Breakout program. New game is started and game loop is entered. The game loop checks for events, updates all objects, and then draws all the objects. """ self.new_game() while not self.game_over: # Game loop self.clock.tick(50) # Frame rate control font = pygame.font.SysFont("monospace", 15) round_counter = font.render("Round " + str(self.round), 2, (255,255,0)) for event in pygame.event.get(): if event.type == pygame.QUIT or event.type == pygame.MOUSEBUTTONDOWN: self.game_over = True break if event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: self.ball.serve() if event.key == pygame.K_LEFT: self.paddle.x_velocity = -4 elif event.key == pygame.K_RIGHT: self.paddle.x_velocity = 4 if event.key == pygame.K_a: self.ball.x_velocity = -3 elif event.key == pygame.K_d: self.ball.x_velocity = 3 # This starts a new round, it's only here for debugging purposes if event.key == pygame.K_r: self.new_round() # This starts a new game, it's only here for debugging purposes if event.key == pygame.K_g: self.new_game() if event.type == pygame.KEYUP: if event.key == pygame.K_LEFT and self.paddle.x_velocity < 0: self.paddle.x_velocity = 0 if event.key == pygame.K_RIGHT and self.paddle.x_velocity > 0: self.paddle.x_velocity = 0 else: self.paddle.update() contact = self.ball.update(self.paddle, self.bricks) for brick in self.bricks: if contact == brick: self.bricks.remove(brick) self.screen.fill((0, 0, 0)) self.screen.blit(round_counter, (0, 0)) ball_loc = font.render(str(self.ball.x) + "," + str(self.ball.y), 2, (255,255,0)) self.screen.blit(ball_loc, (0, 14)) self.paddle.draw(self.screen) self.ball.draw(self.screen) pygame.display.flip() for brick in self.bricks: brick.draw(self.screen) pygame.display.flip() if self.ball.y >= self.screen_height - self.ball.radius: self.new_round() if self.round > 3: self.new_game() pygame.quit()
class PlayState(BaseState): def __init__(self): super().__init__() self.serving_player = 1 self.winner = 1 self.ball_prev_speed = 0 def enter(self, enter_params=None): # Get needed settings self.window_width = Settings.instance().settings['window_width'] self.window_height = Settings.instance().settings['window_height'] self.paddle_width = Settings.instance().settings['paddle_width'] self.paddle_height = Settings.instance().settings['paddle_height'] self.paddle_tolerance_beginner = Settings.instance( ).settings['paddle_tolerance_beginner'] self.paddle_tolerance_Intermediate = Settings.instance( ).settings['paddle_tolerance_Intermediate'] self.paddle_tolerance_expert = Settings.instance( ).settings['paddle_tolerance_expert'] self.ball_speed_increase_beginner = Settings.instance( ).settings['ball_speed_increase_beginner'] self.ball_speed_increase_intermediate = Settings.instance( ).settings['ball_speed_increase_intermediate'] self.ball_speed_increase_expert = Settings.instance( ).settings['ball_speed_increase_expert'] self.paddle_special_hit_threshold = Settings.instance( ).settings['paddle_special_hit_threshold'] self.paddle_special_hit_increase = Settings.instance( ).settings['paddle_special_hit_increase'] self.net_segments = Settings.instance().settings['net_segments'] self.net_segments_gap = Settings.instance( ).settings['net_segments_gap'] self.net_segments_height = Settings.instance( ).settings['net_segments_height'] self.net_segment_width = Settings.instance( ).settings['net_segment_width'] self.win_score = Settings.instance().settings['win_score'] # Save enter parameters self.num_players = enter_params.get('num_players') self.input_device = enter_params.get('input_device') self.difficulty = enter_params.get('difficulty') self.is_demo = enter_params.get('is_demo') if self.is_demo is None: self.is_demo = False # Load Fonts load_font('fonts\\font.ttf', 'small_medium', self.cached_fonts, 32) load_font('fonts\\font.ttf', 'huge', self.cached_fonts, 128) # Load Sounds load_sound('sounds\\paddle_hit.wav', 'paddle_hit', self.cached_sounds) load_sound('sounds\\score.wav', 'score', self.cached_sounds) load_sound('sounds\\wall_hit.wav', 'wall_hit', self.cached_sounds) load_sound('sounds\\paddle_special_hit.wav', 'paddle_special_hit', self.cached_sounds) # Play music play_music(1, self.music) # Create Entites self.ball = Ball(self.window_width // 2, self.window_height // 2, Settings.instance().settings['ball_radius']) self.player1 = Paddle(self.paddle_width // 2, self.paddle_height // 2 + 100, self.paddle_width, self.paddle_height) self.player2 = Paddle( self.window_width - self.paddle_width // 2, self.window_height - self.paddle_height // 2 - 100, self.paddle_width, self.paddle_height) self.ball.set_initial_speed(self.serving_player == 2) # Set tolerance according to difficulty tolerance = random.randint(self.paddle_tolerance_beginner[0], self.paddle_tolerance_beginner[1]) / 100 self.speed_increase = self.ball_speed_increase_beginner if self.difficulty == 'intermediate': tolerance = random.randint( self.paddle_tolerance_Intermediate[0], self.paddle_tolerance_Intermediate[1]) / 100 self.speed_increase = self.ball_speed_increase_intermediate if self.difficulty == 'expert': tolerance = random.randint(self.paddle_tolerance_expert[0], self.paddle_tolerance_expert[1]) / 100 self.speed_increase = self.ball_speed_increase_expert self.player2.set_tolerance(tolerance) # Load particle system self.particle_system = ParticleSystem( self.ball.get_position()[0], self.ball.get_position()[1], ParticleShape.SQUARE, Settings.instance().settings['particle_size'], Settings.instance().settings['particle_birth_rate'], Settings.instance().settings['particle_speed'], Settings.instance().settings['particle_death_age']) gradient = Gradient( Settings.instance().settings['particle_gradient_color_01'], Settings.instance().settings['particle_gradient_last_color']) gradient.add_color( Settings.instance().settings['particle_gradient_color_02'], Settings.instance().settings['particle_gradient_color_02_pos']) gradient.add_color( Settings.instance().settings['particle_gradient_color_03'], Settings.instance().settings['particle_gradient_color_03_pos']) gradient.add_color( Settings.instance().settings['particle_gradient_color_04'], Settings.instance().settings['particle_gradient_color_04_pos']) self.particle_system.set_gradient(gradient) self.particle_system.set_death_variance( Settings.instance().settings['particle_death_variant']) self.particle_system.set_speed_variance( Settings.instance().settings['particle_speed_variant']) def exit(self): pass def handle_events(self, events): for event in events: if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: if not self.is_demo: statemachine.StateMachine.instance().push('game_menu') else: statemachine.StateMachine.instance().set_change( 'main_menu') if event.key == pygame.K_LCTRL: if self.player1.ball_hits >= self.paddle_special_hit_threshold: self.player1.going_to_hit_special = True if event.key == pygame.K_RCTRL: if self.num_players == 2 and self.player2.ball_hits >= self.paddle_special_hit_threshold: self.player2.going_to_hit_special = True def update(self, dt): if not self.is_demo: # Move player/s with keyboard or mouse if self.input_device == 'keyboard': self.on_keypress(dt) else: self.on_mouse_move() # Update player2 if it is a 1 player game if self.num_players == 1: self.player2.update(dt, self.ball) else: self.player1.demo(self.ball) self.player2.demo(self.ball) # Update ball movement self.ball.update(dt) # Check collisions with bounds self.ball_bounds_collision() # Ball collision with player1 if self.ball.collides(self.player1): self.ball_paddle_collision(self.player1) # Ball collision with player2 if self.ball.collides(self.player2): self.ball_paddle_collision(self.player2) self.particle_system.update(dt) self.particle_system.set_position(self.ball.get_position()) if not self.is_demo: # Player 1 scores if self.ball.left() > self.window_width: self.player_scores(self.player1) # Player 2 scores if self.ball.right() < 0: self.player_scores(self.player2) def render(self, render_screen): # draw the net self.draw_net(render_screen) # draw the score draw_text(render_screen, self.cached_fonts['huge'], (255, 255, 255), True, str(self.player1.score), (self.window_width // 4, self.window_height // 4)) draw_text(render_screen, self.cached_fonts['huge'], (255, 255, 255), True, str(self.player2.score), (self.window_width * 3 // 4, self.window_height // 4)) # Draw special hit prompt time = int(pygame.time.get_ticks() / 500) if self.player1.ball_hits == self.paddle_special_hit_threshold: if not self.player1.going_to_hit_special: if time % 2 == 0: draw_text( render_screen, self.cached_fonts['small_medium'], (255, 255, 255), True, 'Press Left Ctrl for a special hit!', (self.window_width * 1 // 4, self.window_height // 10)) else: if time % 2 == 0: draw_text( render_screen, self.cached_fonts['small_medium'], (255, 255, 255), True, 'Hitting special!', (self.window_width * 1 // 4, self.window_height // 10)) if self.num_players == 2 and self.player2.ball_hits == self.paddle_special_hit_threshold: if not self.player2.going_to_hit_special: if time % 2 == 0: draw_text( render_screen, self.cached_fonts['small_medium'], (255, 255, 255), True, 'Press Right Ctrl for a special hit!', (self.window_width * 3 // 4, self.window_height // 10)) else: if time % 2 == 0: draw_text( render_screen, self.cached_fonts['small_medium'], (255, 255, 255), True, 'Hitting special!', (self.window_width * 3 // 4, self.window_height // 10)) # Draw the ball self.ball.draw(render_screen) # Draw the paddles self.player1.draw(render_screen) self.player2.draw(render_screen) self.particle_system.render(render_screen) def draw_net(self, render_screen): start_pos = (self.window_width // 2, 0) end_pos = (start_pos[0], start_pos[1] + self.net_segments_height) pygame.draw.line(render_screen, (255, 255, 255), start_pos, end_pos, self.net_segment_width) for _ in range(1, self.net_segments): start_pos = (end_pos[0], end_pos[1] + self.net_segments_gap) end_pos = (start_pos[0], start_pos[1] + self.net_segments_height) pygame.draw.line(render_screen, (255, 255, 255), start_pos, end_pos, self.net_segment_width) def on_keypress(self, dt): pressed = pygame.key.get_pressed() if pressed[pygame.K_w]: self.player1.move(True, dt) elif pressed[pygame.K_s]: self.player1.move(False, dt) if self.num_players == 2: if pressed[pygame.K_UP]: self.player2.move(True, dt) elif pressed[pygame.K_DOWN]: self.player2.move(False, dt) def on_mouse_move(self): position = pygame.mouse.get_pos() self.player1.set_position(self.player1.get_position()[0], position[1]) def player_scores(self, player): player.score += 1 self.player1.reset_ball_hits() self.player2.reset_ball_hits() if player == self.player1: self.serving_player = 2 else: self.serving_player = 1 self.cached_sounds['score'].play() if player.score == self.win_score: if player == self.player1: self.winner = 1 else: self.winner = 2 statemachine.StateMachine.instance().set_change( 'win', { 'winner': self.winner, 'player1_score': self.player1.score, 'player2_score': self.player2.score }) else: pygame.time.delay(200) self.ball.reset() self.ball.set_initial_speed(self.serving_player == 2) def ball_bounds_collision(self): # Ball collision with upper bound if self.ball.top() <= 0: self.ball.dy = -self.ball.dy self.ball.set_position(self.ball.get_position()[0], self.ball.radius) self.cached_sounds['wall_hit'].play() # Ball collision with lower bound if self.ball.bottom() > self.window_height: self.ball.dy = -self.ball.dy self.ball.set_position(self.ball.get_position()[0], self.window_height - self.ball.radius) self.cached_sounds['wall_hit'].play() def ball_paddle_collision(self, player): # Add a hit to player if player.ball_hits < self.paddle_special_hit_threshold: player.add_ball_hit() # Set the ball position if player == self.player1: self.ball.set_position(player.width + self.ball.radius + 1, self.ball.get_position()[1]) else: self.ball.set_position( self.window_width - player.width - self.ball.radius - 1, self.ball.get_position()[1]) # Calculate the new speed speed = math.sqrt(self.ball.dx**2 + self.ball.dy**2) if self.difficulty == 'beginner': speed *= self.ball_speed_increase_beginner if self.difficulty == 'intermediate': speed *= self.ball_speed_increase_intermediate if self.difficulty == 'expert': speed *= self.ball_speed_increase_expert if player.going_to_hit_special: self.ball_prev_speed = self.ball.speed() speed *= self.paddle_special_hit_increase player.hit_special = True player.going_to_hit_special = False player.reset_ball_hits() self.cached_sounds['paddle_special_hit'].play() opponent = self.player1 if player == self.player1: opponent = self.player2 if opponent.hit_special: speed = self.ball_prev_speed opponent.hit_special = False # Calculate new direction direction_y = min(random.random(), 0.6) if self.ball.get_position()[1] < player.get_position()[1]: direction_y *= -1.0 direction_x = math.sqrt(1 - direction_y**2) if player == self.player2: direction_x *= -1 # Calculate the new velocity self.ball.dx = direction_x * speed self.ball.dy = direction_y * speed # Play the paddle hit sound self.cached_sounds['paddle_hit'].play()
class Pong: def __init__(self): pygame.init() self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN) self.screen_rect = self.screen.get_rect() self.settings = Settings() self.settings.screen_width = self.screen.get_rect().width self.settings.screen_height = self.screen.get_rect().height pygame.display.set_caption("Pong") self.sound = Sound() self.stats = GameStats(self) self.sb = Scoreboard(self) self.play_button = Button(self, "Play") def run_game(self): while True: self._check_events() if self.stats.game_active: self._check_ball_location() self._check_paddle_ball_collision() self._check_bullet_ball_collision() self.left_paddle.update() self.right_paddle.update() self.ball.update() self._update_bullets() self._update_screen() def _create_game_elements(self): self.settings.initialize_dynamic_settings() self.left_paddle = Paddle(self, 'left') self.right_paddle = Paddle(self, 'right') self.ball = Ball(self) self.left_paddle_bullets = pygame.sprite.Group() self.right_paddle_bullets = pygame.sprite.Group() # Store all game sprites in a managable group. self.sprites = pygame.sprite.Group() self.sprites.add(self.left_paddle) self.sprites.add(self.right_paddle) self.sprites.add(self.ball) def _check_events(self): """"Listen for when user presses buttons""" for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == pygame.MOUSEBUTTONDOWN: mouse_pos = pygame.mouse.get_pos() self._check_play_button(mouse_pos) elif event.type == pygame.KEYDOWN: self._check_keydown_events(event) elif event.type == pygame.KEYUP: self._check_keyup_events(event) def _check_play_button(self, mouse_pos): """Start a new game when the player clicks Play.""" button_clicked = self.play_button.rect.collidepoint(mouse_pos) if button_clicked and not self.stats.game_active: self.stats.reset_stats() self.sb.prep_score() self.stats.game_active = True self._create_game_elements() pygame.mouse.set_visible(False) def _check_keydown_events(self, event): # left_paddle keydown events if event.key == pygame.K_e: self.left_paddle.moving_up = True elif event.key == pygame.K_d: self.left_paddle.moving_down = True elif event.key == pygame.K_c: self._fire_bullet(self.left_paddle) # right_paddle keydown events elif event.key == pygame.K_y: self.right_paddle.moving_up = True elif event.key == pygame.K_h: self.right_paddle.moving_down = True elif event.key == pygame.K_n: self._fire_bullet(self.right_paddle) # System keydown events elif event.key == pygame.K_ESCAPE: sys.exit() def _check_keyup_events(self, event): # left_paddle keyup events if event.key == pygame.K_e: self.left_paddle.moving_up = False elif event.key == pygame.K_d: self.left_paddle.moving_down = False # right_paddle keyup events elif event.key == pygame.K_y: self.right_paddle.moving_up = False elif event.key == pygame.K_h: self.right_paddle.moving_down = False def _check_ball_location(self): # Bounces on the top or bottom of the surface if self.ball.rect.bottom >= self.screen_rect.bottom: self._bounce(1) if self.ball.rect.top <= self.screen_rect.top: self._bounce(1) # Scores a goal on the left or right end of the surface if self.ball.rect.x < self.screen_rect.left: self._goal(self.right_paddle) if self.ball.rect.x >= self.screen_rect.right: self._goal(self.left_paddle) def _check_paddle_ball_collision(self): if (pygame.sprite.collide_rect(self.ball, self.left_paddle) or pygame.sprite.collide_rect(self.ball, self.right_paddle)): if self._check_rim_shot(): self._bounce(1) else: self._normal_shot() def _normal_shot(self): self._bounce(0) self._chaos_generator() self.stats.rally_length += 1 if self.stats.rally_length > 0: if self.stats.rally_length % 3 == 0: self.settings.increase_speed() def _check_rim_shot(self): if (self.ball.rect.left < (self.left_paddle.rect.right - 20) or self.ball.rect.right > (self.right_paddle.rect.left + 20)): return True def _bounce(self, axis): self.settings.velocity[axis] *= -1 def _check_bullet_ball_collision(self): """ Bullets make the ball change y velocity. X velocity is modified so that the ball is moving away from the paddle """ left_collided = pygame.sprite.spritecollideany( self.ball, self.left_paddle_bullets) if left_collided: self._ricochet() self.left_paddle_bullets.remove(left_collided) if self.settings.velocity[0] < 0: self._reflect_bullet() right_collided = pygame.sprite.spritecollideany( self.ball, self.right_paddle_bullets) if right_collided: self._ricochet() self.right_paddle_bullets.remove(right_collided) if self.settings.velocity[0] > 0: self._reflect_bullet() def _ricochet(self): if abs(self.settings.velocity[1]) > abs(self.settings.velocity[0]): self.settings.velocity[0] = self.settings.velocity[0] / ( self.settings.velocity[0] / self.settings.velocity[1]) self.settings.velocity[1] = ( self.settings.velocity[1] * (self.settings.velocity[0] / self.settings.velocity[1])) * ( (-1)**randint(2, 3)) else: self.settings.velocity[1] *= -1 self._chaos_generator() self.sound.ricochet() def _reflect_bullet(self): self._bounce(0) def _chaos_generator(self): """ Adjust velocity of ball slightly after paddle/ball collision to make game more interesting """ chaos_index = (randint(-10, 25) / 100) + 1 # Chaos index will be more likely to make y velocity more accute, # otherwise points can go on too long. self.settings.velocity[1] *= chaos_index def _goal(self, paddle): """Respond to the ball getting past a paddle""" if self.left_paddle == paddle: self.stats.score[0] += 1 elif self.right_paddle == paddle: self.stats.score[1] += 1 self.sb.prep_score() self._update_screen() sleep(1) self._check_score() self.sprites.empty() def _fire_bullet(self, paddle): """Create a new bullet and add it to the bullets group""" if self.left_paddle == paddle: if len(self.left_paddle_bullets) < self.settings.bullets_allowed: new_bullet = Bullet(self, self.left_paddle) self.left_paddle_bullets.add(new_bullet) self.sound.fire() if self.right_paddle == paddle: if len(self.right_paddle_bullets) < self.settings.bullets_allowed: new_bullet = Bullet(self, self.right_paddle) self.right_paddle_bullets.add(new_bullet) self.sound.fire() def _update_bullets(self): """Update position of bullets and get rid of old bullets.""" self.left_paddle_bullets.update() self.right_paddle_bullets.update() # Delete old bullets when they leave the screen # Loop through copy of list because not possible to change list # length during a loop for bullet in self.left_paddle_bullets.copy(): if bullet.rect.left >= self.screen_rect.right: self.left_paddle_bullets.remove(bullet) for bullet in self.right_paddle_bullets.copy(): if bullet.rect.right <= self.screen_rect.left: self.right_paddle_bullets.remove(bullet) def _check_score(self): if self.stats.score[0] >= self.settings.play_to or self.stats.score[ 1] >= self.settings.play_to: sleep(3) self.stats.game_active = False pygame.mouse.set_visible(True) self._reset_game() def _reset_game(self): self._create_game_elements() def _update_screen(self): self.screen.fill(self.settings.bg_color) if self.stats.game_active: self.sb.show_score() self.left_paddle.draw() self.right_paddle.draw() self.ball.draw() for bullet in self.left_paddle_bullets.sprites(): bullet.draw_bullet() for bullet in self.right_paddle_bullets.sprites(): bullet.draw_bullet() # Draw play button if game is inactive elif not self.stats.game_active: self.play_button.draw_button() pygame.display.flip()
def run_game(): # Initialize pygame, settings, and screen object. pygame.init() topbot_settings = Settings(True) side_settings = Settings(False) paddlegap = 10 screen = pygame.display.set_mode( (side_settings.screen_width, side_settings.screen_height)) pygame.display.set_caption("Pong AI without walls") # Make the ball ball = Ball(side_settings, screen) balls = pygame.sprite.Group() balls.add() # Make play button play_button = Button(side_settings.screen_width / 2, side_settings.screen_height / 2, side_settings, screen, "Play") # Make menu menu = Menu(side_settings, screen, play_button) # Make player paddles playerPaddle = Paddle(paddlegap, ((side_settings.screen_height / 2) - (side_settings.paddle_length / 2)), side_settings, screen) playertoppaddle = Paddle(((side_settings.screen_width / 4) - (topbot_settings.paddle_width / 2)), 10, topbot_settings, screen) playerbotpaddle = Paddle(((side_settings.screen_width / 4) - (topbot_settings.paddle_width / 2)), (side_settings.screen_height - paddlegap - topbot_settings.paddle_length), topbot_settings, screen) # Make ai/player 2 paddles aiPaddle = Paddle( (side_settings.screen_width - side_settings.paddle_width - paddlegap), ((side_settings.screen_height / 2) - (side_settings.paddle_length / 2)), side_settings, screen) aitop = Paddle( ((side_settings.screen_width - (side_settings.screen_width / 4)) - (topbot_settings.paddle_width / 2)), paddlegap, topbot_settings, screen) aibot = Paddle( ((side_settings.screen_width - (side_settings.screen_width / 4)) - (topbot_settings.paddle_width / 2)), (side_settings.screen_height - paddlegap - topbot_settings.paddle_length), topbot_settings, screen) # TESTING MENU SCREEN HERE menu.makeScreen(side_settings, screen, play_button) # Start the main loop for the game. while True: gf.check_events(side_settings, screen, playerPaddle, playertoppaddle, playerbotpaddle) gf.update_screen(side_settings, screen, playerPaddle, playertoppaddle, playerbotpaddle) # Watch for keyboard and mouse events. for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() # Redraw the screen during each pass through the loop. screen.fill(side_settings.bg_color) # Draw the ball in the middle ball.draw(screen) # Draws player side paddles playerPaddle.draw() playertoppaddle.draw() playerbotpaddle.draw() # Draws ai side paddles aiPaddle.draw() aitop.draw() aibot.draw() # Draws the middle line pygame.draw.line( screen, (250, 250, 250), (side_settings.screen_width / 2, 0), (side_settings.screen_width / 2, side_settings.screen_height)) # Make the most recently drawn screen visible. pygame.display.flip()
def play_level(level, width, height, sounds, fps, score): screen_rect = pygame.Rect(0, 0, width, height) balls = [] balls.append(Ball([0, 0], pi/2, 10, 15)) bricks = load_level(level, width, height) paddle = Paddle(pygame.Rect(100, height-50, 150, 15), width, (255, 255, 255)) clock = pygame.time.Clock() font = pygame.font.Font(None, 48) spare_balls = 3 sticky_paddle = True while True: # Handle events for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() # Limit the loop speed to `fps` frames per second clock.tick(fps) actual_fps = clock.get_fps() dt = (1000.0 / actual_fps) if actual_fps > 0 else 0 # Destroy any balls that reach the bottom balls = [ball for ball in balls if ball.position[1] < height - ball.radius] if len(balls) == 0: # If we have spare balls, use one and create a new ball if spare_balls > 0: spare_balls -= 1 sticky_paddle = True balls.append(Ball([0, 0], pi/2, 10, 15)) else: # Otherwise, we lose :( print("You lose! Score: {}".format(score)) sys.exit(0) # If there are no bricks left (except immortal bricks), you cleared # this level if len([brick for brick in bricks if brick.life > 0]) == 0: print("Level {} cleared.".format(level)) return score # Move the paddle paddle.move(pygame.mouse.get_pos()) if sticky_paddle: balls[0].position[0] = paddle.x balls[0].position[1] = (paddle.y - int(paddle.height/2) - balls[0].radius - 1) balls[0].speed = 0 balls[0].bearing = -pi/2 if pygame.mouse.get_pressed()[0]: balls[0].speed = 10 sticky_paddle = False # Handle all the ball movement and collision for ball in balls: ball.collide_rect_internal(screen_rect) for brick in bricks: if ball.collide_rect_external(brick.rect, invert=brick.invert): brick.hit() sounds['brick'].play() if brick.life != -1: score += 1 if paddle.collide(ball): sounds['paddle'].play() ball.move(dt) # Handle multiballs: for brick in bricks: if brick.multiball and brick.life == 0: # Multiball release! x = brick.rect.left + int(brick.rect.width / 2) y = brick.rect.top + int(brick.rect.height / 2) balls.append(Ball([x, y], 1.0, 10, 15)) # Remove dead bricks bricks = [brick for brick in bricks if brick.alive()] # Blank the screen, draw all the bricks, draw the balls screen.fill((0, 0, 50)) for brick in bricks: brick.draw(screen) for ball in balls: ball.draw(screen) paddle.draw(screen) score_surf = font.render(str(score), 1, (255, 255, 255)) screen.blit(score_surf, (20, 20)) for idx in range(spare_balls): balls[0].draw(screen, (width - 50 - 40*idx, 20)) pygame.display.flip()