class Log_in_page: def __init__(self, bar_width=BAR_WIDTH, bar_height=BAR_HEIGHT, win_width=WIN_WIDTH, win_height=WIN_HEIGHT, play_button_width=PLAY_BUTTON_WIDTH, play_button_height=PLAY_BUTTON_HEIGHT, fb_button_width=WIN_WIDTH * 0.6, fb_button_height=FB_BUTTON_HEIGHT): self.window = GWindow(win_width, win_height, title='Welcome') self.load_bar = GRect(bar_width, bar_height) self.load_label = GLabel('0%') self.solid_bar = GRect(0, bar_height) self.play_button = GRect(play_button_width, play_button_height) self.play_label = GLabel('Start New Game') self.fb_button = GRect(fb_button_width, fb_button_height) self.fb_label = GLabel('continue with facebook') def loading(self): self.download_label = GLabel('downloading') self.solid_bar.color = 'black' self.solid_bar.filled = True self.solid_bar.fill_color = 'black' self.window.add(self.load_bar, (self.window.width - self.load_bar.width) / 2, self.window.height * 0.7) while self.solid_bar.width < self.load_bar.width: self.window.remove(self.solid_bar) self.window.remove(self.load_label) self.solid_bar.width = self.solid_bar.width + 10 if (bar_ratio := (self.solid_bar.width / self.load_bar.width) * 100) < 100: self.load_label.text = f'{int(bar_ratio)} %' else: self.load_label.text = f'100%' self.window.add(self.solid_bar, self.load_bar.x, self.load_bar.y) self.window.add(self.load_label, self.load_bar.x + self.load_bar.width - self.load_label.width, self.load_bar.y + self.load_bar.height + self.load_label.height + 5) if self.solid_bar.width < self.load_bar.width * 0.33: self.download_label.text = 'downloading....' elif self.load_bar.width * 0.25 <= self.solid_bar.width < self.load_bar.width * 0.66: self.download_label.text = 'downloading........' elif self.load_bar.width * 0.5 <= self.solid_bar.width < self.load_bar.width * 0.99: self.download_label.text = 'downloading............' self.window.add(self.download_label, self.load_bar.x, self.load_bar.y + self.load_bar.height + self.load_label.height + 5) pause(100) self.window.remove(self.download_label) self.download_label.text = 'completed!' self.window.add(self.download_label, self.load_bar.x, self.load_bar.y + self.load_bar.height + self.load_label.height + 5)
class BreakoutGraphics: def __init__(self, ball_radius=BALL_RADIUS, paddle_width=PADDLE_WIDTH, paddle_height=PADDLE_HEIGHT, paddle_offset=PADDLE_OFFSET, brick_rows=BRICK_ROWS, brick_cols=BRICK_COLS, brick_width=BRICK_WIDTH, brick_height=BRICK_HEIGHT, brick_offset=BRICK_OFFSET, brick_spacing=BRICK_SPACING, title='Breakout'): # Create a graphical window, with some extra space. window_width = brick_cols * (brick_width + brick_spacing) - brick_spacing window_height = brick_offset + 3 * (brick_rows * (brick_height + brick_spacing) - brick_spacing) self.window = GWindow(width=window_width, height=window_height, title=title) # Create a paddle. self.paddle = GRect(paddle_width, paddle_height) self.paddle.filled = True self.paddle.fill_color = 'black' # set paddle's instance variable self.pad_width = paddle_width self.pad_height = paddle_height self.pad_offset = paddle_offset """ go will be a variable set to 0 or 1 go equal 1 means it's touch paddle already and go to bricks go equals 0 means it's touch bricks and can go back to paddle """ self.go = 0 # set ball's instance variable self.radius = ball_radius # Center a filled ball in the graphical window. self.ball = GOval(2 * self.radius, 2 * self.radius) self.set_ball() # start set_ball method # set brick's instance variable self.bri_width = brick_width self.bri_height = brick_height self.bri_cols = brick_cols self.bri_rows = brick_rows self.bri_spacing = brick_spacing self.bri_offset = brick_offset self.brick = GRect(self.bri_width, self.bri_height) self.tot_brick = brick_rows * brick_cols self.move_brick = 0 # Default initial velocity for the ball. self.__dx = 0 # use to storage the x speed self.__dy = 0 # use to storage the y speed self.dx = self.get_dx() # get the x speed self.dy = self.get_dy() # get the y speed # Initialize our mouse listeners. onmouseclicked(self.mouse_click) onmousemoved(self.paddle_move) # Draw bricks. self.set_brick() # set label for the text self.dead_label = GLabel('') self.cry_label = GLabel('') self.win_label = GLabel('') self.smile_label = GLabel('') def dead(self): """ if the lives equal zero, it mean the player dead. so it will remove the ball and show you are dead """ self.window.remove(self.ball) # remove the ball self.dead_label = GLabel('You are dead') # add label context self.dead_label.font = 'courier-40' # set text size and type self.cry_label = GLabel('(〒︿〒)') # add label context self.cry_label.font = 'courier-30' # set text size and type self.window.add(self.dead_label, x=self.window.width / 2 - 195, y=self.window.height / 2) # add on windows of specific location self.window.add(self.cry_label, x=self.window.width / 2 - 80, y=(self.window.height / 2 + 80)) # add on windows of specific location def win(self): """ if all the bricks are remove, it means you win the game """ self.window.remove(self.ball) # remove the ball self.win_label = GLabel('Congratulation') # add label context self.win_label.font = 'courier-40' # set text size and type self.smile_label = GLabel('(ノ>ω<)ノ') # add label context self.smile_label.font = 'courier-30' # set text size and type self.window.add(self.win_label, x=self.window.width / 2 - 250, y=self.window.height / 2) # add on windows of specific location self.window.add(self.smile_label, x=self.window.width / 2 - 85, y=(self.window.height / 2 + 80)) # add on windows of specific location def set_ball(self): """ let a ball filled with color """ self.ball.filled = True # True to fill color self.ball.fill_color = 'navy' # choose the color self.__dy = 0 # speed of initial position of the ball self.__dx = 0 # speed of initial position of the ball """ put the ball on a specific location on window """ self.window.add(self.ball, x=(self.window.width - self.radius) / 2, y=(self.window.height - self.radius) / 2) def detect_brick(self): """ use four corner to detect if it touch a brick or not maybe_obj1 to maybe_obj4 is use to get if there is object or not """ maybe_obj1 = self.window.get_object_at(self.ball.x, self.ball.y) maybe_obj2 = self.window.get_object_at(self.ball.x, self.ball.y + (2 * self.radius)) maybe_obj3 = self.window.get_object_at(self.ball.x + (2 * self.radius), self.ball.y) maybe_obj4 = self.window.get_object_at(self.ball.x + (2 * self.radius), self.ball.y + (2 * self.radius)) if maybe_obj1 is not self.paddle and maybe_obj1 is not None: # if it has object and is not paddle - means brick self.window.remove(maybe_obj1) # remove the object self.__dy = -self.__dy # change the direction self.go = 0 # ball can touch the paddle now self.move_brick += 1 # number of remove brick plus 1 elif maybe_obj2 is not self.paddle and maybe_obj2 is not None: # if it has object and is not paddle - means brick self.window.remove(maybe_obj2) # remove the object self.__dy = -self.__dy # change the direction self.go = 0 # ball can touch the paddle now self.move_brick += 1 # number of remove brick plus 1 elif maybe_obj3 is not self.paddle and maybe_obj3 is not None: # if it has object and is not paddle - means brick self.window.remove(maybe_obj3) # remove the object self.__dy = -self.__dy # change the direction self.go = 0 # ball can touch the paddle now self.move_brick += 1 # number of remove brick plus 1 elif maybe_obj4 is not self.paddle and maybe_obj4 is not None: # if it has object and is not paddle - means brick self.window.remove(maybe_obj4) # remove the object self.__dy = -self.__dy # change the direction self.go = 0 # ball can touch the paddle now self.move_brick += 1 # number of remove brick plus 1 def detect_paddle(self): """ use four corner to detect if it touch a paddle or not maybe_obj1 to maybe_obj4 is use to get if there is object or not """ maybe_obj1 = self.window.get_object_at(self.ball.x, self.ball.y) maybe_obj2 = self.window.get_object_at(self.ball.x + (2 * self.radius), self.ball.y) maybe_obj3 = self.window.get_object_at(self.ball.x + (2 * self.radius), self.ball.y) maybe_obj4 = self.window.get_object_at(self.ball.x + (2 * self.radius), self.ball.y + (2 * self.radius)) if self.go == 0: # go is use to let the ball detect the paddle only one times if maybe_obj1 is self.paddle: # if it is paddle self.__dy = -self.__dy # change the direction self.go = 1 # go equal 1 means it's touch and go to bricks elif maybe_obj2 is self.paddle: # if it is paddle self.__dy = -self.__dy # change the direction self.go = 1 # go equal 1 means it's touch and go to bricks elif maybe_obj3 is self.paddle: # if it is paddle self.__dy = -self.__dy # change the direction self.go = 1 # go equal 1 means it's touch and go to bricks elif maybe_obj4 is self.paddle: # if it is paddle self.__dy = -self.__dy # change the direction self.go = 1 # go equal 1 means it's touch and go to bricks def mouse_click(self, event): """ if the x speed of ball and y speed of the ball is 0, it means it's a new start, and click will let the ball move :param event: mouse detect """ if self.__dx == 0 and self.__dy == 0: # x speed and y speed is both zero self.set_ball_velocity() # decide the velocity of ball self.move_ball() # ball move def wall_collision(self): """ 1.touch the wall, and it need to change the direction, beside, consider that it may not touch brick to reflect to paddle, so when touch the wall, go also need to change into 0 2. ball can not touch the bottom of window, it will cause dead, using other way to figure iy out """ if self.ball.x <= 0 or self.ball.x + self.ball.width >= self.window.width: # touch the right and left wall self.__dx = -self.__dx # change the direction self.go = 0 # it can touch the paddle now if self.ball.y <= 0: # touch the up wall self.__dy = -self.__dy # change the direction self.go = 0 # it can touch the paddle now def set_ball_velocity(self): """ let the ball have speed and have different way to move forward """ self.__dx = random.randint( 0, MAX_X_SPEED) # choose a speed rate from 0 and MAX_X_SPEED self.__dy = random.randint( 0, INITIAL_Y_SPEED) # choose a speed rate from 0 and INITIAL_Y_SPEED if self.__dx == 0: # let ball not just move up and down self.__dx = random.randint(0, MAX_X_SPEED) # re-choose a x speed rate if self.__dy == 0: # let the ball not just move left and right self.__dy = random.randint( 0, INITIAL_Y_SPEED) # re-choose a y speed rate if random.random( ) > 0.5: # let the ball have 50-50 chance to move left or right self.__dx = -self.__dx # set to have opposite way if random.random( ) > 0.5: # let the ball have 50-50 chance to move up or down self.__dy = -self.__dy # set to have opposite way def move_ball(self): """ ball move with the speed __dx and __dy """ self.ball.move(self.__dx, self.__dy) def get_dx(self): """ set a getter to get x speed :return: the value of x speed """ return self.__dx # return the x speed def get_dy(self): """ getter to get y speed :return: the value of y speed """ return self.__dy # return the y speed def paddle_move(self, mouse): """ mouse detect to let paddle follow the mouse :param mouse: mouse detect """ paddle_x_position = mouse.x - (self.pad_width / 2 ) # set into middle part of paddle if mouse.x + self.pad_width >= self.window.width: # when the mouse on left side outside of windoe paddle_x_position = self.window.width - self.pad_width # x set into left of window if mouse.x - self.pad_width <= 0: # when the mouse on the right side outside of window paddle_x_position = 0 # x position set into right of window """ add paddle into specific location on the window """ self.window.add(self.paddle, x=paddle_x_position, y=self.window.height - self.pad_offset - self.pad_height) def set_brick(self): """ set brick into initial position """ brick_width_in_window = 0 # initial position of brick in x brick_height_in_window = self.bri_offset # initial position of brick in y for i in range( self.bri_rows): # for loop based on how many rows it has for j in range(self.bri_cols ): # for loop based on how many columns it has self.brick = GRect(self.bri_width, self.bri_height) # set a brick self.brick.filled = True # True to fill with color if j % 4 == 0: # base on the columns to choose color self.brick.fill_color = 'red' self.brick.color = 'red' if j % 4 == 1: # base on the columns to choose color self.brick.fill_color = 'salmon' self.brick.color = 'salmon' if j % 4 == 2: # base on the columns to choose color self.brick.fill_color = 'orange' self.brick.color = 'orange' if j % 4 == 3: # base on the columns to choose color self.brick.fill_color = 'tomato' self.brick.color = 'tomato' self.window.add( self.brick, x=brick_width_in_window, y=brick_height_in_window) # add brick to windows """ move forward to next columns position, include brick width and spacing """ brick_width_in_window += self.bri_width brick_width_in_window += self.bri_spacing brick_width_in_window = 0 # all the row start at x = 0 """ move forward to next rows position, include brick height and spacing """ brick_height_in_window += self.bri_height brick_height_in_window += self.bri_spacing
class BreakoutGraphics: def __init__(self, ball_radius=BALL_RADIUS, paddle_width=PADDLE_WIDTH, paddle_height=PADDLE_HEIGHT, paddle_offset=PADDLE_OFFSET, brick_rows=BRICK_ROWS, brick_cols=BRICK_COLS, brick_width=BRICK_WIDTH, brick_height=BRICK_HEIGHT, brick_offset=BRICK_OFFSET, brick_spacing=BRICK_SPACING, title='Breakout'): # Create a graphical window, with some extra space self.__window_width = brick_cols * (brick_width + brick_spacing) - brick_spacing self.__window_height = brick_offset + 3 * (brick_rows * (brick_height + brick_spacing) - brick_spacing) self.__window = GWindow(width=self.__window_width, height=self.__window_height, title=title) # Create a paddle self.__paddle = GRect(paddle_width, paddle_height) self.__paddle.filled = True self.__window.add(self.__paddle, self.__window.width / 2 - self.__paddle.width / 2, self.__window.height - paddle_offset) # Center a filled ball in the graphical window self.__ball = GOval(ball_radius * 2, ball_radius * 2) self.__ball.filled = True self.__window.add(self.__ball, self.__window.width / 2 - self.__ball.width / 2, self.__window.height / 2 + self.__ball.height / 2) # Default initial velocity for the ball self.__dx = 0 self.__dy = 0 # Initialize our mouse listeners self.__restart_game = False self.__game_start = False onmouseclicked(self.click_event) onmousemoved(self.move_event) # Draw bricks self.__brick_rows = brick_rows self.__brick_cols = brick_cols self.__brick_width = brick_width self.__brick_height = brick_height self.__brick_spacing = brick_spacing self.__brick_offset = brick_offset self.__brick_nums = 0 self.set_bricks(self.__brick_rows, self.__brick_cols, self.__brick_width, self.__brick_height, self.__brick_spacing, self.__brick_offset) # Prepare label self.__score = 0 self.__top_score = 0 self.__game_end_label = GLabel("GAME OVER") self.__game_end_label.font = "Verdana-17" self.__game_end_label.color = (150, 0, 0) self.__score_label = GLabel("Your Score : " + str(self.__score)) self.__score_label.font = "Verdana-15" self.__score_label.color = (100, 100, 100) self.__top_score_label = GLabel("Top Score : " + str(self.__top_score)) self.__top_score_label.font = "Verdana-15" self.__top_score_label.color = (100, 100, 100) self.__hint_label = GLabel("Click to Start") self.__hint_label.font = "Verdana-15" self.__hint_label.color = (100, 100, 100) self.__window.add(self.__game_end_label, self.__window.width / 2 - self.__game_end_label.width / 2, 0) self.__window.add(self.__score_label, 0, self.__score_label.height) self.__window.add(self.__top_score_label, self.__window.width - self.__top_score_label.width, self.__top_score_label.height) self.__window.add(self.__hint_label, self.__window.width / 2 - self.__hint_label.width / 2, self.__window.height / 2 + self.__ball.height / 2 + self.__ball.height + self.__hint_label.height * 4) self.__life_point_text = "" for i in range(3): self.__life_point_text += "❤" self.__life_point_label = GLabel(self.__life_point_text) self.__life_point_label.font = "-22" self.__life_point_label.color = (150, 0, 0) self.__window.add(self.__life_point_label, self.__window.width - self.__life_point_label.width, self.__window.height) def set_bricks(self, brick_rows, brick_cols, brick_width, brick_height, brick_spacing, brick_offset): """ Setting the bricks depends on the brick_rows and brick_cols. """ for x in range(brick_rows): for y in range(brick_cols): __brick = GRect(brick_width, brick_height) __brick.filled = True if y < 2: __brick.fill_color = (RED_R, RED_G, RED_B) elif y < 4: __brick.fill_color = (ORANGE_R, ORANGE_G, ORANGE_B) elif y < 6: __brick.fill_color = (YELLOW_R, YELLOW_G, YELLOW_B) elif y < 8: __brick.fill_color = (GREEN_R, GREEN_G, GREEN_B) else: __brick.fill_color = (BLUE_R, BLUE_G, BLUE_B) __brick.color = (0, 0, 0) # if y == 9: (This line switch for building only one row of bricks.) # self.__window.add(__brick, x * (brick_width + brick_spacing), brick_offset + y * (brick_height + brick_spacing)) # self.__brick_nums += 1 self.__window.add(__brick, x * (brick_width + brick_spacing), brick_offset + y * (brick_height + brick_spacing)) self.__brick_nums += 1 def refill_bricks(self): """ Refill the bricks when game restart. """ for x in range(self.__brick_rows): for y in range(self.__brick_cols): __x_coordinate = x * (self.__brick_width + self.__brick_spacing) __y_coordinate = self.__brick_offset + y * (self.__brick_height + self.__brick_spacing) if self.__window.get_object_at(__x_coordinate, __y_coordinate) is None: __brick = GRect(self.__brick_width, self.__brick_height) __brick.filled = True if y < 2: __brick.fill_color = (RED_R, RED_G, RED_B) elif y < 4: __brick.fill_color = (ORANGE_R, ORANGE_G, ORANGE_B) elif y < 6: __brick.fill_color = (YELLOW_R, YELLOW_G, YELLOW_B) elif y < 8: __brick.fill_color = (GREEN_R, GREEN_G, GREEN_B) else: __brick.fill_color = (BLUE_R, BLUE_G, BLUE_B) __brick.color = (0, 0, 0) # if y == 9: (This line switch for building only one row of bricks.) # self.__window.add(__brick, __x_coordinate, __y_coordinate) # self.__brick_nums += 1 self.__window.add(__brick, __x_coordinate, __y_coordinate) self.__brick_nums += 1 def click_event(self, mouse_obj): """ Setting events when mouse clicked on different pages/conditions. """ if self.__restart_game: self.clean_record() self.set_ball_position() self.__game_end_label.y = 0 self.refill_bricks() self.update_life_point(3) self.__restart_game = False elif not self.__game_start: self.__game_start = True self.__hint_label.y = 0 self.initial_velocity() def move_event(self, mouse_obj): """ Setting events when mouse moved on different pages/conditions. """ if mouse_obj.x <= 0: self.__paddle.x = 0 elif mouse_obj.x + self.__paddle.width >= self.__window_width: self.__paddle.x = self.__window_width - self.__paddle.width else: self.__paddle.x = mouse_obj.x def initial_velocity(self): """ initial the velocity to make ball move. """ self.__dx = random.randint(1, MAX_X_SPEED) if random.random() > 0.5: self.__dx = -self.__dx self.__dy = INITIAL_Y_SPEED def set_ball_position(self): """ Set ball's position to the default on center of screen. """ self.__dx = 0 self.__dy = 0 self.__ball.x = self.__window.width / 2 - self.__ball.width / 2 self.__ball.y = self.__window.height / 2 + self.__ball.height / 2 def one_more_chance(self): """ When losing one life point but still have chances to challenge. """ self.set_ball_position() self.__hint_label.text = "Click to Start" self.__hint_label.y = self.__window.height / 2 + self.__ball.height / 2 + self.__ball.height + self.__hint_label.height * 4 self.update_score() self.__game_start = False def game_over(self): """ When losing all life then game over. """ self.__dx = 0 self.__dy = 0 self.__game_end_label.text = "GAME OVER" self.__game_end_label.y = self.__window.height / 2 + self.__ball.height / 2 - self.__game_end_label.height self.__score_label.text = "Your Score : " + str(self.__score) self.__hint_label.text = "Click to Restart" self.__hint_label.y = self.__window.height / 2 + self.__ball.height / 2 + self.__ball.height + self.__hint_label.height * 4 self.update_score() self.__game_start = False self.__restart_game = True def update_score(self): """ Update the current score and top score. """ if self.__score > self.__top_score: self.__top_score = self.__score self.__score_label.text = "Your Score : " + str(self.__score) self.__top_score_label.text = "Top Score : " + str(self.__top_score) self.__top_score_label.x = self.__window.width - self.__top_score_label.width def clean_record(self): """ Reset the scores record. """ self.__score = 0 def hit_something(self): """ For ball on screen detecting is hitting something or not. """ for x in range(2): for y in range(2): maybe_hit_obj = self.__window.get_object_at(self.__ball.x + x * 2 * BALL_RADIUS, self.__ball.y + y * 2 * BALL_RADIUS) if maybe_hit_obj is None or maybe_hit_obj is self.__game_end_label or maybe_hit_obj is self.__score_label or maybe_hit_obj is self.__top_score_label or maybe_hit_obj is self.__life_point_label or maybe_hit_obj is self.__hint_label: pass else: # when hit bricks if maybe_hit_obj.y < self.__paddle.y: self.__window.remove(maybe_hit_obj) self.__score += 1 self.__brick_nums -= 1 self.update_score() self.all_bricks_clear() # when hit paddle, prevent loop in +-dy if maybe_hit_obj.y >= self.__paddle.y and self.__dy < 0: return False return True def all_bricks_clear(self): """ Check the is all bricks are down to decide if it's game clear. """ if self.__brick_nums == 0: self.update_score() self.__game_end_label.color = (0, 0, 150) self.__game_end_label.text = "GAME CLEAR" self.__game_end_label.y = self.__window.height / 2 + self.__ball.height / 2 - self.__game_end_label.height self.__hint_label.text = "Click to Restart" self.__hint_label.y = self.__window.height / 2 + self.__ball.height / 2 + self.__ball.height + self.__hint_label.height * 4 self.__game_start = False self.__restart_game = True return True def get_window(self): """ Return the GWindow in use. """ return self.__window def get_paddle(self): """ Return the paddle. """ return self.__paddle def get_ball(self): """ Return the ball. """ return self.__ball def get_dx(self): """ Return the ball's x-pace. """ return self.__dx def set_dx(self, dx): """ Set the ball's x-pace. """ self.__dx = dx def get_dy(self): """ Return the ball's y-pace. """ return self.__dy def set_dy(self, dy): """ Set the ball's y-pace. """ self.__dy = dy def update_life_point(self, life_point): """ Update current life point left. """ self.__life_point_text = "" for i in range(life_point): self.__life_point_text += "❤" self.__life_point_label.text = self.__life_point_text
class BreakoutGraphics: def __init__(self, ball_radius=BALL_RADIUS, paddle_width=PADDLE_WIDTH, paddle_height=PADDLE_HEIGHT, paddle_offset=PADDLE_OFFSET, brick_rows=BRICK_ROWS, brick_cols=BRICK_COLS, brick_width=BRICK_WIDTH, brick_height=BRICK_HEIGHT, brick_offset=BRICK_OFFSET, brick_spacing=BRICK_SPACING, title='Breakout'): # Create a graphical window, with some extra space. window_width = brick_cols * (brick_width + brick_spacing) - brick_spacing window_height = brick_offset + 3 * (brick_rows * (brick_height + brick_spacing) - brick_spacing) self.game_start = False self.window = GWindow(width=window_width, height=window_height, title=title) # Create a paddle. self.paddle = GRect(width=paddle_width, height=paddle_height) self.paddle.filled = True self.paddle_offset = paddle_offset self.window.add(self.paddle, (window_width - paddle_width) / 2, window_height - paddle_offset) # Center a filled ball in the graphical window. self.ball = GOval(ball_radius * 2, ball_radius * 2) self.ball.filled = True self.window.add(self.ball, window_width / 2 - ball_radius, window_height / 2 - ball_radius) # Default initial velocity for the ball. self.__dy = 0 self.__dx = 0 # Calculate times of removing brick self.count = 0 # Draw bricks. self.brick_rows = brick_rows self.brick_cols = brick_cols for i in range(self.brick_rows): for j in range(self.brick_cols): self.brick = GRect(brick_width, brick_height) self.brick.filled = True if j == 0 or j == 1: color = 'red' elif j == 2 or j == 3: color = 'gold' elif j == 4 or j == 5: color = 'yellow' elif j == 6 or j == 7: color = 'green' else: color = 'blue' self.brick.fill_color = color self.brick.color = color self.window.add(self.brick, (brick_spacing + brick_width) * i, (brick_spacing + brick_height) * j + brick_offset) # Initialize our mouse listeners. onmousemoved(self.paddle_move) onmouseclicked(self.initialize_velocity) def set_dx(self): self.__dx = -self.__dx def set_dy(self): self.__dy = -self.__dy def reset_ball(self): self.window.add(self.ball, self.window.width / 2 - self.ball.width, self.window.height / 2 - self.ball.width) self.__dy = 0 self.__dx = 0 self.game_start = False def initialize_velocity(self, mouse): if not self.game_start: self.set_ball_velocity() self.game_start = True def set_ball_velocity(self): self.__dx = random.randint(1, MAX_X_SPEED) self.__dy = INITIAL_Y_SPEED if random.random() > 0.5: self.__dx = -self.__dx def ball_out_of_window(self): is_ball_out_of_window = self.ball.y >= self.window.height return is_ball_out_of_window def paddle_move(self, mouse): if 0 <= mouse.x <= self.window.width - self.paddle.width: self.window.add(self.paddle, mouse.x, self.window.height - self.paddle_offset) def get_dx(self): return self.__dx def get_dy(self): return self.__dy def count(self): self.count += 1 return self.count def check_ball(self): # Name 4 point of ball maybe_1 = self.window.get_object_at(self.ball.x, self.ball.y) maybe_2 = self.window.get_object_at(self.ball.x + self.ball.width, self.ball.y) maybe_3 = self.window.get_object_at(self.ball.x, self.ball.y + self.ball.width) maybe_4 = self.window.get_object_at(self.ball.x + self.ball.width, self.ball.y + self.ball.width) # Check if one of point hit paddle or brick if maybe_1 is not None: # Check if first point hit brick because only bottom of ball will hid paddle if maybe_1 is not self.paddle: self.set_dy() self.window.remove(maybe_1) self.count += 1 else: if maybe_2 is not None: # Check if second point hit brick because only bottom of ball will hid paddle if maybe_2 is not self.paddle: self.set_dy() self.window.remove(maybe_2) self.count += 1 else: if maybe_3 is not None: if maybe_3 is self.paddle: self.set_dy() else: self.set_dy() self.window.remove(maybe_3) self.count += 1 else: if maybe_4 is not None: if maybe_4 is self.paddle: self.set_dy() else: self.set_dy() self.window.remove(maybe_4) self.count += 1 def all_clear(self): is_all_clear = self.count == self.brick_cols * self.brick_rows return is_all_clear def remove_ball(self): self.window.remove(self.ball) def game_over(self): game_over = GLabel('Game Over') game_over.font = 'Georgia-50-Bold' self.window.add(game_over, (self.window.width - game_over.width) / 2, (self.window.height - game_over.height) / 2)
class BreakoutGraphics: def __init__(self, ball_radius=BALL_RADIUS, paddle_width=PADDLE_WIDTH, paddle_height=PADDLE_HEIGHT, paddle_offset=PADDLE_OFFSET, brick_rows=BRICK_ROWS, brick_cols=BRICK_COLS, brick_width=BRICK_WIDTH, brick_height=BRICK_HEIGHT, brick_offset=BRICK_OFFSET, brick_spacing=BRICK_SPACING, title='Breakout'): # Create a graphical window, with some extra space. window_width = brick_cols * (brick_width + brick_spacing) - brick_spacing window_height = brick_offset + 3 * (brick_rows * (brick_height + brick_spacing) - brick_spacing) self.window = GWindow(width=window_width, height=window_height, title=title) # Create a paddle. self.paddle = GRect(paddle_width, paddle_height) self.window.add(self.paddle, (self.window.width - paddle_width) / 2, self.window.height - paddle_offset - paddle_height) self.paddle.filled = True self.paddle.fill_color = 'blue' self.paddle.color = 'blue' # Center a filled ball in the graphical window. self.ball = GOval(ball_radius * 2, ball_radius * 2) self.ball.filled = True self.reset_ball() # Default initial velocity for the ball. self.__dx = 0 self.__dy = 0 self.switch = False # Initialize our mouse listeners. onmouseclicked(self.game_start) onmousemoved(self.move_paddle) # Draw bricks. by = 0 for i in range(brick_rows): bx = 0 for j in range(brick_cols): self.brick = GRect(brick_width, brick_height) self.brick.filled = True if i < brick_cols / 5: self.brick.fill_color = 'red' elif brick_cols / 5 <= i < brick_cols / 5 * 2: self.brick.fill_color = 'orange' elif brick_cols / 5 * 2 <= i < brick_cols / 5 * 3: self.brick.fill_color = 'yellow' elif brick_cols / 5 * 3 <= i < brick_cols / 5 * 4: self.brick.fill_color = 'green' else: self.brick.fill_color = 'blue' self.window.add(self.brick, bx, brick_offset+by) bx += brick_width + brick_spacing by += brick_height + brick_spacing # scoreboard self.earned_score = 0 self.total_score = brick_cols * brick_rows self.scoreboard = GLabel(f'score: {self.earned_score}/{self.total_score}', x=10, y=30) self.scoreboard.font = 'courier-20' self.window.add(self.scoreboard) def update_scoreboard(self): self.window.remove(self.scoreboard) self.scoreboard = GLabel(f'score: {self.earned_score}/{self.total_score}', x=10, y=30) self.window.add(self.scoreboard) def reset_ball(self): self.window.add(self.ball, (self.window.width - self.ball.width) / 2, (self.window.height - self.ball.height) / 2) self.__dx = 0 self.__dy = 0 self.switch = False def move_paddle(self, event): self.paddle.x = event.x - self.paddle.width/2 def game_start(self, event): if self.__dx == 0: self.__dx = random.randint(1, MAX_X_SPEED) if random.random() > 0.5: self.__dx = -self.__dx self.__dy = INITIAL_Y_SPEED self.switch = True def get_dx(self): return self.__dx def get_dy(self): return self.__dy
class Graphics: def __init__(self, width=500, height=500): """ width : the window's width height : the window's height """ # Setting variables self.brick_width = (width + BRICK_SPACE) // COLUMNS - BRICK_SPACE self.brick_height = int((height * BRICK_HEIGHT_FRACTION + BRICK_SPACE) / ROWS - BRICK_SPACE) self.brick_offset = int(height * BRICK_OFFSET_FRACTION) self.paddle_width = width // 4 self.paddle_height = self.brick_height//2 self.paddle_offset = height // 8 self.ball_size = min(self.brick_width, self.brick_height) self.gift_speed = width // 200 self.gift_size = self.ball_size # Create a graphical window. self.window = GWindow(width=width, height=height, title="Breakout") # Create a paddle. self.paddle = GRect(self.paddle_width, self.paddle_height) self.paddle.x = (self.window.width - self.paddle_width) // 2 self.paddle.y = self.window.height - self.paddle_offset color_set(self.paddle, "blue") # Draw balls. self.ball_list = [GOval(0, 0)] * MAX_BALL_AMOUNT self.ball_set() self.lives = MAX_LIFE self.ball_lives = [0] * MAX_BALL_AMOUNT self.ball_amount = 1 self.fake_ball_x = (self.window.width - self.ball_size) // 2 self.fake_ball_y = self.paddle.y - self.ball_size # Default initial velocity for the ball. self.vx_list = [0] * MAX_BALL_AMOUNT self.vy_list = [0] * MAX_BALL_AMOUNT self.speed_set() self.slow_fraction = 1 # Draw bricks. self.brick_list = [GRect(0, 0)] * (ROWS * COLUMNS) self.brick_score_list = [0] * (ROWS * COLUMNS) self.brick_lives = [1] * (ROWS * COLUMNS) self.brick_gift = [0] * (ROWS * COLUMNS) # Initial gift boxes self.gift_vy = [0] * (ROWS * COLUMNS) self.gift_switch = [0] * (ROWS * COLUMNS) self.gift_list = [GRect(0, 0)] * (ROWS * COLUMNS) self.example_gift = [GRect(0, 0)] * len(GIFT_COLOR) self.gift_explanation = [GLabel(0, 0)] * len(GIFT_COLOR) self.brick_set() self.gift_set() # Graphics label self.intro_text = GLabel("Breakout") self.intro_click_text = GLabel("Click to Start") self.loading_text = GLabel("Loading") self.progress_bar = GLabel(" ") self.menu_text = GLabel("Symbols") self.ending_text = GLabel("") self.highscore_text = GLabel("Highscore") self.highscore = [GLabel("")] * HIGHSCORE_AMOUNT self.highscore_eg = GLabel("0. "+str(sum(self.brick_score_list))) self.highscore_eg.font = "-25" self.highscore_eg.x = self.window.width//2 - self.highscore_eg.width//2 self.retry_click_text = GLabel("Click to Restart ( 3 sec left )") # Score label self.score = 0 self.score_text = GLabel("Score : " + str(self.score)) self.score_text.font = "-20" self.score_text.x = 0 self.score_text.y = self.window.height - 1 self.life_score = 0 # Life label self.life_label = GLabel("") for i in range(MAX_LIFE): self.life_label.text += "♥" self.life_label.font = "-30" self.life_label.x = self.window.width - self.life_label.width self.life_label.y = self.window.height - 1 # mouse listener onmouseclicked(self.start) self.game_start = False onmousemoved(self.paddle_move) def full_reset(self): """ reset all the variables """ self.paddle_width = self.window.width // 4 self.ball_size = min(self.brick_width, self.brick_height) self.paddle = GRect(self.paddle_width, self.paddle_height) self.paddle.x = (self.window.width - self.paddle_width) // 2 self.paddle.y = self.window.height - self.paddle_offset color_set(self.paddle, "blue") self.ball_set() self.lives = MAX_LIFE self.ball_lives = [0] * MAX_BALL_AMOUNT self.ball_amount = 1 self.fake_ball_x = (self.window.width - self.ball_size) // 2 self.fake_ball_y = self.paddle.y - self.ball_size self.speed_set() self.slow_fraction = 1 self.brick_lives = [1] * (ROWS * COLUMNS) self.brick_gift = [0] * (ROWS * COLUMNS) self.gift_vy = [0] * (ROWS * COLUMNS) self.gift_switch = [0] * (ROWS * COLUMNS) self.brick_set() self.gift_set() self.score = 0 self.score_text.text = "Score : 0" self.score_text.x = 0 self.score_text.y = self.window.height - 1 self.life_score = 0 self.life_label.text = "" for i in range(MAX_LIFE): self.life_label.text += "♥" self.life_label.x = self.window.width - self.life_label.width def speed_set(self): """ set a random speed for every ball, y direction is always negative """ for index in range(MAX_BALL_AMOUNT): self.vx_list[index] = random.randint(0, MAX_SPEED*2)-MAX_SPEED while abs(self.vx_list[index]) < MIN_SPEED: self.vx_list[index] = random.randint(0, MAX_SPEED*2)-MAX_SPEED self.vy_list[index] = -random.randint(MIN_SPEED, MAX_SPEED) def speed_change(self): """ change the speed by the effect of the score and the gifts """ vx = [0] * MAX_BALL_AMOUNT vy = [0] * MAX_BALL_AMOUNT gvy = [0] * (ROWS * COLUMNS) multiplier = (1 + min((self.score - self.life_score) / sum(self.brick_score_list)*4, 2)) * self.slow_fraction for index in range(MAX_BALL_AMOUNT): vx[index] = int(self.vx_list[index] * multiplier) vy[index] = int(self.vy_list[index] * multiplier) for num in range(ROWS*COLUMNS): gvy[num] = int(self.gift_vy[num] * multiplier) return vx, vy, gvy def object_show(self): """ show the object in the correct order """ self.window.add(self.paddle) self.window.add(self.score_text) self.window.add(self.life_label) for index in range(self.ball_amount): self.window.add(self.ball_list[index]) self.ball_lives[index] = 1 for index in range(ROWS * COLUMNS): self.window.add(self.brick_list[index]) def paddle_reset(self): """ reset the paddle """ self.paddle_width = self.window.width // 4 self.window.remove(self.paddle) xcor = self.paddle.x ycor = self.paddle.y self.paddle = GRect(self.paddle_width, self.paddle_height, x=xcor, y=ycor) color_set(self.paddle, "blue") self.window.add(self.paddle) def paddle_resize(self): """ change the paddle width by replacing a new one """ self.window.remove(self.paddle) xcor = self.paddle.x ycor = self.paddle.y self.paddle = GRect(self.paddle_width, self.paddle_height, x=xcor, y=ycor) color_set(self.paddle, "blue") self.window.add(self.paddle) def ball_show(self): """ show the balls on the window for self.ball_amount of balls """ for index in range(self.ball_amount): self.window.add(self.ball_list[index]) self.ball_lives[index] = 1 def ball_set(self): """ setting the balls' graphics """ for index in range(MAX_BALL_AMOUNT): self.ball_list[index] = GOval(self.ball_size, self.ball_size) self.ball_list[index].x = (self.window.width - self.ball_size) // 2 self.ball_list[index].y = self.window.height - self.paddle_offset - self.ball_size color_set(self.ball_list[index], "black") def ball_resize(self): """ changing the balls' size by replacing a new one """ self.fake_ball_y = self.paddle.y - self.ball_size for index in range(MAX_BALL_AMOUNT): self.window.remove(self.ball_list[index]) xcor = self.ball_list[index].x ycor = self.ball_list[index].y self.ball_list[index] = GOval(self.ball_size, self.ball_size, x=xcor, y=ycor) color_set(self.ball_list[index], "black") self.window.add(self.ball_list[index]) def ball_add(self): """ add one more ball to the game (maximum 10) """ self.window.add(self.ball_list[self.ball_amount-1]) self.ball_lives[self.ball_amount-1] = 1 def ball_amount_reset(self): """ set the ball amount to 1 """ for index in range(1, self.ball_amount): self.window.remove(self.ball_list[index]) self.ball_lives[index] = 0 self.ball_amount = 1 def ball_reset(self): """ reset all the balls position """ for index in range(MAX_BALL_AMOUNT): self.ball_list[index].x = self.fake_ball_x self.ball_list[index].y = self.fake_ball_y def brick_set(self): """ bricks' initial setting """ for by in range(ROWS): for bx in range(COLUMNS): index = bx + by * COLUMNS self.brick_list[index] = GRect(self.brick_width, self.brick_height) self.brick_list[index].x = bx * (self.brick_width + BRICK_SPACE) self.brick_list[index].y = self.brick_offset + by * (self.brick_height + BRICK_SPACE) color = (0xFFFFFF // ROWS) * (index // COLUMNS) self.brick_score_list[index] = (ROWS - by) * 10 color_set(self.brick_list[index], color) if random.randint(1, int(1/GIFT_CHANCE)) == 1: self.brick_gift[index] = random.randint(1, 4) def gift_set(self): """ gifts' initial setting """ for num in range(ROWS*COLUMNS): self.gift_list[num] = GRect(self.gift_size, self.gift_size) color_set(self.gift_list[num], GIFT_COLOR[self.brick_gift[num]-1][0]) self.gift_list[num].x = self.brick_list[num].x + self.brick_width // 2 - self.gift_size // 2 self.gift_list[num].y = self.brick_list[num].y + self.brick_height // 2 - self.gift_size // 2 def clear_gift(self): """ removing all the shown gifts from the window """ for index in range(ROWS * COLUMNS): if self.gift_switch[index] == 1: self.window.remove(self.gift_list[index]) self.gift_switch[index] = 0 self.gift_vy[index] = 0 def paddle_move(self, event): """ change the paddle x position when the mouse moves """ if event.x < self.paddle.width // 2: self.paddle.x = 0 self.fake_ball_x = (self.paddle.width - self.ball_size) // 2 elif self.window.width - self.paddle.width // 2 < event.x: self.paddle.x = self.window.width - self.paddle.width self.fake_ball_x = self.window.width - self.paddle.width // 2 - self.ball_size // 2 else: self.paddle.x = event.x - self.paddle.width // 2 self.fake_ball_x = event.x - self.ball_size // 2 def start(self, event): """ set the starting boolean to True """ self.game_start = True def life_check(self): """ check if the ball's life or the bricks' life hits zero if ball's life hits zero, return 1 if bricks' life hits zero, return 2 else, return 0 """ if self.lives == 0: return 1 elif sum(self.brick_lives) == 0: return 2 return 0 def lose_life(self): """ change settings when the ball fell to the bottom """ self.lives -= 1 self.game_start = False self.speed_set() self.paddle_reset() self.ball_amount_reset() self.clear_gift() self.slow_fraction = 1 for index in range(self.ball_amount): self.ball_lives[index] = 1 self.ball_show() hearts = "" for i in range(self.lives): hearts += "♥" self.life_label.text = hearts self.life_label.x = self.window.width - self.life_label.width self.life_score = self.score def boundary_bump(self): """ check if the ball has contact with the boundary """ for index in range(MAX_BALL_AMOUNT): if self.ball_lives[index] == 1: if self.window.width - self.ball_size < self.ball_list[index].x: self.vx_list[index] = -abs(self.vx_list[index]) elif self.ball_list[index].x < 0: self.vx_list[index] = abs(self.vx_list[index]) if self.ball_list[index].y < 0: self.vy_list[index] = abs(self.vy_list[index]) elif self.window.height - self.ball_size < self.ball_list[index].y: self.ball_lives[index] = 0 self.window.remove(self.ball_list[index]) if sum(self.ball_lives) == 0: self.lose_life() def single_brick(self, brick): """ brick : the brick object that the ball has contact with change settings when a ball collides into a single brick """ self.window.remove(brick) index = self.brick_list.index(brick) self.brick_lives[index] = 0 self.score += self.brick_score_list[index] self.score_text.text = "Score : " + str(self.score) if self.brick_gift[index] >= 1: self.gift_switch[index] = 1 self.gift_vy[index] = self.gift_speed self.window.add(self.gift_list[index]) def ball_bump(self): """ check if the ball has contact with the bricks or the paddle """ for index in range(MAX_BALL_AMOUNT): if self.ball_lives[index] == 1: lx = self.ball_list[index].x mx = self.ball_list[index].x + self.ball_size // 2 rx = self.ball_list[index].x + self.ball_size uy = self.ball_list[index].y my = self.ball_list[index].y + self.ball_size // 2 dy = self.ball_list[index].y + self.ball_size up_object = self.window.get_object_at(mx, uy-1) down_object = self.window.get_object_at(mx, dy+1) left_object = self.window.get_object_at(lx-1, my) right_object = self.window.get_object_at(rx+1, my) if up_object is self.paddle or left_object is self.paddle or right_object is self.paddle or down_object is self.paddle: self.vy_list[index] = -abs(self.vy_list[index]) elif up_object in self.brick_list: self.vy_list[index] = abs(self.vy_list[index]) self.single_brick(up_object) elif down_object in self.brick_list: self.vy_list[index] = -abs(self.vy_list[index]) self.single_brick(down_object) elif left_object in self.brick_list: self.vx_list[index] = abs(self.vx_list[index]) self.single_brick(left_object) elif right_object in self.brick_list: self.vx_list[index] = -abs(self.vx_list[index]) self.single_brick(right_object) def object_move(self): """ move the objects(shown balls, shown gifts) """ vx, vy, gvy = self.speed_change() for index in range(MAX_BALL_AMOUNT): if self.ball_lives[index] == 1: self.ball_list[index].x += vx[index] self.ball_list[index].y += vy[index] else: self.ball_list[index].x = self.fake_ball_x self.ball_list[index].y = self.fake_ball_y for num in range(ROWS * COLUMNS): self.gift_list[num].y += self.gift_vy[num] def gift_bump(self): """ check if the gifts has contact with the paddle """ for index in range(ROWS * COLUMNS): if self.gift_switch[index] == 1: lx = self.gift_list[index].x mx = self.gift_list[index].x + self.gift_size // 2 rx = self.gift_list[index].x + self.gift_size uy = self.gift_list[index].y my = self.gift_list[index].y + self.gift_size // 2 dy = self.gift_list[index].y + self.gift_size up_object = self.window.get_object_at(mx, uy-1) down_object = self.window.get_object_at(mx, dy+1) left_object = self.window.get_object_at(lx-1, my) right_object = self.window.get_object_at(rx+1, my) if up_object is self.paddle or left_object is self.paddle or right_object is self.paddle or down_object is self.paddle: self.gift_switch[index] = 0 self.window.remove(self.gift_list[index]) self.gift_vy[index] = 0 if self.brick_gift[index] == 1: self.paddle_width += self.window.width//20 self.paddle_resize() elif self.brick_gift[index] == 2: self.ball_amount += 1 self.ball_add() elif self.brick_gift[index] == 3: self.slow_fraction *= 0.9 elif self.brick_gift[index] == 4: if self.paddle_width >= self.window.width//8: self.paddle_width -= self.window.width//10 self.paddle_resize() def intro(self): """ the intro page setup """ self.intro_text.font = "-80" self.intro_text.x = (self.window.width - self.intro_text.width) // 2 self.intro_text.y = self.window.height//2 + self.intro_text.height // 2 self.window.add(self.intro_text) self.intro_click_text.font = "-20" self.intro_click_text.x = (self.window.width - self.intro_click_text.width) // 2 self.intro_click_text.y = (self.intro_text.y + self.window.height)//2 self.window.add(self.intro_click_text) def loading(self): """ the loading page setup """ self.loading_text.font = "-70" self.loading_text.x = (self.window.width - self.loading_text.width) // 2 self.loading_text.y = self.window.height // 3 self.window.add(self.loading_text) self.progress_bar.font = "-40" self.progress_bar.x = (self.window.width - self.progress_bar.width) // 2 self.progress_bar.y = self.loading_text.y + self.loading_text.height self.window.add(self.progress_bar) self.menu_text.x = (self.window.width - self.menu_text.width) // 2 self.menu_text.y = self.progress_bar.y + int(self.progress_bar.height*1.2) self.window.add(self.menu_text) for num in range(len(GIFT_COLOR)): self.example_gift[num] = GRect(self.gift_size, self.gift_size) color_set(self.example_gift[num], GIFT_COLOR[num][0]) self.example_gift[num].x = self.window.width//2 - self.gift_size*3 self.example_gift[num].y = self.menu_text.y + int(self.gift_size*1.5*(num+0.7)) - self.gift_size//3 self.gift_explanation[num] = GLabel(GIFT_COLOR[num][1]) self.gift_explanation[num].x = self.window.width//2 - self.gift_size*1 self.gift_explanation[num].y = self.menu_text.y + int(self.gift_size*1.5*(num+0.7)) + self.gift_explanation[num].height self.window.add(self.example_gift[num]) self.window.add(self.gift_explanation[num]) for tick in range(6): self.single_bar(["▏", "▎", "▍", "▌", "▋", "▊", "▉", "█"], tick) def single_bar(self, sign, tick): """ sign : the progress bar sign tick : the index of the changing bar sign changing the progress bar """ for i in range(8): self.progress_bar.text = self.progress_bar.text[:tick]+sign[i]+self.progress_bar.text[tick+1:len(self.progress_bar.text)-1] pause(50) def win(self): """ the winning label setting """ self.ending_text.text = "Congratulations!!!" self.ending_text.font = "-45" self.ending_text.x = (self.window.width - self.ending_text.width) // 2 self.ending_text.y = (self.window.height + self.ending_text.height) // 3 self.window.add(self.ending_text) def lose(self): """ the losing label setting """ self.ending_text.text = "Game Over" self.ending_text.font = "-70" self.ending_text.color = "red" self.ending_text.x = (self.window.width - self.ending_text.width) // 2 self.ending_text.y = (self.window.height + self.ending_text.height) // 3 self.window.add(self.ending_text) def final_score(self): """ the final score page setup """ self.score_text.text = "Score : " + str(self.score) + " / " + str(sum(self.brick_score_list)) self.score_text.x = (self.window.width - self.score_text.width) // 2 self.score_text.y = self.ending_text.y + self.score_text.height * 5 self.window.add(self.score_text) self.retry_click_text.font = "-15" self.retry_click_text.x = (self.window.width - self.retry_click_text.width) // 2 self.retry_click_text.y = (self.window.height + self.score_text.y) // 2 self.window.add(self.retry_click_text) self.game_start = False for tick in range(3): pause(1000) self.retry_click_text.text = self.retry_click_text.text[:19] + str(2-tick) + self.retry_click_text.text[20:] pause(1000) def high_score(self, all_score): """ the high score page setup """ all_score.sort(reverse=True) self.highscore_text.font = "-40" self.highscore_text.x = self.window.width//2 - self.highscore_text.width//2 self.highscore_text.y = self.window.height//5 self.window.add(self.highscore_text) nan_text = "" for i in range(len(str(sum(self.brick_score_list)))): nan_text += "- " for num in range(HIGHSCORE_AMOUNT): if num < len(all_score): spacing = "" for s in range(len(str(sum(self.brick_score_list))) - len(str(all_score[num]))): spacing += " " self.highscore[num] = GLabel(str(num+1)+". "+spacing+str(all_score[num])) else: self.highscore[num] = GLabel(str(num+1)+". "+nan_text) self.highscore[num].font = "-25" self.highscore[num].x = self.highscore_eg.x self.highscore[num].y = self.highscore_text.y + self.highscore[num].height*2*(num+1) self.window.add(self.highscore[num])
class BreakoutGraphics: def __init__(self, ball_radius=BALL_RADIUS, paddle_width=PADDLE_WIDTH, paddle_height=PADDLE_HEIGHT, paddle_offset=PADDLE_OFFSET, brick_rows=BRICK_ROWS, brick_cols=BRICK_COLS, brick_width=BRICK_WIDTH, brick_height=BRICK_HEIGHT, brick_offset=BRICK_OFFSET, brick_spacing=BRICK_SPACING, title='Breakout'): # Initialize variable self.state = 0 self.ball_radius = ball_radius self.brick_width = brick_width self.__bullets = BULLETS self.__paddle_width = paddle_width self.__paddle_height = paddle_height color = 'black' # Create a graphical window, with some extra space. window_width = brick_cols * (brick_width + brick_spacing) - brick_spacing window_height = brick_offset + 3 * (brick_rows * (brick_height + brick_spacing) - brick_spacing) self.window = GWindow(width=window_width, height=window_height, title=title) # Loading Animation self.icon = GImage('icon/breakoutico.png') self.window.add(self.icon, (self.window.width - self.icon.width) / 2, self.window.height / 9) loading = GRect(30, 30) loading_width = 30 loading.filled = True self.window.add(loading, 50, self.window.height / 2) for i in range(11): self.window.remove(loading) loading_width += 30 loading = GRect(loading_width, 30) loading.filled = True self.window.add(loading, 50, self.window.height * 2 / 3) pause(200) # Loading Animation End # Create a paddle. paddle = GRect(paddle_width, paddle_height) paddle.filled = True paddle.fill_color = 'black' self.paddle = paddle self.paddle_height = self.window.height - paddle_offset self.window.add(paddle, (self.window.width - self.paddle.width) / 2, self.paddle_height) # Center a filled ball in the graphical window. self.ball = [] self.ball.append( Ball(ball_radius * 2, ball_radius * 2, dx=MAX_X_SPEED, dy=INITIAL_Y_SPEED)) self.window.add(self.ball[0], (self.window.width / 2 - ball_radius), (self.window.height / 2 - ball_radius)) # Create treasure array self.treasure = [] self.bullet = [] # Draw bricks and initial brick lives self.brick = [] self.brick_live = [] for i in range(0, brick_cols): for j in range(0, brick_rows): life = 1 if j // 2 == 0: color = 'red' life = 5 elif j // 2 == 1: color = 'orange' life = 4 elif j // 2 == 2: color = 'yellow' life = 3 elif j // 2 == 3: color = 'green' life = 2 elif j // 2 == 4: color = 'blue' life = 1 self.brick.append(GRect(brick_width, brick_height)) self.brick_live.append(life) self.brick[-1].filled = True self.brick[-1].fill_color = color self.brick[-1].color = color self.window.add(self.brick[-1], x=i * (brick_width + brick_spacing), y=j * (brick_height + brick_spacing) + brick_offset) # Loading page end self.window.remove(loading) self.icon.move(0, 200) def start(self, e): """ Start the game :param e: event :return: None """ onmousemoved(self.paddle_move) onmouseclicked(self.click) self.window.remove(self.icon) def paddle_move(self, e): """ The paddle will follow the mouse :param e: the mouse coordinate :return: None """ if self.paddle.width / 2 < e.x < self.window.width - self.paddle.width / 2: self.paddle.x = e.x - self.paddle.width / 2 elif e.x < self.paddle.width / 2: self.paddle.x = 0 else: self.paddle.x = self.window.width - self.paddle.width def click(self, e): """ The event when mouse clicked (Start game of fire bullet) :param e: mouse event :return: None """ if not self.state: self.state = 1 elif self.bullets: self.bullet_fire(x=e.x) def reset(self): """ Reset the game when lose ball :return: None """ self.state = 0 self.ball.append(Ball(self.ball_radius * 2, self.ball_radius * 2)) self.window.add(self.ball[-1], self.window.width / 2 - self.ball_radius, self.window.height / 2 - self.ball_radius) for i in range(len(self.treasure)): self.window.remove(self.treasure[len(self.treasure) - i - 1]) del self.treasure[len(self.treasure) - i - 1] if self.paddle.width != self.__paddle_width: self.window.remove(self.paddle) paddle = GRect(self.__paddle_width, self.__paddle_height) paddle.filled = True paddle.fill_color = 'black' self.paddle = paddle self.window.add(paddle, (self.window.width - self.paddle.width) / 2, self.paddle_height) def if_collide(self, x, y): """ Return if (x, y) have object :param x: x-coordinate :param y: y-coordinate :return: (Bool) If have object """ maybe_object = self.window.get_object_at(x, y) if maybe_object is not None: return True else: return False def add_ball(self, x, y): """ Add ball at (x, y) :param x: x-coordinate :param y: y-coordinate :return: None """ self.ball.append(Ball(self.ball_radius * 2, self.ball_radius * 2)) self.window.add(self.ball[-1], x, y) def add_treasure(self, types, brick_index): """ Add treasure at brick center :param types: (int) the type of treasure :param brick_index: (int) the index of the brick where treasure being add :return: None """ self.treasure.append(Treasure(types)) self.window.add(self.treasure[-1], self.brick[brick_index].x + self.brick_width, self.brick[brick_index].y) def paddle_increase(self): """ Double the width of paddle :return: None """ x = self.paddle.x + self.paddle.width / 2 self.window.remove(self.paddle) if self.paddle.width >= self.__paddle_width: paddle = GRect(self.__paddle_width * 2, self.__paddle_height) else: paddle = GRect(self.__paddle_width, self.__paddle_height) paddle.filled = True paddle.fill_color = 'black' self.paddle = paddle self.window.add(paddle, x - (self.paddle.width / 2), self.paddle_height) def paddle_decrease(self): """ Decrease paddle width by 1/2 :return: None """ x = self.paddle.x + self.paddle.width / 2 self.window.remove(self.paddle) if self.paddle.width <= self.__paddle_width: paddle = GRect(self.__paddle_width / 2, self.__paddle_height) else: paddle = GRect(self.__paddle_width, self.__paddle_height) paddle.filled = True paddle.fill_color = 'black' self.paddle = paddle self.window.add(paddle, x - (self.paddle.width / 2), self.paddle_height) def brick_collide(self, index): """ Handles the brick related function when being hit :param index: (int) the brick index which being hit :return: None """ self.brick_live[index] -= 1 self.brick[index].fill_color = (BRICK_LIFE[self.brick_live[index]]) self.brick[index].color = (BRICK_LIFE[self.brick_live[index]]) if self.brick_live[index] <= 0: if_treasure = random.randint(0, 800) if if_treasure < 80: self.add_treasure(if_treasure % 8, index) self.brick_remove(index) def brick_remove(self, index): """ Remove brick from window :param index: (int) the brick index to remove :return: None """ self.window.remove(self.brick[index]) del self.brick[index] del self.brick_live[index] def bullet_fire(self, x=0): """ Fire the bullet :param x: the x-coordinate to fire the bullet :return: None """ self.bullet.append(Bullet()) self.window.add(self.bullet[-1], x, self.paddle_height) self.__bullets -= 1 def add_bullets(self, number): """ Add bullets storage :param number: (int) how many bullets to add :return: """ self.__bullets += number @property def bullets(self): return self.__bullets
class BreakoutGraphics: def __init__(self, ball_radius=BALL_RADIUS, paddle_width=PADDLE_WIDTH, paddle_height=PADDLE_HEIGHT, paddle_offset=PADDLE_OFFSET, brick_rows=BRICK_ROWS, brick_cols=BRICK_COLS, brick_width=BRICK_WIDTH, brick_height=BRICK_HEIGHT, brick_offset=BRICK_OFFSET, brick_spacing=BRICK_SPACING, lives=0, title='Breakout'): self.brick_width = brick_width self.brick_height = brick_height self.brick_rows = brick_rows self.brick_offset = brick_offset self.brick_cols = brick_cols self.brick_spacing = brick_spacing self.lives = lives self.bricks_total = brick_cols * brick_rows self.winning_label = GLabel('You Win') # Create a graphical window, with some extra space. window_width = brick_cols * (brick_width + brick_spacing) - brick_spacing window_height = brick_offset + 3 * (brick_rows * (brick_height + brick_spacing) - brick_spacing) self.window = GWindow(width=window_width, height=window_height, title=title) self.window_height = window_height self.window_width = window_width self.paddle_offset = paddle_offset # Create a paddle. self.paddle = GRect(paddle_width, paddle_height) self.paddle.filled = True self.paddle.fill_color = 'darkgray' self.paddle.color = 'darkgray' self.window.add(self.paddle, (window_width - self.paddle.width) / 2, window_height - paddle_offset) # Center a filled ball in the graphical window. self.ball = GOval(2 * ball_radius, 2 * ball_radius) self.ball.filled = True self.window.add(self.ball, (self.window_width - self.ball.width) / 2, (self.window_height - self.ball.width) / 2) self.set_bricks() self.start_x = (self.window_width - self.ball.width) / 2 self.start_y = (self.window_height - self.ball.width) / 2 # Default initial velocity for the ball. self.__dx = random.randint(1, MAX_X_SPEED) self.__dy = INITIAL_Y_SPEED if random.random() > 0.5: self.__dx = -self.__dx # Initialize our mouse listeners. onmousemoved(self.moving_paddle) onmouseclicked(self.handle_click) self.start_the_game = False # Draw bricks. def set_bricks(self): for i in range(self.brick_rows): for j in range(self.brick_cols): self.brick = GRect(self.brick_width, self.brick_height) self.brick.filled = True if i % 2 != 0: self.brick.fill_color = 'rosybrown' self.brick.color = 'rosybrown' else: self.brick.fill_color = 'steelblue' self.brick.color = 'steelblue' self.window.add( self.brick, self.brick_spacing * (j - 1) + self.brick.width * j, self.brick_offset + self.brick.height * (i - 1) + self.brick_spacing * (i - 1)) #move the paddle def moving_paddle(self, mouse): if mouse.x - (self.paddle.width ) / 2 >= self.window_width - self.paddle.width: self.paddle.x = self.window_width - self.paddle.width elif mouse.x <= 0: self.paddle.x = 0 else: self.paddle.x = mouse.x - (self.paddle.width) / 2 self.paddle.y = self.window_height - self.paddle_offset # start onemouseclicked def handle_click(self, event): self.start_the_game = True # getters def get_dx(self): return self.__dx def get_dy(self): return self.__dy def hit_wall(self): if self.ball.x <= 0 or self.ball.x + self.ball.width >= self.window.width: self.__dx *= -1 if self.ball.y <= 0: self.__dy *= -1 if self.ball.y + self.ball.height >= self.window.height: self.window.add(self.ball, self.start_x, self.start_y) self.start_the_game = False self.lives -= 1 def hit_bricks(self): upper_left = self.window.get_object_at(self.ball.x, self.ball.y) upper_right = self.window.get_object_at(self.ball.x + self.ball.width, self.ball.y) downer_left = self.window.get_object_at(self.ball.x, self.ball.y + self.ball.width) downer_right = self.window.get_object_at(self.ball.x + self.ball.width, self.ball.y + self.ball.width) if upper_left is not None: if upper_left is self.paddle: if self.__dy > 0: self.__dy *= -1 self.bricks_total -= 1 else: self.window.remove(upper_left) self.__dy *= -1 self.bricks_total -= 1 elif upper_right is not None: if upper_right is self.paddle: if self.__dy > 0: self.__dy *= -1 else: self.window.remove(upper_right) self.__dy *= -1 self.bricks_total -= 1 elif downer_left is not None: if downer_left is self.paddle: if self.__dy > 0: self.__dy *= -1 else: self.window.remove(downer_left) self.__dy *= -1 elif downer_right is not None: if downer_right is self.paddle: if self.__dy > 0: self.__dy *= -1 else: self.window.remove(downer_right) self.__dy *= -1 self.bricks_total -= 1
class BreakoutGraphics: def __init__(self, ball_radius=BALL_RADIUS, paddle_width=PADDLE_WIDTH, paddle_height=PADDLE_HEIGHT, paddle_offset=PADDLE_OFFSET, brick_rows=BRICK_ROWS, brick_cols=BRICK_COLS, brick_width=BRICK_WIDTH, brick_height=BRICK_HEIGHT, brick_offset=BRICK_OFFSET, brick_spacing=BRICK_SPACING, title='Breakout'): # Create a graphical window, with some extra space window_width = brick_cols * (brick_width + brick_spacing) - brick_spacing window_height = brick_offset + 3 * (brick_rows * (brick_height + brick_spacing) - brick_spacing) self.window = GWindow(width=window_width, height=window_height, title=title) # Create a paddle self.paddle = GRect(paddle_width, paddle_height) self.paddle.filled = True self.paddle.fill_color = 'black' self.window.add(self.paddle, (window_width - paddle_width) / 2, window_height - paddle_offset) # Center a filled ball in the graphical window self.ball = GOval(ball_radius * 2, ball_radius * 2) self.ball.filled = True self.ball.fill_color = 'black' self.window.add(self.ball, (window_width - ball_radius * 2) / 2, (window_height - ball_radius * 2) / 2) # Default initial velocity for the ball self._dx = random.randint(1, MAX_X_SPEED) self._dy = INITIAL_Y_SPEED if random.random() > 0.5: self._dx = -self._dx # Initialize our mouse listeners onmousemoved(self.move_paddle) onmouseclicked(self.game_start) # Draw bricks self.brick_count = 0 for i in range(brick_rows): for x in range(brick_cols): brick_x = 0 + (i * (brick_width + brick_spacing)) brick_y = 0 + brick_offset + (x * (brick_height + brick_spacing)) self.brick = GRect(brick_width, brick_height) self.brick.filled = True self.brick_color = color_setter(x) self.brick.fill_color = self.brick_color self.window.add(self.brick, brick_x, brick_y) self.brick_count += 1 # Score label self.user_score = 0 self.score_label = GLabel('Score :' + str(self.user_score)) self.window.add(self.score_label, 10, self.score_label.height + 10) # Live label # Please ignore the attribute of 5 as it will be updated through set_user_live() self.user_life = 5 self.live_label = GLabel('Number of Live Left :') self.window.add(self.live_label, window_width - self.live_label.width - 10, self.live_label.height + 10) # Game start switch self.game_switch = False # Method to move paddle def move_paddle(self, m): if m.x + self.paddle.width / 2 <= self.window.width: self.paddle.x = m.x - self.paddle.width / 2 if m.x - self.paddle.width / 2 <= 0: self.paddle.x = m.x # Method to determine ball action when meet the 4 walls of the window def ball_action(self): """ When the ball hits the upper, right and left wall, the direction will be opposite to enable bounce :return: When ball falls below the lower wall, the module return True """ if self.ball.y + self.ball.height / 2 >= self.window.height: return True if self.ball.y + self.ball.height / 2 <= 0: self._dy *= -1 return False if self.ball.x <= 0 or self.ball.x + self.ball.width / 2 >= self.window.width: self._dx *= -1 return False # Method to reset ball """ Once ball_action returns True, the method enables the reset of ball and flip game_switch back to False """ def reset_ball(self): self.window.add(self.ball, (self.window.width - self.ball.width) / 2, (self.window.height - self.ball.height)\ / 2) self.game_switch = False # Method to start the game """ The method takes the user mouse click and check if the ball is at the starting position It then move on to flip the game_switch to True """ def game_start(self, e): if self.ball.x == (self.window.width - self.ball.width) / 2: if self.ball.y == (self.window.height - self.ball.height) / 2: self.game_switch = True else: pass # Method to detect object around ball def obj_detect(self): """ The method checks the 4 corners of the ball for any objects that these 4 points met :return: if any of the 4 points met objects, the method returns the x and y of the specific point """ object_left_1 = self.window.get_object_at(self.ball.x, self.ball.y) object_right_1 = self.window.get_object_at( self.ball.x + self.ball.width, self.ball.y) object_left_2 = self.window.get_object_at( self.ball.x, self.ball.y + self.ball.height) object_right_2 = self.window.get_object_at( self.ball.x + self.ball.width, self.ball.y + self.ball.height) if object_left_1 is not None: return object_left_1 if object_left_2 is not None: return object_left_2 if object_right_1 is not None: return object_right_1 if object_right_2 is not None: return object_left_2 else: pass # Method to determine action when encounter obstacle def obj_action(self): """ The method further distinguish the met objects between, paddle, label and bricks :return: If the met object is brick, the method returns True for scoring and removes the brick """ if self.obj_detect() is self.paddle: if self._dy >= 0: self._dy *= -1 else: pass if self.obj_detect() is not None and self.obj_detect() is not self.score_label and self.obj_detect() is not\ self.live_label: self.window.remove(self.obj_detect()) self._dy *= -1 return True else: pass # Method for score counter def score_count(self): self.user_score += 1 self.score_label.text = 'Score :' + str(self.user_score) # Live setter def set_user_live(self, lives): """ This is to bring the user set number of lives into the code :param lives: Number of lives that user set """ self.user_life = lives # Live label update def live_update(self): """ This method serve to show the beginning number of lives in the Glabel """ self.live_label.text = 'Number of lives left :' + str(self.user_life) # Method for live counter def live_count(self): self.user_life -= 1 self.live_label.text = 'Number of lives left :' + str(self.user_life) # Method for game over determination def game_over(self): if self.user_score == self.brick_count: return True elif self.user_life > 0: self.reset_ball() else: return True # Getter for ball movement attributes def get_ball_x(self): return self._dx def get_ball_y(self): return self._dy
class BreakoutGraphics: def __init__(self, ball_radius=BALL_RADIUS, paddle_width=PADDLE_WIDTH, paddle_height=PADDLE_HEIGHT, paddle_offset=PADDLE_OFFSET, brick_rows=BRICK_ROWS, brick_cols=BRICK_COLS, brick_width=BRICK_WIDTH, brick_height=BRICK_HEIGHT, brick_offset=BRICK_OFFSET, brick_spacing=BRICK_SPACING, title='Breakout'): # Create a graphical window, with some extra space. window_width = brick_cols * (brick_width + brick_spacing) - brick_spacing window_height = brick_offset + 3 * (brick_rows * (brick_height + brick_spacing) - brick_spacing) self.window = GWindow(width=window_width, height=window_height, title=title) # Create a paddle. self.paddle = GRect(paddle_width, paddle_height) self.paddle.filled = True self.window.add(self.paddle, (window_width - paddle_width) / 2, window_height - paddle_offset) # Center a filled ball in the graphical window. self.ball = GOval(ball_radius * 2, ball_radius * 2, x=window_width / 2 - ball_radius, y=window_height / 2 - ball_radius) self.ball.filled = True self.window.add(self.ball) # Create a scoreboard. self.__score = 0 self.__board = GLabel('Score: ' + str(self.__score)) self.__board.font = '-30' self.window.add(self.__board, 0, self.__board.height + 5) # Default initial velocity for the ball. self.__dx = 0 self.__dy = 0 self.reverse_dy = -INITIAL_Y_SPEED # Initialize our mouse listeners. onmousemoved(self.move_paddle) onmouseclicked(self.click_to_start) self.__start = False # Draw bricks. self.__count = 0 for i in range(brick_rows): for j in range(brick_cols): self.__brick = GRect(brick_width, brick_height) self.__brick.filled = True if i // 2 == 0: self.__brick.fill_color = 'red' self.__brick.color = 'red' if i // 2 == 1: self.__brick.fill_color = 'orange' self.__brick.color = 'orange' if i // 2 == 2: self.__brick.fill_color = 'yellow' self.__brick.color = 'yellow' if i // 2 == 3: self.__brick.fill_color = 'green' self.__brick.color = 'green' if i // 2 == 4: self.__brick.fill_color = 'blue' self.__brick.color = 'blue' brick_y = brick_offset + (brick_height + brick_spacing) * i brick_x = (brick_width + brick_spacing) * j self.window.add(self.__brick, brick_x, brick_y) self.__count += 1 def move_paddle(self, mouse): """ Set the paddle to move horizontally with mouse moved and is contained in window. Input: event (GMouseEvent): mouse moved event """ self.paddle.x = mouse.x - self.paddle.width / 2 if self.paddle.x <= 0: self.paddle.x = 0 if self.paddle.x + self.paddle.width >= self.window.width: self.paddle.x = self.window.width - self.paddle.width def click_to_start(self, event): """ Start the game if the mouse is clicked and detect whether the game is started. Input: event (GMouseEvents): mouse clicked event """ if not self.__start: self.set_ball_direction() self.__start = True def set_ball_direction(self): """ Give ball x, y velocity which will determine its initial direction. """ self.__dx = random.randint(1, MAX_X_SPEED) self.__dy = INITIAL_Y_SPEED if random.random() > 0.5: self.__dx = -self.__dx def get_x_velocity(self): """ Return ball x velocity. """ return self.__dx def get_y_velocity(self): """ Return ball y velocity. """ return self.__dy def move_ball(self): """ Move ball by the change in x and the change in y stored in class BreakoutGraphics. """ self.ball.move(self.__dx, self.__dy) def wall_collisions(self): """ Update dx and dy depending on whether the ball has hit walls. """ if 0 >= self.ball.x or self.ball.x + self.ball.width >= self.window.width: self.__dx = -self.__dx if 0 >= self.ball.y: self.__dy = -self.__dy def ball_collisions(self): """ Remove bricks and change ball's direction when the ball hit bricks. Rebound the ball by changing its y velocity when the ball hit the paddle. The score will add one when each time brick was removed. """ up_l_corner = self.window.get_object_at(self.ball.x, self.ball.y) up_r_corner = self.window.get_object_at(self.ball.x + self.ball.width, self.ball.y) down_l_corner = self.window.get_object_at( self.ball.x, self.ball.y + self.ball.height) down_r_corner = self.window.get_object_at( self.ball.x + self.ball.width, self.ball.y + self.ball.height) # The situation that the ball hits the paddle. if down_l_corner == self.paddle: self.__dy = self.reverse_dy elif down_r_corner == self.paddle: self.__dy = self.reverse_dy # The situation that the ball hits bricks and remove them. if up_l_corner is not None and up_l_corner is not self.paddle and up_l_corner is not self.__board: self.__dy = -self.__dy self.window.remove(up_l_corner) self.__count -= 1 self.__score += 1 self.__board.text = 'Score: ' + str(self.__score) elif up_r_corner is not None and up_r_corner is not self.paddle and up_r_corner is not self.__board: self.__dy = -self.__dy self.window.remove(up_r_corner) self.__count -= 1 self.__score += 1 self.__board.text = 'Score: ' + str(self.__score) elif down_l_corner is not None and down_l_corner is not self.paddle and down_l_corner is not self.__board: self.__dy = -self.__dy self.window.remove(down_l_corner) self.__count -= 1 self.__score += 1 self.__board.text = 'Score: ' + str(self.__score) elif down_r_corner is not None and down_r_corner is not self.paddle and down_r_corner is not self.__board: self.__dy = -self.__dy self.window.remove(down_r_corner) self.__count -= 1 self.__score += 1 self.__board.text = 'Score: ' + str(self.__score) def outside_window(self): """ Check whether the ball has fallen outside the window bottom. :return: Bool """ if self.ball.y >= self.window.height: return True def reset_ball(self): """ Reset the ball's location and velocity after the ball has fallen outside the window. :return: Bool """ self.window.remove(self.ball) self.ball.x = (self.window.width - self.ball.width) / 2 self.ball.y = (self.window.height - self.ball.height) / 2 self.__dx = 0 self.__dy = 0 self.window.add(self.ball) self.__start = False def game_over(self): """ One of the conditions for game over. When all chances were used out. """ self.reset_ball() lose = GLabel('You lose!') lose.font = '-70-bold' self.window.add(lose, (self.window.width - lose.width) / 2, 500) def end_game(self): """ One of the conditions for game over. When all bricks were remove. :return: Bool """ if self.__count == 0: self.window.remove(self.ball) congrats = GLabel('Congratulation!') congrats.font = '-70-bold' congrats.color = 'red' self.window.add(congrats, (self.window.width - congrats.width) / 2, 500) return True
class BreakoutGraphics: def __init__(self, ball_radius=BALL_RADIUS, paddle_width=PADDLE_WIDTH, paddle_height=PADDLE_HEIGHT, paddle_offset=PADDLE_OFFSET, brick_rows=BRICK_ROWS, brick_cols=BRICK_COLS, brick_width=BRICK_WIDTH, brick_height=BRICK_HEIGHT, brick_offset=BRICK_OFFSET, brick_spacing=BRICK_SPACING, title='Breakout'): # Create a graphical window, with some extra space. window_width = brick_cols * (brick_width + brick_spacing) - brick_spacing window_height = brick_offset + 3 * (brick_rows * (brick_height + brick_spacing) - brick_spacing) self.window = GWindow(width=window_width, height=window_height, title=title) # Create a paddle. # set the dimension of the paddle and fill the color of the paddle. self.paddle = GRect(PADDLE_WIDTH, PADDLE_HEIGHT) self.paddle.filled = True self.window.add(self.paddle, (window_width - PADDLE_WIDTH) / 2, window_height - PADDLE_HEIGHT - PADDLE_OFFSET) # Center a filled ball in the graphical window. # set the dimension of the ball and fill the color of the ball self.ball = GOval(BALL_RADIUS * 2, BALL_RADIUS * 2) self.ball.filled = True self.window.add(self.ball, window_width / 2 - BALL_RADIUS, window_height / 2 - BALL_RADIUS) # Default initial velocity for the ball. # Initialize our mouse listeners. # set the mouse function and the velocities of x-direction and y-direction onmouseclicked(self.start) onmousemoved(self.reset) self.__dx = 0 self.__dy = 0 # set the score for counting how many bricks does the user break self.score = 0 # set the max score for ending the game self.max_score = BRICK_COLS * BRICK_COLS # Draw bricks. # use the row and column to draw the bricks. With different rows, the colors are different. for i in range(BRICK_COLS): for j in range(BRICK_ROWS): self.bricks = GRect(BRICK_WIDTH, BRICK_HEIGHT) self.bricks.filled = True if 0 <= j < 2: self.bricks.fill_color = 'red' elif 2 <= j < 4: self.bricks.fill_color = 'orange' elif 4 <= j < 6: self.bricks.fill_color = 'yellow' elif 6 <= j < 8: self.bricks.fill_color = 'green' elif 8 <= j < 10: self.bricks.fill_color = 'blue' self.window.add(self.bricks, 0 + (BRICK_SPACING + BRICK_WIDTH) * i, 0 + (BRICK_SPACING + BRICK_HEIGHT) * j) def reset(self, mouse): """ let the paddle is controlled by the mouse. only the x-direction will move. the paddle cannot move out side of the window. """ self.paddle.x = mouse.x - PADDLE_WIDTH / 2 if self.paddle.x >= (self.window.width - PADDLE_WIDTH): self.paddle.x = self.window.width - PADDLE_WIDTH if self.paddle.x <= 0: self.paddle.x = 0 def start(self, mouse): """ when the mouse is clicked, give the ball velocities of x direction and y direction. also, let the velocity of x-direction change randomly. users cannot directly get the velocities of x-direction and y-direction. """ random_x = random.randint(1, MAX_X_SPEED) self.__dx = random_x if (random.random() > 0.5): self.__dx = -self.__dx self.__dy = INITIAL_Y_SPEED def get_vx(self): """ let user can get the velocity of x-direction. """ return self.__dx def get_vy(self): """ let user can get the velocity of y-direction. """ return self.__dy def object_check(self): """ set the reflection of the ball. when there are something touched to the four points of the ball, the ball will reflect. """ if self.ball.y <= (self.window.height - PADDLE_OFFSET ): # prevention of the ball touching to the label if self.window.get_object_at(self.ball.x, self.ball.y) is not None: self.__dy = -self.__dy elif self.window.get_object_at(self.ball.x + BALL_RADIUS * 2, self.ball.y) is not None: self.__dy = -self.__dy elif self.window.get_object_at(self.ball.x, self.ball.y + BALL_RADIUS * 2) is not None: self.__dy = -self.__dy elif self.window.get_object_at(self.ball.x + BALL_RADIUS * 2, self.ball.y + BALL_RADIUS * 2) is not None: self.__dy = -self.__dy def eliminate_brick(self): """ when the ball touches bricks, eliminate the bricks """ # bricks are on the top side of the window. # the paddle cannot be eliminated if self.ball.y <= (self.window.height - PADDLE_OFFSET - PADDLE_HEIGHT - BALL_RADIUS * 2): if self.window.get_object_at(self.ball.x, self.ball.y) is not None: a = self.window.get_object_at(self.ball.x, self.ball.y) self.window.remove(a) self.score += 1 # when the bricks are eliminated, get one point. elif self.window.get_object_at(self.ball.x + BALL_RADIUS * 2, self.ball.y) is not None: a = self.window.get_object_at(self.ball.x + BALL_RADIUS * 2, self.ball.y) self.window.remove(a) self.score += 1 elif self.window.get_object_at(self.ball.x, self.ball.y + BALL_RADIUS * 2) is not None: a = self.window.get_object_at(self.ball.x, self.ball.y + BALL_RADIUS * 2) self.window.remove(a) self.score += 1 elif self.window.get_object_at(self.ball.x + BALL_RADIUS * 2, self.ball.y + BALL_RADIUS * 2) is not None: a = self.window.get_object_at(self.ball.x + BALL_RADIUS * 2, self.ball.y + BALL_RADIUS * 2) self.window.remove(a) self.score += 1 def edge_check(self): """ do not let the ball go out side of the window, except the bottom side """ if self.ball.x <= 0: self.__dx = -self.__dx if self.ball.x >= self.window.width - self.ball.width: self.__dx = -self.__dx if self.ball.y <= 0: self.__dy = -self.__dy def check_dead(self): """ if the ball go to the bottom side, the function should be stopped """ if self.ball.y >= (self.window.height - BALL_RADIUS * 2): return -1 else: return 1 def ball_restart(self): """ after stopped, the velocity should be zero in x and y directions """ self.__dx = 0 self.__dy = 0
class BreakoutGraphicsExtension: def __init__(self, ball_radius=BALL_RADIUS, paddle_width=PADDLE_WIDTH, paddle_height=PADDLE_HEIGHT, paddle_offset=PADDLE_OFFSET, brick_rows=BRICK_ROWS, brick_cols=BRICK_COLS, brick_width=BRICK_WIDTH, brick_height=BRICK_HEIGHT, brick_offset=BRICK_OFFSET, brick_spacing=BRICK_SPACING, title='Breakout'): # How many lives left. self.lives_left = LIVES # Calculate the score. self.score = 0 # Create a graphical window, with some extra space. self.window_width = brick_cols * (brick_width + brick_spacing) - brick_spacing self.window_height = brick_offset + 3 * ( brick_rows * (brick_height + brick_spacing) - brick_spacing) self.window = GWindow(width=self.window_width, height=self.window_height, title=title) # Create a start label. self.start_label = GLabel(f'Click To Start The Game') self.start_label.color = 'hotpink' self.start_label.font = 'Verdana-30-bold' self.window.add(self.start_label, x=(self.window_width - self.start_label.width) / 2, y=(self.window_height - self.start_label.height) / 2) # Create a paddle. self.paddle = GRect(PADDLE_WIDTH, PADDLE_HEIGHT, x=(self.window_width - PADDLE_WIDTH) / 2, y=self.window_height - PADDLE_OFFSET) self.paddle.filled = True self.paddle.color = 'hotpink' self.paddle.fill_color = 'hotpink' self.window.add(self.paddle) # Create a lives label. self.lives_label = GLabel(f'Your Lives : {self.lives_left}') self.lives_label.color = 'hotpink' self.lives_label.font = 'Verdana-15-bold' self.window.add(self.lives_label, x=0, y=self.window.height) # Create a score label. self.score_label = GLabel(f'Score : {self.score}') self.score_label.color = 'hotpink' self.score_label.font = 'Verdana-15-bold' self.window.add(self.score_label, x=self.window.width - self.score_label.width, y=self.window.height) # Center a filled ball in the graphical window. self.ball = GOval(BALL_RADIUS * 2, BALL_RADIUS * 2, x=self.window_width / 2 - BALL_RADIUS, y=self.window_height / 2 - BALL_RADIUS) self.ball.filled = True self.ball.color = 'hotpink' self.ball.fill_color = 'hotpink' self.window.add(self.ball) # Default initial velocity for the ball. self.__dx = random.randint(1, MAX_X_SPEED) self.__dy = INITIAL_Y_SPEED if random.random() > 0.5: self.__dx = -self.__dx # Determine whether game has been started. self.start_or_not = False # Initialize our mouse listeners. onmouseclicked(self.start) # Determine the game has started. onmousemoved(self.drag) # Draw bricks. for i in range(BRICK_ROWS): for j in range(BRICK_COLS): self.brick = GRect(BRICK_WIDTH, BRICK_HEIGHT) self.brick.filled = True if i == 1 and j == 1: self.brick.color = 'lightpink' self.brick.fill_color = 'lightpink' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 2 and j == 2: self.brick.color = 'lightpink' self.brick.fill_color = 'lightpink' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 0 and j == 2: self.brick.color = 'lightpink' self.brick.fill_color = 'lightpink' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 0 and j == 3: self.brick.color = 'lightpink' self.brick.fill_color = 'lightpink' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 1 and j == 4: self.brick.color = 'lightpink' self.brick.fill_color = 'lightpink' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 2 and j == 5: self.brick.color = 'lightpink' self.brick.fill_color = 'lightpink' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 2 and j == 6: self.brick.color = 'lightpink' self.brick.fill_color = 'lightpink' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 1 and j == 7: self.brick.color = 'lightpink' self.brick.fill_color = 'lightpink' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 0 and j == 6: self.brick.color = 'lightpink' self.brick.fill_color = 'lightpink' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 1 and j == 7: self.brick.color = 'lightpink' self.brick.fill_color = 'lightpink' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 4 and j == 1: self.brick.color = 'lavenderblush' self.brick.fill_color = 'lavenderblush' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 3 and j == 2: self.brick.color = 'lavenderblush' self.brick.fill_color = 'lavenderblush' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 3 and j == 3: self.brick.color = 'lavenderblush' self.brick.fill_color = 'lavenderblush' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 3 and j == 4: self.brick.color = 'lavenderblush' self.brick.fill_color = 'lavenderblush' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 3 and j == 5: self.brick.color = 'lavenderblush' self.brick.fill_color = 'lavenderblush' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 3 and j == 6: self.brick.color = 'lavenderblush' self.brick.fill_color = 'lavenderblush' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 4 and j == 7: self.brick.color = 'lavenderblush' self.brick.fill_color = 'lavenderblush' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 5 and j == 2: self.brick.color = 'lavenderblush' self.brick.fill_color = 'lavenderblush' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 5 and j == 6: self.brick.color = 'lavenderblush' self.brick.fill_color = 'lavenderblush' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 6 and j == 1: self.brick.color = 'lightpink' self.brick.fill_color = 'lightpink' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 6 and j == 2: self.brick.color = 'lightpink' self.brick.fill_color = 'lightpink' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 6 and j == 3: self.brick.color = 'lightpink' self.brick.fill_color = 'lightpink' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 6 and j == 4: self.brick.color = 'lightpink' self.brick.fill_color = 'lightpink' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 6 and j == 5: self.brick.color = 'lightpink' self.brick.fill_color = 'lightpink' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 6 and j == 6: self.brick.color = 'lightpink' self.brick.fill_color = 'lightpink' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 6 and j == 7: self.brick.color = 'lightpink' self.brick.fill_color = 'lightpink' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 7 and j == 1: self.brick.color = 'lavenderblush' self.brick.fill_color = 'lavenderblush' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 7 and j == 2: self.brick.color = 'lavenderblush' self.brick.fill_color = 'lavenderblush' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 7 and j == 3: self.brick.color = 'lavenderblush' self.brick.fill_color = 'lavenderblush' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 7 and j == 4: self.brick.color = 'lavenderblush' self.brick.fill_color = 'lavenderblush' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 7 and j == 5: self.brick.color = 'lavenderblush' self.brick.fill_color = 'lavenderblush' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 7 and j == 6: self.brick.color = 'lavenderblush' self.brick.fill_color = 'lavenderblush' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 7 and j == 7: self.brick.color = 'lavenderblush' self.brick.fill_color = 'lavenderblush' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 8 and j == 1: self.brick.color = 'lavenderblush' self.brick.fill_color = 'lavenderblush' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 8 and j == 2: self.brick.color = 'lavenderblush' self.brick.fill_color = 'lavenderblush' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 8 and j == 3: self.brick.color = 'lavenderblush' self.brick.fill_color = 'lavenderblush' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 8 and j == 4: self.brick.color = 'lavenderblush' self.brick.fill_color = 'lavenderblush' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 8 and j == 5: self.brick.color = 'lavenderblush' self.brick.fill_color = 'lavenderblush' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 8 and j == 6: self.brick.color = 'lavenderblush' self.brick.fill_color = 'lavenderblush' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 8 and j == 7: self.brick.color = 'lavenderblush' self.brick.fill_color = 'lavenderblush' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 9 and j == 1: self.brick.color = 'lightpink' self.brick.fill_color = 'lightpink' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 9 and j == 2: self.brick.color = 'lightpink' self.brick.fill_color = 'lightpink' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 9 and j == 3: self.brick.color = 'lightpink' self.brick.fill_color = 'lightpink' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 9 and j == 4: self.brick.color = 'lightpink' self.brick.fill_color = 'lightpink' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 9 and j == 5: self.brick.color = 'lightpink' self.brick.fill_color = 'lightpink' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 9 and j == 6: self.brick.color = 'lightpink' self.brick.fill_color = 'lightpink' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif i == 9 and j == 7: self.brick.color = 'lightpink' self.brick.fill_color = 'lightpink' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) else: self.brick.color = 'hotpink' self.brick.fill_color = 'hotpink' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) # Calculate how many bricks exist. self.numbers_of_brick = BRICK_ROWS * BRICK_COLS def check_for_collision(self): ball_left = self.window.get_object_at(self.ball.x - 0.5, self.ball.y + BALL_RADIUS) ball_right = self.window.get_object_at( self.ball.x + 2 * BALL_RADIUS + 0.5, self.ball.y + BALL_RADIUS) ball_top = self.window.get_object_at(self.ball.x + BALL_RADIUS, self.ball.y - 0.5) ball_bottom = self.window.get_object_at( self.ball.x + BALL_RADIUS, self.ball.y + 2 * BALL_RADIUS + 0.5) # Check whether is lives label: if ball_left is self.lives_label: pass elif ball_right is self.lives_label: pass elif ball_top is self.lives_label: pass elif ball_bottom is self.lives_label: pass # Check whether is start label: if ball_left is self.start_label: pass elif ball_right is self.start_label: pass elif ball_top is self.start_label: pass elif ball_bottom is self.start_label: pass # Check whether is right edge. if self.ball.x + 2 * BALL_RADIUS > self.window.width: self.__dx = -self.__dx # Check whether is left edge. if self.ball.x < 0: self.__dx = -self.__dx # Check whether is upper edge. if self.ball.y < 0: self.__dy = -self.__dy # Check whether is paddle. if ball_bottom is self.paddle: self.__dy = -INITIAL_Y_SPEED elif ball_bottom is self.lives_label or self.start_label: pass # Check whether is brick. if ball_left is not None and ball_left is not self.paddle and ball_left is not self.lives_label\ and ball_left is not self.score_label: self.window.remove(ball_left) self.window.remove(self.score_label) self.__dy = -self.__dy self.numbers_of_brick -= 1 self.score += 1 self.score_label = GLabel(f'Score : {self.score}') self.score_label.color = 'hotpink' self.score_label.font = 'Verdana-15-bold' self.window.add(self.score_label, x=self.window.width - self.score_label.width, y=self.window.height) elif ball_right is not None and ball_right is not self.paddle and ball_right is not self.lives_label\ and ball_right is not self.score_label: self.window.remove(ball_right) self.window.remove(self.score_label) self.__dy = -self.__dy self.numbers_of_brick -= 1 self.score += 1 self.score_label = GLabel(f'Score : {self.score}') self.score_label.color = 'hotpink' self.score_label.font = 'Verdana-15-bold' self.window.add(self.score_label, x=self.window.width - self.score_label.width, y=self.window.height) elif ball_top is not None and ball_top is not self.paddle and ball_top is not self.lives_label\ and ball_top is not self.score_label: self.window.remove(ball_top) self.window.remove(self.score_label) self.__dy = -self.__dy self.numbers_of_brick -= 1 self.score += 1 self.score_label = GLabel(f'Score : {self.score}') self.score_label.color = 'hotpink' self.score_label.font = 'Verdana-15-bold' self.window.add(self.score_label, x=self.window.width - self.score_label.width, y=self.window.height) elif ball_bottom is not None and ball_bottom is not self.paddle and ball_bottom is not self.lives_label\ and ball_bottom is not self.score_label: self.window.remove(ball_bottom) self.window.remove(self.score_label) self.__dy = -self.__dy self.numbers_of_brick -= 1 self.score += 1 self.score_label = GLabel(f'Score : {self.score}') self.score_label.color = 'hotpink' self.score_label.font = 'Verdana-15-bold' self.window.add(self.score_label, x=self.window.width - self.score_label.width, y=self.window.height) def reset_ball(self): # Check whether is lower edge. if self.ball.y > self.window.height: self.lives_left -= 1 self.window.remove(self.lives_label) self.lives_label = GLabel(f'Your Lives : {self.lives_left}') self.lives_label.color = 'hotpink' self.lives_label.font = 'Verdana-15-bold' self.window.add(self.lives_label, x=0, y=self.window.height) self.start_or_not = False self.window.add(self.ball, x=self.window_width / 2 - BALL_RADIUS, y=self.window_height / 2 - BALL_RADIUS) def drag(self, mouse): if PADDLE_WIDTH / 2 <= mouse.x <= self.window.width - PADDLE_WIDTH / 2: self.paddle.x = mouse.x - PADDLE_WIDTH / 2 def start(self, mouse): self.start_or_not = True self.window.remove(self.start_label) def get_dx(self): return self.__dx def get_dy(self): return self.__dy
class BreakoutGraphics: def __init__(self, ball_radius=BALL_RADIUS, paddle_width=PADDLE_WIDTH, paddle_height=PADDLE_HEIGHT, paddle_offset=PADDLE_OFFSET, brick_rows=BRICK_ROWS, brick_cols=BRICK_COLS, brick_width=BRICK_WIDTH, brick_height=BRICK_HEIGHT, brick_offset=BRICK_OFFSET, brick_spacing=BRICK_SPACING, title='Breakout'): # Create a graphical window, with some extra space. window_width = brick_cols * (brick_width + brick_spacing) - brick_spacing window_height = brick_offset + 3 * (brick_rows * (brick_height + brick_spacing) - brick_spacing) self.window = GWindow(width=window_width, height=window_height, title=title) # Create a paddle. self.paddle = GRect(paddle_width, paddle_height, x=(self.window.width - paddle_width) / 2, y=self.window.height - paddle_offset) self.paddle.filled = True self.window.add(self.paddle) # Center a filled ball in the graphical window. self.ball = GOval(ball_radius * 2, ball_radius * 2, x=(self.window.width - ball_radius * 2) / 2, y=(self.window.height - ball_radius * 2) / 2) self.ball.filled = True self.window.add(self.ball) # Create life bars self.live_1 = GRect(10, 20, x=self.window.width - 10 - brick_spacing, y=self.window.height - 20 - brick_spacing) self.live_1.filled = True self.live_1.fill_color = 'blue' self.window.add(self.live_1) self.live_2 = GRect(10, 20, x=self.window.width - (10 + brick_spacing) * 2, y=self.window.height - 20 - brick_spacing) self.live_2.filled = True self.live_2.fill_color = 'blue' self.window.add(self.live_2) self.live_3 = GRect(10, 20, x=self.window.width - (10 + brick_spacing) * 3, y=self.window.height - 20 - brick_spacing) self.live_3.filled = True self.live_3.fill_color = 'blue' self.window.add(self.live_3) # Create score label self.score = 0 self.switch = 0 self.label = GLabel(f'Score:{self.score}', 0, self.window.height) self.label.font = "-20" self.window.add(self.label) # Create game over label self.label_e = GLabel(f'【Game Over】', x=(self.window.width - 340) / 2, y=(self.window.height - 20) / 2) self.label_e.font = "-40" # Draw bricks. for i in range(BRICK_COLS): for j in range(BRICK_ROWS): self.brick = GRect(brick_width, brick_height, x=(brick_width + brick_spacing) * i, y=brick_offset + (brick_height + brick_spacing) * j) self.brick.filled = True if j == 0 or j == 1: self.brick.fill_color = 'maroon' self.brick.color = 'maroon' if j == 2 or j == 3: self.brick.fill_color = 'crimson' self.brick.color = 'crimson' if j == 4 or j == 5: self.brick.fill_color = 'salmon' self.brick.color = 'salmon' if j == 6 or j == 7: self.brick.fill_color = 'pale violetred' self.brick.color = 'pale violetred' if j == 8 or j == 9: self.brick.fill_color = 'light pink' self.brick.color = 'light pink' self.window.add(self.brick) # Default initial velocity for the ball. self.__dx = 0 self.__dy = 0 # Initialize our mouse listeners. onmousemoved(self.paddle_move) onmouseclicked(self.start) def get_dx(self): return self.__dx def get_dy(self): return self.__dy def reset_dx(self): self.__dx = 0 def reset_dy(self): self.__dy = 0 def change_dx(self): self.__dx = -self.__dx def change_dy(self): self.__dy = -self.__dy # Start the game def start(self, event): if self.switch == 0: self.set_v() self.switch = 1 def b_or_p(self): # To decide whether it's brick or addle obj = self.object() if obj is self.paddle: self.__dy = -self.__dy if obj is not self.paddle and obj.y < self.paddle.y: self.window.remove(obj) self.__dy = -self.__dy self.score += 10 self.window.remove(self.label) self.label = GLabel(f'Score:{self.score}', 0, self.window.height) self.label.font = "-20" self.window.add(self.label) def object(self): # Four coordinates of the ball obj1 = self.window.get_object_at(self.ball.x, self.ball.y) obj2 = self.window.get_object_at(self.ball.x, self.ball.y + self.ball.height) obj3 = self.window.get_object_at(self.ball.x + self.ball.width, self.ball.y) obj4 = self.window.get_object_at(self.ball.x + self.ball.width, self.ball.y + self.ball.height) obj = obj1 or obj2 or obj3 or obj4 return obj def reset_ball(self): # Set the ball at the center of the graphical window self.ball = GOval(self.ball.width, self.ball.height, x=(self.window.width - self.ball.width) / 2, y=(self.window.height - self.ball.height) / 2) self.ball.filled = True self.window.add(self.ball) def set_v(self): # Set the speed of the ball. self.__dx = random.randint(1, MAX_X_SPEED) self.__dy = INITIAL_Y_SPEED if (random.random()) > 0.5: self.__dx = -self.__dx def paddle_move(self, event): # Let the paddle move. if self.paddle.width / 2 >= event.x: self.paddle.x = 0 self.paddle.y = self.paddle.y elif event.x >= self.window.width - self.paddle.width / 2: self.paddle.x = self.window.width - self.paddle.width self.paddle.y = self.paddle.y else: self.paddle.x = event.x - self.paddle.width / 2 self.paddle.y = self.paddle.y
class BreakoutGraphics: def __init__(self, ball_radius=BALL_RADIUS, paddle_width=PADDLE_WIDTH, paddle_height=PADDLE_HEIGHT, paddle_offset=PADDLE_OFFSET, brick_rows=BRICK_ROWS, brick_cols=BRICK_COLS, brick_width=BRICK_WIDTH, brick_height=BRICK_HEIGHT, brick_offset=BRICK_OFFSET, brick_spacing=BRICK_SPACING, title='Breakout'): self.game_started = False # Create a graphical window, with some extra space. window_width = brick_cols * (brick_width + brick_spacing) - brick_spacing window_height = brick_offset + 3 * (brick_rows * (brick_height + brick_spacing) - brick_spacing) self.window = GWindow(width=window_width, height=window_height, title=title) # Create a score and a live self.sscore = GLabel('{score}: 0') self.sscore.font = '-20' self.window.add(self.sscore, x=0, y=self.sscore.height + 20) self.live = GLabel('3 :{live}') self.live.font = '-20' self.window.add(self.live, x=window_width - self.live.width, y=self.live.height + 20) # Create a paddle. self.paddle = GRect(paddle_width, paddle_height, x=window_width // 2 - paddle_width // 2, y=window_height - paddle_offset) self.paddle.filled = True self.window.add(self.paddle) # Center a filled ball in the graphical window. self.ball = GOval(ball_radius * 2, ball_radius * 2, x=window_width // 2 - ball_radius, y=window_height // 2 - ball_radius) self.ball.filled = True self.window.add(self.ball) # Default initial velocity for the ball. self.__dyr__dxr() # Initialize our mouse listeners. onmousemoved(self.move_paddle) onmouseclicked(self.start) # Draw bricks. for cols in range(brick_cols): for row in range(brick_rows): block = GRect(brick_width, brick_height) self.block = block block.filled = True block.color = self.block_color(cols) block.fill_color = self.block_color(cols) self.window.add(block, x=(block.width + brick_spacing) * row, y=brick_offset + (brick_spacing + block.height) * cols) # draw a disturb playing block self.brick_width = brick_width self.disturb = GRect(brick_width + 20, brick_height, x=self.window.width - brick_width, y=250) self.disturb.color = 'magenta' self.disturb.filled = True self.disturb.fill_color = 'magenta' self.window.add(self.disturb) self.d = -1 # set self self.brick_c = brick_cols self.brick_row = brick_rows def __dyr__dxr(self): """ set __dx and __dy """ self.__dy = INITIAL_Y_SPEED self.__dx = random.randint(1, MAX_X_SPEED) if (random.random() > 0.5): self.__dx = -self.__dx def block_color(self, c): """ :param c: brick's cols :return: the brick's color """ if int(c // 2) == 0: return 'red' elif int(c // 2) == 1: return 'orange' elif int(c // 2) == 2: return 'yellow' elif int(c // 2) == 3: return 'green' elif int(c // 2) == 4: return 'blue' def move_paddle(self, event): """ :param event: mouse """ if not event.x < 0 + self.paddle.width // 2 and not event.x + self.paddle.width // 2 > self.window.width: self.paddle.x = event.x - self.paddle.width // 2 def get_dx(self): """ :return __dx: the speed of the ball x """ return self.__dx def get_dy(self): """ :return __dy: the speed of the ball y """ return self.__dy def bounce_ball(self, dx, dy, lives, score, delay, score2): """ :param dx: the speed of the ball x :param dy: the speed of the ball y :param lives: the lives you left :param score: the score you have :param delay: the pause time :return lives, score, delay: the lives , score, pause time """ self.disturb.x += self.d self.d -= 1 if self.disturb.x <= 0: self.d = -self.d elif self.disturb.x > self.window.width - self.disturb.width: self.disturb.x = self.window.width - self.brick_width - 50 self.d = -1 # bounce at the edge if self.ball.x + self.ball.width > self.window.width or self.ball.x < 0: # x if self.ball.y + self.ball.width > self.window.height or self.ball.y < 0: # if the ball bounce at the corner dx *= -1 dy *= -1 else: dx *= -1 elif self.ball.y < 0: # y if self.ball.x + self.ball.width > self.window.width or self.ball.x < 0: # if the ball bounce at the corner dy *= -1 dx *= -1 else: dy *= -1 elif self.ball.y + self.ball.width > self.window.height: # if the ball bounce at the ground lives -= 1 # live - 1 self.game_started = False # the ball is not bouncing now self.ball.x = self.window.width // 2 - self.ball.width // 2 self.ball.y = self.window.height // 2 - self.ball.width // 2 self.__dyr__dxr() self.sscore.text = '{score}: ' + str(score) self.live.text = str(lives) + ' :{live}' return lives, score, delay, score2, self.brick_c * self.brick_row # bounce at the block elif self.window.get_object_at(self.ball.x, self.ball.y): maybe_obj = self.window.get_object_at(self.ball.x, self.ball.y) if self.ball.y > 50: if self.ball.y < 250 and self.ball.y > 49: self.window.remove(maybe_obj) score += self.score(maybe_obj.y) score2 += 1 delay -= 0.2 elif self.ball.y > 350: self.ball.y = self.paddle.y - self.ball.height if self.ball.y > 49: dy *= -1 elif self.window.get_object_at(self.ball.x + BALL_RADIUS * 2, self.ball.y): maybe_obj = self.window.get_object_at( self.ball.x + self.ball.width, self.ball.y) if self.ball.y > 50: if self.ball.y < 250 and self.ball.y > 49: self.window.remove(maybe_obj) score += self.score(maybe_obj.y) score2 += 1 delay -= 0.2 elif self.ball.y > 350: self.ball.y = self.paddle.y - self.ball.height if self.ball.y > 49: dy *= -1 elif self.window.get_object_at(self.ball.x, self.ball.y + self.ball.width): maybe_obj = self.window.get_object_at( self.ball.x, self.ball.y + self.ball.width) if self.ball.y > 50: if self.ball.y + self.ball.width < 250 and self.ball.y + self.ball.width > 49: self.window.remove(maybe_obj) score += self.score(maybe_obj.y) score2 += 1 delay -= 0.2 elif self.ball.y > 350: self.ball.y = self.paddle.y - self.ball.height if self.ball.y > 49: dy *= -1 elif self.window.get_object_at(self.ball.x + self.ball.width, self.ball.y + self.ball.width): maybe_obj = self.window.get_object_at( self.ball.x + self.ball.width, self.ball.y + self.ball.width) if self.ball.y > 50: if self.ball.y + self.ball.width < 250 and self.ball.y + self.ball.width > 49: self.window.remove(maybe_obj) score += self.score(maybe_obj.y) score2 += 1 delay -= 0.2 elif self.ball.y > 350: self.ball.y = self.paddle.y - self.ball.height if self.ball.y > 49: dy *= -1 self.ball.move(dx, dy) self.__dx = dx self.__dy = dy self.sscore.text = '{score}: ' + str(score) self.live.text = str(lives) + ' :{live}' return lives, score, delay, score2, self.brick_c * self.brick_row def start(self, event): """ :param event: mouse """ if not self.game_started: self.game_started = True def get_game_state(self): """ :return game_start: is the game running? """ return self.game_started def score(self, y): if y < 80: return 5 elif y < 120: return 4 elif y < 160: return 3 elif y < 200: return 2 elif y < 240: return 1 def remove_all(self, score): self.window.remove(self.ball) self.window.remove(self.paddle) self.window.remove(self.sscore) self.window.remove(self.live) self.window.remove(self.disturb) if score == 300: win = GLabel('YOU WIN!! . . YA!!!!!!!!!\n U', x=50, y=350) win.font = '-20' self.window.add(win) else: sscore = GLabel('YOUR SCORE IS:' + str(score) + '\n HA HA HA YOU LOSE!!!', x=50, y=350) sscore.font = '-20' self.window.add(sscore)
class BreakoutGraphics: def __init__(self, ball_radius=BALL_RADIUS, paddle_width=PADDLE_WIDTH, paddle_height=PADDLE_HEIGHT, paddle_offset=PADDLE_OFFSET, brick_rows=BRICK_ROWS, brick_cols=BRICK_COLS, brick_width=BRICK_WIDTH, brick_height=BRICK_HEIGHT, brick_offset=BRICK_OFFSET, brick_spacing=BRICK_SPACING, title='Breakout'): # Create a graphical window, with some extra space. window_width = brick_cols * (brick_width + brick_spacing) - brick_spacing window_height = brick_offset + 3 * (brick_rows * (brick_height + brick_spacing) - brick_spacing) self.window = GWindow(width=window_width, height=window_height, title=title) self.brick_offset = brick_offset #win condition- for bricks hitted self.break_hit = 0 # Create a paddle. self.paddle = GRect(paddle_width, paddle_height, x=(self.window.width - paddle_width) / 2, y=(self.window.height - paddle_offset)) self.paddle.filled = True self.window.add(self.paddle) self.brick_rows = brick_rows self.brick_cols = brick_cols self.paddle_offset = paddle_offset # Draw bricks. for i in range(brick_rows): for j in range(brick_cols): self.brick = GRect(brick_width, brick_height) self.brick.filled = True self.window.add(self.brick, x=j * (brick_width + brick_spacing), y=(brick_offset + brick_height) + i * (brick_height + brick_spacing)) if i < 2: self.brick.fill_color = 'red' self.brick.color = 'red' elif 1 < i < 4: self.brick.fill_color = 'orange' self.brick.color = 'orange' elif 3 < i < 6: self.brick.fill_color = 'yellow' self.brick.color = 'yellow' elif 5 < i < 8: self.brick.fill_color = 'seagreen' self.brick.color = 'seagreen' elif 7 < i < 10: self.brick.fill_color = 'royalblue' self.brick.color = 'royalblue' elif 9 < i < 12: self.brick.fill_color = 'midnightblue' self.brick.color = 'midnightblue' elif 11 < i < 14: self.brick.fill_color = 'purple' self.brick.color = 'purple' else: self.brick.fill_color = 'silver' self.brick.color = 'silver' # Center a filled ball in the graphical window. self.ball_r = ball_radius self.ball = GOval(self.ball_r * 2, self.ball_r * 2, x=(self.window.width - self.ball_r * 2) / 2, y=(self.window.height - self.ball_r * 2) / 2) self.ball.filled = True self.window.add(self.ball) # Default initial velocity for the ball. self.__bx = random.randint(1, MAX_X_SPEED) if random.random() > 0.5: self.__bx = -self.__bx self.__by = INITIAL_Y_SPEED # Initialize our mouse listeners. onmouseclicked(self.start_game) onmousemoved(self.move_paddle) def start_game(self, click): global is_playing is_playing = True # if ball drops, game needs to restart def end_game(self): global is_playing is_playing = False def move_paddle(self, mouse): if self.paddle.width / 2 <= mouse.x <= self.window.width - self.paddle.width / 2: self.window.add(self.paddle, x=mouse.x - self.paddle.width / 2, y=self.window.height - self.paddle_offset) elif self.paddle.width / 2 >= mouse.x: self.window.add(self.paddle, x=0, y=self.window.height - self.paddle_offset) elif mouse.x >= self.window.width - self.paddle.width / 2: self.window.add(self.paddle, x=self.window.width - self.paddle.width, y=self.window.height - self.paddle_offset) # to know if the ball hit on sth or not def ball_hit(self): is_ball1point_hit = self.window.get_object_at(self.ball.x, self.ball.y) is not None is_ball2point_hit = self.window.get_object_at( self.ball.x + 2 * self.ball_r, self.ball.y) is not None is_ball3point_hit = self.window.get_object_at( self.ball.x, self.ball.y + 2 * self.ball_r) is not None is_ball4point_hit = self.window.get_object_at( self.ball.x + 2 * self.ball_r, self.ball.y + 2 * self.ball_r) is not None return is_ball1point_hit or is_ball2point_hit or is_ball3point_hit or is_ball4point_hit # to remove brick def remove_brick(self): global is_playing ball1point_brick = self.window.get_object_at(self.ball.x, self.ball.y) ball2point_brick = self.window.get_object_at( self.ball.x + 2 * self.ball_r, self.ball.y) ball3point_brick = self.window.get_object_at( self.ball.x, self.ball.y + 2 * self.ball_r) ball4point_brick = self.window.get_object_at( self.ball.x + 2 * self.ball_r, self.ball.y + 2 * self.ball_r) if ball1point_brick is not None and ball1point_brick is not self.paddle: self.window.remove(ball1point_brick) self.break_hit += 1 if ball2point_brick is not None and ball2point_brick is not self.paddle: self.window.remove(ball2point_brick) if ball1point_brick != ball2point_brick: self.break_hit += 1 if ball3point_brick is not None and ball3point_brick is not self.paddle: self.window.remove(ball3point_brick) self.break_hit += 1 if ball4point_brick is not None and ball4point_brick is not self.paddle: self.window.remove(ball4point_brick) if ball3point_brick != ball4point_brick: self.break_hit += 1 return self.break_hit # to check if ball drop def ball_drop(self): is_ball_drop = self.ball.y + self.ball.height >= self.window.height return is_ball_drop # let the ball back to initial point def set_ball_position(self): self.window.remove(self.ball) self.window.add(self.ball, x=(self.window.width - self.ball_r * 2) / 2, y=(self.window.height - self.ball_r * 2) / 2) # getters def get_speedx(self): return self.__bx def get_speedy(self): return self.__by def get_isplaying(self): return is_playing
class BreakoutGraphics1: def __init__(self, ball_radius=BALL_RADIUS, paddle_width=PADDLE_WIDTH, paddle_height=PADDLE_HEIGHT, paddle_offset=PADDLE_OFFSET, brick_rows=BRICK_ROWS, brick_cols=BRICK_COLS, brick_width=BRICK_WIDTH, brick_height=BRICK_HEIGHT, brick_offset=BRICK_OFFSET, brick_spacing=BRICK_SPACING, title='Breakout'): # Create a graphical window, with some extra space. window_width = brick_cols * (brick_width + brick_spacing) - brick_spacing window_height = brick_offset + 3 * (brick_rows * (brick_height + brick_spacing) - brick_spacing) self.window = GWindow(width=window_width, height=window_height, title=title) # Create a paddle. self.paddle = GRect(paddle_width, paddle_height, x=(self.window.width - paddle_width) / 2, y=self.window.height - paddle_offset) self.paddle.filled = True self.paddle.fill_color = 'medium blue' self.window.add(self.paddle) # Center a filled ball in the graphical window. self.ball = GOval(2 * ball_radius, 2 * ball_radius, x=window_width / 2 - 2 * ball_radius, y=window_height / 2 - 2 * ball_radius) self.ball.filled = True self.ball.fill_color = 'medium blue' self.window.add(self.ball) # Default initial velocity for the ball. # for x self.__dx = random.randint(0, MAX_X_SPEED) if random.random() > 0.5: self.__dx = -self.__dx # for y self.__dy = INITIAL_Y_SPEED # Initialize our mouse listeners. self.is_started = False onmouseclicked(self.switch) onmousemoved(self.mouse_move_paddle) # Draw bricks. count_rows = 0 count_rows_color = 1 for i in range(brick_cols): for j in range(brick_rows): self.brick = GRect(brick_width, brick_height, x=count_rows + j * brick_spacing, y=BRICK_OFFSET + i * (brick_height + brick_spacing)) self.brick.filled = True if count_rows_color == 1 or count_rows_color == 2: self.brick.fill_color = 'royal blue' elif count_rows_color == 3 or count_rows_color == 4: self.brick.fill_color = 'dodger blue' elif count_rows_color == 5 or count_rows_color == 6: self.brick.fill_color = 'deep sky blue' elif count_rows_color == 7 or count_rows_color == 8: self.brick.fill_color = 'aqua' elif count_rows_color == 9 or count_rows_color == 10: self.brick.fill_color = 'pale turquoise' self.window.add(self.brick) count_rows += brick_width count_rows = 0 count_rows_color += 1 # to check if there are any bricks left on window. # when bricks count > bricks amount , it means all the bricks are deleted. self.bricks_amount = brick_rows * brick_cols self.bricks_count = 1 # life label self.life = 3 self.life_label = GLabel(f'Lives: {self.life}') self.life_label.font = '-25' self.window.add(self.life_label, x=self.window.width - self.life_label.width, y=self.window.height) # score label self.scores = 0 self.score_label = GLabel(f'Score: {self.scores}', x=0, y=self.window.height) self.score_label.font = '-25' self.window.add(self.score_label) # paddle movement def mouse_move_paddle(self, event): self.paddle.x = event.x - self.paddle.width / 2 if self.paddle.x <= 0: self.paddle.x = 0 if self.paddle.x >= self.window.width - self.paddle.width: self.paddle.x = self.window.width - self.paddle.width # ball movement def get_ball_dx(self): return self.__dx def get_ball_dy(self): return self.__dy def set_ball_dx(self, new_dx): self.__dx = new_dx def set_ball_dy(self, new_dy): self.__dy = new_dy def reset_ball(self): self.ball.x = self.window.width / 2 - self.ball.width self.ball.y = self.window.height / 2 - self.ball.height self.__dx = random.randint(0, MAX_X_SPEED) if random.random() > 0.5: self.__dx = -self.__dx # for y self.__dy = INITIAL_Y_SPEED # switch def switch(self, mouse): self.is_started = True # check for touching bricks def obstacles(self): maybe_brick_1 = self.window.get_object_at(self.ball.x, self.ball.y) maybe_brick_2 = self.window.get_object_at( self.ball.x + self.ball.width, self.ball.y) maybe_brick_3 = self.window.get_object_at( self.ball.x, self.ball.y + self.ball.height) maybe_brick_4 = self.window.get_object_at( self.ball.x + self.ball.width, self.ball.y + self.ball.height) if maybe_brick_1 is not None: if maybe_brick_1 is not self.paddle and maybe_brick_1 is not self.score_label and maybe_brick_1 is not self.life_label: self.window.remove(maybe_brick_1) if self.scores <= 0.25 * self.bricks_amount: self.__dy = -1 * self.__dy elif 0.25 * self.bricks_amount < self.scores <= 0.5 * self.bricks_amount: self.__dy = -1.05 * self.__dy elif 0.5 * self.bricks_amount < self.scores <= 0.75 * self.bricks_amount: self.__dy = -1.075 * self.__dy elif 0.75 * self.bricks_amount < self.scores <= self.bricks_amount: self.__dy = -1.1 * self.__dy self.bricks_count += 1 self.scores += 1 self.score_label.text = f'Score: {self.scores}' elif maybe_brick_1 is self.paddle: # make sure the ball will not het into paddle. self.ball.y = self.paddle.y - self.ball.height self.__dy = -1 * self.__dy elif maybe_brick_2 is not None: if maybe_brick_2 is not self.paddle and maybe_brick_2 is not self.score_label and maybe_brick_2 is not self.life_label: self.window.remove(maybe_brick_2) if self.scores <= 0.25 * self.bricks_amount: self.__dy = -1 * self.__dy elif 0.25 * self.bricks_amount < self.scores <= 0.5 * self.bricks_amount: self.__dy = -1.05 * self.__dy elif 0.5 * self.bricks_amount < self.scores <= 0.75 * self.bricks_amount: self.__dy = -1.075 * self.__dy elif 0.75 * self.bricks_amount < self.scores <= self.bricks_amount: self.__dy = -1.1 * self.__dy self.bricks_count += 1 self.scores += 1 self.score_label.text = f'Score: {self.scores}' elif maybe_brick_2 is self.paddle: # make sure the ball will not het into paddle. self.ball.y = self.paddle.y - self.ball.height self.__dy = -1 * self.__dy elif maybe_brick_3 is not None: if maybe_brick_3 is not self.paddle and maybe_brick_3 is not self.score_label and maybe_brick_3 is not self.life_label: self.window.remove(maybe_brick_3) if self.scores <= 0.25 * self.bricks_amount: self.__dy = -1 * self.__dy elif 0.25 * self.bricks_amount < self.scores <= 0.5 * self.bricks_amount: self.__dy = -1.05 * self.__dy elif 0.5 * self.bricks_amount < self.scores <= 0.75 * self.bricks_amount: self.__dy = -1.075 * self.__dy elif 0.75 * self.bricks_amount < self.scores <= self.bricks_amount: self.__dy = -1.1 * self.__dy self.bricks_count += 1 self.scores += 1 self.score_label.text = f'Score: {self.scores}' elif maybe_brick_3 is self.paddle: # make sure the ball will not het into paddle. self.ball.y = self.paddle.y - self.ball.height self.__dy = -1 * self.__dy elif maybe_brick_4 is not None: if maybe_brick_4 is not self.paddle and maybe_brick_4 is not self.score_label and maybe_brick_4 is not self.life_label: self.window.remove(maybe_brick_4) if self.scores <= 0.25 * self.bricks_amount: self.__dy = -1 * self.__dy elif 0.25 * self.bricks_amount < self.scores <= 0.5 * self.bricks_amount: self.__dy = -1.05 * self.__dy elif 0.5 * self.bricks_amount < self.scores <= 0.75 * self.bricks_amount: self.__dy = -1.075 * self.__dy elif 0.75 * self.bricks_amount < self.scores <= self.bricks_amount: self.__dy = -1.1 * self.__dy self.bricks_count += 1 self.scores += 1 self.score_label.text = f'Score: {self.scores}' elif maybe_brick_4 is self.paddle: # make sure the ball will not het into paddle. self.ball.y = self.paddle.y - self.ball.height self.__dy = -1 * self.__dy
class BreakoutGraphics: def __init__(self, ball_radius=BALL_RADIUS, paddle_width=PADDLE_WIDTH, paddle_height=PADDLE_HEIGHT, paddle_offset=PADDLE_OFFSET, brick_rows=BRICK_ROWS, brick_cols=BRICK_COLS, brick_width=BRICK_WIDTH, brick_height=BRICK_HEIGHT, brick_offset=BRICK_OFFSET, brick_spacing=BRICK_SPACING, title='Breakout'): # Create a graphical window, with some extra space. window_width = brick_cols * (brick_width + brick_spacing) - brick_spacing window_height = brick_offset + 3 * (brick_rows * (brick_height + brick_spacing) - brick_spacing) self.window = GWindow(width=window_width, height=window_height, title=title) # total bricks self.all = brick_rows * brick_cols * 10 # set up score self.score = 0 self.scorelabel = GLabel('score=' + str(self.score), x=5, y=self.window.height - 5) self.scorelabel.font = '-25' self.window.add(self.scorelabel) # set up lives self.lives = 3 self.liveslabel = GLabel('lives=' + str(self.lives), x=320, y=self.window.height - 5) self.liveslabel.font = '-25' self.window.add(self.liveslabel) # Create a paddle. self.paddle = GRect(paddle_width, paddle_height, x=(self.window.width - paddle_width) / 2, y=self.window.height - paddle_offset) self.paddle.filled = True self.window.add(self.paddle) # Center a filled ball in the graphical window. self.ball_radius = ball_radius self.ball = GOval(ball_radius * 2, ball_radius * 2) self.ball.filled = True self.window.add(self.ball, (self.window.width - ball_radius) / 2, (self.window.height - ball_radius) / 2) # Default initial velocity for the ball. self.__dx = 0 self.__dy = INITIAL_Y_SPEED self.__dx = random.randint( 1, MAX_X_SPEED) # dx is randomly picked from 1 to MAX_X_SPEED. if random.random() > 0.5: self.__dx = -self.__dx # Draw bricks. for i in range(brick_rows): self.brick = GRect(brick_width, brick_height, x=(brick_width + brick_spacing) * i, y=0) self.brick.fill_color = (0, 0, 255 - (i * 20)) self.brick.color = (0, 0, 255 - (i * 20)) self.brick.filled = True self.window.add(self.brick) for j in range(brick_cols): self.brick = GRect(brick_width, brick_height, x=(brick_width + brick_spacing) * i, y=(brick_height + brick_spacing) * j) self.brick.fill_color = (0, 0, 255 - (j * 20)) self.brick.color = (0, 0, 255 - (i * 20)) self.brick.filled = True self.window.add(self.brick) # Initialize our mouse listeners. onmousemoved(self.paddle_move) onmouseclicked(self.play) # click to start self.user_click = False # to detect if user clicked or not def play(self, m): if 0 <= m.x <= self.window.width and 0 <= m.y <= self.window.height: self.user_click = True def paddle_move(self, m): if m.x <= self.window.width - self.paddle.width: self.paddle.x = m.x def reset_ball(self): self.ball = GOval(self.ball_radius * 2, self.ball_radius * 2) self.ball.filled = True self.window.add(self.ball, (self.window.width - self.ball_radius) / 2, (self.window.height - self.ball_radius) / 2) def resetscore(self, new): self.window.remove(self.scorelabel) self.score = new self.scorelabel = GLabel('score=' + str(self.score), x=5, y=self.window.height - 5) self.scorelabel.font = '-25' self.window.add(self.scorelabel) def resetlive(self, new): self.window.remove(self.liveslabel) self.lives = new self.liveslabel = GLabel('lives=' + str(self.lives), x=320, y=self.window.height - 5) self.liveslabel.font = '-25' self.window.add(self.liveslabel) def is_hitup(self): if self.ball.y < 0: return True def is_hitside(self): if self.ball.x < 0 or self.ball.x + self.ball.width > self.window.width: return True def is_hitpaddle(self): if self.window.get_object_at(self.ball.x+self.ball_radius*2, self.ball.y+self.ball_radius*2) == self.paddle or\ self.window.get_object_at(self.ball.x, self.ball.y) == self.paddle or\ self.window.get_object_at(self.ball.x+self.ball_radius*2, self.ball.y) == self.paddle or\ self.window.get_object_at(self.ball.x, self.ball.y+self.ball_radius*2) == self.paddle: return True def is_hitground(self): if self.ball.y > self.window.height: return True # if wh is brick , it will be true and enter a loop to remove the brick def is_brick(self, wh): if wh is not self.paddle and wh is not self.scorelabel and wh is not self.liveslabel: return True # to check four angle of the ball is None or not def is_hit_something(self): if self.window.get_object_at(self.ball.x, self.ball.y) is None: if self.window.get_object_at(self.ball.x + self.ball_radius * 2, self.ball.y) is None: if self.window.get_object_at( self.ball.x + self.ball_radius * 2, self.ball.y + self.ball_radius * 2) is None: if self.window.get_object_at( self.ball.x, self.ball.y + self.ball_radius * 2) is not None: return True else: return True else: return True else: return True # if the ball hit something, this function will return what thing is this def hit_something(self): if self.window.get_object_at(self.ball.x, self.ball.y) is None: if self.window.get_object_at(self.ball.x + self.ball_radius * 2, self.ball.y) is None: if self.window.get_object_at( self.ball.x + self.ball_radius * 2, self.ball.y + self.ball_radius * 2) is None: return self.window.get_object_at( self.ball.x, self.ball.y + self.ball_radius * 2) else: return self.window.get_object_at( self.ball.x + self.ball_radius * 2, self.ball.y + self.ball_radius * 2) else: return self.window.get_object_at( self.ball.x + self.ball_radius * 2, self.ball.y) else: return self.window.get_object_at(self.ball.x, self.ball.y) # get dx and dy def get_dx(self): return self.__dx def get_dy(self): return self.__dy # run out of all lives def lose(self): lose = GLabel('You Lose:(') lose.font = '-40' self.window.add(lose, x=(self.window.width - lose.width) / 2, y=(self.window.height - lose.width) / 2) # clean all the bricks def win(self): win = GLabel('You win:D') win.font = '-40' self.window.add(win, x=(self.window.width - win.width) / 2, y=(self.window.height - win.width) / 2)
class BreakoutGraphics: def __init__(self, ball_radius=BALL_RADIUS, paddle_width=PADDLE_WIDTH, paddle_height=PADDLE_HEIGHT, paddle_offset=PADDLE_OFFSET, brick_rows=BRICK_ROWS, brick_cols=BRICK_COLS, brick_width=BRICK_WIDTH, brick_height=BRICK_HEIGHT, brick_offset=BRICK_OFFSET, brick_spacing=BRICK_SPACING, title='Breakout'): # How many lives left. self.lives_left = LIVES # Create a graphical window, with some extra space. self.window_width = brick_cols * (brick_width + brick_spacing) - brick_spacing self.window_height = brick_offset + 3 * (brick_rows * (brick_height + brick_spacing) - brick_spacing) self.window = GWindow(width=self.window_width, height=self.window_height, title=title) # Create a paddle. self.paddle = GRect(PADDLE_WIDTH, PADDLE_HEIGHT, x=(self.window_width - PADDLE_WIDTH) / 2, y=self.window_height - PADDLE_OFFSET) self.paddle.filled = True self.paddle.color = 'lavenderblush' self.paddle.fill_color = 'lavenderblush' self.window.add(self.paddle) # Center a filled ball in the graphical window. self.ball = GOval(BALL_RADIUS * 2, BALL_RADIUS * 2, x=self.window_width / 2 - BALL_RADIUS, y=self.window_height / 2 - BALL_RADIUS) self.ball.filled = True self.ball.color = 'lightpink' self.ball.fill_color = 'lightpink' self.window.add(self.ball) # Default initial velocity for the ball. self.__dx = random.randint(1, MAX_X_SPEED) self.__dy = INITIAL_Y_SPEED if random.random() > 0.5: self.__dx = -self.__dx # Determine whether game has been started. self.start_or_not = False # Initialize our mouse listeners. onmouseclicked(self.start) # Determine the game has started. onmousemoved(self.drag) # Draw bricks. for i in range(BRICK_ROWS): for j in range(BRICK_COLS): self.brick = GRect(BRICK_WIDTH, BRICK_HEIGHT) self.brick.filled = True if j == 0 or j == 1: self.brick.color = 'darkmagenta' self.brick.fill_color = 'darkmagenta' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif j == 2 or j == 3: self.brick.color = 'mediumvioletred' self.brick.fill_color = 'mediumvioletred' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif j == 4 or j == 5: self.brick.color = 'deeppink' self.brick.fill_color = 'deeppink' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif j == 6 or j == 7: self.brick.color = 'hotpink' self.brick.fill_color = 'hotpink' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) elif j == 8 or j == 9: self.brick.color = 'pink' self.brick.fill_color = 'pink' self.window.add(self.brick, x=(BRICK_SPACING * i + BRICK_WIDTH * i), y=(BRICK_SPACING * j + BRICK_HEIGHT * j + BRICK_OFFSET)) # Calculate how many bricks exist. self.numbers_of_brick = BRICK_ROWS * BRICK_COLS def check_for_collision(self): ball_upper_left = self.window.get_object_at(self.ball.x, self.ball.y) ball_upper_right = self.window.get_object_at(self.ball.x + 2 * BALL_RADIUS, self.ball.y) ball_lower_left = self.window.get_object_at(self.ball.x, self.ball.y + 2 * BALL_RADIUS) ball_lower_right = self.window.get_object_at(self.ball.x + 2 * BALL_RADIUS, self.ball.y + 2 * BALL_RADIUS) # Check whether is right edge. if self.ball.x + 2 * BALL_RADIUS > self.window.width: self.__dx = -self.__dx # Check whether is left edge. if self.ball.x < 0: self.__dx = -self.__dx # Check whether is upper edge. if self.ball.y < 0: self.__dy = -self.__dy # Check whether is paddle. if ball_lower_left or ball_lower_right is self.paddle: self.__dy = -INITIAL_Y_SPEED # Check whether is brick. if ball_upper_left is not None and ball_upper_left is not self.paddle: self.window.remove(ball_upper_left) self.__dy = -self.__dy self.numbers_of_brick -= 1 elif ball_upper_right is not None and ball_upper_right is not self.paddle: self.window.remove(ball_upper_right) self.__dy = -self.__dy self.numbers_of_brick -= 1 elif ball_lower_left is not None and ball_lower_left is not self.paddle: self.window.remove(ball_lower_left) self.__dy = -self.__dy self.numbers_of_brick -= 1 elif ball_lower_right is not None and ball_lower_right is not self.paddle: self.window.remove(ball_lower_right) self.__dy = -self.__dy self.numbers_of_brick -= 1 def reset_ball(self): # Check whether is lower edge. if self.ball.y > self.window.height: self.lives_left -= 1 self.start_or_not = False self.window.add(self.ball, x=self.window_width / 2 - BALL_RADIUS, y=self.window_height / 2 - BALL_RADIUS) def drag(self, mouse): if PADDLE_WIDTH / 2 <= mouse.x <= self.window.width - PADDLE_WIDTH / 2: self.paddle.x = mouse.x - PADDLE_WIDTH / 2 def start(self, mouse): self.start_or_not = True def get_dx(self): return self.__dx def get_dy(self): return self.__dy
class BreakoutGraphics: ''' Description: 1. Set up initial attributes. 2. Create graphical window 3. Create a paddle & filled ball in the graphical window 4. Draw bricks 5. Default initial velocity for the ball & Initialize our mouse listeners 6. Make method to check collision between ball and wall or bricks ''' def __init__(self, ball_radius=BALL_RADIUS, paddle_width=PADDLE_WIDTH, paddle_height=PADDLE_HEIGHT, paddle_offset=PADDLE_OFFSET, brick_rows=BRICK_ROWS, brick_cols=BRICK_COLS, brick_width=BRICK_WIDTH, brick_height=BRICK_HEIGHT, brick_offset=BRICK_OFFSET, brick_spacing=BRICK_SPACING, title='Breakout'): # 方便改constant # Create a graphical window, with some extra space window_width = brick_cols * (brick_width + brick_spacing) - brick_spacing window_height = brick_offset + 3 * (brick_rows * (brick_height + brick_spacing) - brick_spacing) self.window = GWindow(width=window_width, height=window_height, title=title) # Create a paddle self.paddle = GRect(paddle_width, paddle_height) self.paddle_offset = paddle_offset self.paddle.filled = True self.paddle.color = 'gray' self.paddle.fill_color = 'gray' # Center a filled ball in the graphical window self.ball = GOval(ball_radius * 2, ball_radius * 2) self.ball.filled = True self.ball.color = 'pink' self.ball.fill_color = 'pink' self.window.add(self.ball, (self.window.width - self.ball.width) / 2, (self.window.height - self.ball.height) / 2) # Default initial velocity for the ball self.__dx = random.randint( 1, MAX_X_SPEED) # Set up one velocity randomly, then change self.__dy = INITIAL_Y_SPEED # direction of velocity by conditions of methods # Initialize our mouse listeners onmousemoved(self.track) onmouseclicked(self.switch) self.is_in_a_move = False # Draw bricks self.brick_r = brick_rows self.brick_c = brick_cols self.brick_width = brick_width self.brick_height = brick_height self.brick_spacing = brick_spacing self.brick_offset = brick_offset self.draw_bricks() # Ball's attributes self.ball.r = ball_radius # maybe_brick attributes self.maybe_brick = self.window.get_object_at(self.ball.x, self.ball.y) self.brick_x0 = 0 self.brick_y0 = 0 # Setup label self.score = 0 # 小心!! 要放在method之前 self.label = GLabel('Scores:' + str(self.score)) self.setup_label() # Setup life self.setup_life() self.rect0 = GRect(12, 12) self.time = 0 self.ball_is_out = False # Minus life def setup_label(self): # self.score = 0 # 為什麼要有這一行?? # print(self.score) self.label = GLabel('Scores:' + str(self.score)) # 跨method 所以要再上面寫 self.label.color = 'black' self.label.font = 'Courier-12-bold' self.window.add(self.label, x=10, y=30) def setup_life(self): for i in range(3): self.rect0 = GRect(12, 12) self.rect0.filled = True self.rect0.color = 'magenta' self.rect0.fill_color = 'magenta' self.window.add(self.rect0, x=420 - 20 * i, y=15) # remove1 = self.window.get_object_at(x=420-20*1, y=610) # 如果用loop製造多個物件,電腦"當下"只會儲存最新的一個物件 # self.window.remove(remove1) # 要移除其餘物件的話要先用get_object_at 來取得物件,再移除 def check_wall(self): print('time:', self.time) if self.ball.y <= 0: self.__dy = -self.__dy elif self.ball.x <= 0: self.__dx = -self.__dx elif self.ball.x + self.ball.width >= self.window.width: self.__dx = -self.__dx elif self.ball.y >= self.window.height: # For testing self.ball_is_out = True remove1 = self.window.get_object_at(x=380 + 20 * self.time, y=15) self.window.remove(remove1) self.time += 1 print('New time:', self.time) def check_brick2( self ): # Set up four corners to determine whether there is an object # 碰到板子就直接把球往上移就不會抖 self.left_up = self.window.get_object_at(self.ball.x, self.ball.y) self.right_up = self.window.get_object_at( self.ball.x + self.ball.width, self.ball.y) self.left_down = self.window.get_object_at( self.ball.x, self.ball.y + self.ball.height) self.right_down = self.window.get_object_at( self.ball.x + self.ball.width, self.ball.y + self.ball.height) if self.ball.y + self.ball.height < self.paddle.y: # Brick if self.left_up is not None and self.left_up is not self.label: self.window.remove(self.left_up) self.__dy = -self.__dy self.score += 1 elif self.right_up is not None and self.right_up is not self.label: self.window.remove(self.right_up) self.__dy = -self.__dy self.score += 1 elif self.left_down is not None and self.left_down is not self.label: self.window.remove(self.left_down) self.__dy = -self.__dy self.score += 1 elif self.right_down is not None and self.right_down is not self.label: self.window.remove(self.right_down) self.__dy = -self.__dy self.score += 1 self.label.text = 'Scores:' + str(self.score) # print(self.score) return self.score elif self.ball.y + self.ball.height >= self.paddle.y: # Paddle if self.left_up is not None: self.__dy = -self.__dy elif self.right_up is not None: self.__dy = -self.__dy elif self.left_down is not None: self.__dy = -self.__dy elif self.right_down is not None: self.__dy = -self.__dy def check_brick( self): # 要設四個corner,還有 if 跟 else if 來檢查。才不會同時偵測到兩個,因此速度負負得正而沒有反彈 num = 0 for i in range(2): for j in range(2): self.maybe_brick = self.window.get_object_at( self.ball.x + i * self.ball.height, self.ball.y + j * self.ball.height) if self.maybe_brick is not None: if self.ball.y + self.ball.height <= self.paddle.y: # brick self.window.remove(self.maybe_brick) self.__dy *= -1 num += 1 elif self.ball.y + self.ball.height >= self.paddle.y: # paddle self.__dy = -self.__dy def switch(self, m): self.is_in_a_move = True print('----------') # self.set_ball_velocity() def set_ball_velocity(self): # Increase the fun of game self.__dx = random.randint(1, MAX_X_SPEED) self.__dy = INITIAL_Y_SPEED if random.random() > 0.5: # print(random.random()) # Each random.random is different from 0 to 1 self.__dx = -self.__dx self.__dy = self.__dy def get_dx(self): return self.__dx def get_dy(self): return self.__dy def track(self, m): # Function in onmousemoved, m is data of mouse # 用 if 設兩個 x 與 y 的邊界 self.paddle.x = m.x - self.paddle.width / 2 if m.x <= self.paddle.width / 2: # left m.x boundary self.paddle.x = 0 if m.x >= self.window.width - self.paddle.width / 2: # right m.x boundary self.paddle.x = self.window.width - self.paddle.width self.paddle.y = self.window.height - self.paddle_offset # paddle.y is a constant self.window.add(self.paddle, x=self.paddle.x, y=self.paddle.y) def draw_bricks(self): for i in range(self.brick_r): # 上限不包含 for j in range(self.brick_c): brick = GRect(self.brick_width, self.brick_height) brick.filled = True if 0 <= j < 2: brick.fill_color = 'red' brick.color = 'red' elif 2 <= j < 4: brick.fill_color = 'orange' brick.color = 'orange' elif 4 <= j < 6: brick.fill_color = 'yellow' brick.color = 'yellow' elif 6 <= j < 8: brick.fill_color = 'green' brick.color = 'green' else: brick.fill_color = 'blue' brick.color = 'blue' self.window.add(brick, x=0 + i * self.brick_width + i * self.brick_spacing, \ y=self.brick_offset + j * self.brick_height + j * self.brick_spacing) def the_end(self): num = 0 vx = 1 vy = 0 if self.score <= 4: gameover = GLabel('Game Over') gameover.color = 'goldenrod' gameover.font = 'Courier-35-bold' self.window.add(gameover, x=80, y=400) while True: pause(1000 / 120) if num == 10: break else: gameover.move(vx, vy) if gameover.x + gameover.width >= self.window.width or gameover.x == 0: vx = -vx num += 1 elif self.score >= 5: goodgame = GLabel('Congratulation!') goodgame.color = 'red' goodgame.font = 'Courier-30-bold' self.window.add(goodgame, x=30, y=400) while True: pause(1000 / 120) if num == 100: break else: goodgame.move(vx, vy) if 0 <= goodgame.x <= 20: goodgame.color = 'red' elif 20 <= goodgame.x <= 40: goodgame.color = 'orange' elif 40 <= goodgame.x <= 60: goodgame.color = 'yellow' elif 60 <= goodgame.x <= 80: goodgame.color = 'green' elif 80 <= goodgame.x <= 100: goodgame.color = 'blue' elif 100 <= goodgame.x <= 109: goodgame.color = 'purple' if goodgame.x + goodgame.width >= self.window.width or goodgame.x == 0: vx = -vx num += 1 print(goodgame.x)
class BreakoutGraphics: def __init__(self, ball_radius=BALL_RADIUS, paddle_width=PADDLE_WIDTH, paddle_height=PADDLE_HEIGHT, paddle_offset=PADDLE_OFFSET, brick_rows=BRICK_ROWS, brick_cols=BRICK_COLS, brick_width=BRICK_WIDTH, brick_height=BRICK_HEIGHT, brick_offset=BRICK_OFFSET, brick_spacing=BRICK_SPACING, title='Breakout'): self.ball_radius = ball_radius self.over = GLabel('GAME OVER') self.over.color = 'red' # Create a graphical window, with some extra space. self.window_width = brick_cols * (brick_width + brick_spacing) - brick_spacing self.window_height = brick_offset + 3 * ( brick_rows * (brick_height + brick_spacing) - brick_spacing) self.window = GWindow(width=self.window_width, height=self.window_height, title=title) # Create a paddle. self.pad = GRect(paddle_width, paddle_height) self.pad.filled = True self.pad.fill_color = 'black' self.window.add(self.pad, x=(self.window_width - paddle_width) / 2, y=self.window_height - paddle_offset) # Default initial velocity for the ball. self.__dx = 0 self.__dy = 0 # Initialize our mouse listeners. onmousemoved(self.move_pad) onmouseclicked(self.start_check) # the checker to decide whether the game can start,if 1, start, if 0, pending self.chk = 0 # Draw bricks. for y in range( brick_offset, brick_rows * (brick_height + brick_spacing) + brick_offset, brick_height + brick_spacing): for x in range(0, self.window_width - brick_width + 1, brick_width + brick_spacing): self.brick = GRect(brick_width, brick_height) self.brick.filled = True self.brick.fill_color = 'yellow' self.brick.color = 'green' self.window.add(self.brick, x=x, y=y) self.num_bricks = brick_cols * brick_rows # Center a filled ball in the graphical window. self.ball = GOval(ball_radius * 2, ball_radius * 2) self.ball.filled = True self.ball.fill_color = 'navy' self.ball.color = 'blue' self.window.add(self.ball, x=self.window_width / 2 - ball_radius, y=self.window_height / 2 - ball_radius) def move_pad(self, event): """ To make the paddle moves following the mouse :param event: int, the coordinate(x,y) of the mouse """ if event.x < self.pad.width / 2: self.pad.x = 0 elif event.x > self.window.width - self.pad.width / 2: self.pad.x = self.window.width - self.pad.width else: self.pad.x = event.x - self.pad.width / 2 def get_dx(self): """ To return the hidden object dx :return: int, the distance to move on x-coordinate per movement """ return self.__dx def get_dy(self): """ To return the hidden object dy :return: int, the distance to move on y-coordinate per movement """ return self.__dy def reset_ball(self): """ To set the ball at initial position and resetting chk to 0 """ self.window.add(self.ball, x=self.window_width / 2 - self.ball_radius, y=self.window_height / 2 - self.ball_radius) self.chk = 0 def start_check(self, m): """ Check if the ball is at the center, if yes, start bouncing; if no, the click is ignored """ if self.ball.x == self.window_width / 2 - self.ball_radius and self.ball.y == self.window_height / 2 - \ self.ball_radius and self.num_bricks > 0: self.__dx = random.randint(1, MAX_X_SPEED) self.__dy = INITIAL_Y_SPEED if (random.random()) > 0.5: self.__dx = -self.__dx self.chk = 1 def get_chk(self): """ To return chk :return: int, the checker to detect whether the game should starts """ return self.chk def check_collision(self): """ Check if the 4 vertex touch paddle or brick :return: str or object, to indicate if the ball touches anything """ for i in range(0, self.ball_radius * 2 + 1, self.ball_radius * 2): for j in range(0, self.ball_radius * 2 + 1, self.ball_radius * 2): is_obj = self.window.get_object_at(self.ball.x + j, self.ball.y + i) if is_obj is not None: if is_obj is self.pad: self.ball.move(0, -self.pad.height) print('touch pad') return 'pad' else: self.window.remove(is_obj) self.num_bricks -= 1 print('touch brick') return 'brick' return 'not collide'
class BreakoutGraphics: def __init__(self, ball_radius=BALL_RADIUS, paddle_width=PADDLE_WIDTH, paddle_height=PADDLE_HEIGHT, paddle_offset=PADDLE_OFFSET, brick_rows=BRICK_ROWS, brick_cols=BRICK_COLS, brick_width=BRICK_WIDTH, brick_height=BRICK_HEIGHT, brick_offset=BRICK_OFFSET, brick_spacing=BRICK_SPACING, title='Breakout'): # Create a graphical window, with some extra space window_width = brick_cols * (brick_width + brick_spacing) - brick_spacing window_height = brick_offset + 3 * (brick_rows * (brick_height + brick_spacing) - brick_spacing) self.window = GWindow(width=window_width, height=window_height, title='Breakout') # Element score label self.score = 0 self.score_label = GLabel('Score: ' + str(self.score)) # Element for game winning self.win_show = GLabel('Create by Mike Lin', x=100, y=100) self.win_show2 = GLabel('March 20 stanCode SC101', x=135, y=115) # Create a paddle self.paddle = GRect(paddle_width, paddle_height, x=(window_width - paddle_width) / 2, y=window_height - paddle_offset) self.window.add(self.paddle) self.paddle.filled = True # Center a filled ball in the graphical window self.ball = GOval(2 * ball_radius, 2 * ball_radius, x=window_width / 2 - ball_radius, y=window_height / 2 - ball_radius) self.ball_x = window_width / 2 - ball_radius self.ball_y = window_height / 2 - ball_radius # Default initial velocity for the ball self.__dx = 0 self.__dy = 0 # Other variables self.total_bricks = 0 # Initialize our mouse listeners onmousemoved( self.paddle_move) # using own method must add 'self.' in the front onmouseclicked(self.clicked) self.draw_bricks_and_ball() def draw_bricks_and_ball(self): """ set the bricks and balls """ self.window.add(self.score_label, x=0, y=15) self.window.add(self.ball) self.ball.filled = True color_num = BRICK_COLS / 5 for i in range(BRICK_ROWS): for j in range(BRICK_COLS): if j // color_num == 0: color = 'red' elif j // color_num == 1: color = 'orange' elif j // color_num == 2: color = 'yellow' elif j // color_num == 3: color = 'green' else: color = 'blue' bricks = GRect(BRICK_WIDTH, BRICK_HEIGHT) self.window.add(bricks, x=0 + i * (BRICK_WIDTH + BRICK_SPACING), y=BRICK_OFFSET + j * (BRICK_HEIGHT + BRICK_SPACING)) bricks.filled = True bricks.fill_color = color self.total_bricks += 1 def paddle_move(self, m): """ :param m: mouse you move this function controls the moving of the paddle and prevents it from disappearing """ if self.paddle.width / 2 <= m.x <= self.window.width - self.paddle.width / 2: self.paddle.x = m.x - self.paddle.width / 2 elif m.x >= self.window.width: self.paddle.x = self.window.width - self.paddle.width elif m.x < 0: self.paddle.x = 0 def clicked(self, m): """ the boolean that controls the start of the game once you clicked the mouse """ if (self.ball.x, self.ball.y) == (self.ball_x, self.ball_y): self.__dx = random.randint(1, MAX_X_SPEED) if random.random() > 0.5: self.__dx = -self.__dx self.__dy = INITIAL_Y_SPEED def set_ball_direct(self): """ to set the ball's direction and the action the ball takes when hitting the walls, bricks, paddle """ self.ball.move(self.__dx, self.__dy) self.meet_the_wall() if self.meet_object() is self.paddle: self.__dy = -abs(self.__dy) elif self.meet_object() is self.ball: pass elif self.meet_object() is self.score_label: pass elif self.meet_object() is not None: self.window.remove(self.meet_object()) self.__dy *= -1 self.total_bricks -= 1 self.score += 1 self.score_label.text = 'Score: ' + str(self.score) if self.total_bricks == 0: self.ball.x = self.ball_x self.ball.y = self.ball_y self.window.add(self.win_show) self.window.add(self.win_show2) self.win_show.font = '-30' def meet_the_wall(self): """ the function that determines the ball's vy """ if self.ball.x <= 0: self.__dx *= -1 elif self.ball.x + self.ball.width >= self.window.width: self.__dx *= -1 elif self.ball.y <= 0: self.__dy *= -1 elif self.ball.y + self.ball.height >= self.window.height: self.__dx = 0 self.__dy = 0 def dead(self): """ to set the ball to start point when falling under the bottom window """ if self.ball.y + self.ball.height >= self.window.height: self.ball.x = self.ball_x self.ball.y = self.ball_y return True def meet_object(self): """ the detector for checking what the ball hits :return: the obstacle that ball hits """ obstacle1 = self.window.get_object_at(self.ball.x, self.ball.y) obstacle2 = self.window.get_object_at(self.ball.x + self.ball.width, self.ball.y) obstacle3 = self.window.get_object_at(self.ball.x + self.ball.width, self.ball.y + self.ball.height) obstacle4 = self.window.get_object_at(self.ball.x, self.ball.y + self.ball.height) if obstacle1 is not None and not self.ball: return obstacle1 elif obstacle2 is not None: return obstacle2 elif obstacle3 is not None: return obstacle3 elif obstacle4 is not None: return obstacle4 else: return None def get_dx(self): """ to get dx speed :return: dx speed """ return self.__dx def get_dy(self): """ to get dy speed :return: dy speed """ return self.__dy
class BreakoutGraphics: def __init__(self, ball_radius=BALL_RADIUS, paddle_width=PADDLE_WIDTH, paddle_height=PADDLE_HEIGHT, paddle_offset=PADDLE_OFFSET, brick_rows=BRICK_ROWS, brick_cols=BRICK_COLS, brick_width=BRICK_WIDTH, brick_height=BRICK_HEIGHT, brick_offset=BRICK_OFFSET, brick_spacing=BRICK_SPACING, title='Breakout'): # to create win situation self.remove_count = brick_rows * brick_cols self.brick_number = brick_rows * brick_cols # check click to start but not restart self.cc = TIME # check if the four vertex of the ball has touched anything self.not_touch_anything = True # Create a graphical window, with some extra space window_width = brick_cols * (brick_width + brick_spacing) - brick_spacing window_height = brick_offset + 3 * (brick_rows * (brick_height + brick_spacing) - brick_spacing) self.window = GWindow(width=window_width, height=window_height, title=title) # create score board self.scores = GLabel('Scores: 0') self.scores.font = '-20' self.window.add(self.scores, x=10, y=30) self.score = 0 # Create a paddle self.paddle = GRect(paddle_width, paddle_height) self.paddle.filled = True self.paddle.fill_color = 'black' self.paddle_x = (window_width - paddle_width) / 2 self.paddle_y = self.window.height - paddle_offset self.window.add(self.paddle, self.paddle_x, self.paddle_y) # Center a filled ball in the graphical window self.ball = GOval(ball_radius * 2, ball_radius * 2) self.ball.filled = True self.ball.fill_color = 'black' self.ball_x = (window_width - self.ball.width) / 2 self.ball_y = (window_height - self.ball.height) / 2 self.window.add(self.ball, self.ball_x, self.ball_y) # Default initial velocity for the ball self.__dx = random.randint(1, MAX_X_SPEED) self.__dy = INITIAL_Y_SPEED if random.random() > 0.5: self.__dx = -self.__dx # Initialize our mouse listeners onmouseclicked(self.click_check) onmousemoved(self.paddle_reset_position) # Draw bricks for i in range(brick_rows): if i == 0: brick_y = brick_offset else: brick_y += brick_height + brick_spacing for j in range(brick_cols): if j == 0: brick_x = 0 else: brick_x += brick_width + brick_spacing brick = GRect(brick_width, brick_height) color_list = ['red', 'orange', 'yellow', 'green', 'blue'] per_row = brick_rows // len(color_list) if per_row < 1: per_row = 1 brick.color = color_list[i//per_row] brick.filled = True brick.fill_color = color_list[i//per_row] self.window.add(brick, brick_x, brick_y) # getter def get_dx(self): return self.__dx def get_dy(self): return self.__dy # change direction def change_dx_direction(self): self.__dx = -self.__dx return self.__dx def change_dy_direction(self): self.__dy = -self.__dy return self.__dy def paddle_reset_position(self, mouse): """ if mouse is outside the window, the paddle will be at the edge. """ if (0 + self.paddle.width / 2) <= mouse.x <= (self.window.width - self.paddle.width / 2): self.paddle_x = mouse.x - self.paddle.width / 2 self.window.add(self.paddle, self.paddle_x, self.paddle_y) def click_check(self, mouse): """ The first click (or revived click) starts the game, and the others no impact. onmouseclicked(self.click_check) """ self.cc += 1 return self.cc def remove_brick(self): for ball_x_ in range(int(self.ball.x), int(self.ball.x + self.ball.width + 1), self.ball.width): for ball_y_ in range(int(self.ball.y), int(self.ball.y + self.ball.height + 1), self.ball.height): if self.not_touch_anything: maybe_brick = self.window.get_object_at(ball_x_, ball_y_) # ball's four vertex if maybe_brick is not None and maybe_brick is not self.paddle and maybe_brick is not self.scores: # brick # print('maybe_brick: ', maybe_brick.x, maybe_brick.y) # print(self.check_is_none) # print('in', self.__dy) self.change_dy_direction() # print('change', self.__dy) self.not_touch_anything = False self.window.remove(maybe_brick) # check if win self.remove_count -= 1 # count score self.score += 1 self.scores.text = 'Scores: ' + str(self.score) self.more_difficult() # print('remove: ', maybe_brick.x, maybe_brick.y, 'ball: ', ball_x_, ball_y_) # if maybe_brick.x == 0: # print('self.ball.x/', self.ball.x,'self.ball.x + self.ball.width+1/',self.ball.x + self.ball.width+1) # print('BALL.X: ', self.ball.x, 'ball_x: ', ball_x_, 'ball: ', self.ball.y, 'ball_y+height: ', # ball_y_+self.ball.height, # 'paddle_x: ', self.paddle.x, 'paddle_x_tail: ', self.paddle.x+self.paddle.width, # 'paddle_y: ', self.paddle.y, 'paddle_y+height', self.paddle.y+self.paddle.height) # print(self.not_touch_anything) elif maybe_brick is not None and maybe_brick is not self.scores and maybe_brick is not self.__dy > 0: # paddle self.change_dy_direction() self.not_touch_anything = False # reset for the next ball_move self.not_touch_anything = True def more_difficult(self): # print(self.score, self.brick_number) level_one = int(self.brick_number/5) level_two = int(self.brick_number/3) level_three = int(self.brick_number/2) level_four = int(self.brick_number*0.8) if self.score == level_four: self.__dy = self.__dy* 2 # print('level_four') elif self.score == level_three: # print('level_three: ', level_three, 'score: ', self.score, self.__dy) self.__dy = self.__dy * 1.5 elif self.score == level_two: self.__dy = self.__dy * 1.25 # print('level_two') elif self.score == level_one: self.__dy = self.__dy * 1.2 # print(self.brick_number, 'level_one: ', level_one, 'score: ', self.score, self.__dy) # print('self.__dy', self.__dy) def reset_ball(self): self.window.add(self.ball, self.ball_x, self.ball_y)
class BreakoutGraphics: def __init__(self, ball_radius=BALL_RADIUS, paddle_width=PADDLE_WIDTH, paddle_height=PADDLE_HEIGHT, paddle_offset=PADDLE_OFFSET, brick_rows=BRICK_ROWS, brick_cols=BRICK_COLS, brick_width=BRICK_WIDTH, brick_height=BRICK_HEIGHT, brick_offset=BRICK_OFFSET, brick_spacing=BRICK_SPACING, title='Breakout'): # Create a graphical window, with some extra space. window_width = brick_cols * (brick_width + brick_spacing) - brick_spacing window_height = brick_offset + 3 * (brick_rows * (brick_height + brick_spacing) - brick_spacing) self.window = GWindow(width=window_width, height=window_height, title=title) # Create a paddle. self.paddle = GRect(paddle_width, paddle_height) self.paddle.filled = True self.window.add(self.paddle, x=(self.window.width - paddle_width) / 2, y=self.window.height - paddle_offset - paddle_height) # Center a filled ball in the graphical window. self.ball = GOval(ball_radius * 2, ball_radius * 2) self.ball.filled = True self.window.add(self.ball, self.window.width * 1 / 2 - ball_radius * 2, self.window.height * 1 / 2 - ball_radius * 2) self.ball_start_x = self.window.width * 1 / 2 - ball_radius * 2 self.ball_start_y = self.window.height * 1 / 2 - ball_radius * 2 # Default initial velocity for the ball. self.__dx = 0 self.__dy = 0 # Initialize our mouse listeners. self.count = 0 onmouseclicked(self.click) onmousemoved(self.paddle_move) # Draw bricks. for i in range(brick_rows): for j in range(brick_cols): self.brick = GRect(brick_width, brick_height) self.brick.filled = True fill_the_color(self.brick, i) self.window.add(self.brick, x=0 + (brick_width + BRICK_SPACING) * j, y=BRICK_OFFSET + (brick_height + BRICK_SPACING) * i) self.how_many_bricks = brick_rows * brick_cols def click(self, mouse): """ int, how many times the user clicks the mouse :param mouse: the information which the coder get when the user clicks the mouse """ self.count += 1 def paddle_move(self, k): """ int, the place of the paddle and set the boundaries of the paddle can move :param k: the place where the paddle is """ self.paddle.x = k.x - PADDLE_WIDTH / 2 self.paddle.y = self.window.height - PADDLE_OFFSET - PADDLE_HEIGHT if self.paddle.x >= self.window.width - PADDLE_WIDTH: self.paddle.x = self.window.width - PADDLE_WIDTH if self.paddle.x <= 0: self.paddle.x = 0 def set_ball_velocity(self): """ int, the velocity of the ball and change the horizontal speed randomly """ self.__dx = random.randint(1, MAX_X_SPEED) self.__dy = INITIAL_Y_SPEED if random.random() > 0.5: self.__dx = -self.__dx def collision_and_bounce(self): """ check the object that the ball collides. If the ball collides the paddle, it will change the vertical speed. If the ball collides the brick, it will change the vertical speed and remove the brick. """ ball_upperleft = self.window.get_object_at(self.ball.x, self.ball.y) ball_upperright = self.window.get_object_at( self.ball.x + 2 * BALL_RADIUS, self.ball.y) ball_lowerleft = self.window.get_object_at( self.ball.x, self.ball.y + 2 * BALL_RADIUS) ball_lowerright = self.window.get_object_at( self.ball.x + 2 * BALL_RADIUS, self.ball.y + 2 * BALL_RADIUS) if ball_upperleft is not None: if ball_upperleft is not self.paddle: self.__dy *= -1 self.window.remove(ball_upperleft) self.how_many_bricks -= 1 print(self.how_many_bricks) if ball_upperleft is self.paddle: self.__dy = -INITIAL_Y_SPEED elif ball_upperright is not None: if ball_upperright is not self.paddle: self.__dy *= -1 self.window.remove(ball_upperright) self.how_many_bricks -= 1 print(self.how_many_bricks) if ball_upperright is self.paddle.x: self.__dy = -INITIAL_Y_SPEED elif ball_lowerleft is not None: if ball_lowerleft is not self.paddle: self.__dy *= -1 self.window.remove(ball_lowerleft) self.how_many_bricks -= 1 print(self.how_many_bricks) if ball_lowerleft is self.paddle: self.__dy = -INITIAL_Y_SPEED elif ball_lowerright is not None: if ball_lowerright is not self.paddle: self.__dy *= -1 self.window.remove(ball_lowerright) self.how_many_bricks -= 1 print(self.how_many_bricks) if ball_lowerright is self.paddle: self.__dy = -INITIAL_Y_SPEED def get_x_velocity(self): """ :return: int, the horizontal speed for the ball """ return self.__dx def get_y_velocity(self): """ :return: int, the vertical speed for the ball """ return self.__dy def set_x_velocity(self): """ int, change the horizontal speed for the ball """ self.__dx *= -1 def set_y_velocity(self): """ int, change the vertical speed for the ball """ self.__dy *= -1 def get_ball_start_x(self): """ :return: int, the initial horizontal place of the ball """ return self.ball_start_x def get_ball_start_y(self): """ :return: int, the initial vertical place of the ball """ return self.ball_start_y def remove_ball(self): """ remove the ball from the window """ self.window.remove(self.ball)
class BreakoutGraphics: def __init__(self, ball_radius=BALL_RADIUS, paddle_width=PADDLE_WIDTH, paddle_height=PADDLE_HEIGHT, paddle_offset=PADDLE_OFFSET, brick_rows=BRICK_ROWS, brick_cols=BRICK_COLS, brick_width=BRICK_WIDTH, brick_height=BRICK_HEIGHT, brick_offset=BRICK_OFFSET, brick_spacing=BRICK_SPACING, title='Breakout', __dy=INITIAL_Y_SPEED): # Create a graphical window, with some extra space. self.window_width = brick_cols * (brick_width + brick_spacing) - brick_spacing self.window_height = brick_offset + 3 * (brick_rows * (brick_height + brick_spacing) - brick_spacing) self.window = GWindow(width=self.window_width, height=self.window_height, title=title) # Create a paddle. self.paddle = GRect(width=paddle_width, height=paddle_height, x=(self.window_width-paddle_width)/2, y=(self.window_height-paddle_offset-paddle_height)) self.paddle.filled = True self.paddle.color = '#513743' self.paddle.fill_color = '#513743' self.window.add(self.paddle) self.life_label = GLabel('● ● ●') self.life_label.font = '-15' self.life_label.color = '#c53d43' self.score_label = GLabel('score: 0') self.score_label.font = '-15' self.score_label.color = '#455765' self.brick_rows = BRICK_ROWS self.brick_cols = BRICK_COLS # Initialize our mouse listeners. onmousemoved(self.reset_paddle_location) # Draw bricks. self.create_bricks() def create_bricks(self, brick_offset=BRICK_OFFSET, brick_width=BRICK_WIDTH, brick_height=BRICK_HEIGHT, brick_spacing=BRICK_SPACING): d_y = brick_offset color = ['#96514d', '#d3381c', '#2c4f54', '#00a381', '#008899', '#3e62ad', '#316745', '#028760', '#fabf14', '#274a78'] for i in range(self.brick_rows): c = color[random.randint(0, 9)] d_x = 0 for j in range(self.brick_cols - 1): brick = GRect(brick_width, brick_height, x=d_x, y=d_y) brick.filled = True brick.color = c brick.fill_color = brick.color self.window.add(brick) d_x = d_x + brick_width + brick_spacing brick = GRect(brick_width, brick_height, x=d_x, y=d_y) brick.filled = True brick.color = c brick.fill_color = brick.color self.window.add(brick) d_y = d_y + brick_height + brick_spacing def reset_paddle_location(self, mouse): if mouse.x >= self.window.width: self.paddle.x = self.window.width - self.paddle.width/2 elif mouse.x <= 0: self.paddle.x = -self.paddle.width/2 else: self.paddle.x = mouse.x - self.paddle.width/2 # Default initial velocity for the ball. def get_dx(self): __dx = random.randint(1, MAX_X_SPEED) if random.random() > 0.5: __dx = -__dx return __dx def get_dy(self): __dy = INITIAL_Y_SPEED return __dy def ball_collide_paddle(self): if self.window.get_object_at(self.ball.x, self.ball.y+self.ball.height) is self.paddle: return True if self.window.get_object_at(self.ball.x+self.ball.width, self.ball.y+self.ball.height) is self.paddle: return True if self.window.get_object_at(self.ball.x+self.ball.width, self.ball.y) is self.paddle: return True if self.window.get_object_at(self.ball.x, self.ball.y) is self.paddle: return True def ball_collide_brick(self): if self.window.get_object_at(self.ball.x, self.ball.y+self.ball.height) is not None and self.window.get_object_at(self.ball.x, self.ball.y+self.ball.height) is not self.paddle and self.window.get_object_at(self.ball.x, self.ball.y+self.ball.height) is not self.life_label and self.window.get_object_at(self.ball.x, self.ball.y+self.ball.height) is not self.score_label: self.window.remove(self.window.get_object_at(self.ball.x, self.ball.y+self.ball.height)) return True if self.window.get_object_at(self.ball.x+self.ball.width, self.ball.y+self.ball.height) is not self.paddle and self.window.get_object_at(self.ball.x+self.ball.width, self.ball.y+self.ball.height) is not None and self.window.get_object_at(self.ball.x+self.ball.width, self.ball.y+self.ball.height) is not self.life_label and self.window.get_object_at(self.ball.x+self.ball.width, self.ball.y+self.ball.height) is not self.score_label: self.window.remove(self.window.get_object_at(self.ball.x+self.ball.width, self.ball.y+self.ball.height)) return True if self.window.get_object_at(self.ball.x+self.ball.width, self.ball.y) is not self.paddle and self.window.get_object_at(self.ball.x+self.ball.width, self.ball.y) is not None and self.window.get_object_at(self.ball.x+self.ball.width, self.ball.y) is not self.life_label and self.window.get_object_at(self.ball.x+self.ball.width, self.ball.y) is not self.score_label: self.window.remove(self.window.get_object_at(self.ball.x+self.ball.width, self.ball.y)) return True if self.window.get_object_at(self.ball.x, self.ball.y) is not self.paddle and self.window.get_object_at(self.ball.x, self.ball.y) is not None and self.window.get_object_at(self.ball.x, self.ball.y) is not self.life_label and self.window.get_object_at(self.ball.x, self.ball.y) is not self.score_label: self.window.remove(self.window.get_object_at(self.ball.x, self.ball.y)) return True # Center a filled ball in the graphical window. def reset_ball_location(self, ball_radius=BALL_RADIUS): self.ball = GOval(ball_radius*2, ball_radius*2, x=self.window_width/2-ball_radius, y=self.window_height/2-ball_radius) self.ball.filled = True self.ball.color = '#705b67' self.ball.fill_color = self.ball.color self.window.add(self.ball) def lose(self): self.window.clear() lose_background = GRect(self.window.width, self.window.height) lose_background.filled = True lose_background.color = '#a6a5c4' lose_background.fill_color = '#a6a5c4' lose_label = GLabel('GAME OVER') lose_label.font = '-50' lose_label.color = '#e7e7eb' self.window.add(lose_background) self.window.add(lose_label, self.window.width/2-lose_label.width/2, self.window.height/2.5) self.window.add(self.score_label, (self.window_width-self.score_label.width)/2, lose_label.y+50) def win(self): self.window.clear() win_background = GRect(self.window.width, self.window.height) win_background.filled = True win_background.color = '#e5abbe' win_background.fill_color = '#e5abbe' win_label = GLabel('WIN') win_label.font = '-50' win_label.color = '#fdeff2' self.window.add(win_background) self.window.add(win_label, self.window.width/2-win_label.width/2, self.window.height/2.5) self.window.add(self.score_label, (self.window_width-self.score_label.width)/2, win_label.y+50)
class BreakoutGraphics: def __init__(self, ball_radius=BALL_RADIUS, paddle_width=PADDLE_WIDTH, paddle_height=PADDLE_HEIGHT, paddle_offset=PADDLE_OFFSET, brick_rows=BRICK_ROWS, brick_cols=BRICK_COLS, brick_width=BRICK_WIDTH, brick_height=BRICK_HEIGHT, brick_offset=BRICK_OFFSET, brick_spacing=BRICK_SPACING, title='Breakout'): # only three lives self.num_lives = NUM_LIVES # win img self.img = GImage('WIN!!.png') # Create a graphical window, with some extra space. window_width = brick_cols * (brick_width + brick_spacing) - brick_spacing window_height = brick_offset + 3 * (brick_rows * (brick_height + brick_spacing) - brick_spacing) self.window = GWindow(width=window_width, height=window_height, title=title) # Start button self.button_back = GRect(250, 50) self.button_back.filled = True self.button_back.fill_color = 'darkgrey' self.window.add(self.button_back, x=(self.window.width - self.button_back.width) // 2, y=352.5) self.button = GRect(250, 50) self.button.filled = True self.button.fill_color = 'grey' self.window.add(self.button, x=(self.window.width - self.button.width) // 2, y=350) self.button_word = GLabel('CLICK TO START') self.button_word.font = '-30' self.window.add(self.button_word, x=(self.window.width - self.button_word.width) // 2, y=350 + self.button_word.height + 10) # Create a paddle. self.paddle = GRect(paddle_width, paddle_height, x=(window_width - paddle_width) // 2, y=window_height - paddle_offset) self.paddle.filled = True self.window.add(self.paddle) # Center a filled ball in the graphical window. self.ball = GOval(ball_radius * 2, ball_radius * 2, x=window_width // 2 - ball_radius, y=window_height // 2 - ball_radius) self.ball.filled = True self.window.add(self.ball) # Default initial velocity for the ball. self.__dx = self.set_ball_x_velocity() self.__dy = INITIAL_Y_SPEED # Initialize our mouse listeners. onmouseclicked(self.start) onmousemoved(self.control_paddle) # the switch of the game self.start = False # Score board. self.score = 0 self.score_label = GLabel('Score: ' + str(self.score)) self.score_label.font = '-22' self.window.add(self.score_label, x=0, y=self.score_label.height + 5) # how many lives self.life1 = GLabel('❤️') self.life1.font = '-20' self.window.add(self.life1, self.window.width - self.life1.width, self.life1.height + 7) self.life2 = GLabel('❤️') self.life2.font = '-20' self.window.add(self.life2, self.window.width - self.life2.width * 2, self.life2.height + 7.35) self.life3 = GLabel('❤️') self.life3.font = '-20' self.window.add(self.life3, self.window.width - self.life3.width * 3, self.life3.height + 7.35) # Draw bricks. x = 0 # to change row space = 0 self.change = 0 self.color = 'red' # 5 colors for i in range(brick_rows // 2): # each color 2 rows for j in range(2): # x bricks for k in range(brick_cols): self.brick = GRect(brick_width, brick_height, x=0 + x, y=brick_offset + space) x += (brick_width + brick_spacing) self.brick.filled = True self.brick.fill_color = self.color self.brick.color = self.color self.window.add(self.brick) x = 0 space += (brick_height + brick_spacing) self.change_color() def change_color(self): """ a method for making different color of the bricks :return: color """ self.change += 1 if self.change == 1: self.color = 'orange' elif self.change == 2: self.color = 'yellow' elif self.change == 3: self.color = 'green' elif self.change == 4: self.color = 'blue' def control_paddle(self, m): """ This method controls the paddle by moving your mouse inside the window. The midpoint of the paddle follows the mouse :param m: mouse event """ if self.paddle.width // 2 <= m.x <= self.window.width - self.paddle.width // 2: self.paddle.x = m.x - self.paddle.width // 2 def start(self, m): """ The switch of this game """ self.window.remove(self.button) self.window.remove(self.button_back) self.window.remove(self.button_word) if self.num_lives > 0: self.start = True def set_ball_x_velocity(self): """ This method gives random dx for the ball whenever the ball starts moving. """ # ball start w/ different dx speed self.__dx = random.randint(1, MAX_X_SPEED) # ball start w/ different direction if random.random() > 0.5: self.__dx = -self.__dx return self.__dx # getter: ball dx def get_ball_x_velocity(self): return self.__dx # getter: ball dy def get_ball_y_velocity(self): return self.__dy def touch_thing(self): """ This method checks whether the ball has touched something. No, keep moving Yes, return the thing to next place to check what is the thing """ # object sensor: left up, right up, left down, right down obj1 = self.window.get_object_at(self.ball.x, self.ball.y) obj2 = self.window.get_object_at(self.ball.x + self.ball.width, self.ball.y) obj3 = self.window.get_object_at(self.ball.x, self.ball.y + self.ball.width) obj4 = self.window.get_object_at(self.ball.x + self.ball.width, self.ball.y + self.ball.width) # check whether ball touch object if obj1 is None: if obj2 is None: if obj3 is None: if obj4 is None: pass else: return obj4 else: return obj3 else: return obj2 else: return obj1 def check_hit_wall(self): """ This method checks whether the ball hits the top, left or right wall and changes its direction dx = -dx """ if self.ball.x <= 0 or self.ball.x >= self.window.width - self.ball.width: self.__dx = -self.__dx if self.ball.y <= 0: self.__dy = -self.__dy def check_what_object(self): """ This method checks what object did the ball hit """ if self.touch_thing() is self.paddle: # avoid the situation: when the ball touches the edge of paddle, it will stuck in the paddle, up and down if self.__dy > 0: self.__dy = -self.__dy else: pass elif self.touch_thing() is self.score_label: pass elif self.touch_thing() is self.img: pass elif self.touch_thing() is not None: self.window.remove(self.touch_thing()) self.score += 1 self.score_label.text = 'Score: ' + str(self.score) self.__dy = -self.__dy elif self.touch_thing() is self.life1 or self.life2 or self.life3: pass # def bonus_ball(self): # while self.ball.y < self.window.height//2: # self.ball.fill_color = 'red' def win(self): """ This method shows an image and label if the user wins the game by clearing all the bricks """ if self.score == 100: win = GLabel('WIN!!') win.font = 'Times-50' self.window.add(win, 50, 235) self.window.add(self.img, 10, 25) self.window.remove(self.ball) def dead(self): """ This method will check whether the ball falls below the window and will show a label 'Gameover' when there's no lives left. """ if self.ball.y >= self.window.height: self.window.remove(self.ball) self.num_lives -= 1 if self.num_lives > 0: self.reset_ball() # lives left if self.num_lives == 2: self.window.remove(self.life3) elif self.num_lives == 1: self.window.remove(self.life2) else: # last life if self.num_lives == 0: self.window.remove(self.life1) lose = GLabel('GAMEOVER!!!') lose.font = 'Trattatello-60-italic' self.window.add(lose, x=(self.window.width - lose.width) // 2, y=(self.window.height + lose.height) // 2) def reset_ball(self): """ This method resets the ball to the middle of the window and assign a new speed in order to reset the game. """ self.ball = GOval(self.ball.width, self.ball.width, x=(self.window.width - self.ball.width) // 2, y=(self.window.height - self.ball.width) // 2) self.ball.filled = True self.window.add(self.ball) self.start = False self.set_ball_x_velocity()
class BreakoutGraphics: def __init__(self, ball_radius=BALL_RADIUS, paddle_width=PADDLE_WIDTH, paddle_height=PADDLE_HEIGHT, paddle_offset=PADDLE_OFFSET, brick_rows=BRICK_ROWS, brick_cols=BRICK_COLS, brick_width=BRICK_WIDTH, brick_height=BRICK_HEIGHT, brick_offset=BRICK_OFFSET, brick_spacing=BRICK_SPACING, title='Breakout'): # Create a graphical window, with some extra space. window_width = brick_cols * (brick_width + brick_spacing) - brick_spacing window_height = brick_offset + 3 * (brick_rows * (brick_height + brick_spacing) - brick_spacing) self.window = GWindow(width=window_width, height=window_height, title=title) # Create a paddle. self.pof = paddle_offset self.paddle = GRect(paddle_width, paddle_height) self.paddle.filled = True self.window.add(self.paddle, (window_width - self.paddle.width) / 2, window_height - self.pof) # Center a filled ball in the graphical window. self.ball = GOval(2 * ball_radius, 2 * ball_radius) self.ball.filled = True self.window.add(self.ball, self.window.width / 2 - self.ball.width / 2, self.window.height / 2) self.initial_x = self.window.width / 2 - self.ball.width / 2 self.initial_y = self.window.height / 2 # Default initial velocity for the ball. self.__dx = 0 self.__dy = 0 self.set_speed() self.get_dx() self.get_dy() # Initialize our mouse listeners. self.click = False onmousemoved(self.paddle_follow) onmouseclicked(self.start) # Draw bricks. self.br = brick_rows self.bc = brick_cols self.sp = brick_spacing self.of = brick_offset self.set_brick() # self.check() # self.rest_ball() self.total = self.br * self.bc # self.break_all_brick() def start(self, m): # make a button for mouseclick to let user start the game if self.ball.x == self.initial_x and self.ball.y == self.initial_y: self.click = True def break_all_brick(self): # to check the amount of brick if self.total == 0: return True def rest_ball(self): self.window.add(self.ball, self.window.width / 2 - self.ball.width / 2, self.window.height / 2) def check(self): maybe_wall = self.window.get_object_at(self.ball.x, self.ball.y) maybe_wall1 = self.window.get_object_at(self.ball.x, self.ball.y + self.ball.height) maybe_wall2 = self.window.get_object_at(self.ball.x + self.ball.width, self.ball.y) maybe_wall3 = self.window.get_object_at(self.ball.x + self.ball.width, self.ball.y + self.ball.width) if maybe_wall is None: if maybe_wall2 is None: if maybe_wall3 is None: if maybe_wall1 is None: return False else: if maybe_wall1 is self.paddle: return True else: # the object is brick self.window.remove(maybe_wall1) self.total -= 1 return True else: if maybe_wall3 is self.paddle: return True else: # the object is brick self.window.remove(maybe_wall3) self.total -= 1 return True else: if maybe_wall2 is self.paddle: return False else: # the object is brick self.window.remove(maybe_wall2) self.total -= 1 return True else: if maybe_wall is self.paddle: return False else: # the object is brick self.window.remove(maybe_wall) self.total -= 1 return True def get_dy(self): return self.__dy def get_dx(self): return self.__dx def set_speed(self): self.__dx = random.randint(1, MAX_X_SPEED) self.__dy = INITIAL_Y_SPEED if random.random() > 0.5: self.__dx = -self.__dx if random.random() > 0.5: self.__dy = -self.__dy def paddle_follow(self, event): if self.paddle.width / 2 <= event.x <= self.window.width - self.paddle.width / 2: self.window.add(self.paddle, event.x - self.paddle.width / 2, self.window.height - PADDLE_OFFSET) def set_brick(self): for i in range(self.br): for k in range(self.bc): # produce the brick brick = GRect(BRICK_WIDTH, BRICK_HEIGHT) brick.filled = True # change the color of brick at different row if 2 > i >= 0: brick.fill_color = 'red' elif 4 > i >= 2: brick.fill_color = 'orange' elif 6 > i >= 4: brick.fill_color = 'yellow' elif 8 > i >= 6: brick.fill_color = 'green' elif 10 > i >= 8: brick.fill_color = 'blue' self.window.add(brick, k * (brick.width + self.sp), self.of + i * (brick.height + self.sp))
class BreakoutGraphics: def __init__(self, ball_radius=BALL_RADIUS, paddle_width=PADDLE_WIDTH, paddle_height=PADDLE_HEIGHT, paddle_offset=PADDLE_OFFSET, brick_rows=BRICK_ROWS, brick_cols=BRICK_COLS, brick_width=BRICK_WIDTH, brick_height=BRICK_HEIGHT, brick_offset=BRICK_OFFSET, brick_spacing=BRICK_SPACING, title='Breakout'): self.pw = paddle_width # Class variable to store paddle width. self.ph = paddle_height # Class variable to store paddle height. self.pos = paddle_offset # Class variable to store paddle offset. self.br = ball_radius # Class variable to store ball radius. self.brk_row = brick_rows # Class variable to store the number of brick rows. self.brk_col = brick_cols # Class variable to store the number of brick columns. self.click = 1 # Class variable as a switch to control game status, where 1 equals to game termination. self.brick_count = 0 # Class variable to store the number of bricks being eliminated. self.score = 0 # Class variable to store the score of the game. # Create a graphical window, with some extra space. window_width = brick_cols * (brick_width + brick_spacing) - brick_spacing window_height = brick_offset + 3 * (brick_rows * (brick_height + brick_spacing) - brick_spacing) self.window = GWindow(width=window_width, height=window_height, title=title) self.wh = window_height # Class variable to store window height. self.ww = window_width # Class variable to store window width. # Create a label to show the score. self.label_s = GLabel('Scores: ' + str(self.score), x=2, y=window_height - 2) self.label_s.font = '-10' self.window.add(self.label_s) # Create a paddle. self.paddle = GRect(width=paddle_width, height=paddle_height, x=(window_width - paddle_width) / 2, y=window_height - paddle_offset - paddle_height) self.paddle.filled = True self.paddle.fill_color = 'black' self.paddle.color = 'black' self.window.add(self.paddle) # Center a filled ball in the graphical window. self.ball = GOval(ball_radius * 2, ball_radius * 2) self.ball.filled = True self.ball.fill_color = 'black' self.ball.color = 'black' self.set_ball( ) # Method to set ball place at initial, details shown as below. self.window.add(self.ball) # Method to set initial velocity of the ball, details shown as below. self.set_ball_velocity() # Initialize mouse listeners. onmousemoved(self.paddle_location ) # Method to move paddle while moving the mouse. onmouseclicked( self.game_start ) # Method to control game status while clicking the mouse. # Draw bricks with different colors, which is determined ny the number of rows. for i in range(brick_cols): for j in range(brick_rows): self.brick = GRect(brick_width, brick_height, x=i * (brick_width + brick_spacing), y=j * (brick_height + brick_spacing) + BRICK_OFFSET) self.brick.filled = True if j % 10 == 0 or j % 10 == 1: self.brick.fill_color = 'Red' self.brick.color = 'Red' elif j % 10 == 2 or j % 10 == 3: self.brick.fill_color = 'Orange' self.brick.color = 'Orange' elif j % 10 == 4 or j % 10 == 5: self.brick.fill_color = 'Yellow' self.brick.color = 'Yellow' elif j % 10 == 6 or j % 10 == 7: self.brick.fill_color = 'Green' self.brick.color = 'Green' else: self.brick.fill_color = 'Blue' self.brick.color = 'Blue' self.window.add(self.brick) def set_ball(self): """ A method to set ball at initial place. """ self.ball.x = (self.ww - self.br) / 2 self.ball.y = (self.wh - self.br) / 2 def set_ball_velocity(self): """ A method to set the initial velocity of the ball speed. """ self.__dx = random.randint(1, MAX_X_SPEED) self.__dy = INITIAL_Y_SPEED if random.random() > 0.5: self.__dx = -self.__dx def game_start(self, event): """ :param event: Detect when the user presses the button on their mouse and then minus variable click by 1. :return: Continuing the game when the number of click is less than 1. """ self.click -= 1 def paddle_location(self, event): """ :param event: Detect when the user moves the mouse. :return:Move paddle when the mouse is moved and make sure that the paddle completely stays in the window. """ if event.x - (self.pw / 2) < 0: self.paddle.x = 0 elif event.x + (self.pw / 2) >= self.ww: self.paddle.x = self.ww - self.pw else: self.paddle.x = event.x - self.pw / 2 self.paddle.y = self.wh - self.pos def check_for_wall(self): """ A method that changes the direction of the ball when it hits the wall. """ if self.ball.x <= 0 or self.ball.x + self.ball.width >= self.window.width: self.__dx = -self.__dx if self.ball.y <= 0: self.__dy = -self.__dy def check_for_collision(self): """ A method that changes the direction of the ball when it hits the paddle. """ ul_obj = self.window.get_object_at(self.ball.x, self.ball.y) ur_obj = self.window.get_object_at(self.ball.x + self.ball.width, self.ball.y) ll_obj = self.window.get_object_at(self.ball.x, self.ball.y + self.ball.width) lr_obj = self.window.get_object_at(self.ball.x + self.ball.width, self.ball.y + self.ball.width) if ul_obj is not None and ul_obj is not self.paddle and ul_obj is not self.label_s: self.window.remove(ul_obj) self.brick_count += 1 self.score += 1 self.label_s.text = 'Scores: ' + str(self.score) self.__dy *= -1.1 elif ur_obj is not None and ur_obj is not self.paddle and ul_obj is not self.label_s: self.window.remove(ur_obj) self.brick_count += 1 self.score += 1 self.label_s.text = 'Scores: ' + str(self.score) self.__dy *= -1.1 elif ll_obj is self.paddle: self.__dy *= -1 elif lr_obj is self.paddle: self.__dy *= -1 def get_dx(self): """ Getter function for x velocity. """ return self.__dx def get_dy(self): """ Getter function for y velocity. """ return self.__dy
class BreakoutGraphics: def __init__(self, ball_radius=BALL_RADIUS, paddle_width=PADDLE_WIDTH, paddle_height=PADDLE_HEIGHT, paddle_offset=PADDLE_OFFSET, brick_rows=BRICK_ROWS, brick_cols=BRICK_COLS, brick_width=BRICK_WIDTH, brick_height=BRICK_HEIGHT, brick_offset=BRICK_OFFSET, brick_spacing=BRICK_SPACING, title='Breakout'): # Create a graphical window, with some extra space. self.window_width = brick_cols * (brick_width + brick_spacing) - brick_spacing self.window_height = brick_offset + 3 * ( brick_rows * (brick_height + brick_spacing) - brick_spacing) self.window = GWindow(width=self.window_width, height=self.window_height, title=title) self.paddle_offset = paddle_offset # Create a paddle. self.paddle = GRect(paddle_width, paddle_height, x=(self.window_width - paddle_width) / 2, y=self.window_height - self.paddle_offset - paddle_height) self.paddle.filled = True self.window.add(self.paddle) # Center a filled ball in the graphical window. self.size = ball_radius * 2 self.ball = GOval(self.size, self.size, x=(self.window_width - self.size) / 2, y=(self.window_height - self.size) / 2) self.ball.filled = True self.window.add(self.ball) # Default initial velocity for the ball. self.__dx = 0 self.__dy = INITIAL_Y_SPEED self.brick_count = brick_cols * brick_rows # Initialize our mouse listeners. # onmouseclicked(self.handle_click()) onmousemoved(self.move_paddle) # Create bricks for i in range(brick_cols): brick_on_x = i * (brick_width + brick_spacing) for j in range(brick_rows): num_of_same_color_row = brick_rows // 5 brick_on_y = brick_offset + j * (brick_height + brick_spacing) brick = GRect(brick_width, brick_height) brick.filled = True if 0 <= j < num_of_same_color_row: brick.fill_color = 'black' brick.color = 'black' elif num_of_same_color_row <= j < 2 * num_of_same_color_row: brick.fill_color = 'darkgray' brick.color = 'darkgray' elif 2 * num_of_same_color_row <= j < 3 * num_of_same_color_row: brick.fill_color = 'dimgray' brick.color = 'dimgray' elif 3 * num_of_same_color_row <= j < 4 * num_of_same_color_row: brick.fill_color = 'gray' brick.color = 'gray' else: brick.fill_color = 'lightgray' brick.color = 'lightgray' self.window.add(brick, x=brick_on_x, y=brick_on_y) # collide with paddle def is_collide_paddle(self): ball_left_top = self.window.get_object_at(self.ball.x, self.ball.y) ball_right_top = self.window.get_object_at(self.ball.x + self.size, self.ball.y) ball_left_bottom = self.window.get_object_at(self.ball.x, self.ball.y + self.size) ball_right_bottom = self.window.get_object_at(self.ball.x + self.size, self.ball.y + self.size) if ball_left_bottom == self.paddle or ball_right_bottom == self.paddle: return True # collide with brick def is_collide_brick(self): ball_left_top = self.window.get_object_at(self.ball.x, self.ball.y) ball_right_top = self.window.get_object_at(self.ball.x + self.size, self.ball.y) ball_left_bottom = self.window.get_object_at(self.ball.x, self.ball.y + self.size) ball_right_bottom = self.window.get_object_at(self.ball.x + self.size, self.ball.y + self.size) if ball_left_top is not None and ball_left_top is not self.paddle: self.window.remove(ball_left_top) return True if ball_right_top is not None and ball_right_top is not self.paddle: self.window.remove(ball_right_top) return True # Getter def get_dx(self): return self.__dx def get_dy(self): return self.__dy # def reset_ball(self): # self.set_ball_velocity() def set_ball_velocity(self): self.__dx = random.randint(1, MAX_X_SPEED) if random.random() > 0.5: self.__dx = -self.__dx def reset_ball_position(self): self.ball.x = (self.window_width - self.size) / 2 self.ball.y = (self.window_height - self.size) / 2 def move_paddle(self, event): if event.x >= self.window.width - self.paddle.width: self.paddle.x = self.window.width - self.paddle.width elif event.x <= self.paddle.width / 2: self.paddle.x = 0 else: self.paddle.x = event.x - self.paddle.width / 2
class BreakoutGraphics: def __init__(self, ball_radius = BALL_RADIUS, paddle_width = PADDLE_WIDTH, paddle_height = PADDLE_HEIGHT, paddle_offset = PADDLE_OFFSET, brick_rows = BRICK_ROWS, brick_cols = BRICK_COLS, brick_width = BRICK_WIDTH, brick_height = BRICK_HEIGHT, brick_offset = BRICK_OFFSET, brick_spacing = BRICK_SPACING, title='Breakout'): # Create a graphical window, with some extra space window_width = brick_cols * (brick_width + brick_spacing) - brick_spacing window_height = brick_offset + 3 * (brick_rows * (brick_height + brick_spacing) - brick_spacing) self.window = GWindow(width=window_width, height=window_height, title=title) # Create a paddle self.paddle_touch = 0 # (0:untouch paddle; 1: touch paddle) # self.paddle = GRect(paddle_width, paddle_height) self.paddle = GRect(paddle_width, paddle_height) # Test width "430" self.paddle.filled = True self.window.add(self.paddle, x=(window_width-paddle_width)/2, y=window_height-paddle_offset) # Center a filled ball in the graphical window self.ball_radius = ball_radius self.remove_succ = 0 # (0: untouch bricks; 1: touch bricks) self.ball = GOval(ball_radius*2, ball_radius*2) self.ball.filled = True self.window.add(self.ball, x=(window_width-ball_radius)/2, y=(window_height-ball_radius)/2) # Default initial velocity for the ball self.__dy = INITIAL_Y_SPEED self.__dx = random.randint(1, MAX_X_SPEED+1) if random.random() > 0.5: self.__dx = -self.__dx # Initialize our mouse listeners self.switch = 0 # This variable controls if the game start or not. (1:start, 0: unstart) onmouseclicked(self.click_m) onmousemoved(self.move_m) # Draw bricks self.sum_bricks = brick_rows * brick_cols self.bricks_remove = 0 # record how many bricks were removed brick_spacing = (window_width - (brick_width*brick_rows))/(brick_rows-1) position_height = brick_offset for i in range(brick_cols): position_width = 0 for j in range(brick_rows): bricks = GRect(brick_width, brick_height) bricks.filled = True self.window.add(bricks, x=position_width, y=position_height) position_width += (brick_spacing + brick_width) position_height += (brick_spacing + brick_height) # The following variables are used to control user's life or die self.dead = 0 # (0: still life; 1: die) def click_m(self, mouse): """ This method process when the mouse click. :param mouse: shows where the place of mouse :return: NA """ if self.switch == 0: self.switch = 1 else: pass def move_m(self,mouse): """ This method will track where the mouse, and the paddle will follow the mouse :param mouse: shows where the place of the mouse :return: NA """ if mouse.x >= self.paddle.width/2 and mouse.x <= self.window.width-(self.paddle.width/2): self.paddle.x = mouse.x - self.paddle.width/2 def getter_dx(self): """ The method will give the class user the variable, self.__dx. :return: if the game is processing, return the speed of x :return: if the game is stop, the speed of x is 0. """ if self.switch == 1: return self.__dx return 0 def getter_dy(self): """ The method will give the class user the variable, self.__dy. :return: if the game is processing, return the speed of y :return: if the game is stop, the speed of y is 0. """ if self.switch == 1: return self.__dy return 0 def ball_tracker_bricks(self): """ This method is charge of the following situation. 1. When the ball touch the bricks. 2. When the ball remove all the bricks. :return: if the situation is true, removing the ball. """ ball_tracker_x = [self.ball.x, self.ball.x+2*self.ball_radius] ball_tracker_y = [self.ball.y, self.ball.y+2*self.ball_radius] for x in ball_tracker_x: for y in ball_tracker_y: ball_may = self.window.get_object_at(x=x, y=y) if ball_may is not self.paddle: if ball_may is not None: self.remove_succ = 1 # When the ball remove the bricks, adding one to the recorder # The the brick remove recoder == the number of all bricks → stop the game self.bricks_remove += 1 print(str(self.bricks_remove)) if self.bricks_remove == self.sum_bricks: self.window.remove(self.ball) # reset the ball on the middle of the window self.window.add(self.ball, x=(self.window.width - self.ball.width) / 2, y=(self.window.height - self.ball.height) / 2) print('YOU WIN in breakoutgraphics.py') return self.window.remove(ball_may) def ball_tracker_paddle(self): """ This method is charge of the following situation. 1. When the ball touch paddle. 2. When the ball below the bottom of the window. :return: NA """ ball_tracker_x = [self.ball.x, self.ball.x+2*self.ball_radius] ball_tracker_y = [self.ball.y, self.ball.y+2*self.ball_radius] # When the ball touch the paddle. for x in ball_tracker_x: for y in ball_tracker_y: paddle_may = self.window.get_object_at(x=x, y=y) if paddle_may is self.paddle: self.paddle_touch = 1 """ 這行是時為了解決反彈的時候球黏在板子上,研判原因應該是板子快速的滑入,導致球的偵測點卡在板子上下。 我強制球碰到板子後會先跳到板子以上,才開始走反彈的code。 請問有什麼其他方法可以解決球的偵測點卡在板子上的問題??因為我強制讓球跳到板子以上,看起來會微微奇怪。 """ self.ball.y = self.paddle.y-self.ball.height return # Checking if the ball below the bottom of the window if self.ball.y > self.window.height: self.dead = 1 self.switch = 0 # restart the mouse click function self.window.remove(self.ball) # reset the ball on the middle of the window self.window.add(self.ball, x=(self.window.width - self.ball.width) / 2, y=(self.window.height - self.ball.height) / 2)
class BreakoutGraphics: def __init__(self, ball_radius=BALL_RADIUS, paddle_width=PADDLE_WIDTH, paddle_height=PADDLE_HEIGHT, paddle_offset=PADDLE_OFFSET, brick_rows=BRICK_ROWS, brick_cols=BRICK_COLS, brick_width=BRICK_WIDTH, brick_height=BRICK_HEIGHT, brick_offset=BRICK_OFFSET, brick_spacing=BRICK_SPACING, title='Breakout'): self.start = False self.count = brick_cols * brick_rows # Create a graphical window, with some extra space. window_width = brick_cols * (brick_width + brick_spacing) - brick_spacing window_height = brick_offset + 3 * (brick_rows * (brick_height + brick_spacing) - brick_spacing) self.window = GWindow(width=window_width, height=window_height, title=title) # Create a paddle. self.paddle = GRect(paddle_width, paddle_height, x=(self.window.width - paddle_width) / 2, y=self.window.height - paddle_offset) self.paddle.filled = True self.paddle.fill_color = 'black' self.window.add(self.paddle) # Center a filled ball in the graphical window. # func: set_ball_position() self.ball = GOval(ball_radius * 2, ball_radius * 2) self.ball.filled = True self.ball.fill_color = 'black' # Default initial velocity for the ball. # func: set_ball_velocity() self.__dx = 0 self.__dy = 0 # Initialize our mouse listeners. self.reset_ball() onmouseclicked(self.mouse_click) onmousemoved(self.mouse_move) # Draw bricks. colors = [ 'royalblue', 'cadetblue', 'steelblue', 'darkturquoise', 'deepskyblue', 'skyblue', 'lightskyblue' ] x = 0 y = brick_offset c = 0 for row in range(0, brick_rows): for col in range(0, brick_cols): self.bricks = GRect(brick_width, brick_height, x=x, y=y) self.bricks.filled = True self.bricks.fill_color = colors[c] self.window.add(self.bricks) x = x + brick_width + brick_spacing y = y + brick_height + brick_spacing x = 0 if row % 2 == 1: c += 1 # check the ball touches bricks or paddle def get_obj(self): obj_ball_x_y = self.window.get_object_at(self.ball.x, self.ball.y) obj_ball_x_y_2r = self.window.get_object_at( self.ball.x, self.ball.y + self.ball.height) obj_ball_x_2r_y = self.window.get_object_at( self.ball.x + self.ball.width, self.ball.y + self.ball.height) obj_ball_x_2r_y_2r = self.window.get_object_at( self.ball.x + self.ball.width, self.ball.y + self.ball.height) if obj_ball_x_y is not None: self.check_obj(obj_ball_x_y) return True elif obj_ball_x_2r_y is not None: self.check_obj(obj_ball_x_2r_y) return True elif obj_ball_x_y_2r is not None: self.check_obj(obj_ball_x_y_2r) return True elif obj_ball_x_2r_y_2r is not None: self.check_obj(obj_ball_x_2r_y_2r) return True # if obj_ball_x_y or obj_ball_x_y_2r or obj_ball_x_2r_y or obj_ball_x_2r_y_2r is not None: # if obj_ball_x_y is not self.paddle: # 當 obj_ball_x_y == None 時也會是 True # self.window.remove(obj_ball_x_y) # self.count -= 1 # elif obj_ball_x_y_2r is not self.paddle: # self.window.remove(obj_ball_x_y_2r) # self.count -= 1 # elif obj_ball_x_2r_y is not self.paddle: # self.window.remove(obj_ball_x_2r_y) # self.count -= 1 # elif obj_ball_x_2r_y_2r is not self.paddle: # self.window.remove(obj_ball_x_2r_y_2r) # self.count -= 1 # return True def check_obj(self, obj): if obj is not self.paddle: self.window.remove(obj) self.count -= 1 def set_ball_position(self): self.ball.x = (self.window.width - self.ball.width) / 2 self.ball.y = (self.window.height - self.ball.height) / 2 def set_ball_velocity(self): self.__dy = INITIAL_Y_SPEED self.__dx = random.randint(1, MAX_X_SPEED) if random.random() > 0.5: self.__dx = -self.__dx def reset_ball(self): self.start = False self.set_ball_position() self.set_ball_velocity() self.window.add(self.ball) def mouse_click(self, mouse_click): self.start = True def mouse_move(self, mouse_move): self.paddle.x = mouse_move.x - self.paddle.width / 2 def get_x_speed(self): return self.__dx def get_y_speed(self): return self.__dy