class Gorillas(object): """Create a game of Gorillas.""" def __init__(self): pygame.init() # Gorillas is displayed as Window Title pygame.display.set_caption(WINDOW_TITLE) self.screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT)) self.background = self.new_round(WINDOW_WIDTH, WINDOW_HEIGHT) # Use a clock to control frame rate self.clock = pygame.time.Clock() def new_round(self, width, height, score=[0, 0]): # Use screen height and width to generate buildings # Setting bananna = None here and calling it to be drawn later self.banana = None self.wind = random.uniform(-1, 1) / 10 self.score = score self.phase = 1 self.angle = '' self.velocity = '' # Crater = spot in building to be removed after banana has made contact with buiding. self.craters = [] self.buildings = [] self.left = 0 sky = self.screen.copy() sky.fill(pygame.Color('lightblue')) # Buildings are created here while self.left < width: building_width = int(random.uniform(width * .1, width * .15)) building_height = int(random.uniform(height *.15, height * .5)) building_width = min(building_width, width-self.left) building = Building((self.left, WINDOW_HEIGHT - building_height), building_width, building_height) self.left += building_width self.buildings.append(building) self.gorilla = Gorilla(self.buildings, 1) self.gorilla2 = Gorilla(self.buildings, 2) return sky def play(self): """Start Gorillas program. """ running = True font = pygame.font.SysFont("monospace", 15) while running: # Max frames per second self.clock.tick(FPS) # Phase 1: player1's angle input # Phase 4: player2's angle input # Phase 2: player2's velocity input # Phase 5: players2's velcity input # Phase 3: player1's banana being thrown # Phase 6: player2's banana being thrown # Event handling for event in pygame.event.get(): if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_q): running = False if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: running = False # When Backspace button is pressed elif event.key == pygame.K_BACKSPACE: if self.phase == 1 or self.phase == 4: self.angle = self.angle[0:-1] elif self.phase == 2 or self.phase == 5: self.velocity = self.velocity[0:-1] # When Enter button is pressed elif event.key == pygame.K_RETURN: self.phase += 1 # Player1's banana is thrown, Phase = 3 if self.phase == 3: self.banana = Banana(int(self.angle), int(self.velocity) / 3, self.wind, self.gorilla.rect.topleft) # Player2's banana is thrown, Phase = 6 if self.phase == 6: self.banana = Banana(180 - int(self.angle), int(self.velocity) / 3, self.wind, self.gorilla2.rect.topleft) else: if self.phase == 1 or self.phase == 4: self.angle += str(event.key - 48) elif self.phase == 2 or self.phase == 5: self.velocity += str(event.key - 48) # Draws the background self.screen.blit(self.background, (0, 0)) # If banana is called (phase 3 or 6), drawn to screen if self.banana: self.screen.blit(self.banana.image, self.banana.rect) # Sees if banana has left the screen. # If banana has left the screen, banana is removed, angle and velocity are cleared, and moves to next phase. if self.banana.rect.right > WINDOW_WIDTH or self.banana.rect.left < 0 or self.banana.rect.top < 0: self.phase += 1 self.banana = None self.angle = '' self.velocity = '' # Determines if banana rect has collided with one of the gorilla rects. # If collided, adds one to score for player1 and new round is being called elif self.banana.rect.colliderect(self.gorilla) and self.phase == 6: self.score[1] += 1 self.background = self.new_round(WINDOW_WIDTH, WINDOW_HEIGHT, self.score) # Determines if banana rect has collided with one of the gorilla rects. # If collided, adds one to score for player2 and new round is being called elif self.banana.rect.colliderect(self.gorilla2) and self.phase == 3: self.score[0] += 1 self.background = self.new_round(WINDOW_WIDTH, WINDOW_HEIGHT, self.score) # Determines if banana rect has collided with one of the building rects in the list. # If banana rect collides with a building rect, a secitoin in the building is removed. # Angle and Velcity are reset and moves onto the next phase. for building in self.buildings: try: if building.rect.collidepoint(self.banana.rect.center): self.phase += 1 self.angle = '' self.velocity = '' crater = pygame.Rect((0, 0) ,(26, 26)) crater.center = self.banana.rect.center self.craters.append(crater) self.banana = None break except: pass # Buildings are drawn to the screen. for building in self.buildings: self.screen.blit(building.image, building.rect.topleft) # When phase reaches 3 or 4, gorilla image is changed if self.phase == 3 or self.phase == 4: self.gorilla.update(self.phase) # When phase reaches 6 or 1, gorilla image is changed elif self.phase == 6 or self.phase == 1: self.gorilla2.update(self.phase) # When phase reaches 3 or 6, banana is thrown. if self.phase == 3 or self.phase == 6: self.banana.update() # The crater is being drawn to the screen here, which is the section of the building to be removed. for crater in self.craters: art = pygame.Surface(crater.size) art.set_colorkey(pygame.Color('black')) pygame.draw.circle(art, pygame.Color('lightblue'), (13, 13), 13) self.screen.blit(art, crater.center) # Gorillas are drawn to the screen. self.screen.blit(self.gorilla.image, self.gorilla.rect.topleft) self.screen.blit(self.gorilla2.image, self.gorilla2.rect.topleft) # Sun is created and drawn to the screen. sun = pygame.Surface((50, 50)) pygame.draw.circle(sun, pygame.Color('Yellow'), (25, 25), 25) sun.set_colorkey(pygame.Color('Black')) self.screen.blit(sun, (WINDOW_WIDTH/2, WINDOW_HEIGHT*.1)) # Once phase reaches 7, Phase is now reset to one so game can continue if self.phase == 7: self.phase = 1 # This is where player input (angle, velocity) is being displayed on screen. # Wind vector and score is also displayed on screen. angle = font.render("Angle " + self.angle, 2, (255,255,0)) self.screen.blit(angle, (0, 14)) velocity = font.render("Velocity " + self.velocity, 2, (255,255,0)) self.screen.blit(velocity, (0, 28)) score = font.render("Score: " + str(self.score[0]) + ' ' + str(self.score[1]), 2, (255,255,0)) self.screen.blit(score, (0, 42)) wind = font.render("Wind: " + str(self.wind*10)[0:5], 2, (255,255,0)) self.screen.blit(wind, (0, 56)) pygame.display.flip()
coordinates[1] + y)) if break_stamp_bitmap[x + 3, y + 3] != 0: try: background_bitmap[coordinates[0] + x, coordinates[1] + y] = 0 except IndexError: pass # Loop through each sprite in the sprite sheet source_index = 0 prev_btn_vals = ugame.buttons.get_pressed() while True: if banana in main_group: banana.update() time.sleep(0.10) cur_btn_vals = ugame.buttons.get_pressed() if CURRENT_STATE == STATE_PREGAME_SETUP: background_bitmap.fill(0) for building in range(0, 160, 16): random_height = random.randint(16, 70) random_color = random.choice([1, 2, 3]) for y in range(0, random_height): for x in range(0, 16): background_bitmap[building + x, display.height - y] = random_color # Windows
class Scene(pygame.sprite.Group): block_count = 16 max_block_height = 0.85 def __init__(self, surface): super(Scene, self).__init__() self.surface = surface self.blocks = pygame.sprite.Group() self.players = pygame.sprite.Group() self.block_rects = [] self.player_positions = [] self.banana = None self.generate_blocks() self.block_fall = self.surface.get_height() / 40 self.init_background() def __str__(self): mask = '%%0%dd' % len(str(self.surface.get_height())) return ' '.join(mask % v for v in self.get_block_heights()) def add_player(self, player): w, h = self.surface.get_size() new_position = random.choice(range(self.block_count)) while new_position in self.player_positions: new_position = random.choice(range(self.block_count)) self.player_positions.append(new_position) block_width = w / self.block_count block_rect = self.block_rects[new_position] x = block_rect[0] + (block_width - player.size[0]) / 2 y = h - block_rect[3] - player.size[1] player.rect = player.rect.move(x, y) self.players.add(player) self.add(player) def end(self): pygame.event.post(pygame.event.Event(pygame.USEREVENT, {'winner': self.banana.player})) def fire_banana(self, player, angle, speed): self.banana = Banana(player, angle, speed) self.add(self.banana) def kill_banana(self): self.remove(self.banana) self.banana = None def get_block_heights(self): return [s.image.get_height() for s in self.blocks.sprites()] def generate_blocks(self, heights=None): w, h = self.surface.get_size() block_width = w / self.block_count for i, bh in enumerate(heights or self._randomize_blocks()): block_height = bh * h block = pygame.sprite.Sprite(self, self.blocks) block.image = pygame.surface.Surface((block_width, block_height)) block.rect = block.image.get_rect().move(i * block_width, h - block_height) block.image.fill((127, 15, 31)) self.block_rects.append(block.rect) def _smooth(self, l, width=1, iterations=5, strength=0.20): for _ in range(iterations): smooth = [] for i in range(len(l)): v = 0.0 for j in range(-width, width + 1): v += l[(i + j) % len(l)] v /= 2 * width + 1 smooth.append((v * strength) + (l[i] * (1.0 - strength))) l = smooth return l def _randomize_blocks(self): r, m = random.random, self.max_block_height return self._smooth([r() * m for i in range(self.block_count)]) def init_background(self): w, h = self.surface.get_size() self.background = generate_gradient((63, 95, 127), (195, 195, 255), w, h) self.update() def update(self): self.update_banana() self.surface.blit(self.background, (0, 0)) self.draw(self.surface) pygame.time.wait(10) sys.stdout.write('.') sys.stdout.flush() def update_banana(self): if self.banana is None: return banana_x, banana_y = self.banana.update() if banana_y > self.surface.get_height() + self.banana.size[1]: self.kill_banana() collided_blocks = pygame.sprite.spritecollide(self.banana, self.blocks, False) if collided_blocks: for block in collided_blocks: block.rect.top += self.block_fall self.kill_banana() return collided_players = pygame.sprite.spritecollide(self.banana, self.players, False) if collided_players: for player in collided_players: if player == self.banana.player: continue # Banana cannot harm the shooter else: self.end()