def opening(): black_cover = GRect(w.width, w.height, x=0, y=0) black_cover.filled = True black_cover.fill_color = "black" w.add(black_cover) far = GLabel("A long time ago in a galaxy far, \nfar away...") far.color = "blue" far.font = "-20" w.add(far, x=w.width / 2 - far.width / 2 + 60, y=w.height / 2) pause(1200) w.remove(far) main_title = GLabel("STAR\nWARS") main_title.color = "yellow" for i in range(20): size = (160 // (int(i) + 1)) size = -size main_title.font = str(size) w.add(main_title, x=w.width / 2 - main_title.width / 4, y=w.height / 2) pause(FRAME_RATE * 6) w.remove(main_title) opening_crawl = GLabel("It is a period of civil war\n" "Princess Leia races home abroad\n" "her spaceship but was later\n" "captured by Empires's agents\n" "Use your lightsaber to destroy\n" "the force field to save the\n" "princess") opening_crawl.color = "yellow" opening_crawl.font = "-15" w.add(opening_crawl, x=w.width / 2 - 130, y=w.height + 1) for i in range(50): opening_crawl.move(0, -10) pause(FRAME_RATE * 6) w.remove(black_cover) w.remove(opening_crawl)
def main(): graphics = BreakoutGraphics() dx = graphics.get_x_speed() dy = graphics.get_y_speed() lives = NUM_LIVES # Add animation loop here! while True: pause(FRAME_RATE) if graphics.start and lives > 0 and graphics.count > 0: graphics.ball.move(dx, dy) if graphics.ball.y >= graphics.window.height: lives -= 1 graphics.reset_ball() else: # ball touches paddle or bricks if graphics.get_obj(): if graphics.ball.y < graphics.window.height / 2: # bricks dy = -dy else: # paddle if dy > 0: # ensure won’t stick on the paddle dy = -dy # ball touches the window if graphics.ball.x <= 0 or graphics.ball.x + graphics.ball.width >= graphics.window.width: dx = -dx if graphics.ball.y <= 0: dy = -dy # update ball velocity if graphics.score > 0 and graphics.score % 200 == 0: dy += 0.1 graphics.update_dy(dy) elif lives <= 0: # game over label = GLabel('Game Over', x=0, y=graphics.window.height / 2) label.font = '-48-bold' label.color = 'red' graphics.window.add(label) graphics.window.remove(graphics.ball) break elif graphics.count <= 0: # you win label = GLabel('You Win!!!', x=0, y=graphics.window.height / 2) label.font = '-48-bold' label.color = 'forestgreen' graphics.window.add(label) graphics.window.remove(graphics.ball) break # label animation label_dx = 1 while label.x <= graphics.window.width / 2 - 120: label.move(label_dx, 0) pause(10)
def main(): graphics = BreakoutGraphics() dx = graphics.get_x_speed() dy = graphics.get_y_speed() lives = NUM_LIVES # Add animation loop here! while True: pause(FRAME_RATE) if graphics.start and lives > 0 and graphics.count > 0: graphics.ball.move(dx, dy) if graphics.ball.y + graphics.ball.height >= graphics.window.height: lives -= 1 graphics.reset_ball() else: if graphics.get_obj(): dy = -dy if graphics.ball.x <= 0 or graphics.ball.x + graphics.ball.width >= graphics.window.width: dx = -dx if graphics.ball.y <= 0: dy = -dy elif lives <= 0: # game over label = GLabel('Game Over', x=0, y=graphics.window.height / 2) label.font = '-48-bold' label.color = 'red' graphics.window.add(label) graphics.window.remove(graphics.ball) break elif graphics.count <= 0: # you win label = GLabel('You Win!!!', x=0, y=graphics.window.height / 2) label.font = '-48-bold' label.color = 'forestgreen' graphics.window.add(label) graphics.window.remove(graphics.ball) break # move the label dx = 1 while label.x <= graphics.window.width / 2 - 120: label.move(dx, 0) pause(10)
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)
def pilot(self): # Instructions line_1 = GLabel('Welcome to my Breakout Game!') line_1.font = 'Courier-12-bold' line_2 = GLabel('Your mission is to get the highest score.') line_2.font = 'Courier-12-bold' line_3 = GLabel('No matter how you get it >.^') line_3.font = 'Courier-12-bold' self.window.add(line_1, x=(self.window.width - line_1.width) / 2, y=self.window.height - 40) self.window.add(line_2, x=(self.window.width - line_2.width) / 2, y=self.window.height - 20) self.window.add(line_3, x=(self.window.width - line_3.width) / 2, y=self.window.height) # Animation while True: # Update line_1.move(0, -5) line_2.move(0, -5) line_3.move(0, -5) # Check if line_1.y <= self.window.height / 2: break # Pause pause(100) pause(1000) self.window.remove(line_1) self.window.remove(line_2) self.window.remove(line_3) pause(1000)
def main(): """ it shows the animation of a guinea pig with zentangle pattern, and a label will show on the top of window """ #background background = GRect(600, 600) background.filled = True window.add(background) #zentangle for i in range(0,600,30): line = GLine(i,0,600,600) window.add(line) line.color = 'white' pause(10) for j in range(0,600,30): line = GLine(600,j,0,600) window.add(line) line.color = 'wheat' pause(10) for k in range(0, 600, 30): line = GLine(600-k, 600, 0, 0) window.add(line) line.color = 'whitesmoke' pause(10) for l in range(0, 600, 30): line = GLine(0, 600-l, 600, 0) window.add(line) line.color = 'grey' pause(10) for m in range(0,300, 10): circle = GOval(m, m, x=random.randrange(0, window.width), y=random.randrange(0, window.width)) window.add(circle) circle.color = 'red' pause(10) for n in range(0, 200, 40): circle = GOval(n, n, x=random.randrange(0, window.width), y=random.randrange(0, window.width)) window.add(circle) circle.color = 'orange' pause(10) for o in range(100,300, 35): circle = GOval(o, o, x=random.randrange(0, window.width), y=random.randrange(0, window.width)) window.add(circle) circle.color = 'yellow' pause(10) for p in range(50,200, 25): circle = GOval(p, p, x=random.randrange(0, window.width), y=random.randrange(0, window.width)) window.add(circle) circle.color = 'lime' pause(10) for q in range(0,100, 15): circle = GOval(q, q, x=random.randrange(0, window.width), y=random.randrange(0, window.width)) window.add(circle) circle.color = 'lightblue' pause(10) for r in range(300, 500, 30): circle = GOval(r, r, x=random.randrange(0, window.width), y=random.randrange(0, window.width)) window.add(circle) circle.color = 'navy' pause(10) for s in range(0, 400, 50): circle = GOval(s, s, x=random.randrange(0, window.width), y=random.randrange(0, window.width)) window.add(circle) circle.color = 'purple' pause(10) #face face = GPolygon() face.add_vertex((255, 250)) face.add_vertex((345, 250)) face.add_vertex((355, 340)) face.add_vertex((245, 340)) forehead = GPolygon() forehead.add_vertex((270, 255)) forehead.add_vertex((330, 255)) forehead.add_vertex((335, 275)) forehead.add_vertex((265, 275)) l_chin = GPolygon() l_chin = GPolygon() l_chin.add_vertex((250, 310)) l_chin.add_vertex((300, 305)) l_chin.add_vertex((300, 340)) l_chin.add_vertex((247, 340)) r_chin = GPolygon() r_chin = GPolygon() r_chin.add_vertex((300, 305)) r_chin.add_vertex((350, 310)) r_chin.add_vertex((353, 340)) r_chin.add_vertex((300, 340)) nose = GOval(18, 35, x=292, y=290) l_eye = GOval(15, 17, x=280, y=285) r_eye = GOval(15, 17, x=310, y=285) l_foot = GOval(20, 30, x=233, y=315) r_foot = GOval(20, 30, x=348, y=315) l_ear = GOval(25, 15, x=230, y=265) r_ear = GOval(25, 15, x=345, y=265) mouse1 = GLine(300, 340, 300, 333) mouse2 = GLine(300, 333, 293, 323) mouse3 = GLine(300, 333, 307, 323) window.add(l_foot) l_foot.filled = True l_foot.fill_color = 'lightsalmon' l_foot.color = 'lightsalmon' window.add(r_foot) r_foot.filled = True r_foot.fill_color = 'lightsalmon' r_foot.color = 'lightsalmon' window.add(face) face.filled = True face.fill_color = 'goldenrod' face.color = 'goldenrod' window.add(forehead) forehead.filled = True forehead.fill_color = 'lightyellow' forehead.color = 'peachpuff' window.add(l_chin) l_chin.filled = True l_chin.fill_color = 'wheat' l_chin.color = 'wheat' window.add(r_chin) r_chin.filled = True r_chin.fill_color = 'wheat' r_chin.color = 'wheat' window.add(nose) nose.filled = True nose.fill_color = 'wheat' nose.color = 'wheat' window.add(mouse1) mouse1.color = 'brown' window.add(mouse2) mouse2.color = 'brown' window.add(mouse3) mouse3.color = 'brown' window.add(l_eye) l_eye.filled = True window.add(r_eye) r_eye.filled = True window.add(l_ear) l_ear.filled = True l_ear.fill_color = 'brown' l_ear.color = 'brown' window.add(r_ear) r_ear.filled = True r_ear.fill_color = 'brown' r_ear.color = 'brown' # words label = GLabel('Python is just like Zentangle - impossible to have the same works') label.font = 'Courier-10-italic' words_frame = GRect(530, 40, x=(window.width - label.width - 10) / 2, y=18) label.color = 'navy' window.add(words_frame) words_frame.filled = True words_frame.fill_color = 'lemonchiffon' words_frame.color = 'gold' window.add(label, x=(window.width - label.width) / 2, y=50) vx = 1 while True: label.move(vx, 0) words_frame.move(vx, 0) if words_frame.x <= 0 or words_frame.x + words_frame.width >= window.width: vx = -vx pause(DELAY)
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.brick_rows = brick_rows self.brick_cols = brick_cols # 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.ball_radius = BALL_RADIUS self.ball = GOval(ball_radius * 2, ball_radius * 2) self.ball.filled = 'True' # Center a filled ball in the graphical window self.window.add(self.ball, x=(self.window.width - self.ball.width) / 2, y=(self.window.height - self.ball.height) / 2) # Create a paddle self.paddle = GRect(width=paddle_width, height=paddle_height) self.paddle.filled = True self.paddle_offset = PADDLE_OFFSET self.paddle.fill_color = 'black' self.window.add(self.paddle, x=(self.window.width - self.paddle.width) / 2, y=self.window.height - paddle_offset) # Draw bricks for i in range(brick_rows): for j in range(brick_cols): self.brick = GRect(width=brick_width, height=brick_height) self.brick.filled = 'True' self.brick.color = 'black' self.window.add(self.brick, x=(brick_width * j + brick_spacing * j), y=brick_offset + brick_height * i + brick_spacing * i) if (i+j)% 2 == 0: self.brick.fill_color = 'ivory' else: self.brick.fill_color = 'black' # Create label when user hits 10 balls self.half = GLabel("WOW! TEN BRICKS ALREADY! KEEP GOING!") self.half.font = '-15' # Score cnt self.score_cnt = 0 self.score = GLabel('SCORE:' + str(self.score_cnt)) self.score.font = 'Helvetica-30-bold' self.score.color = 'silver' self.vx = 0 self.vy = 0 # Life self.life = GLabel('LIVES:') self.life.font = 'Helvetica-30' self.life.color = 'plum' self.life1 = GOval(20, 20) self.life1.filled = True self.life1.fill_color = 'plum' self.life1.color = 'plum' self.life2 = GOval(20, 20) self.life2.filled = True self.life2.fill_color = 'plum' self.life2.color = 'plum' self.life3 = GOval(20, 20) self.life3.filled = True self.life3.fill_color = 'plum' self.life3.color = 'plum' # Default initial velocity for the ball self.__dx = 0 self.__dy = 0 self.lives = 3 onmouseclicked(self.start_ball) onmousemoved(self.track_paddle) def start_ball(self, event): if (self.__dx == 0) and (self.__dy == 0) and (not self.lives == 0): self.window.add(self.ball, x=(self.window.width - self.ball.width) / 2, y=(self.window.height - self.ball.height) / 2) self.ball.fill_color = 'black' 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 return True def track_paddle(self, e): self.paddle.x = e.x - self.paddle.width / 2 # make sure the paddle will always be in the window if e.x <= 0: self.paddle.x = 0 elif e.x > self.window.width - self.paddle.width / 2: self.paddle.x = self.window.width - self.paddle.width def check_wall(self): 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_pts(self): p1 = self.window.get_object_at(self.ball.x, self.ball.y) p2 = self.window.get_object_at(self.ball.x, self.ball.y + self.ball_radius * 2) p3 = self.window.get_object_at(self.ball.x + self.ball_radius * 2, self.ball.y) p4 = self.window.get_object_at(self.ball.x + self.ball_radius * 2, self.ball.y + self.ball_radius * 2) if p2 is not None: # determine which item the ball hits if self.ball.y > self.window.height/2: if self.__dy > 0: self.__dy = -self.__dy self.ball.fill_color = 'red' else: if p2 != self.half and p2 != self.score \ and p2 != self.life and p2!=self.life1 and p2!= self.life2 and p2!= self.life3 : self.window.remove(p2) self.score_cnt += 1 self.score.text = ("SCORE: " + str(self.score_cnt)) self.__dy = -self.__dy self.ball.fill_color = 'gold' elif p4 is not None: if self.ball.y > self.window.height/2: if self.__dy > 0: self.__dy = -self.__dy self.ball.fill_color = 'red' else: if p4 != self.half and p4 != self.score \ and p4 != self.life and p4!=self.life1 and p4 != self.life2 and p4 != self.life3: self.window.remove(p4) self.score_cnt += 1 self.score.text = ("SCORE: " + str(self.score_cnt)) self.__dy = -self.__dy self.ball.fill_color = 'gold' elif p1 is not None: if self.ball.y > self.window.height/2: if self.__dy > 0: self.__dy = -self.__dy self.ball.fill_color = 'red' else: if p1 != self.half and p1 != self.score \ and p1 != self.life and p1 != self.life1 and p1 != self.life2 and p1 != self.life3: self.window.remove(p1) self.score_cnt += 1 self.score.text = ("SCORE: " + str(self.score_cnt)) self.__dy = -self.__dy self.ball.fill_color = 'gold' elif p3 is not None: if self.ball.y > self.window.height/2: if self.__dy > 0: self.__dy = -self.__dy self.ball.fill_color = 'red' else: if p3 != self.half and p3 != self.score \ and p3 != self.life and p3 !=self.life1 and p3 != self.life2 and p3 != self.life3: self.window.remove(p3) self.score_cnt += 1 self.score.text = ("SCORE: " + str(self.score_cnt)) self.__dy = -self.__dy self.ball.fill_color = 'gold' def score_run(self): if self.vx == 0 and self.vy == 0: self.vx = 5 self.vy = 3 elif (self.score.x <= 0) or (self.score.x + self.score.width >= self.window.width): self.vx = -self.vx self.score.color = 'salmon' elif (self.score.y - self.score.height <= 0) or (self.score.y >= self.window.height)and self.vy > 0: self.vy = -self.vy self.score.color = 'powderblue' self.score.move(self.vx, self.vy) def cheer(self): # Cheering words obj = self.window.get_object_at(x=(self.window.width - self.half.width) / 2, y=(self.window.height - self.half.height) / 2) if obj is None and self.score_cnt == 10: self.window.add(self.half, x=(self.window.width - self.half.width) / 2, y=(self.window.height - self.half.height) / 2) if self.score_cnt == 15: self.window.remove(self.half) def get_dx(self): return self.__dx def get_dy(self): return self.__dy def set_dx(self, new_speed): self.__dx = -self.__dx def set_dy(self, new_speed): self.__dy = -self.__dy def set2_dx(self, new_speed2): self.__dx = 0 def set2_dy(self, new_speed2): self.__dy = 0
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) # set up the paddle. self.paddle_width = paddle_width self.paddle_height = paddle_height self.paddle = GRect(paddle_width, paddle_height, x=(self.window_width - PADDLE_WIDTH) / 2, y=self.window_height - paddle_offset - paddle_height) self.paddle.filled = True self.paddle.color = 'slategrey' self.paddle.fill_color = 'slategrey' # set up a the ball. self.ball_radius = ball_radius self.ball = GOval(self.ball_radius * 2, self.ball_radius * 2, x=(self.window_width - self.ball_radius * 2) / 2, y=(self.window_height - self.ball_radius * 2) / 2) self.ball.filled = True self.ball.color = 'crimson' self.ball.fill_color = 'crimson' # Default initial velocity for the ball. self.__dx = random.randint(MIN_X_SPEED, MAX_X_SPEED) if random.random() > 0.5: self.__dx = -self.__dx self.__dy = INITIAL_Y_SPEED # Initialize our mouse listeners. onmousemoved(self.move_paddle) onmouseclicked(self.switch) # Control whether the user can start the game self.__start = False # Determine the lives the user gets self.__num_lives = 0 # Attributes relate to the score self.__score = 0 self.__win_score = BRICK_COLS * BRICK_ROWS * 10 self.score_sign = GLabel(f'SCORE : {self.__score}') self.can_move = False self.can_drop = True self.reward = 0 # Attribute relate to live sign self.live_2 = GOval(self.ball_radius * 2, self.ball_radius * 2, x=self.window_width - (self.ball_radius * 2 + 8), y=self.window_height - (self.ball_radius * 2 + 8)) self.live_1 = GOval(self.ball_radius * 2, self.ball_radius * 2, x=self.window_width - (self.ball_radius * 2 + 8) * 2, y=self.window_height - (self.ball_radius * 2 + 8)) # Attributes relate to extension opening self.o_ball = GOval(30, 30, x=(self.window.width - 30) / 2, y=240) self.start_button = GLabel('S T A R T') self.__enter_game = False # Attributes relate to extension 'game over' scene self.game_over_w = GLabel('G A M E O V E R') # Attributes relate to rewards self.hint_sign = 0 self.reverse_paddle = False self.paddle_adding = False self.adding_count = 0 # To store the mouse event self.paddle_x = 0 def set_game(self): """ This method set up the starting interface for the game. Including materials such as: paddle, window, score sign and bricks. """ # Create a paddle. self.window.add(self.paddle) # Center a filled ball in the graphical window. self.window.add(self.ball) # Build the score sign self.score_sign = GLabel(f'SCORE : {self.__score}') self.score_sign.color = 'crimson' self.score_sign.font = 'Mamelon-20' self.window.add(self.score_sign, x=8, y=self.window.height - 8) # Build lives sign self.live_2.filled = True self.live_2.color = 'crimson' self.live_2.fill_color = 'crimson' self.window.add(self.live_2) self.live_1.filled = True self.live_1.color = 'crimson' self.live_1.fill_color = 'crimson' self.window.add(self.live_1) # Draw bricks. for i in range(BRICK_ROWS): for j in range(BRICK_COLS): brick = GRect(BRICK_WIDTH, BRICK_HEIGHT, x=i * (BRICK_WIDTH + BRICK_SPACING), y=BRICK_OFFSET + j * (BRICK_HEIGHT + BRICK_SPACING)) brick.filled = True if j == 0 or j == 1: brick.color = 'darkslategrey' brick.fill_color = 'darkslategrey' elif j == 2 or j == 3: brick.color = 'teal' brick.fill_color = 'teal' elif j == 4 or j == 5: brick.color = 'cadetblue' brick.fill_color = 'cadetblue' elif j == 6 or j == 7: brick.color = 'lightseagreen' brick.fill_color = 'lightseagreen' else: brick.color = 'mediumturquoise' brick.fill_color = 'mediumturquoise' self.window.add(brick) def move_paddle(self, event): """ This method keep mouse event regarding reverse and not reverse situation of the paddle. Also, it keeps the paddle within the window . :param event: mouse event """ if self.reverse_paddle: # reverse paddle movement event_x = self.window_width - event.x else: # Normal paddle movement event_x = event.x # Keeping the paddle within the window if event_x - self.paddle_width / 2 < 0: self.paddle.x = 0 elif event_x + self.paddle_width / 2 > self.window.width: self.paddle.x = self.window.width - self.paddle_width # Control the paddle when the mouse is in the window else: self.paddle.x = event_x - self.paddle_width / 2 # To store the mouse event self.paddle_x = self.paddle.x def reset_ball(self): """ This method resets the ball at the starting position, and will not drop unless the the user clicks. """ self.ball = GOval(self.ball_radius * 2, self.ball_radius * 2, x=(self.window_width - self.ball_radius * 2) / 2, y=(self.window_height - self.ball_radius * 2) / 2) self.ball.filled = True self.ball.color = 'crimson' self.ball.fill_color = 'crimson' self.window.add(self.ball) self.__start = False # getter for the ball's moving speed. def get_dx(self): return self.__dx # getter for the ball's moving speed. def get_dy(self): return self.__dy # getter, see if the ball is ready to be click and fall def start(self): return self.__start # getter, see if the start button in the opening scene is clicked def get_enter_game(self): return self.__enter_game # setter, the user can set up the initial lives. def set_num_lives(self, num_lives): self.__num_lives = num_lives def switch(self, e): """ This method is the switch for 2 purpose. 1. whether the user can start the game. In the start of each round, if user's lives > 0, the switch will set to open, the ball will move after the user click the window. 2. whether the start button in the opening scene is clicked. If clicked, set up the game. If not, wait for the click. """ if self.__num_lives > 0: self.__start = True if self.window.get_object_at(e.x, e.y) is self.o_ball or \ self.window.get_object_at(e.x, e.y) is self.start_button: self.__enter_game = True # To get the position of the 4 corners of the ball def corner_hits(self): """ This method check from corner_1 to corner_4, to see if any corner of the ball has encounter obstacles. If so, return the method to remove object encountered. If not, move on to the next corner. :return: method, remove the object on the encountered corner. """ # To get position of each corner of the ball corner_1 = self.window.get_object_at(self.ball.x, self.ball.y) corner_2 = self.window.get_object_at( self.ball.x + 2 * self.ball_radius, self.ball.y) corner_3 = self.window.get_object_at( self.ball.x, self.ball.y + 2 * self.ball_radius) corner_4 = self.window.get_object_at( self.ball.x + 2 * self.ball_radius, self.ball.y + 2 * self.ball_radius) # To check which corner hits things if corner_1 is not None: return corner_1 elif corner_2 is not None: return corner_2 elif corner_3 is not None: return corner_3 elif corner_4 is not None: return corner_4 else: pass # To check whether the ball hits the wall def if_hits_walls(self): """ This method checks whether the ball hits the side walls and the the top wall. If so, the ball will bounce back. """ # The ball hits the side walls and the the top wall if self.ball.x <= 0 or self.ball.x + 2 * self.ball_radius >= self.window.width: self.__dx *= -1 # The ball hits the the top wall if self.ball.y <= 0: self.__dy *= -1 # To check what the ball hits def if_hits_things(self): """ This method determines what kind of object the ball hits, and run the actions after hitting certain objects. """ # The ball hits the paddle if self.corner_hits() is self.paddle: # bounce back if self.__dy >= 0: self.__dy *= -1 else: # debug: keep the ball from sticking on the paddle pass # Clean up the hint sign self.window.remove(self.hint_sign) # the ball hits other item, pass elif self.corner_hits() is self.score_sign or self.corner_hits() is self.hint_sign or self.corner_hits() is self.reward \ or self.corner_hits() is self.live_2 or self.corner_hits() is self.live_1: pass # The ball hits the paddle elif self.corner_hits() is not None: # The thing hit by the ball need to be removed self.window.remove(self.corner_hits()) # Speed up and bounce self.__dy *= -1.005 self.__score += 10 # Show score self.show_score() # The reward will dropped everytime the user get 70 more score. if self.__score % 70 == 0 and self.can_drop: # Choose the dropping x position randomly t_x = random.choice(range(1, 10)) # Set up the reward object self.reward = GRect(10, 10, x=self.window.width * t_x // 10, y=self.window.height / 3) self.reward.filled = True self.reward.fill_color = 'darkslateblue' self.reward.color = 'darkslateblue' self.window.add(self.reward) self.can_move = True else: pass def show_score(self): """ This method remove the previous score sign and create a new one. """ self.window.remove(self.score_sign) self.score_sign = GLabel(f'SCORE : {self.__score}') self.score_sign.color = 'crimson' self.score_sign.font = 'Mamelon-20' self.window.add(self.score_sign, x=8, y=self.window.height - 8) # To check: if the reward is allowed to drop / if it was obtained or missed. def test_move(self): if self.can_move: self.can_drop = False self.reward.move(0, 5) # The user got the reward if self.window.get_object_at(self.reward.x + 7, self.reward.y + 15) is self.paddle: self.window.remove(self.reward) self.run_reward() self.can_move = False self.can_drop = True # The user miss the reward -- clean up if self.reward.y + 15 >= self.window.height: self.window.remove(self.reward) self.can_move = False self.can_drop = True def run_reward(self): """ This method uses random to choose a reward to run randomly. Also, it shows a sign for the running reward. Possible situation are listed below: 1. Make the paddle longer 2. Make the paddle shorter 3. Reverse the paddle's movement 4. Speed up the ball 5. Slow down the ball """ # Choose a reward randomly choice = random.choice(range(6)) self.window.remove(self.hint_sign) # paddle width ++ if choice == 0: self.window.remove(self.paddle) self.paddle_width += 20 self.paddle = GRect(self.paddle_width, self.paddle_height, x=self.paddle_x - self.paddle_width / 2, y=self.window_height - PADDLE_OFFSET - self.paddle_height) self.build_paddle() self.hint_sign = GLabel('ADD UP') self.show_hint() # paddle width -- elif choice == 1: self.paddle_adding = False if self.paddle_width <= 30: pass else: self.window.remove(self.paddle) self.paddle_width -= 30 self.paddle = GRect(self.paddle_width, self.paddle_height, x=self.paddle_x - self.paddle_width / 2, y=self.window_height - PADDLE_OFFSET - self.paddle_height) self.build_paddle() self.hint_sign = GLabel('WATCH OUT') self.show_hint() # Set reverse paddle movement elif choice == 2 or choice == 3: if self.reverse_paddle: self.reverse_paddle = False self.hint_sign = GLabel('REVERSE AGAIN') self.show_hint() else: self.reverse_paddle = True self.hint_sign = GLabel('REVERSE') self.show_hint() # Speed up the ball elif choice == 4: self.__dy *= 1.1 self.hint_sign = GLabel('SPEED UP') self.show_hint() # Slow down the ball else: self.__dy *= 0.9 self.hint_sign = GLabel('SLOW DOWN') self.show_hint() def build_paddle(self): """ This methods build up paddle for each reward. """ self.window.add(self.paddle) self.paddle.filled = True self.paddle.color = 'slategrey' self.paddle.fill_color = 'slategrey' def show_hint(self): """ This method shows a sign to tell user that clicking can earn rewards """ self.hint_sign.color = 'crimson' self.hint_sign.font = 'Mamelon-20' self.window.add(self.hint_sign, x=(self.window.width - self.hint_sign.width) / 2, y=self.window_height - PADDLE_OFFSET - PADDLE_HEIGHT - 30) def if_lose_life(self): """ This method check if the user lost life. If so, will reset the ball if there's still lives remain. """ if self.ball.y >= self.window.height: self.window.remove(self.ball) self.window.remove(self.hint_sign) self.__num_lives -= 1 if self.__num_lives == 2: # Build 1 point self.window.remove(self.live_1) elif self.__num_lives == 1: # empty self.window.remove(self.live_2) # Avoid being too hard for players to get ball with reverse paddle self.reverse_paddle = False self.__dy = INITIAL_Y_SPEED if self.__num_lives > 0: # User still has chances self.reset_ball() # Getter, to check if it's the end of the game (either win or lose) def end_game(self): if self.__num_lives <= 0 or self.__score >= self.__win_score: return True # To check if the game is over def game_over(self): if self.__num_lives <= 0: self.__enter_game = False return True def build_game_over(self): """ This method builds the 'Game Over' scene """ # delete the score line = GLine(4, self.window.height - 18, 12 + self.score_sign.width, self.window.height - 18) line.color = 'crimson' self.window.add(line) # Clean up self.window.remove(self.reward) self.window.remove(self.hint_sign) # Build up the 'Game Over' sign self.game_over_w.font = "Mamelon-35" self.game_over_w.color = 'midnightblue' self.window.add(self.game_over_w, x=(self.window.width - self.game_over_w.width) / 2, y=self.window.height / 2) # Create the movement of the 'Game Over' sign speed = self.__dy while True: self.game_over_w.move(0, speed) speed += 0.5 if self.game_over_w.y >= self.window.height * 2 // 3: speed *= -0.7 pause(10) # The sign will end with a shaking animation. # To check if the user won the game def win_game(self): if self.__score >= self.__win_score: return True def build_win(self): """ This method builds the 'Winning' scene """ win_sign_1 = GLabel('S A V A G E') win_sign_1.font = 'Mamelon-40' win_sign_1.color = 'mediumturquoise' win_sign_2 = GLabel('S A V A G E') win_sign_2.font = 'Mamelon-40' win_sign_2.color = 'mediumturquoise' win_sign_3 = GLabel('S A V A G E') win_sign_3.font = 'Mamelon-40' win_sign_3.color = 'mediumturquoise' # To create the flashing animation for i in range(12): if i % 2 != 0: self.window.add(win_sign_1, x=(self.window.width - win_sign_1.width) / 2, y=(self.window.height - win_sign_1.height) / 2) self.window.add( win_sign_2, x=(self.window.width - win_sign_2.width) / 2, y=(self.window.height - win_sign_2.height) / 2 + 50) self.window.add( win_sign_3, x=(self.window.width - win_sign_3.width) / 2, y=(self.window.height - win_sign_3.height) / 2 + 100) else: self.window.remove(win_sign_1) self.window.remove(win_sign_2) self.window.remove(win_sign_3) pause(100) self.fire_work() def fire_work(self): """ This method creates a firework animation. """ # Numbers of the firework for i in range(10): f_x = random.randint(self.window.width // 8, self.window.width * 7 // 8) f_y = random.randint(self.window.height // 10, self.window.height * 9 // 10) size = random.randint(4, 7) # The size of the firework for j in range(size): fire = GOval(10 + 20 * j, 10 + 20 * j, x=f_x - 10 * j, y=f_y - 10 * j) # Choose color randomly fire.color = self.choose_color() self.window.add(fire) pause(100) self.window.remove(fire) pause(500) @staticmethod def choose_color(): """ This method help choose the color for each circle of the firework randomly """ num = random.choice(range(6)) if num == 0: return "crimson" elif num == 1: return "midnightblue" elif num == 2: return "limegreen" elif num == 3: return "cyan" elif num == 4: return 'darkviolet' else: return "gold" def window_clear(self): """ This method clean up the whole window after the opening scene is over. """ self.window.clear() def set_opening(self): """ This method set up the whole opening scene. """ # To create the tube start_button_1 = GRect(60, 211, x=(self.window.width - 60) / 2, y=-1) start_button_1.color = 'slategrey' start_button_1.filled = True start_button_1.fill_color = 'slategrey' start_button_2 = GRect(50, 206, x=(self.window.width - 50) / 2) start_button_2.color = 'gainsboro' start_button_2.filled = True start_button_2.fill_color = 'gainsboro' self.window.add(start_button_1) self.window.add(start_button_2) head = GPolygon() head.add_vertex(((self.window.width - 60) / 2, 210)) head.add_vertex(((self.window.width - 60) / 2 + 60, 210)) head.add_vertex(((self.window.width - 60) / 2 + 60 + 20, 240)) head.add_vertex(((self.window.width - 60) / 2 - 20, 240)) head.color = 'slategrey' head.filled = True head.fill_color = 'slategrey' self.window.add(head) # Loading animation for i in range(10): load = GRect(40, 15, x=(self.window.width - 60) / 2 + 10, y=5 + 20 * i) load.filled = 'True' load.color = 'slategrey' load.fill_color = 'slategrey' self.window.add(load) pause(100) # Bouncing ball self.o_ball.filled = 'True' self.o_ball.color = 'crimson' self.o_ball.fill_color = 'crimson' self.window.add(self.o_ball) ball_vy = 5 count = 0 while True: self.o_ball.move(0, ball_vy) ball_vy += 1 if self.o_ball.y + 30 >= self.window.height: ball_vy *= -0.9 count += 1 if count == 5 and ball_vy >= 0: break pause(10) self.window.remove(self.o_ball) # Blowing balloon animation for i in range(55): self.o_ball = GOval(30 + i, 30 + i, x=(self.window.width - 30 + i) / 2 - i, y=415 - i) self.o_ball.filled = 'True' self.o_ball.color = 'crimson' self.o_ball.fill_color = 'crimson' self.window.add(self.o_ball) pause(7) # Flashing start sign animation for i in range(10): self.start_button.font = 'Mamelon-20' if i % 2 == 0: self.start_button.color = 'crimson' else: self.start_button.color = 'snow' self.window.add(self.o_ball) self.window.add(self.start_button, x=(self.window.width - 64) / 2, y=413) pause(100) # Show the rules rule_1 = GLabel('3 LIVES.') rule_1.color = 'darkslategrey' rule_1.font = 'Mamelon-20' rule_2 = GLabel("CATCH ' ' FOR RANDOM EFFECTS.") rule_2.color = 'darkslategrey' rule_2.font = 'Mamelon-20' rule_3 = GLabel('SCORE 1000 ---> FIREWORKS.') rule_3.color = 'crimson' rule_3.font = 'Mamelon-20' square = GRect(10, 10, x=self.window.width / 10 + 63, y=self.window.height * 4 // 5 + 10) square.filled = True square.fill_color = 'darkslateblue' square.color = 'darkslateblue' self.window.add(square) self.window.add(rule_1, x=self.window.width / 10, y=self.window.height * 4 // 5) self.window.add(rule_2, x=self.window.width / 10, y=self.window.height * 4 // 5 + 25) self.window.add(rule_3, x=self.window.width / 10, y=self.window.height * 4 // 5 + 50)