class Game(object): def __init__(self): # Global setup self.screen_w = 640 self.screen_h = 480 self.screen_size = (self.screen_w, self.screen_h) self.screen = pygame.display.set_mode(self.screen_size) pygame.display.set_caption('Hero I') self.clock = pygame.time.Clock() self.fps = 60 self.planet = Planet(*self.screen_size) self.player = Player(self.screen_w / 2, self.screen_h / 2) self.spider = Monster('spider', 50, 100) self.slime = Monster('slime', 200, 400) self.monsters = pygame.sprite.Group(self.spider, self.slime) self.allsprites = pygame.sprite.Group(self.player, self.monsters) self.camera = Camera(self.screen_size) def main_loop(self): """ This is the Main Loop of the Game. """ while True: for event in pygame.event.get(): if event.type == pygame.QUIT: return None elif event.type == KEYDOWN: if event.key in (K_LEFT, K_RIGHT, K_UP, K_DOWN): self.player.change_speed(event.key, key_down=True) elif event.key in (K_ESCAPE, K_q): pygame.event.post(pygame.event.Event(QUIT)) elif event.type == KEYUP: if event.key in (K_LEFT, K_RIGHT, K_UP, K_DOWN): self.player.change_speed(event.key, key_down=False) self.screen.fill(Color('#FF00FF')) self.player.update() self.planet.update() self.camera.update(self.player.center) for tile, position in self.planet.render(self.player.center): self.screen.blit(tile, self.camera.apply(position)) for a in self.allsprites: if a is not self.player: a.update() self.screen.blit(a.image, self.camera.apply(a.rect.topleft)) pygame.display.update() self.clock.tick(self.fps)
class CameraTest(unittest.TestCase): def setUp(self): self.camera = Camera(800, 800, 10, 10) def test_apply(self): self.assertEqual(self.camera.apply((10, 10)), (10, 10)) self.assertEqual(self.camera.apply(Vector((10, 10))), Vector(10, 10)) self.assertEqual(self.camera.apply([Vector((10, 10)), Vector((5, 5))]), [Vector((10, 10)), Vector((5, 5))]) def test_update(self): self.camera.update((50, 50)) self.assertEqual(self.camera.state.x, -45.0) self.camera.update(Vector((100, 100))) self.assertEqual(self.camera.state.x, -95.0) def test_reverse_apply(self): self.assertEqual(self.camera.reverse_apply((10, 10)), (10, 10)) self.assertEqual(self.camera.reverse_apply(Vector((10, 10))), Vector(10, 10)) self.assertEqual(self.camera.reverse_apply([Vector((10, 10)), Vector((5, 5))]), [Vector((10, 10)), Vector((5, 5))]) def test_functionality(self): self.assertEqual(self.camera.functionality((50, 50)).x, -45.0) self.assertEqual(self.camera.functionality((50, 50)).y, -45.0)
def render(self, colors, camera: Camera): for y in range(self.height): for x in range(self.width): x_in_camera, y_in_camera = camera.apply(x, y) wall = self.is_blocked(x, y) visible = self.fov[x, y] if visible: if wall: terminal.printf( x=x_in_camera, y=y_in_camera, s=f'[color={colors.get("light_wall")}]#[/color]') else: terminal.printf( x=x_in_camera, y=y_in_camera, s=f'[color={colors.get("light_ground")}].[/color]') elif self.explored[x, y]: if wall: terminal.printf( x=x_in_camera, y=y_in_camera, s=f'[color={colors.get("dark_wall")}]#[/color]') else: terminal.printf( x=x_in_camera, y=y_in_camera, s=f'[color={colors.get("dark_ground")}].[/color]') self.explored |= self.fov
def main(): pygame.init() screen = pygame.display.set_mode((s.WIDTH, s.HEIGHT)) clock = pygame.time.Clock() map = BaseMap() map.load_map('resources/tiled/map3') camera = Camera(cam_width=s.WIDTH, cam_height=s.HEIGHT, map_width=map.get_width(), map_height=map.get_height()) handler = NazwijMnie(b.alucard, map) #### all_sprites = pygame.sprite.Group() stones_sprites = pygame.sprite.Group() for sp in map.get_all_tiles(): all_sprites.add(sp) all_sprites.add(b.alucard) for stone in b.stones: all_sprites.add(stone) stones_sprites.add(stone) running = True while running: clock.tick(s.FPS) #screen.blit(b.background, (0,0)) for event in pygame.event.get(): if event.type == pygame.QUIT: raise (SystemExit, "QUIT") if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: running = False if event.type == pygame.MOUSEBUTTONDOWN: #print("prawy przycick myszka") pos = pygame.mouse.get_pos() b.alucard.shoot(pos) all_sprites.update() hits = pygame.sprite.spritecollide(b.alucard, stones_sprites, False) if hits: print("pedal") #running = False handler.domything() camera.follow(b.alucard) print(camera.state) for sprite in all_sprites: screen.blit(sprite.image, camera.apply(sprite)) pygame.display.flip() pygame.quit()
class Display: """Holds all of the game's internals and objects.""" _ent_in_control = None def __init__(self, size): self.surface = pygame.surface.Surface(size) self.hud = HUD(self.surface) def load_game(self, gamemode): self.camera = Camera(Map.current_map.rect.w, Map.current_map.rect.h, self.surface.get_width(), self.surface.get_height()) self.hud.acquire_gamemode_hud(gamemode, self.camera) def update(self): self.camera.update() self.hud.action() @property def ent_in_control(self): return self._ent_in_control @ent_in_control.setter def ent_in_control(self, ent): self._ent_in_control = ent self.camera.target = ent def render(self): self.surface.fill((0xff, 0xff, 0xff)) bg = Map.current_map.background if bg is not None: self.surface.blit(bg, (0,0)) self.surface.blit(Map.current_map.image, self.camera.apply(Map.current_map)) for object in Map.current_map.objects: self.surface.blit(object.image, self.camera.apply(object)) for element in self.hud.elements: if element.visible: self.surface.blit(element.image, element.rect)
def main_loop(self, level, screen, player, timer, entities): """ Метод содержит игровой цикл в котором обрабатывает управление, расчитывает физику и отрисовывает кадр """ total_level_width = len( level[0]) * Platform.width # Высчитываем фактическую ширину уровня total_level_height = len(level) * Platform.height # высоту camera = Camera(camera_configure, total_level_width, total_level_height) while self.run: # Основной цикл программы timer.tick(60) for e in pygame.event.get(): # Обрабатываем события if e.type == pygame.QUIT: pygame.quit() if e.type == pygame.KEYDOWN and e.key == pygame.K_LEFT: self.left = True if e.type == pygame.KEYDOWN and e.key == pygame.K_RIGHT: self.right = True if e.type == pygame.KEYUP and e.key == pygame.K_RIGHT: self.right = False if e.type == pygame.KEYUP and e.key == pygame.K_LEFT: self.left = False if e.type == pygame.KEYDOWN and e.key == pygame.K_UP: self.up = True if e.type == pygame.KEYUP and e.key == pygame.K_UP: self.up = False for i in entities: if isinstance(i, Player): i.update(left_control=self.left, right_control=self.right, up_control=self.up, entities=entities) elif isinstance(i, Ember): i.update(entities) camera.update(player) screen.blit(Game.background_image, (0, 0)) for e in entities: screen.blit(e.image, camera.apply(e)) pygame.display.update( ) # обновление и вывод всех изменений на экран if player.winner: self.run = False
def main(): pygame.init() screen = pygame.display.set_mode(DISPLAY) pygame.display.set_caption('test v0.0.1') bg, _, _ = get_image('640_winter_lab_by_kooner_cz.png') entities = pygame.sprite.Group() # Все объекты hero = Player(0, 50) entities.add(hero) platforms, total_level_width, total_level_height = load_level(entities) camera = Camera(WIN_WIDTH, WIN_HEIGHT, total_level_width, total_level_height) timer = pygame.time.Clock() keys = { K_UP: False, K_DOWN: False, K_LEFT: False, K_RIGHT: False, K_SPACE: False, } while True: timer.tick(60) for e in pygame.event.get(): if e.type == QUIT: return if e.type == KEYDOWN: if e.key == K_ESCAPE: return keys[e.key] = True if e.type == KEYUP: keys[e.key] = False hero.update(keys, platforms) # передвижение camera.update(hero) # центризируем камеру относительно персонажа screen.blit(bg, (0, 0)) # каждую итерацию необходимо всё перерисовывать for e in entities: screen.blit(e.image, camera.apply(e)) pygame.display.update() # обновление и вывод всех изменений на экран
def render(self, console: Console, camera: Camera) -> None: """Renders the map. If a tile is in the "visible" array, then draw it with the "light" colors. If it isn't, but it's in the "explored" array, then draw it with the "dark" color. Otherwise, the default is "SHROUD".""" x_lower = camera.x x_upper = camera.x + camera.width y_lower = camera.y y_upper = camera.y + camera.height camera.update(self.engine.player) console.tiles_rgb[0:camera.width, 0:camera.height] = np.select( condlist=[self.visible, self.explored], choicelist=[self.tiles["light"], self.tiles["dark"]], default=tile_types.SHROUD, )[camera.x:camera.x + camera.width, camera.y:camera.y + camera.height] entities_sorted_for_rendering = sorted( self.entities, key=lambda x: x.render_order.value) for entity in entities_sorted_for_rendering: # Only print entities that are in the FOV if self.visible[entity.x, entity.y]: x, y = camera.apply(entity.x, entity.y) console.print(x=x, y=y, string=entity.char, fg=entity.color)
class Game(): def __init__(self): self.map = self.load_map(Constants.MAP_FILE) self.player = PlayerSprite(Constants.PLAYER_IMAGES, self.player_start_position, self.map_bounds) self.bullet_group = pygame.sprite.Group() self.player_group = pygame.sprite.Group(self.player) self.cursor = CursorSprite(Constants.CURSOR_IMAGE) def load_map(self, map): # Load map f = open(map, 'r') contents = f.read() f.close() json_contents = json.loads(contents) map_array = json_contents['map'] blocks = [] y = 0 for row in map_array: x = 0 for entry in row: if entry == 0: image = 'grass.png' passable = True destroyable = False elif entry == 1: image = 'water.png' passable = False destroyable = True elif entry == 2: image = 'lava.png' passable = False destroyable = False elif entry == 3: image = 'dirt.png' passable = True destroyable = False else: print("map file corrupted") sys.exit(1) # add on a new sprite at x*box_size, y*box_size block = TileSprite( Constants.IMAGE_PATH + image, (x * Constants.BLOCK_SIZE, y * Constants.BLOCK_SIZE), passable, destroyable) blocks.append(block) x += 1 y += 1 self.total_level_width = len( map_array[0] ) * Constants.BLOCK_SIZE # calculate size of level in pixels self.total_level_height = len( map_array) * Constants.BLOCK_SIZE # maybe make 32 an constant self.camera = Camera(Camera.complex_camera, self.total_level_width, self.total_level_height) self.tile_group = pygame.sprite.Group(*blocks) self.player_start_position = (Constants.BLOCK_SIZE * json_contents['start'][0], Constants.BLOCK_SIZE * json_contents['start'][1]) self.map_bounds = (Constants.BLOCK_SIZE * len(map_array[0]), Constants.BLOCK_SIZE * len(map_array)) def add_bullet(self): self.bullet_group.add( BulletSprite( self.camera.apply(self.player).center, pygame.mouse.get_pos())) def update_bullets(self): for bullet in self.bullet_group: if not pygame.Rect(0, 0, self.total_level_width, self.total_level_height).contains(bullet.rect): self.bullet_group.remove(bullet) else: bullet.update(self, self.tile_group)
class Game(): def __init__(self): pygame.init() self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) pygame.display.set_caption("Future") self.clock = pygame.time.Clock() self.a_map = World_map() self.bender = Robot(self) self.mouse_pos_x, self.mouse_pos_y = 0, 0 self.bullets = pygame.sprite.Group() self.bots1 = pygame.sprite.Group() bot1 = Bot1(self) bot1.rect.x = 904 bot1.rect.y = 282 bot1.real_x = 904 bot1.real_y = 282 bot1.x_on_a_map = 904 bot1.y_on_a_map = 282 self.bots1.add(bot1) bot1 = Bot1(self) bot1.rect.x = 104 bot1.rect.y = 292 bot1.real_x = 104 bot1.real_y = 292 bot1.x_on_a_map = 104 bot1.y_on_a_map = 292 self.bots1.add(bot1) self.bots2 = pygame.sprite.Group() self.bot2 = Bot2(self) self.bot2.rect.x = 600 self.bot2.rect.y = 92 self.bots2.add(self.bot2) self.gun1 = Guns(self) self.fire = False self.gun1_status = False self.move_left = False self.move_right = False self.camera = Camera(self.camera_configure, self) def camera_configure(self, camera, target_rect): l, t, _, _ = target_rect _, _, w, h = camera l, t = -l + SCREEN_WIDTH / 2, -t + SCREEN_HEIGHT / 2 l = min(0, l) # Не движемся дальше левой границы l = max(-(self.a_map.level_wight * TILE - camera.width), l) # Не движемся дальше правой границы t = max(-(self.a_map.level_height * TILE - camera.height), t) # Не движемся дальше нижней границы t = min(0, t) # Не движемся дальше верхней границы return pygame.Rect(l, t, w, h) def _check_events(self): for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() if event.type == pygame.MOUSEBUTTONDOWN: mouse_pos = pygame.mouse.get_pos() #self.fire_direction(mouse_pos) self.fire_bullets(mouse_pos) #self.fire_direction(mouse_pos) if event.type == pygame.KEYDOWN: if event.key == pygame.K_q: sys.exit() if event.key == pygame.K_SPACE: self.bender.jump() if event.key == pygame.K_a: self.bender.direction = 'left' #self.bender.moving_left = True self.move_left = True if event.key == pygame.K_d: #self.bender.moving_right = True self.bender.direction = 'right' self.move_right = True if event.key == pygame.K_f: self.bender.shot_f = True print( f'self.bender.real_x = {self.bender.real_x} self.bender.real_y = {self.bender.real_y}' ) #for bot1 in self.bots1: #print(f'self.bot1.x_on_a_map = {bot1.x_on_a_map} self.bot1._on_a_map_y = {bot1.y_on_a_map}') #print(f'self.bot1.rect.x = {bot1.rect.x} self.bot1.rect.y = {bot1.rect.y}') if event.key == pygame.K_k: pass if event.key == pygame.K_l: self.fire = True mouse_pos = pygame.mouse.get_pos() self.fire_bullets(mouse_pos) if event.key == pygame.K_1: if self.gun1_status == False: self.gun1_status = True elif self.gun1_status == True: self.gun1_status = False if event.key == pygame.K_LEFT: self.angle_minus = True if event.key == pygame.K_RIGHT: self.angle_plus = True if event.type == pygame.KEYUP: if event.key == pygame.K_a: self.move_left = False if event.key == pygame.K_d: self.move_right = False if event.key == pygame.K_f: self.bender.shot_f = False if event.key == pygame.K_k: pass if event.key == pygame.K_LEFT: self.angle_minus = False if event.key == pygame.K_RIGHT: self.angle_plus = False def fire_bullets(self, mouse_pos): if len(self.bullets) <= 999999: #BULLET_LIMIT: #my fire limit self.rect = pygame.draw.circle(self.screen, RED, (0, 0), 6) if self.bender.direction == 'right': self.rect = self.camera.apply(self.bender) self.rect.x += 80 self.rect.y += 60 self.mouse_pos_x, self.mouse_pos_y = mouse_pos self.mouse_pos_x = self.mouse_pos_x - self.rect.x self.mouse_pos_y = self.mouse_pos_y - self.rect.y print( f'self.mouse_pos_x = {self.mouse_pos_x}, self.mouse_pos_y = {self.mouse_pos_y}' ) xx = self.mouse_pos_x yy = self.mouse_pos_y line = (math.sqrt(xx**2 + yy**2)) print(f'line = {line} xx == {xx} yy== {yy}') print( f'self.bender.real_x = {self.bender.real_x} self.bender.real_y = {self.bender.real_y}' ) self.mouse_cos = xx / line self.mouse_sin = yy / line if -1 <= self.mouse_cos <= 1 and -1 <= self.mouse_sin <= 1 and self.gun1_status == True: new_bullet = Bullet(self, self.bender.direction) self.bullets.add(new_bullet) if self.bender.direction == 'left': self.rect = self.camera.apply(self.bender) self.rect.x -= 25 self.rect.y += 60 self.mouse_pos_x, self.mouse_pos_y = mouse_pos self.mouse_pos_x = self.mouse_pos_x - self.rect.x self.mouse_pos_y = self.mouse_pos_y - self.rect.y print( f'self.mouse_pos_x = {self.mouse_pos_x}, self.mouse_pos_y = {self.mouse_pos_y}' ) xx = self.mouse_pos_x yy = self.mouse_pos_y line = (math.sqrt(xx**2 + yy**2)) print(f'line = {line} xx == {xx} yy== {yy}') print( f'self.bender.real_x = {self.bender.real_x} self.bender.real_y = {self.bender.real_y}' ) self.mouse_cos = xx / line self.mouse_sin = yy / line if -1 <= self.mouse_cos <= 1 and -1 <= self.mouse_sin <= 1 and self.gun1_status == True: new_bullet = Bullet(self, self.bender.direction) self.bullets.add(new_bullet) def jump_of_hero(self): ##hit in a celling during a jump self.checking_for_a_celling() if self.bender.jump_activate < self.bender.height_jump and self.bender.jump_up == True: self.bender.real_y -= self.bender.size_of_jump # real self.bender.jump_activate += 1 elif self.bender.jump_activate == self.bender.height_jump and self.bender.jump_up == True: self.bender.jump_up = False self.bender.jump_activate -= 1 self.bender.real_y += self.bender.size_of_jump elif self.bender.jump_activate > 0 and self.bender.jump_up == False: self.bender.real_y += self.bender.size_of_jump self.bender.jump_activate -= 1 elif self.bender.jump_activate == 0 and self.bender.jump_up == False: self.bender.jump_act = False def checking_for_a_celling(self): self.bender.celling = False for x, y in self.a_map.hard_wall_left_to_right[( (self.bender.real_y) // TILE) - 1]: if x <= self.bender.real_x <= x + TILE and y <= self.bender.real_y - self.bender.size_of_jump <= y + TILE: # LEFT TOP self.bender.jump_up = False self.bender.celling = True if x <= self.bender.real_x + self.bender.X_WIGHT / 2 <= x + TILE and y <= self.bender.real_y - self.bender.size_of_jump <= y + TILE: # LEFT MIDLE self.bender.jump_up = False self.bender.celling = True if x <= self.bender.real_x + self.bender.X_WIGHT <= x + TILE and y <= self.bender.real_y - self.bender.size_of_jump <= y + TILE: # RIGHT TOP self.bender.jump_up = False self.bender.celling = True def run(self): while True: for r in range(1000): self._check_events() self.screen.fill(BGR_COLOR) self.jump_of_hero() #BOTTOM #looking for a surface fall = True for x, y in self.a_map.hard_wall_left_to_right[( (self.bender.real_y + self.bender.Y_HEIGHT) // TILE)]: if (x <= self.bender.real_x <= x + TILE and y <= self.bender.real_y + self.bender.Y_HEIGHT + self.bender.size_of_jump <= y + 5 # LEFT DOWN or x <= self.bender.real_x + self.bender.X_WIGHT / 2 <= x + TILE and y <= self.bender.real_y + self.bender.Y_HEIGHT <= y + 5 # MIDLE DOWN or x <= self.bender.real_x + self.bender.X_WIGHT <= x + TILE and y <= self.bender.real_y + self.bender.Y_HEIGHT <= y + 5): # RIGHT DOWN self.bender.jump_activate = 0 self.bender.jump_up = False fall = False # LEFT SIDE #checking_for_the_left_brick step_left = False step_right = False if self.move_left == True: if fall or self.bender.jump_activate != 0: #to avoid akward momens in the air for y, x in self.a_map.hard_wall[( (self.bender.real_x) // TILE) - 1]: if (x <= self.bender.real_x - self.bender.speed <= x + TILE and y <= self.bender.real_y <= y + TILE # LEFT TOP or x <= self.bender.real_x - self.bender.speed <= x + TILE and y <= self.bender.real_y + TILE <= y + TILE # LEFT MIDLE or x <= self.bender.real_x - self.bender.speed <= x + TILE and y <= self.bender.real_y + TILE * 2 <= y + TILE # downer LEFT MIDLE or x <= self.bender.real_x - self.bender.speed <= x + TILE and y <= self.bender.real_y + TILE * 3 <= y + TILE # mode downer LEFT MIDLE or x <= self.bender.real_x - self.bender.speed <= x + TILE and y <= self.bender.real_y + TILE * 4 <= y + TILE): # bottom LEFT MIDLE self.move_left = False elif not fall or self.bender.jump_activate == 0: for y, x in self.a_map.hard_wall[( (self.bender.real_x) // TILE) - 1]: if (x <= self.bender.real_x - self.bender.speed <= x + TILE and y <= self.bender.real_y <= y + TILE # LEFT TOP or x <= self.bender.real_x - self.bender.speed <= x + TILE and y <= self.bender.real_y + TILE <= y + TILE # LEFT MIDLE or x <= self.bender.real_x - self.bender.speed <= x + TILE and y <= self.bender.real_y + TILE * 2 <= y + TILE # downer LEFT MIDLE or x <= self.bender.real_x - self.bender.speed <= x + TILE and y <= self.bender.real_y + TILE * 3 <= y + TILE): # mode downer LEFT MIDLE self.move_left = False #checking_for_a_step for y, x in self.a_map.hard_wall[( (self.bender.real_x) // TILE)]: if x <= self.bender.real_x - self.bender.speed <= x + TILE and y <= self.bender.real_y + TILE * 4 <= y + TILE: #step step_left = True print(True) break self.checking_for_a_celling() #during climing if step_left == True and self.move_left != False and self.bender.celling != True: if r % 2 == 0: #it is for hard climing!!!! self.bender.real_x -= TILE self.bender.real_y += -TILE ##moving to left if step_left == False and self.move_left == True: self.bender.real_x -= self.bender.speed print('moving left') # RIGHT #checking_for_the_right_brick if self.move_right == True: if fall or self.bender.jump_activate != 0: #to avoid akward momens in the air for y, x in self.a_map.hard_wall[( (self.bender.real_x + self.bender.X_WIGHT) // TILE) + 1]: if (x <= self.bender.real_x + self.bender.X_WIGHT + self.bender.speed <= x + TILE and y <= self.bender.real_y <= y + TILE # right TOP or x <= self.bender.real_x + self.bender.X_WIGHT + self.bender.speed <= x + TILE and y <= self.bender.real_y + TILE <= y + TILE # right MIDLE or x <= self.bender.real_x + self.bender.X_WIGHT + self.bender.speed <= x + TILE and y <= self.bender.real_y + TILE * 2 <= y + TILE # downer right MIDLE or x <= self.bender.real_x + self.bender.X_WIGHT + self.bender.speed <= x + TILE and y <= self.bender.real_y + TILE * 3 <= y + TILE # mode downer right MIDLE or x <= self.bender.real_x + self.bender.X_WIGHT + self.bender.speed <= x + TILE and y <= self.bender.real_y + TILE * 4 <= y + TILE): # bottom right MIDLE self.move_right = False elif not fall or self.bender.jump_activate == 0: for y, x in self.a_map.hard_wall[( (self.bender.real_x + self.bender.X_WIGHT) // TILE) + 1]: if (x <= self.bender.real_x + self.bender.X_WIGHT + self.bender.speed <= x + TILE and y <= self.bender.real_y <= y + TILE # right TOP or x <= self.bender.real_x + self.bender.X_WIGHT + self.bender.speed <= x + TILE and y <= self.bender.real_y + TILE <= y + TILE # right MIDLE or x <= self.bender.real_x + self.bender.X_WIGHT + self.bender.speed <= x + TILE and y <= self.bender.real_y + TILE * 2 <= y + TILE # downer right MIDLE or x <= self.bender.real_x + self.bender.X_WIGHT + self.bender.speed <= x + TILE and y <= self.bender.real_y + TILE * 3 <= y + TILE): # mode downer right MIDLE self.move_right = False #checking_for_a_step for y, x in self.a_map.hard_wall[( (self.bender.real_x + self.bender.X_WIGHT) // TILE)]: if x <= self.bender.real_x + self.bender.X_WIGHT + self.bender.speed <= x + TILE and y <= self.bender.real_y + TILE * 4 <= y + TILE: #step step_right = True print(True) break self.checking_for_a_celling() #during climing if step_right == True and self.move_right != False and self.bender.celling != True: if r % 2 == 0: #it is for hard climing!!!! self.bender.real_x += TILE self.bender.real_y += -TILE ##moving to right if step_right == False and self.move_right == True: self.bender.real_x += self.bender.speed print('moving right') ### fallen if fall and self.bender.jump_act == False: self.bender.real_y += self.bender.size_of_jump self.bender.rect.x = self.bender.real_x self.bender.rect.y = self.bender.real_y self.camera.update(self.bender) self.a_map.draw(self) #TESTING I am watching neded row that way #for y,x in self.a_map.hard_wall[((self.bender.real_x + self.bender.X_WIGHT) // TILE)+1]:#self.bender.real_y // TILE]: for x,y in self.a_map.hard_wall_left_to_right[(self.bender.real_y // TILE)-1]: #for x,y in self.a_map.hard_wall_left_to_right[((self.bender.real_y) // TILE)]: #for y,x in self.a_map.hard_wall[((self.bender.real_x + self.bender.X_WIGHT) // TILE)+1]: for y, x in self.a_map.hard_wall[( (self.bender.real_x) // TILE) - 1]: square = pygame.Rect(x, y, TILE, TILE) pygame.draw.rect(self.screen, DARKGRAY, self.camera.apply_wall(square), 2) if r % 20 == 0: self.bot2.bore() if r % 6 == 0: self.bender.bore() self.bender.blitme(self.camera.apply(self.bender)) for bot1 in self.bots1: bot1.blitme(self.camera.apply(bot1)) for bot2 in self.bots2: bot2.blitme(self.camera.apply(bot2)) if self.gun1_status == True: self.gun1.draw(self.camera.apply(self.bender), self.bender.direction, self.fire) if self.fire == True: self.fire = False for bullet in self.bullets: for bot1 in self.bots1: if bot1.x_on_a_map <= bullet.x_on_a_map <= bot1.x_on_a_map + bot1.size_x and bot1.y_on_a_map <= bullet.y_on_a_map <= bot1.y_on_a_map + bot1.size_y: self.bots1.remove(bot1) self.bullets.remove(bullet) for bot2 in self.bots2: if bot2.rect.x <= bullet.x_on_a_map <= bot2.rect.x + bot2.size_x and bot2.rect.y <= bullet.y_on_a_map <= bot2.rect.y + bot2.size_y: self.bots2.remove(bot2) self.bullets.remove(bullet) ## If you wanna destroy black and white squares ##for row in range(len(self.a_map.world_map_left_to_right)): ##for xy in range(len(self.a_map.world_map_left_to_right[row])): ##if self.a_map.world_map_left_to_right[row][xy][0] <= bullet.x_on_a_map <= self.a_map.world_map_left_to_right[row][xy][0] +TILE and self.a_map.world_map_left_to_right[row][xy][1] <= bullet.y_on_a_map <= self.a_map.world_map_left_to_right[row][xy][1] +TILE: ##self.bullets.remove(bullet) ##self.a_map.world_map_left_to_right[row].pop(xy) ##break first_flag_break = False for row in range(len(self.a_map.hard_wall)): if first_flag_break == True: break for xy in range(len(self.a_map.hard_wall[row])): if self.a_map.hard_wall[row][xy][ 1] <= bullet.x_on_a_map <= self.a_map.hard_wall[ row][xy][1] + TILE and self.a_map.hard_wall[ row][xy][ 0] <= bullet.y_on_a_map <= self.a_map.hard_wall[ row][xy][0] + TILE: self.bullets.remove(bullet) #print(f'self.a_map.hard_wall[row][xy] {self.a_map.hard_wall[row][xy]}') flag_break = False for lr_row in range( len(self.a_map.hard_wall_left_to_right) ): if flag_break == True: break for xy_lr in range( len(self.a_map. hard_wall_left_to_right[lr_row] )): if (self.a_map.hard_wall[row][xy][1] == self.a_map. hard_wall_left_to_right[lr_row] [xy_lr][0] and self.a_map.hard_wall[row] [xy][0] == self.a_map. hard_wall_left_to_right[lr_row] [xy_lr][1]): self.a_map.hard_wall_left_to_right[ lr_row].pop(xy_lr) flag_break = True break self.a_map.hard_wall[row].pop(xy) first_flag_break = True break if bullet.need_to_delete() == True: self.bullets.remove(bullet) bullet.update() for bullet in self.bullets: bullet.draw_bullet(self.camera.apply(bullet)) pygame.display.flip() self.clock.tick(FPS)
class Game(object): def __init__(self): # Global setup self.screen_w = 640 self.screen_h = 480 self.screen_size = (self.screen_w, self.screen_h) self.screen = pygame.display.set_mode(self.screen_size) pygame.display.set_caption('Hero I') self.clock = pygame.time.Clock() self.fps = 60 self.planet = Planet(*self.screen_size) self.player = Player(self.screen_w/2, self.screen_h/2) self.spider = Monster('spider', 50, 100) self.slime = Monster('slime', 200, 400) self.monsters = pygame.sprite.Group(self.spider, self.slime) self.allsprites = pygame.sprite.Group(self.player, self.monsters) self.camera = Camera(self.screen_size) def main_loop(self): """ This is the Main Loop of the Game. """ while True: for event in pygame.event.get(): if event.type == pygame.QUIT: return None elif event.type == KEYDOWN: if event.key in (K_LEFT, K_RIGHT, K_UP, K_DOWN): self.player.change_speed(event.key, key_down=True) elif event.key in (K_ESCAPE, K_q): pygame.event.post(pygame.event.Event(QUIT)) elif event.type == KEYUP: if event.key in (K_LEFT, K_RIGHT, K_UP, K_DOWN): self.player.change_speed(event.key, key_down=False) self.screen.fill(Color('#FF00FF')) self.player.update() self.planet.update() self.camera.update(self.player.center) for tile, position in self.planet.render(self.player.center): self.screen.blit(tile, self.camera.apply(position)) for a in self.allsprites: if a is not self.player: a.update() self.screen.blit(a.image, self.camera.apply(a.rect.topleft)) pygame.display.update() self.clock.tick(self.fps)
def main(): pygame.init() size = (constants.SCREEN_WIDTH, constants.SCREEN_HEIGHT) screen = pygame.display.set_mode(size) pygame.display.set_caption("Xeon2") game = Game() pc = Player(game) level_list = [] level_list.append(cosmos.Level1(pc)) player_level = 0 current_level = level_list[player_level] active_sprite_list = pygame.sprite.Group() pc.level = current_level camera = Camera(complex_camera, constants.SCREEN_WIDTH*4, constants.SCREEN_HEIGHT*4) pc.rect.x = 15 pc.rect.y = 700 #active_sprite_list.add(pc) end = False won = False font = pygame.font.Font(None, 40) youlost = font.render("YOU LOST", 1, (255, 255, 255)) youwon = font.render("YOU WIN!", 1, (255, 255, 255)) done = False clock = pygame.time.Clock() while not pc.quit: pc.update() current_level.update() if pc.get_score() >= 14: pc.won = True ''' #if player_level < len(level_list)-1: if player_level < 2: pc.rect.x = 120 pc.rect.y = 0 player_level += 1 level_list.append(cosmos.Level2(pc)) current_level = level_list[player_level] pc.level = current_level elif pc.get_score() >= 2: ''' # Draw camerafocus = pc camera.update(camerafocus) # Draw the background screen.fill(constants.BLUE) current_level.drawBackground(screen) #this calls cosmos.Level.draw() # Draw the spritegroups for p in pc.game.backgrounds: screen.blit(p.image, camera.apply(p)) for p in game.enemygroup: screen.blit(p.image, camera.apply(p)) for p in game.enemygroup2: screen.blit(p.image, camera.apply(p)) for p in pc.game.entities: screen.blit(p.image, camera.apply(p)) for p in game.playerentity: screen.blit(p.image, camera.apply(p)) for p in game.projectilegroup: screen.blit(p.image, camera.apply(p)) for p in game.lives: for i in range (0, pc.get_health()): # draws hearts depending on the player's hp screen.blit(p.image, (i*50,0)) score = pc.get_score() score_conv = str(score) score_text = font.render("Score: " + score_conv, 1, (255,255,255)) if not pc.lost: if not pc.won: screen.blit(score_text, (1060, 0)) if player_level == 0: screen.blit(font.render("Level 1", 1, (255, 255, 255)), (1070, 30)) elif player_level == 1: screen.blit(font.render("Level 2", 1, (255, 255, 255)), (1070, 30)) else: if pc.restart: main() msg = font.render("Press Escape to quit or the 'R' key to restart", 1, (255, 255, 255)) screen.blit(msg, (300, 100)) screen.blit(youwon, (500, 50)) screen.blit(score_text, (510, 150)) pc.won = True else: if pc.restart: main() #pc.quit = True msg = font.render("Press Escape to quit or the 'R' key to restart", 1, (255, 255, 255)) screen.blit(msg, (300, 100)) screen.blit(score_text, (500, 100)) screen.blit(youlost, (500, 50)) clock.tick(60) pygame.display.flip() pygame.quit()
class Game: def __init__(self): # initialize game window, etc pygame.init() pygame.mixer.init() pygame.display.set_caption(TITLE) self.screen = pygame.display.set_mode((DISPLAY_WIDTH, DISPLAY_HEIGHT)) self.clock = pygame.time.Clock() self.running = True def new(self): # start a new game self.map = Map(128, 64) self.map.generate() self.player = Player(self, self.map.spawn_point[0] * TILESIZE, self.map.spawn_point[1] * TILESIZE) self.camera = Camera(4000, 4000) self.run() def run(self): # run game loop self.playing = True while self.playing: # tick clock and store delta time for last frame self.dt = self.clock.tick(FPS) / 1000 self.events() self.update() self.draw() def update(self): # game loop update self.camera.update(self.player) self.player.update() pass def events(self): # game loop events for event in pygame.event.get(): # check for closing window if event.type == pygame.QUIT: if self.playing: self.playing = False self.running = False def draw(self): # game loop draw self.screen.fill(DARKGRAY) for row in range(self.map.height): for col in range(self.map.width): tile = Tile(self, TILESIZE * col, TILESIZE * row, self.map.array[row][col]) self.screen.blit(tile.image, self.camera.apply(tile)) self.screen.blit(self.player.image, self.camera.apply(self.player)) pygame.display.flip() def show_main_menu(self): # main game menu self.new() pass def show_splash_screen(self): self.clock.tick(FPS) self.screen.fill(LIGHTGRAY) self.draw_text(TITLE, 128, y=DISPLAY_HEIGHT / 4) self.draw_text("Press Any Key to Start", 48, x=DISPLAY_WIDTH * 0.05, y=DISPLAY_HEIGHT * 7 / 8) pygame.display.flip() self.wait_for_key() def draw_text(self, text, size, x=None, y=(DISPLAY_HEIGHT / 4)): f = pygame.font.Font("fonts/SF_Archery_Black.ttf", size) surf = f.render(text, True, BLACK) if not x: x = DISPLAY_WIDTH / 2 - surf.get_width() / 2 self.screen.blit(surf, (x, y)) def wait_for_key(self): waiting = True while waiting: for event in pygame.event.get(): if event.type == pygame.QUIT: waiting = False self.running = False if event.type == pygame.KEYUP: waiting = False
def main( level, number, screen, timer ): # передаем уровень сюда, чтобы можно было потом запускать main с разными уровнями number += 1 pygame.display.set_caption("Yet another Mario") # Пишем в шапку bg = Surface((WIN_WIDTH, WIN_HEIGHT)) # Создание видимой поверхности # будем использовать как фон bg.fill(Color(BACKGROUND_COLOR)) # Заливаем поверхность сплошным цветом hero = Player(55, 655) # создаем героя по (x,y) координатам left = right = False # по умолчанию — стоим up = False entities = pygame.sprite.Group() # Все объекты platforms = [] # то, во что мы будем врезаться или опираться coins = [] # монетки level_width = len(level[0]) * PLATFORM_WIDTH level_height = len(level) * PLATFORM_HEIGHT camera = Camera(camera_configure, level_width, level_height) x = y = 0 # координаты for row in level: # вся строка for col in row: # каждый символ if col == "-": pf = Platform(x, y) entities.add(pf) platforms.append(pf) elif col == "M": cn = Coin(x, y) entities.add(cn) coins.append(cn) elif col == "F": finish = Finish(x, y) finish_flag = Finish_flag(x, y) entities.add(finish) entities.add(finish_flag) x += PLATFORM_WIDTH # блоки платформы ставятся на ширине блоков y += PLATFORM_HEIGHT # то же самое и с высотой x = 0 # на каждой новой строчке начинаем с нуля for e in entities: # отображение всего bg.blit(e.image, camera.apply( e)) # перерисовываются все блоки, создавая эффект движения камеры startscene = StartCutscene(screen, timer) nick = startscene.start(bg) # вот здес bg.fill(Color(BACKGROUND_COLOR)) while 1: # Основной цикл программы timer.tick(30) for e in pygame.event.get(): # Обрабатываем события if e.type == QUIT: terminate() if e.type == KEYDOWN and e.key == K_LEFT: left = True if e.type == KEYDOWN and e.key == K_RIGHT: right = True if e.type == KEYUP and e.key == K_RIGHT: right = False if e.type == KEYUP and e.key == K_LEFT: left = False if e.type == KEYDOWN and e.key == K_UP: mus = MUSIC.Music() mus.jump() up = True if e.type == KEYUP and e.key == K_UP: up = False isFinished = hero.update(left, right, up, platforms, coins, finish) # передвижение if isFinished: # когда из апдейта (строчка выше) передается, что финиш достигнут, попадаем сюда cutscene = FinalCutscene(screen, timer, number, nick, isFinished) cutscene.start() return screen.blit(bg, (0, 0)) # Каждую итерацию необходимо всё перерисовывать entities.add(hero) camera.update( hero) # камера центрируется относительно главного персонажа for e in entities: # отображение всего screen.blit( e.image, camera.apply(e) ) # перерисовываются все блоки, создавая эффект движения камеры camera.update( hero) # камера центрируется относительно главного персонажа for e in entities: # отображение всего screen.blit( e.image, camera.apply(e) ) # перерисовываются все блоки, создавая эффект движения камеры pygame.display.update() # обновление и вывод всех изменений на экран
class World: def __init__(self): self.screen = None self.player = None self.camera = Camera() self.initialize_tiles() self.flash_counter = [0, 0] self.flash_image = Surface((WIN_WIDTH, WIN_HEIGHT)) def initialize_screen(self, screen_manager, game_screen): """ l.initialize_screen( ScreenManager, GameScreen ) -> None Associate this level with the given screen_manager and game_screen. """ self.screen_manager = screen_manager self.screen = game_screen.screen_image def initialize_tiles(self): #TEMP self.tiles = [] for y in xrange(WORLD_HEIGHT): self.tiles.append([]) for x in xrange(WORLD_WIDTH): t = Tile(x, y, MEADOW_GRASS) self.tiles[y].append(t) for y in range(WORLD_HEIGHT*3/8, WORLD_HEIGHT*3/8 + WORLD_HEIGHT/4): for x in range(WORLD_WIDTH*3/8, WORLD_WIDTH*3/8 + WORLD_WIDTH/4): self.tiles[y][x] = Tile(x, y, FOREST_GRASS) for y in range(WORLD_HEIGHT*5/8, WORLD_HEIGHT*6/8): for x in range(WORLD_WIDTH*3/8, WORLD_WIDTH*3/8 + WORLD_WIDTH/4): self.tiles[y][x] = Tile(x, y, BUG_GRASS) for y in range(0, WORLD_HEIGHT): for x in range(WORLD_WIDTH*7/8, WORLD_WIDTH): self.tiles[y][x] = Tile(x, y, CHARRED_GRASS) for y in range(19, 21): for x in range(38, 40): self.tiles[y][x] = Tile(x, y, DARK_GRASS) self.tiles[WORLD_HEIGHT/2][WORLD_WIDTH/2].set_entity(TileEntity(HEALING_TOTEM)) self.tiles[20][WORLD_WIDTH*15/16].set_entity(TileEntity(SVON)) def update(self, up, down, left, right): player = self.player self.camera.update(player) player.update() self.draw_tiles() self.screen.blit(player.world_image, self.camera.apply(player)) self.flash_update() def begin_flash(self, color, duration): self.flash_counter = [duration, duration] self.flash_image.fill(color) def draw_tiles(self): for row in self.tiles: for t in row: if t: self.screen.blit(t.image, self.camera.apply(t)) def flash_update(self): if self.flash_counter[0] <= 0: return half = self.flash_counter[1]/2 if half <= 0: return current = self.flash_counter[0] if current > half: alpha = int(255.0 - ((current - half)/float(half))*255.0) else: alpha = int(((current)/float(half))*255.0) self.flash_image.set_alpha(alpha) self.screen.blit(self.flash_image, (0, 0)) self.flash_counter[0] -= 1 def add_player(self, player, x, y): self.player = player player.rect.left, player.rect.top = x*TILE_SIZE, y*TILE_SIZE def add_tile(self, tile, x, y): self.tiles[y][x] = tile def tile_at(self, x, y): width, height = len(self.tiles[0]), len(self.tiles) if x < 0 or x > width: return None if y < 0 or y > height: return None return self.tiles[y][x]
def play(player): pygame.init() screen = pygame.display.set_mode(DISPLAY) pygame.display.set_caption("Bounce") background = Surface((WIN_WIDTH, WIN_HEIGHT)) background.fill(Color(BACKGROUND_COLOR)) score_ground = Surface((WIN_WIDTH, WIN_HEIGHT - 3 * 32)) score_ground.fill(Color(SCORE_GROUND_COLOR)) ball = player(64, 32) up = left = right = False my_font = pygame.font.SysFont('Arial', 30) entities_back = pygame.sprite.Group() entities_front = pygame.sprite.Group() platforms = [] level = level_1 x = y = 0 for row in level: for col in row: if col == "-": pf = Platform(x, y) entities_back.add(pf) platforms.append(pf) if col == "i": pf = Spike(x + 7, y) entities_back.add(pf) platforms.append(pf) if col == "s": pf = SavePoint(x, y) entities_back.add(pf) platforms.append(pf) if col == "b": pf = BonusLife(x, y) entities_back.add(pf) platforms.append(pf) if col == "e": pf = Exit(x, y) entities_back.add(pf) platforms.append(pf) if col == "r": ball.ring_count += 1 pf = Ring(x + 17, y) entities_back.add(pf) platforms.append(pf) pf = BackFontRing(x + 17, y - 32) entities_back.add(pf) platforms.append(pf) pf = FrontFontRing(x + 8, y - 32) entities_front.add(pf) platforms.append(pf) pf = Invisible(x + 12, y - 32) platforms.append(pf) pf = Invisible(x + 12, y + 22) platforms.append(pf) if col == "v": ball.ring_count += 1 pf = HRing(x + 32, y + 17) entities_back.add(pf) platforms.append(pf) pf = HBackFontRing(x, y + 9) entities_front.add(pf) platforms.append(pf) pf = HFrontFontRing(x, y) entities_back.add(pf) platforms.append(pf) pf = HInvisible(x + 2, y + 8) platforms.append(pf) pf = HInvisible(x + 54, y + 8) platforms.append(pf) x += PLATFORM_WIDTH y += PLATFORM_HEIGHT x = 0 total_level_width = len(level[0]) * PLATFORM_WIDTH total_level_height = len(level) * PLATFORM_HEIGHT camera = Camera(camera_configure, total_level_width, total_level_height) timer = pygame.time.Clock() while True: timer.tick(60) for e in pygame.event.get(): if e.type == QUIT: raise SystemExit if e.type == KEYDOWN and e.key == K_LEFT: left = True if e.type == KEYDOWN and e.key == K_RIGHT: right = True if e.type == KEYUP and e.key == K_RIGHT: right = False if e.type == KEYUP and e.key == K_LEFT: left = False if e.type == KEYDOWN and e.key == K_UP: up = True if e.type == KEYUP and e.key == K_UP: up = False screen.blit(background, (0, 0)) ball.update(left, right, up, platforms) camera.update(ball) for e in entities_back: screen.blit(e.image, camera.apply(e)) screen.blit(ball.image, camera.apply(ball)) for e in entities_front: screen.blit(e.image, camera.apply(e)) screen.blit(score_ground, (0, 8 * 32)) score = my_font.render(ball.Score, True, (255, 255, 255)) screen.blit(score, (5 * 32, 8 * 32 + 5)) x = 10 y = 8 * 32 + 3 for i in range(ball.lifes): screen.blit(ball.life_image, (x, y)) x += 26 x = 10 y = 9 * 32 for i in range(ball.ring_count): screen.blit(ball.ring_image, (x, y)) x += 18 if ball.is_game_over(): raise SystemExit pygame.display.update()
left = False if e.type == pg.KEYUP and e.key == pg.K_UP: up = False if e.type == pg.KEYUP and e.key == pg.K_DOWN: down = False screen.fill((0,0, 0)) hero.update(left, right, up, down, wall) # передвижение camera.update(hero) layer_monster.update(hero, layer_2, layer_bullet, wall) layer_2.update(layer_all_monster_and_layer, base_interface) for e in layer_0: if -camera.state.x+radius*32 < e.rect.x and -camera.state.x + 800-radius*32-32 > e.rect.x and -camera.state.y+radius*32 < e.rect.y and -camera.state.y + 600-radius*32-32 > e.rect.y: screen.blit(e.image, camera.apply(e)) elif e.light_status == True: screen.blit(e.image, camera.apply(e)) for e in layer_1: if -camera.state.x+radius*32 < e.rect.x and -camera.state.x + 800-radius*32-32 > e.rect.x and -camera.state.y+radius*32 < e.rect.y and -camera.state.y + 600-radius*32-32 > e.rect.y: screen.blit(e.image, camera.apply(e)) elif e.light_status == True: screen.blit(e.image, camera.apply(e)) for e in layer_monster: if -camera.state.x+radius*32 < e.rect.x and -camera.state.x + 800-radius*32-32 > e.rect.x and -camera.state.y+radius*32 < e.rect.y and -camera.state.y + 600-radius*32-32 > e.rect.y: screen.blit(e.image, camera.apply(e)) for e in layer_2: if -camera.state.x+radius*32 < e.rect.x and -camera.state.x + 800-radius*32-32 > e.rect.x and -camera.state.y+radius*32 < e.rect.y and -camera.state.y + 600-radius*32-32 > e.rect.y:
def main(): pygame.init() screen = pygame.display.set_mode(DISPLAY) pygame.display.set_caption("Platformer Title") bg = Surface((WIN_WIDTH, WIN_HEIGHT)) bg.fill(Color(BACKGROUND_COLOR)) hero = Player(55, 55) left = right = False up = False timer = pygame.time.Clock() entities = pygame.sprite.Group() # all objects platforms = [] # object to hit or stay entities.add(hero) level = [ "----------------------------------", "- -", "- -- -", "- -", "- -- -", "- -", "-- -", "- -", "- ---- --- -", "- -", "-- -", "- -", "- --- -", "- -", "- -", "- --- -", "- -", "- ------- ---- -", "- -", "- - -", "- -- -", "- -", "- -", "----------------------------------" ] x = y = 0 for row in level: for col in row: if col == "-": pf = Platform(x, y) entities.add(pf) platforms.append(pf) x += PLATFORM_WIDTH y += PLATFORM_HEIGHT x = 0 total_level_width = len(level[0]) * PLATFORM_WIDTH # real level width total_level_height = len(level) * PLATFORM_HEIGHT # height camera = Camera(camera_configure, total_level_width, total_level_height) while 1: timer.tick(60) for e in pygame.event.get(): if e.type == QUIT: raise SystemExit("QUIT") if e.type == KEYDOWN and e.key == K_UP: up = True if e.type == KEYDOWN and e.key == K_LEFT: left = True if e.type == KEYDOWN and e.key == K_RIGHT: right = True if e.type == KEYUP and e.key == K_UP: up = False if e.type == KEYUP and e.key == K_RIGHT: right = False if e.type == KEYUP and e.key == K_LEFT: left = False screen.blit(bg, (0, 0)) hero.update(left, right, up, platforms) camera.update(hero) for e in entities: screen.blit(e.image, camera.apply(e)) pygame.display.update()
class GameScreen(Screen_): def __init__(self, levelInd): super(GameScreen, self).__init__() self.fadeScreen = pygame.image.load("../img/backgrounds/blackscreen.png").convert() self.font = getFont("VolterGoldfish", 20) self.nextColorIcon = pygame.image.load("../img/hud/nextColor23.png").convert_alpha() self.progressIcon = pygame.image.load("../img/hud/progress.png").convert_alpha() self.timebar = pygame.image.load("../img/hud/timebar.png").convert_alpha() self.shieldbar = pygame.image.load("../img/hud/shieldbar.png").convert_alpha() self.lifebar_ = pygame.image.load("../img/hud/lifebar_.png").convert() self.level = Level(levelInd) self.camera = Camera(640, 800, 3200) # running = True self.retry = False self.frame_number = 0 self.anims = [] self.stopDelay = 0 self.stopped = False self.killFragments = [] self.dust = [] self.starting = True self.ending = False self.alpha = 255 # Music load # pygame.mixer.music.load("../sounds/piano.wav") # pygame.mixer.music.play(-1) pygame.mixer.music.set_volume(0.5) # Player self.player = Player() self.fire = Rect((0,3200),(800,5)) self.playerDown = False self.answerPos = [(100,300),(100,400),(100,500)] self.answerChoice = 0 self.activecolor = THECOLORS['white'] self.inactivecolor = THECOLORS['grey21'] if exist('powers'): self.player.timePower, self.player.mines, self.player.shields = load('powers') def killFragmentsUpdate(self): for kf in self.killFragments: kf.update() if kf.kill: self.killFragments.remove(kf) def render(self, backgroundScreen): # draw background backgroundScreen.blit(self.level.background,(0, 0)) for d in self.dust: backgroundScreen.fill(d.color,d.rect) backgroundScreen.blit(self.level.background_alpha,(0,self.camera.apply(Rect(0, 0, 0, 0))[1]/2)) for e in self.level.enemies: e.render(backgroundScreen, self.camera) if not self.player.killed: self.player.render(backgroundScreen, self.camera) for b in self.level.blocks: b.render(backgroundScreen,self.camera) # Display bottom bar backgroundScreen.fill(THECOLORS['black'],Rect((0,600),(800,40))) backgroundScreen.blit(self.nextColorIcon, to_pygame((35,35), backgroundScreen), (0, 30, 50, 30)) backgroundScreen.blit(self.font.render(str(self.player.timePower), 1, (170,174,48)), (50,607)) backgroundScreen.blit(self.progressIcon, to_pygame((35,5), backgroundScreen), (0, 10, self.player.timePowerCount*10, 10)) backgroundScreen.blit(self.nextColorIcon, to_pygame((120,35), backgroundScreen), (0, 60, 50, 30)) backgroundScreen.blit(self.font.render(str(self.player.mines), 1, (131,43,93)), (135,607)) backgroundScreen.blit(self.progressIcon, to_pygame((120,5), backgroundScreen), (0, 20, self.player.minesCount*10, 10)) backgroundScreen.blit(self.nextColorIcon, to_pygame((205,35), backgroundScreen), (0, 0, 50, 30)) backgroundScreen.blit(self.font.render(str(self.player.shields), 1, (8,108,110)), (220,607)) backgroundScreen.blit(self.progressIcon, to_pygame((205,5), backgroundScreen), (0, 0, self.player.shieldsCount*10, 10)) backgroundScreen.blit(self.lifebar_, to_pygame((400,40), backgroundScreen)) if self.player.slomoDelay > 0: backgroundScreen.blit(self.timebar, to_pygame((404,31), backgroundScreen), (0, 0, (math.ceil(self.player.slomoDelay*2/20)*20), 22)) elif self.player.shieldDelay > 0: backgroundScreen.blit(self.shieldbar, to_pygame((404,31), backgroundScreen), (0, 0, (math.ceil(self.player.shieldDelay*2/20)*20), 22)) if self.player.killed: for kf in self.killFragments: kf.render(backgroundScreen,self.camera) if self.starting: self.fadeScreen.set_alpha(self.alpha) backgroundScreen.blit(self.fadeScreen,(0,0)) if self.alpha < 0: self.starting = False self.alpha = 0 self.alpha -= 10 if self.ending: # pygame.mixer.music.set_volume(1-self.alpha/255) self.fadeScreen.set_alpha(self.alpha) backgroundScreen.blit(self.fadeScreen,(0,0)) if self.alpha > 255: self.stopped = True self.alpha += 10 if self.player.finished: self.fadeScreen.set_alpha(self.alpha) backgroundScreen.blit(self.fadeScreen,(0,0)) if self.alpha > 255: self.stopped = True self.alpha += 10 backgroundScreen.blit(self.font.render(self.level.question,1,THECOLORS['red']),(400,100)) for i in range(len(self.level.answers)): if self.answerChoice != i: backgroundScreen.blit(self.font.render(self.level.answers[i],1,self.inactivecolor),self.answerPos[i]) else: backgroundScreen.blit(self.font.render(self.level.answers[i],1,self.activecolor),self.answerPos[i]) def handle_events(self, events): for event in events: if event.type == QUIT: exit() elif event.type == KEYDOWN: if event.key == K_ESCAPE: self.manager.go_to('levelSelectScreen') if self.player.finished: if event.key == K_DOWN: self.answerChoice = (self.answerChoice + 1) % 3 elif event.key == K_UP: self.answerChoice = (self.answerChoice - 1) % 3 elif event.key == K_RETURN: save([('powers',[self.player.timePower,self.player.mines,self.player.shields])]) self.manager.go_to_game(self.level.index + 1 ) def update(self): # Update blocks for b in self.level.blocks: b.update(self.player) # Update enemies for e in self.level.enemies: e.update( self.player, self.level.blocks) if e.hit: self.level.enemies.remove(e) # Update player if not self.player.finished: if not self.player.killed: self.player.update(self.level.blocks, self.frame_number) else: if not self.stopped: self.stopped = True self.ending = True else: self.manager.go_to_game(self.level.index) self.camera.update((self.player.rect.x, self.player.rect.y, 0, 0)) self.killFragmentsUpdate() if self.player.rect.y + 64 > abs(self.camera.state.y-600): self.player.killed = True if self.player.killed and not self.playerDown: # self.player.hitSound.play() self.playerDown = True if random.randint(0,10) == 5: s = random.randint(2,10) self.dust.append(Dust(Rect(random.randint(200,600),700,s,s))) if self.player.slomoDelay > 0: for d in self.dust: d.update(d.speed/5) else: for d in self.dust: d.update(d.speed) if d.rect.y < 0: self.dust.remove(d)
def play_game(player, entities, game_map, message_log, game_state, con, panel, animation_console, constants): fov_recompute = True fov_map = initialize_fov(game_map) key = libtcod.Key() mouse = libtcod.Mouse() game_state = GameStates.PLAYERS_TURN previous_game_state = game_state camera = Camera( x=0, y=0, width=constants['screen_width'], height=constants['screen_height'], map_width=constants['map_width'], map_height=constants['map_height'], ) camera.update(player) targeting_item = None weapon_target = None while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event( libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse) x_in_camera, y_in_camera = camera.apply(player.x, player.y) if fov_recompute: recompute_fov(fov_map, player.x, player.y, constants['fov_radius'], constants['fov_light_walls'], constants['fov_algorithm']) render_all(con, panel, entities, player, game_map, fov_map, fov_recompute, message_log, constants['screen_width'], constants['screen_height'], constants['bar_width'], constants['panel_height'], constants['panel_y'], mouse, constants['colors'], game_state, camera) fov_recompute = False libtcod.console_flush() clear_all(con, entities, camera) action = handle_keys(key, game_state) mouse_action = handle_mouse(mouse) move = action.get('move') wait = action.get('wait') pickup = action.get('pickup') show_inventory = action.get('show_inventory') drop_inventory = action.get('drop_inventory') inventory_index = action.get('inventory_index') take_stairs = action.get('take_stairs') level_up = action.get('level_up') show_character_screen = action.get('show_character_screen') targeter = action.get('targeter') fire = action.get('fire') exit = action.get('exit') fullscreen = action.get('fullscreen') left_click = mouse_action.get('left_click') right_click = mouse_action.get('right_click') player_turn_results = [] if move and game_state == GameStates.PLAYERS_TURN: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy if not game_map.is_blocked(destination_x, destination_y): target = get_blocking_entities_at_location( entities, destination_x, destination_y) if target: attack_results = player.fighter.attack(target) player_turn_results.extend(attack_results) else: player.move(dx, dy) camera.update(player) fov_recompute = True for entity in entities: if entity != player and entity.x == player.x and entity.y == player.y: see_results = [{ 'message': Message('{0}(이)가 보인다.'.format(entity.name), libtcod.white) }] player_turn_results.extend(see_results) game_state = GameStates.ENEMY_TURN elif wait: game_state = GameStates.ENEMY_TURN elif pickup and game_state == GameStates.PLAYERS_TURN: for entity in entities: if entity.item and entity.x == player.x and entity.y == player.y: pickup_results = player.inventory.add_item(entity) player_turn_results.extend(pickup_results) break else: message_log.add_message( Message('여기에는 주울 수 있는 것이 없다.', libtcod.yellow)) if targeter: previous_game_state = GameStates.PLAYERS_TURN testfunc() game_state = GameStates.WEAPON_TARGETING if show_inventory: previous_game_state = game_state game_state = GameStates.SHOW_INVENTORY if drop_inventory: previous_game_state = game_state game_state = GameStates.DROP_INVENTORY if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len( player.inventory.items): item = player.inventory.items[inventory_index] if game_state == GameStates.SHOW_INVENTORY: player_turn_results.extend( player.inventory.use(item, entities=entities, fov_map=fov_map)) elif game_state == GameStates.DROP_INVENTORY: player_turn_results.extend(player.inventory.drop_item(item)) if take_stairs and game_state == GameStates.PLAYERS_TURN: for entity in entities: if entity.stairs and entity.x == player.x and entity.y == player.y: entities = game_map.next_floor(player, message_log, constants) fov_map = initialize_fov(game_map) fov_recompute = True camera.update(player) libtcod.console_clear(con) break else: message_log.add_message(Message('여기에는 계단이 없다.', libtcod.yellow)) if level_up: if level_up == 'hp': player.fighter.base_max_hp += 20 player.fighter.hp += 20 elif level_up == 'str': player.fighter.base_power += 1 elif level_up == 'def': player.fighter.base_ += 1 game_state = previous_game_state if show_character_screen: previous_game_state = game_state game_state = GameStates.CHARACTER_SCREEN if game_state == GameStates.CHARACTER_SCREEN: x, y = get_mouse_movement(mouse) get_player_tooltip(animation_console, x, y, mouse, constants['screen_width'], constants['screen_height']) if left_click: game_state = previous_game_state if game_state == GameStates.WEAPON_TARGETING: wx, wy = get_mouse_movement(mouse) get_targeting_radius( con, panel, wx, wy, entities, player, game_map, fov_map, fov_recompute, message_log, constants['screen_width'], constants['screen_height'], constants['bar_width'], constants['panel_height'], constants['panel_y'], mouse, constants['colors'], game_state, camera, left_click, right_click, animation_console) if left_click: weapon_target_x, weapon_target_y = left_click weapon_target_x -= camera.x weapon_target_y -= camera.y if not libtcod.map_is_in_fov(fov_map, weapon_target_x, weapon_target_y): message_log.add_message(Message('시야 밖의 적을 목표로 지정할 수는 없다.')) for entity in entities: if entity.distance( weapon_target_x, weapon_target_y) == 0 and entity.name == 'Player': message_log.add_message( Message('자기 자신을 목표로 지정할 수는 없다.')) elif entity.distance( weapon_target_x, weapon_target_y) == 0 and entity.fighter: player_turn_results.append({'wep_targetted': True}) weapon_target = entity elif right_click: player_turn_results.append({'targeting_cancelled': True}) if fire: #수동으로 타겟을 잡았거나, 자동 발사로 타겟이 잡혔을 때 #원거리 무기 미장비시 if not player.equipment.main_hand: message_log.add_message(Message('발사할 수 있는 것을 장비하고 있지 않다.')) #원거리 무기 장비시 elif player.equipment.main_hand.equippable.ranged_weapon == True: #타겟이 지정되었을 때 if weapon_target is not None: print(weapon_target) message_log.add_message( Message('당신은 {0}을(를) 발사한다! '.format( player.equipment.main_hand.name))) attack_results = player.fighter.attack(weapon_target) player_turn_results.extend(attack_results) if weapon_target.fighter.hp <= 0: weapon_target = None game_state = GameStates.ENEMY_TURN #타겟이 지정되지 않았을 때 자동 발사 else: closest_distance = 10 + 1 for entity in entities: if entity.fighter and libtcod.map_is_in_fov( fov_map, entity.x, entity.y ) and entity.name != 'Player' and entity.blocks == True: distance = player.distance_to(entity) if distance < closest_distance: weapon_target = entity closest_distance = distance #자동 발사 대상 지정 후 발사, 타겟 지정 if weapon_target: message_log.add_message( Message('당신은 {0}을(를) 발사한다! '.format( player.equipment.main_hand.name))) attack_results = player.fighter.attack(weapon_target) player_turn_results.extend(attack_results) if weapon_target.fighter.hp <= 0: weapon_target = None game_state = GameStates.ENEMY_TURN #타겟이 지정되지 않았고 적이 Fov 외에 있을 때 else: message_log.add_message( Message('사격할 수 있는 대상이 보이지 않는다.')) weapon_target = None game_state = GameStates.ENEMY_TURN else: message_log.add_message(Message('발사할 수 있는 것을 장비하고 있지 않다.')) if game_state == GameStates.TARGETING: x, y = get_mouse_movement(mouse) get_targeting_radius( con, panel, x, y, entities, player, game_map, fov_map, fov_recompute, message_log, constants['screen_width'], constants['screen_height'], constants['bar_width'], constants['panel_height'], constants['panel_y'], mouse, constants['colors'], game_state, camera, left_click, right_click, animation_console) if left_click: target_x, target_y = left_click target_x -= camera.x target_y -= camera.y item_use_results = player.inventory.use(targeting_item, entities=entities, fov_map=fov_map, target_x=target_x, target_y=target_y) player_turn_results.extend(item_use_results) elif right_click: player_turn_results.append({'targeting_cancelled': True}) if exit: if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY, GameStates.CHARACTER_SCREEN): game_state = previous_game_state elif game_state == GameStates.LEVEL_UP: level_up_menu(con, 'Level up! Choose a stat to raise:', player, 40, constants['screen_width'], constants['screen_height']) elif game_state == GameStates.CHARACTER_SCREEN: character_screen(player, 30, 10, constants['screen_width'], constants['screen_height']) elif game_state == GameStates.TARGETING: player_turn_results.append({'targeting_cancelled': True}) else: save_game(player, entities, game_map, message_log, game_state) return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) for player_turn_result in player_turn_results: message = player_turn_result.get('message') dead_entity = player_turn_result.get('dead') item_added = player_turn_result.get('item_added') item_consumed = player_turn_result.get('consumed') item_dropped = player_turn_result.get('item_dropped') equip = player_turn_result.get('equip') targeting = player_turn_result.get('targeting') targeting_cancelled = player_turn_result.get('targeting_cancelled') wep_targetted = player_turn_result.get('wep_targetted') xp = player_turn_result.get('xp') if message: message_log.add_message(message) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: victim_cord_x, victim_cord_y = get_victim_cord(dead_entity) explosion(con, panel, victim_cord_x, victim_cord_y, entities, player, game_map, fov_map, fov_recompute, message_log, constants['screen_width'], constants['screen_height'], mouse, constants['colors'], camera, animation_console) blood_splatter(con, game_map, victim_cord_x, victim_cord_y, constants['colors']) libtcod.console_clear(con) fov_recompute = True message = kill_monster(dead_entity) pass message_log.add_message(message) if item_added: entities.remove(item_added) game_state = GameStates.ENEMY_TURN if item_consumed: game_state = GameStates.ENEMY_TURN if item_dropped: entities.append(item_dropped) game_state = GameStates.ENEMY_TURN if equip: equip_results = player.equipment.toggle_equip(equip) for equip_result in equip_results: equipped = equip_result.get('equipped') dequipped = equip_result.get('dequipped') if equipped: message_log.add_message( Message('{0}(을)를 장비했다.'.format(equipped.name))) if dequipped: message_log.add_message( Message('{0}(을)를 해제했다.'.format(dequipped.name))) game_state = GameStates.ENEMY_TURN if wep_targetted: game_state = previous_game_state message_log.add_message(Message('당신은 목표를 조준한다.')) if targeting: previous_game_state = GameStates.PLAYERS_TURN game_state = GameStates.TARGETING targeting_item = targeting message_log.add_message(targeting_item.item.targeting_message) if targeting_cancelled: game_state = previous_game_state message_log.add_message(Message('목표 지정을 취소하였다.')) if xp: leveled_up = player.level.add_xp(xp) message_log.add_message( Message('당신은 {0}의 경험치를 얻었다..'.format(xp))) if leveled_up: message_log.add_message( Message( '레벨 {0}에 도달하였다!'.format(player.level.current_level) + '!', libtcod.yellow)) previous_game_state = game_state game_state = GameStates.LEVEL_UP if game_state == GameStates.ENEMY_TURN: for entity in entities: if entity.ai: enemy_turn_results = entity.ai.take_turn( player, fov_map, game_map, entities) for enemy_turn_result in enemy_turn_results: message = enemy_turn_result.get('message') dead_entity = enemy_turn_result.get('dead') if message: message_log.add_message(message) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message = kill_monster(dead_entity) message_log.add_message(message) if game_state == GameStates.PLAYER_DEAD: break if game_state == GameStates.PLAYER_DEAD: break else: game_state = GameStates.PLAYERS_TURN
class Game: def __init__(self): pg.init() self.screen = pg.display.set_mode((WIDTH, HEIGHT)) pg.display.set_caption(TITLE) self.clock = pg.time.Clock() self.load_data() def load_data(self): game_folder = path.dirname(__file__) img_folder = path.join(game_folder, 'img') map_folder = path.join(game_folder, 'img') self.map = TiledMap(path.join(map_folder, 'map_city.tmx')) self.map_img = self.map.make_map() self.map_rect = self.map_img.get_rect() def new(self): # initialize all variables and do all the setup for a new game self.all_sprites = pg.sprite.Group() self.obstacles = pg.sprite.Group() self.stairsRD = pg.sprite.Group() self.stairsLD = pg.sprite.Group() for tile_object in self.map.tmxdata.objects: if tile_object.name == 'player': self.player_img = [self.map.tmxdata.get_tile_image_by_gid(gid) for gid, duration in tile_object.properties['frames']] self.player = Player(self, tile_object.x, tile_object.y) if tile_object.name == 'obstacle': Obstacle(self, tile_object.x, tile_object.y, tile_object.width, tile_object.height) if tile_object.name == 'stair-right-down': StairRD(self, tile_object.x, tile_object.y, tile_object.width, tile_object.height) if tile_object.name == 'stair-left-down': StairLD(self, tile_object.x, tile_object.y, tile_object.width, tile_object.height) self.camera = Camera(self.map.width, self.map.height) self.draw_debug = False def run(self): # game loop - set self.playing = False to end the game self.playing = True while self.playing: self.dt = self.clock.tick(FPS) / 1000 self.events() self.update() self.draw() def quit(self): pg.quit() sys.exit() def update(self): # update portion of the game loop self.all_sprites.update() self.camera.update(self.player) def draw_grid(self): for x in range(0, WIDTH, TILESIZE): pg.draw.line(self.screen, LIGHTGREY, (x, 0), (x, HEIGHT)) for y in range(0, HEIGHT, TILESIZE): pg.draw.line(self.screen, LIGHTGREY, (0, y), (WIDTH, y)) def draw(self): pg.display.set_caption("{:.2f}".format(self.clock.get_fps())) # self.screen.fill(BGCOLOR) # self.draw_grid() self.screen.blit(self.map_img, self.camera.apply_rect(self.map_rect)) for sprite in self.all_sprites: self.screen.blit(sprite.image, self.camera.apply(sprite)) pg.display.flip() def events(self): # catch all events here for event in pg.event.get(): if event.type == pg.QUIT: self.quit() if event.type == pg.KEYDOWN: if event.key == pg.K_ESCAPE: self.quit() def show_start_screen(self): pass def show_go_screen(self): pass
def game(): global saves, sounds camera = Camera() clock = pygame.time.Clock() dt = 0 running = True # Инициализация групп platform_sprites = pygame.sprite.Group() platforms = [] # объекты, с которыми будет происходить взаимодействие enemies_sprites = pygame.sprite.Group() enemies = [] # Перемещение героя respawn() # Выводим на экран все обьекты на уровня render(load_level("level.txt"), platforms, platform_sprites, enemies, enemies_sprites) # Вызываем экран с обучением if not saves: tutorial() while running: pygame.mouse.set_visible(False) screen.blit(game_bg, (0, 0)) # Отключаем звуки if not sounds: hero.sounds = False else: hero.sounds = True for event in pygame.event.get(): if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: pause_menu() hero.handle_event(event) camera.update(hero) camera.apply(hero) for sprite in platform_sprites: camera.apply(sprite) for sprite in enemies_sprites: camera.apply(sprite) platform_sprites.update(dt) platform_sprites.draw(screen) enemies_sprites.update(dt, platforms, hero_sprites, hero) enemies_sprites.draw(screen) hero_sprites.update(dt, platforms, camera) hero_sprites.draw(screen) if hero.dead: restart() if hero.end: end_screen() dt = clock.tick(fps) / 1000 pygame.display.flip()
class Game: def __init__(self, debug=False): self._debug = debug self._pause = False self.character = "character\\megaman.json" self.backdrop = constants.BLACK self.monster_sprite_list = pygame.sprite.Group() self.scenery_sprite_list = pygame.sprite.Group() self.bullet_sprite_list = pygame.sprite.Group() self.player_sprite_list = pygame.sprite.Group() self.platform_sprite_list = pygame.sprite.Group() self.ladder_sprite_list = pygame.sprite.Group() self.door_sprite_list = pygame.sprite.Group() self.moving_platforms_list = pygame.sprite.Group() self.spawners = [] self.ui_lifebar = [] self.object_list = {} self.create_objects() self.ui_list = [] self.main_menu = Menu() self.menu_flag = True self.start_level = None self.load_splash() #GAME def load_splash(self): self.clear() self.add_title("Run & Gun") self.add_button("New",(constants.DWIDTH/2)-50, 350, 100,50, constants.WHITE, constants.BLUE, self.start_game) self.add_button("Quit",(constants.DWIDTH/2)-50, 450, 100,50, constants.WHITE, constants.BLUE, self.exit_game) def start_game(self): self.clear() self.lives = 3 self.ui_list += self.main_menu.draw_menu() self.current_level = [self.main_menu.selected_name(), 0, 0, "R"] def exit_game(self): pygame.quit() sys.exit() def load_level(self, level): if self.start_level == None: self.start_level = level[0] self.menu_flag = False player_hp = -1 if hasattr(self, 'player'): player_hp = self.player.get_life() self.clear() self.level = Level(self.main_menu.get_level_json(level[0])) if level[1] != 0: self.level.player_x = int(level[1]) if level[2] != 0: self.level.player_y = int(level[2]) self.scenery_sprite_list = self.level.build_scenery() self.platform_sprite_list = self.level.build_platforms() self.ladder_sprite_list = self.level.build_ladders() self.door_sprite_list = self.level.build_doors() self.monster_sprite_list = self.level.build_monsters() self.spawners = self.level.build_spawners() self.backdrop = self.level.backdrop self.add_player(self.character, self.level.player_x, self.level.player_y, level[3]) if player_hp > 0: self.player.set_life(player_hp) self.add_camera() self.add_lifebar(25, 25, 'player', self.player) if self.level.boss and not(self.main_menu.boss_check(self.start_level)): self.boss = self.level.boss_mob self.monster_sprite_list.add(self.boss) self.add_lifebar(constants.DWIDTH - 50, 25, 'boss', self.boss) def reload_level(self): monsters = self.monster_sprite_list player_hp = self.player.get_life() self.menu_flag = False self.clear() self.monster_sprite_list = monsters self.scenery_sprite_list = self.level.build_scenery() self.platform_sprite_list = self.level.build_platforms() self.ladder_sprite_list = self.level.build_ladders() self.door_sprite_list = self.level.build_doors() self.spawners = self.level.build_spawners() self.backdrop = self.level.backdrop self.add_player(self.character, self.level.player_x, self.level.player_y, "R") self.add_camera() self.player.set_life(player_hp) self.add_lifebar(25, 25, 'player', self.player) if self.level.boss and not(self.main_menu.boss_check(self.start_level)): self.boss = self.level.boss_mob self.monster_sprite_list.add(self.boss) self.add_lifebar(constants.DWIDTH - 50, 25, 'boss', self.boss) #Add functions def add_camera(self): self.camera = Camera(self.level.width, self.level.height) def add_lifebar(self, x, y, name, pawn): lifebar = Lifebar( x, y, 20, 200, True) lifebar.set_hp(pawn.get_max_life()) self.ui_lifebar.append([name, lifebar]) def add_title(self, title): TextSurf, TextRect = Text.text_objects(title, constants.largeText, constants.WHITE) TextRect.center = ((constants.DWIDTH / 2), ((constants.DHEIGHT / 2) - 100)) self.ui_list.append({'title':title, 'type': 'text','surface':TextSurf,'rectangle':TextRect}) def add_button(self, button_text, x, y, w, h, ic, ac, action=None): button_rect = pygame.Rect(x,y,w,h) button_surface = pygame.Surface((w,h)) self.ui_list.append({'title':button_text, 'type':'button', 'ac':ac, 'ic':ic, 'action':action, 'rectangle':button_rect}) textSurf, textRect = Text.text_objects(button_text, constants.smallText, constants.BLACK) textRect.center = ( (x+(w/2)), (y+(h/2)) ) self.ui_list.append({'title':button_text,'type':'button_text','surface':textSurf, 'rectangle':textRect}) def add_bullet(self, cord): bullet = Bullet(self.level.rect, self.player.weapon_damage) if cord[0] == 'R': bullet.rect.x = cord[1] + 45 bullet.rect.y = cord[2] + 40 bullet.set_speed(18,0) else: bullet.rect.x = cord[1]+5 bullet.rect.y = cord[2]+40 bullet.set_speed(-18,0) self.bullet_sprite_list.add(bullet) return True def add_platform(self, pawn_file, cord, move): pawn = Pawn(pawn_file, self.level) pawn.rect.x = cord[0] pawn.rect.y = cord[1] pawn.set_movement(move[0], move[1]) self.moving_platforms_list.add(pawn) return True def add_player(self, json, x, y, d): self.player = Player(json, self.level) rect = self.player.set_xy(x, y) print(rect) self.player.direction = d self.player_sprite_list.add(self.player) #Helper functions def create_objects(self): files = listdir("objects") for file in files: with open("objects\\"+file) as data_file: data = json.load(data_file) if data['name'] in self.object_list: print("crap, names matched.") else: self.object_list[data['name']] = "objects\\"+file def clear(self): self.backdrop = constants.BLACK self.monster_sprite_list = pygame.sprite.Group() self.scenery_sprite_list = pygame.sprite.Group() self.bullet_sprite_list = pygame.sprite.Group() self.player_sprite_list = pygame.sprite.Group() self.platform_sprite_list = pygame.sprite.Group() self.ladder_sprite_list = pygame.sprite.Group() self.door_sprite_list = pygame.sprite.Group() self.spawners = [] self.ui_list = [] if hasattr(self, 'camera'): del self.camera if hasattr(self, 'ui_lifebar'): self.ui_lifebar = [] if hasattr(self, 'player'): del self.player if hasattr(self, 'boss'): del self.boss del self.boss_mob def end_level(self): self.main_menu.finished_level(self.start_level) self.start_level = None self.clear() self.menu_flag = True self.ui_list += self.main_menu.draw_menu() def pause(self): self._pause = True def resume(self): self._pause = False def character_death(self): if self.lives > 0: self.lives -= 1 self.player.set_life(self.player.get_max_life()) self.reload_level() else: self.clear() self.ui_list += self.main_menu.draw_menu() def change_level(self): change = False hits_list = pygame.sprite.spritecollide(self.player, self.door_sprite_list, False) for hit in hits_list: self.current_level = [hit.level, hit.px, hit.py, hit.dir] change = True return change def check_dead(self): return self.player.player_death() def spawn_teleport(self): self.teleport, plist = self.level.build_teleport(10,15) self.platform_sprite_list += plist return True #Pygame functions def update(self): if not (self._pause) and hasattr(self, 'player'): self.moving_platforms_list.update(self.player_sprite_list) self.player_sprite_list.update(self.monster_sprite_list.sprites(), self.platform_sprite_list, self.moving_platforms_list) self.monster_sprite_list.update(self.platform_sprite_list, self.moving_platforms_list, self.bullet_sprite_list.sprites(), self.monster_sprite_list.sprites(), self.camera) self.bullet_sprite_list.update(self.platform_sprite_list) if self.change_level(): print("Changing level:", self.current_level) self.load_level(self.current_level) if self.check_dead(): self.character_death() if hasattr(self, 'boss') and self.boss.monster_death(): del self.boss self.ui_lifebar.remove(self.ui_lifebar[1]) self.spawn_teleport() if hasattr(self, 'teleport'): if self.teleport.warp(self.player_sprite_list): self.end_level() #Clean Up dead monsters for monster in self.monster_sprite_list: if monster.monster_death(): monster.kill() for spawner in self.spawners: spawn = spawner.update() if spawn == False: pass elif spawn[0] == "Platform": pawn_type = self.object_list[spawn[1]] self.add_platform(pawn_type, spawn[2], spawn[3]) else: pass if hasattr(self, 'camera'): self.camera.update(self.player) if hasattr(self, 'ui_lifebar'): for lifebar in self.ui_lifebar: if lifebar[0] == "player": lifebar[1].update(self.player) if lifebar[0] == 'boss': lifebar[1].update(self.boss) def draw(self, screen): #Only draw whats actually on camera for ladder in self.ladder_sprite_list: screen.blit(ladder.image, self.camera.apply(ladder)) for door in self.door_sprite_list: screen.blit(door.image, self.camera.apply(door)) for platform in self.platform_sprite_list: screen.blit(platform.image, self.camera.apply(platform)) for monster in self.monster_sprite_list: screen.blit(monster.draw(), self.camera.apply(monster)) for bullet in self.bullet_sprite_list: screen.blit(bullet.image, self.camera.apply(bullet)) for player in self.player_sprite_list: screen.blit(player.draw(), self.camera.apply(player)) for m_platform in self.moving_platforms_list: screen.blit(m_platform.draw(), self.camera.apply(m_platform)) #always draw the UI for ui in self.ui_list: if ui['type'] == 'button': mouse = pygame.mouse.get_pos() click = pygame.mouse.get_pressed() rect = ui['rectangle'] if rect.collidepoint(mouse[0], mouse[1]): pygame.draw.rect(screen, ui['ac'],rect) if click[0] == 1 and ui['action']!=None: ui['action']() else: pygame.draw.rect(screen, ui['ic'],rect) else: try: screen.blit(ui['surface'],ui['rectangle']) except: print(ui['type']) raise if hasattr(self, 'ui_lifebar'): for lifebar in self.ui_lifebar: screen = lifebar[1].draw(screen) return screen # Giant Tree of Input parsing! def on_event(self, event): if self.menu_flag: self.menu_event(event) else: if hasattr(self, 'player'): self.game_event(event) else: print("Dropped Command.") def menu_event(self, event): if event.type == pygame.QUIT: self._running = False if event.type == KEYDOWN: if event.key == K_LEFT: #Left pass if event.key == K_RIGHT: #Right pass if event.key == K_UP: #Up pass if event.key == K_DOWN: #Down pass if event.key == ord('x'): #x pass if event.key == ord('z'): #z pass if event.type == KEYUP: if event.key == K_ESCAPE: self.exit_game() if event.key == K_LEFT: #Left self.main_menu.up() self.current_level = [self.main_menu.selected_name(), 0, 0, "R"] if event.key == K_RIGHT: #Right self.main_menu.down() self.current_level = [self.main_menu.selected_name(), 0, 0, "R"] if event.key == K_UP: #Up self.main_menu.up() self.current_level = [self.main_menu.selected_name(), 0, 0, "R"] if event.key == K_DOWN: #Down self.main_menu.down() self.current_level = [self.main_menu.selected_name(), 0, 0, "R"] if event.key == ord('z'): self.load_level(self.current_level) def game_event(self, event): if event.type == pygame.QUIT: self._running = False if event.type == KEYDOWN: if event.key == K_LEFT: self.player.go_left() if event.key == K_RIGHT: self.player.go_right() if event.key == K_UP: self.player.go_up(self.ladder_sprite_list) if event.key == K_DOWN: self.player.go_down(self.ladder_sprite_list) if event.key == ord('x'): self.player.jump() if event.key == ord('z'): self.add_bullet(self.player.shoot()) if event.type == KEYUP: if event.key == K_ESCAPE: self.exit_game() if event.key == K_LEFT: self.player.stop(self.ladder_sprite_list, 'left') if event.key == K_RIGHT: self.player.stop(self.ladder_sprite_list, 'right') if event.key == K_UP: self.player.stop(self.ladder_sprite_list, 'up') if event.key == K_DOWN: self.player.stop(self.ladder_sprite_list, 'down') if event.key == ord('x'): pass if event.key == ord('z'): self.player.stop_shoot() if event.key == ord('q'): if self._pause: self.resume() else: self.pause() if event.key == ord('r'): if self._debug: self.main_menu.load_json() self.load_level(self.current_level)
def main(): lvl = 0 slot1 = [ image.load( "recource\\textures\\player\\pistols\\strikes\\bananas3.png"), 'Banans', 100, 10, 10 ] slot2 = [ image.load("recource\\textures\\player\\pistols\\pistols\\pistol.png"), 'Gun', 100, 7, 7 ] slot3 = [ image.load("recource\\textures\\player\\pistols\\pistols\\AK47.png"), 'AK47', 100, 30, 30 ] slot4 = [None, None, 0, 0, 0] timess = 0 inventory = [slot1, slot2, slot3, slot4] for leval in levels: reload = False player = Player(leval[1][0], leval[1][1]) player.hp = levels[lvl - 1][2] player.score = levels[lvl - 1][3] player.bananas = levels[lvl - 1][4] level = leval[0] checkp = [55, 55] shift = False speedPlatforms = [] pygame.init() screen = pygame.display.set_mode(display) fon = Surface(display) fon.fill(Color(bgColor)) #fon = image.load('recource\\textures\\bgTextures\\kirpichi.jpg') sprites = pygame.sprite.Group() platforms = [] banans = [] monsters = [] badPlatforms = [] dropped = [] weapones = [] sprites.add(player) left = right = up = False timer = pygame.time.Clock() moneys = [] flymonsters = [] bullets = [] regens = [] chekpoints = [] x = y = 0 boss = None for all in level: for each in all: if each == '-': pf = Platform(x, y) sprites.add(pf) platforms.append(pf) if each == '@': pf = SpeedPlatform(x, y) sprites.add(pf) speedPlatforms.append(pf) if each == 'x': pf = DiePlatform(x, y) sprites.add(pf) badPlatforms.append(pf) if each == '%': pf = DoorPlatform(x, y) sprites.add(pf) door = pf if each == 'M': pf = Monsters(x, y) monsters.append(pf) sprites.add(pf) if each == '$': pf = Money(x, y) moneys.append(pf) sprites.add(pf) if each == 'L': pf = Fly_Monsters(x, y) flymonsters.append(pf) sprites.add(pf) if each == 'B': boss = Boss(x, y) monsters.append(boss) sprites.add(boss) if each == 'b': pf = Banans(x, y) banans.append(pf) sprites.add(pf) if each == 'h': pf = Hp_regen(x, y) sprites.add(pf) regens.append(pf) if each == '+': pf = Chekpoint(x, y) sprites.add(pf) chekpoints.append(pf) if each == 'P': pf = BulletsForGun(x, y) sprites.add(pf) bullets.append(pf) x += platformWidth y += platformHeigh x = 0 total_width = len(level[0]) * 32 total_heigh = len(level) * 32 camera = Camera(camera_config, total_width, total_heigh) black = (0, 0, 0) green = (0, 255, 0) red = (255, 0, 0) font = pygame.font.Font(None, 55) text = font.render("My text", True, black) font2 = pygame.font.Font(None, 100) banani = pygame.font.Font(None, 55) money = image.load('recource\\textures\\money\\money2.png') hpx = 180 hpy = 32 banx = 105 more9 = False more99 = False more92 = False more992 = False bantextx = 143 uminshilos = False times = 0 pistols = [] hps = [] inventory_slots = [ image.load('recource\\textures\\inventory\\inventory.png'), image.load('recource\\textures\\inventory\\inventory.png'), image.load('recource\\textures\\inventory\\inventory.png'), image.load('recource\\textures\\inventory\\inventory.png') ] for i in range(player.hp): hps.append(image.load('recource\\textures\\hp\\hp3.png')) timer.tick(30) banan = None banantext = None pygame.mixer.music.load("recource\\sound-trak\\menu.mp3") #pygame.mixer.music.play(-1, 0.0) now = 0 while not player.next_level: hps = [] for i in range(player.hp): hps.append(image.load('recource\\textures\\hp\\hp3.png')) for e in pygame.event.get(): if e.type == QUIT: raise SystemExit("Quit") if e.type == KEYDOWN and e.key == K_a: left = True if e.type == KEYDOWN and e.key == K_d: right = True if e.type == KEYDOWN and e.key == K_w: up = True if e.type == KEYDOWN and e.key == K_LSHIFT: shift = True if e.type == KEYDOWN and e.key == K_r: reload = True if e.type == KEYDOWN and e.key == K_SPACE: if inventory[player.slot][0] is not None: if inventory[player.slot][1] == 'Banans': if inventory[player.slot][2] > 0: if inventory[player.slot][3] > 0: reload = False inventory[player.slot][3] -= 1 pf = BananPushka(0, player) sprites.add(pf) pistols.append(pf) now = inventory[player.slot][2] if inventory[player.slot][1] == 'Gun': if inventory[player.slot][2] > 0: if inventory[player.slot][3] > 0: reload = False inventory[player.slot][3] -= 1 pf = Gun(1, player) sprites.add(pf) pistols.append(pf) now = inventory[player.slot][2] if inventory[player.slot][1] == 'AK47': if inventory[player.slot][2] > 0: if inventory[player.slot][3] > 0: reload = False inventory[player.slot][3] -= 1 pf = AK47(1, player) sprites.add(pf) pistols.append(pf) now = inventory[player.slot][2] else: player.banas = 0 if e.type == KEYDOWN and e.key == K_q: if inventory[player.slot][1] == 'Gun': gun = Dropped_Gun(player.rect.x, player.rect.y, inventory[player.slot][2], inventory[player.slot][3], inventory[player.slot][4]) inventory[player.slot] = [None, None, 0, 0, 0] dropped.append(gun) sprites.add(gun) if inventory[player.slot][1] == 'AK47': ak47 = Dropped_AK47(player.rect.x, player.rect.y, inventory[player.slot][2], inventory[player.slot][3], inventory[player.slot][4]) inventory[player.slot] = [None, None, 0, 0, 0] dropped.append(ak47) sprites.add(ak47) if e.type == KEYDOWN and e.key == K_1: player.slot = 0 if e.type == KEYDOWN and e.key == K_2: player.slot = 1 if e.type == KEYDOWN and e.key == K_3: player.slot = 2 if e.type == KEYDOWN and e.key == K_4: player.slot = 3 if e.type == KEYUP and e.key == K_d: right = False if e.type == KEYUP and e.key == K_a: left = False if e.type == KEYUP and e.key == K_w: up = False if e.type == KEYUP and e.key == K_LSHIFT: shift = False if player.score > 9: if not more9: hpx += 10 banx += 10 bantextx += 10 more9 = True if player.score > 99: if not more99: hpx += 20 banx += 20 bantextx += 20 more99 = True if player.score < 9: if more9: hpx -= 10 banx -= 10 bantextx -= 10 more9 = False if player.score < 99: if more99: hpx -= 20 banx -= 20 bantextx -= 20 more99 = False if inventory[player.slot][2] > 9: if not more92: hpx += 10 more92 = True if inventory[player.slot][2] > 99: if not more992: hpx += 20 more992 = True if inventory[player.slot][2] < 9: if more92: hpx -= 10 more92 = False if inventory[player.slot][2] < 99: if more992: hpx -= 20 more992 = False for each in dropped: if sprite.collide_rect(player, each): for each2 in range(len(inventory)): if inventory[each2][0] is None: inventory[each2] = [ each.image2, each.name, each.bullets, each.oboima, each.max ] if each in dropped: dropped.remove(each) if each in sprites: sprites.remove(each) break for chekpoint in chekpoints: if sprite.collide_rect(player, chekpoint): checkp = [chekpoint.rect.y, chekpoint.rect.x] print(chekpoint.rect.y) print(chekpoint.rect.x) print('Savepoint') for bullet in bullets: if sprite.collide_rect(player, bullet): for each in range(len(inventory)): if inventory[each][1] == 'Gun': inventory[each][2] += 15 if bullet in bullets: bullets.remove(bullet) if bullet in sprites: sprites.remove(bullet) bullet.kill() for banan1 in banans: if sprite.collide_rect(player, banan1): if banan1 in banans: banans.remove(banan1) if banan1 in sprites: sprites.remove(banan1) banan1.kill() player.bananas += 3 for platform in moneys: if sprite.collide_rect(player, platform): player.score += 1 if platform in platforms: platforms.remove(platform) if platform in sprites: sprites.remove(platform) platform.kill() for each in regens: if sprite.collide_rect(player, each): player.hp += 1 if each in regens: regens.remove(each) if each in sprites: sprites.remove(each) each.kill() screen.blit(fon, (0, 0)) text = font.render(str(player.score), True, black) for each in dropped: each.upadate(platforms) if inventory[player.slot][0] is not None: if inventory[player.slot][1] == 'AK47': banantext = banani.render( '{}/{}'.format(str(inventory[player.slot][3]), str(inventory[player.slot][2])), True, black) banan = image.load( 'recource\\textures\\player\\pistols\\strikes\\bullet.png' ) if inventory[player.slot][1] == 'Gun': banantext = banani.render( '{}/{}'.format(str(inventory[player.slot][3]), str(inventory[player.slot][2])), True, black) banan = image.load( 'recource\\textures\\player\\pistols\\strikes\\bullet.png' ) if inventory[player.slot][1] == 'Banans': banantext = banani.render( '{}/{}'.format(str(inventory[player.slot][3]), str(inventory[player.slot][2])), True, black) banan = image.load( 'recource\\textures\\player\\pistols\\strikes\\bananas2.png' ) else: banan = None banantext = None camera.update(player) for each in flymonsters: fms = each.update(player, platforms, flymonsters, sprites, pistols) if fms is not None: sprites = fms[0] flymonsters = fms[1] if reload: timess += 1 if timess > 10: inventory[player.slot][3] += 1 inventory[player.slot][2] -= 1 timess = 0 if inventory[player.slot][3] == inventory[player.slot][4]: reload = False timess = 0 for each in pistols: sp = each.updata(monsters, sprites, platforms, pistols, flymonsters) if sp is not None: sprites = sp[0] pistols = sp[1] for each in monsters: sm = each.update(player, platforms, monsters, sprites, pistols) if sm is not None: sprites = sm[0] monsters = sm[1] if each == boss: sm = each.updata(player, platforms, monsters, sprites, pistols) if sm is not None: sprites = sm[0] for each in sprites: screen.blit(each.image, camera.apply(each)) for each in range(len(inventory_slots)): screen.blit(inventory_slots[each], [32, 196 + (each * 64)]) screen.blit(image.load('recource\\textures\\inventory\\vibor.png'), [32, 196 + player.slot * 64]) screen.blit(money, [32, 32]) screen.blit(text, [70, 32]) for each in range(len(inventory)): if inventory[each][0] is not None: screen.blit(inventory[each][0], [32, 196 + (each * 64)]) i = 0 if boss != None: bosshps = boss.hp if not boss.died: if boss.hp != 0: if boss.hp < 11: for k in range(10): if bosshps != 0: bosshps -= 1 each = image.load( 'recource\\textures\\hp\\hp3.png') screen.blit(each, [700 + (k * 30), 32]) else: for i in range(2): for v in range(10): if bosshps != 0: bosshps -= 1 each = image.load( 'recource\\textures\\hp\\hp3.png') screen.blit( each, [700 + (v * 30), 32 + (i * 30)]) for each in hps: i += 1 screen.blit(each, [hpx + (35 * i), hpy]) if banan is not None: screen.blit(banan, [banx, 32]) screen.blit(banantext, [bantextx, 32]) if player.hp == 0: player.smert = True sprites_speedplatforms_money = player.updata( left, right, up, shift, platforms, speedPlatforms, badPlatforms, door, sprites, moneys, banans, regens) speedPlatforms = sprites_speedplatforms_money[1] sprites = sprites_speedplatforms_money[0] moneys = sprites_speedplatforms_money[2] banans = sprites_speedplatforms_money[3] regens = sprites_speedplatforms_money[4] levels[lvl][2] = player.hp levels[lvl][3] = player.score levels[lvl][4] = player.bananas if player.smert: if not uminshilos: player.score -= 5 if player.score < 0: player.score = 0 potracheno = font2.render('Потрачено!', True, green) uminshilos = True screen.blit(potracheno, [360, 340]) player.umirat = True times += 1 if times > 100: player.smert = False player.umirat = False player.bananas = player.savepoint[4] player.hp = 5 player.rect.y = checkp[0] player.rect.x = checkp[1] player.faseDie = 0 uminshilos = False print(player.rect.y) print(player.rect.x) times = 0 player.savepoint[0] = player.hp player.savepoint[1] = player.score player.savepoint[2] = player.bananas pygame.display.update() lvl += 1
if e.key == pygame.K_DOWN: down = False if e.type == pygame.K_ESCAPE: pygame.display.quit() exit() """Отрисовка объектов""" info_string.fill((150, 150, 150)) """отображение героя""" hero.update(left, right, up, down) camera.update(hero) for e in sprite_group: screen.blit(e.image, camera.apply(e)) """отрисовка строений""" for e in city_group: screen.blit(e.image, camera.apply(e)) """отрисовка шрифтов""" ind = 0 for e in city_group: screen.blit(e.image, camera.apply(e)) screen.blit(city_font.render(city_name_list[ind], 1, (50, 50, 150)), camera.apply(e)) ind += 1 screen.blit(hero.image, camera.apply(hero))
class Game: def __init__(self): pygame.init() self.screen = pygame.display.set_mode([WIDTH, HEIGHT]) pygame.display.set_caption(TITLE) self.clock = pygame.time.Clock() self.load_data() def load_data(self): pass def reset(self): """Let's load a bigger map and prepare the camera""" self.all_sprites = pygame.sprite.Group() self.walls = pygame.sprite.Group() self.current_map = Map() self.current_map.load_from_file("bigMap.txt") self.current_map.create_sprites_from_data(self) self.player = Player(self, self.current_map.entry_point[0], self.current_map.entry_point[1]) self.camera = Camera(self.current_map.pixel_width, self.current_map.pixel_height) def run(self): self.playing = True while self.playing: self.dt = self.clock.tick(FPS) / 1000 self.events() self.update() self.draw() def quit(self): pygame.quit() sys.exit() def update(self): self.all_sprites.update() self.camera.update(self.player) def draw_grid(self): for x in range(0, WIDTH, TILESIZE): pygame.draw.line(self.screen, LIGHTGREY, (x, 0), (x, HEIGHT)) for y in range(0, HEIGHT, TILESIZE): pygame.draw.line(self.screen, LIGHTGREY, (0, y), (WIDTH, y)) def draw(self): """Drawing is more tricky now, because we have to apply the camera's rect to sprites and points and everthing's position""" self.screen.fill(BGCOLOR) self.draw_grid() for sprite in self.all_sprites: self.screen.blit(sprite.image, self.camera.apply(sprite)) pygame.display.flip() def events(self): for event in pygame.event.get(): if event.type == pygame.QUIT: self.quit() def show_start_screen(self): pass
class Game: def __init__(self): os.environ['SDL_VIDEO_CENTERED'] = '1' pygame.init() pygame.key.set_repeat(KEYBOARD_REPEAT_THRESHOLD, KEYBOARD_REPEAT_INTERVAL) pygame.display.set_icon(pygame.image.load(WINDOW_ICON)) pygame.display.set_caption(SCREEN_TITLE) pygame.mouse.set_visible(False) self.fullscreen = False self.screen = pygame.display.set_mode( (SCREEN_WIDTH, SCREEN_HEIGHT), pygame.HWSURFACE | pygame.DOUBLEBUF) self.clock = pygame.time.Clock() self.load_data() def load_data(self): self.sprite_sheet = Spritesheet(SPRITE_SHEET, (IMAGE_SIZE, IMAGE_SIZE)) self.font = pygame.font.Font(FONT_FILE, 24) self.sounds = { "COIN": pygame.mixer.Sound(PLAYER_PICKUP_COIN_SOUND), "KEY": pygame.mixer.Sound(PLAYER_PICKUP_KEY_SOUND), "HIT": [pygame.mixer.Sound(sound) for sound in HIT_SOUND] } self.highscore = self.load_highscore() def load_highscore(self): if os.path.isfile(HIGHSCORE): with open(HIGHSCORE, "r") as f: return int(f.readline().strip()) else: return 0 def save_highscore(self): with open(HIGHSCORE, "w") as f: f.write(str(self.highscore)) def new(self): self.stage = 0 self.layers = { "FLOOR": pygame.sprite.Group(), "SHADOWS": pygame.sprite.Group(), "WALLS": pygame.sprite.Group(), "PICKUPS": pygame.sprite.Group(), "ENEMIES": pygame.sprite.Group(), "PLAYER": pygame.sprite.Group(), "UI": pygame.sprite.Group() } self.player = Player(self, 0, 0, 0) self.camera = Camera() self.UI = UserInterface(self) self.generator = DungeonGenerator(self) self.new_level() def clear_layer(self, layer): for sprite in layer: sprite.delete() def new_level(self): self.clear_layer(self.layers["FLOOR"]) self.clear_layer(self.layers["WALLS"]) self.clear_layer(self.layers["PICKUPS"]) self.clear_layer(self.layers["ENEMIES"]) self.player.pos.x = 0 self.player.pos.y = 0 self.player.key = False self.generator.generate() self.stage += 1 def game_over(self): self.playing = False def run(self): self.new() self.playing = True self.restart = False while self.playing: self.dt = self.clock.tick(FRAMERATE) / 1000 self.events() self.update() self.draw() def toggle_fullscreen(self): self.fullscreen = not self.fullscreen if self.fullscreen: self.screen = pygame.display.set_mode( (SCREEN_WIDTH, SCREEN_HEIGHT), pygame.HWSURFACE | pygame.DOUBLEBUF | pygame.FULLSCREEN) else: self.screen = pygame.display.set_mode( (SCREEN_WIDTH, SCREEN_HEIGHT), pygame.HWSURFACE | pygame.DOUBLEBUF) def quit(self): pygame.quit() sys.exit() def update(self): self.layers["SHADOWS"].update() self.layers["PICKUPS"].update() self.layers["PLAYER"].update() self.layers["ENEMIES"].update() self.layers["UI"].update() self.camera.update(self.player) def events(self): for event in pygame.event.get(): if event.type == pygame.QUIT: self.quit() if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: self.quit() if event.key == pygame.K_LEFT or event.key == pygame.K_a: self.player.move(dx=-1) if event.key == pygame.K_RIGHT or event.key == pygame.K_d: self.player.move(dx=1) if event.key == pygame.K_UP or event.key == pygame.K_w: self.player.move(dy=-1) if event.key == pygame.K_DOWN or event.key == pygame.K_s: self.player.move(dy=1) if event.key == pygame.K_f: self.toggle_fullscreen() if event.key == pygame.K_r: self.restart = True self.game_over() self.end_screen() def draw(self): self.update() self.events() self.screen.fill(BACKGROUND_COLOUR) for layer in self.layers: for sprite in self.layers[layer]: if layer != "UI": self.screen.blit(sprite.image, self.camera.apply(sprite)) else: self.screen.blit(sprite.image, sprite.rect) #self.draw_grid() pygame.display.flip() def start_screen(self): self.title_screen("PRESS ANY KEY TO START") self.wait_for_key() def end_screen(self): pygame.event.pump() self.screen.fill(BACKGROUND_COLOUR) if self.restart: return score = self.stage * STAGE_POINTS + self.player.coins * COIN_POINTS + self.player.enemies_killed * ENEMY_KILL_POINTS if score > self.highscore: self.highscore = score self.save_highscore() self.render_text("You scored {}".format(score), (SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2 - 32)) self.render_text("Your best {}".format(self.highscore), (SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2)) pygame.display.flip() pygame.time.wait(1000) self.wait_for_key() def wait_for_key(self): waiting = True while waiting: self.clock.tick(FRAMERATE) for event in pygame.event.get(): if event.type == pygame.QUIT: self.quit() if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: self.quit() if event.key == pygame.K_f: self.toggle_fullscreen() self.title_screen("PRESS ANY KEY TO START") continue waiting = False def title_screen(self, text, wait=0): pygame.event.pump() self.screen.fill(BACKGROUND_COLOUR) text = self.font.render(text, False, WHITE, BLACK) text_rect = text.get_rect(center=(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2)) self.screen.blit(text, text_rect) pygame.display.flip() pygame.time.wait(wait) def render_text(self, text, pos): text = self.font.render(text, False, WHITE, BLACK) text_rect = text.get_rect() text_rect.midtop = pos self.screen.blit(text, text_rect) def draw_grid(self): for x in range(0, SCREEN_WIDTH, SPRITE_SIZE): pygame.draw.line(self.screen, LIGHT_GREY, (x, 0), (x, SCREEN_HEIGHT)) for y in range(0, SCREEN_HEIGHT, SPRITE_SIZE): pygame.draw.line(self.screen, LIGHT_GREY, (0, y), (SCREEN_WIDTH, y))
class Game(): def __init__(self): pygame.init() self.dimensions = (WIDTH, HEIGHT) self.screen = pygame.display.set_mode(self.dimensions) pygame.display.set_caption(TITLE) self.clock = pygame.time.Clock() self.running = True self.currentLocation = 'o' self.allSprites = pygame.sprite.Group() self.player = Player(self, 0, 0) self.setupSpriteGroups() def setupSpriteGroups(self): # sprite groups self.water = pygame.sprite.Group() self.stones = pygame.sprite.Group() self.houses = pygame.sprite.Group() self.levelEntrances = pygame.sprite.Group() self.tunnelEntrances = pygame.sprite.Group() self.walls = pygame.sprite.Group() self.doors = pygame.sprite.Group() self.exits = pygame.sprite.Group() def run(self): self.loadOverworld(self.currentLocation) while self.running: self.dt = self.clock.tick(FPS) / CLOCK_TICK self.running = mainGameEvents(self.running) self.update() self.draw() self.quit() def loadOverworld(self, playerPosition): self.setupSpriteGroups() self.currentLocation = 'o' self.map = TiledMap(self.currentLocation) self.mapImg = self.map.render() self.map.rect = self.mapImg.get_rect() for tileObj in self.map.tmxdata.objects: objCenter = getObjCenter(tileObj) # put the player in the correct place if tileObj.name == 'player_' + playerPosition: print(tileObj.name) self.player.setNewBounds(objCenter.x, objCenter.y) # load entrances if 'entrance_l' in tileObj.name: Obstacle(self, tileObj.x, tileObj.y, tileObj.width, tileObj.height, self.levelEntrances, tileObj.name) if 'entrance_t' in tileObj.name: Obstacle(self, tileObj.x, tileObj.y, tileObj.width, tileObj.height, self.tunnelEntrances, tileObj.name) # obstacles if tileObj.name == 'water': Obstacle(self, tileObj.x, tileObj.y, tileObj.width, tileObj.height, self.water, tileObj.name) if tileObj.name == 'stone': Obstacle(self, tileObj.x, tileObj.y, tileObj.width, tileObj.height, self.stones, tileObj.name) if tileObj.name == 'house': Obstacle(self, tileObj.x, tileObj.y, tileObj.width, tileObj.height, self.houses, tileObj.name) # update camera self.camera = Camera(self.map.width, self.map.height) def loadSubLevel(self, entranceName): self.setupSpriteGroups() self.currentLocation = entranceName self.map = TiledMap(self.currentLocation) self.mapImg = self.map.render() self.map.rect = self.mapImg.get_rect() for tileObj in self.map.tmxdata.objects: objCenter = objCenter = getObjCenter(tileObj) # player position if tileObj.name == 'player': print('player location') self.player.setNewBounds(objCenter.x, objCenter.y) # exits if tileObj.name == 'exit': Obstacle(self, tileObj.x, tileObj.y, tileObj.width, tileObj.height, self.exits, tileObj.name) # obstacles if tileObj.name == 'wall': Obstacle(self, tileObj.x, tileObj.y, tileObj.width, tileObj.height, self.walls, tileObj.name) if tileObj.name == 'door': Obstacle(self, tileObj.x, tileObj.y, tileObj.width, tileObj.height, self.doors, tileObj.name) if tileObj.name == 'stone': Obstacle(self, tileObj.x, tileObj.y, tileObj.width, tileObj.height, self.stones, tileObj.name) # update camera self.camera = Camera(self.map.width, self.map.height) def update(self): self.allSprites.update() self.camera.update(self.player) def draw(self): self.screen.blit(self.mapImg, self.camera.apply(self.map)) for sprite in self.allSprites: self.screen.blit(sprite.image, self.camera.apply(sprite)) pygame.display.flip() def quit(self): pygame.quit() sys.exit()
class GameEngine(object): def __init__(self): pygame.init() pygame.font.init() pygame.mixer.init() os.environ["SDL_VIDEO_CENTERED"] = "1" self.screen = SCREEN.display self.fpsClock = pygame.time.Clock() self.fps = GAME.fps self.ticks = 0 self.firstrun = True self.music = Music("mainmenu.ogg", 0.5, -1) self.menu_music = False self.game_music = False self.game_time = GameText("0", 24, True) self.game_time.font_file = FONT.default self.game_time.centerx = SCREEN.width/2 self.game_time.y = 18 self.game_time.color = COLOR.white self.game_time.create() self.timer_red = False self.flash_timer = 0 self.p1_score = GameText("0", 24, True) self.p1_score.font_file = FONT.default self.p1_score.left = 30 self.p1_score.y = 18 self.p1_score.color = COLOR.blue_sea self.p1_score.create() self.p2_score = GameText("0", 24, True) self.p2_score.font_file = FONT.default self.p2_score.right = SCREEN.width - 30 self.p2_score.y = 18 self.p2_score.color = COLOR.petal_green self.p2_score.create() self.bg_text = GameText("01", 72, True) self.bg_text.font_file = FONT.kenpixel_blocks self.bg_text.centerx = SCREEN.width/2 self.bg_text.centery = SCREEN.height/2 self.bg_text.color = COLOR.gray7 self.bg_text.create() self.state = STATE.logo self.stage_number = 1 self.stage = Stage(self.stage_number) self.hi_score = 0 self.splashscreen = SplashScreen(0, 0, SPLASHSCREEN.width, SPLASHSCREEN.height) self.logoscreen = LogoScreen(0, 0, LOGO.width, LOGO.height) self.timer = GAME.time self.totalscore = 0 self.p1_scores = {} self.p2_scores = {} self.camera = Camera(self.complex_camera, self.stage.level.width, self.stage.level.height) self.bg = SCREEN.bg self.screen_color = (choice(COLOR.colors)) self.menu = Menu(SCREEN.width, SCREEN.height, self.screen_color) self.score_screen = ScoreScreen() self.controls_screen = Controls() self.screen_number = 1 self.capture_video = False self.countdownOverlay = CountDownOverlay() self.intro = True self.intro_countdown = self.fps * 4 self.scanlines = ScanLines() self.controller_present = False try: self.player1_joy = pygame.joystick.Joystick(0) self.player1_joy.init() self.controller_present = True except: pass def reset(self): self.stage_number += 1 if self.stage_number > self.stage.number_of_levels: self.stage_number = 1 self.state = STATE.menu self.score_screen = ScoreScreen() self.controls_screen = Controls() self.firstrun = True else: self.firstrun = False self.state = STATE.game self.stage = Stage(self.stage_number) self.timer = GAME.time self.camera = Camera(self.complex_camera, self.stage.level.width, self.stage.level.height) self.screen_color = (choice(COLOR.colors)) self.menu = Menu(SCREEN.width, SCREEN.height, self.screen_color) self.countdownOverlay = CountDownOverlay() self.intro = True self.intro_countdown = self.fps * 4 def handle_events(self): for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() if event.type == KEYDOWN: if event.key == K_ESCAPE: self.state = STATE.menu if event.key == K_p: if not self.capture_video: self.capture_video = True # change to True and press p to capture screenshots else: self.capture_video = False if event.key == K_q: #self.stage.level.spawn_data() pass elif event.type == JOYBUTTONDOWN: if self.player1_joy.get_button(9) == 1: self.state = STATE.menu if self.state == STATE.game: if self.stage.level.timer == 0: self.stage.level.timer = pygame.time.get_ticks()/1000.0 self.stage.level.player1.handle_events(event) self.stage.level.player2.handle_events(event) elif self.state == STATE.menu: self.menu.handle_events(event) self.state = self.menu.state elif self.state == STATE.controls: self.controls_screen.handle_events(event) self.state = self.controls_screen.state elif self.state == STATE.scorescreen: self.score_screen.handle_events(event) self.state = self.score_screen.state elif self.state == STATE.exit: pygame.quit() sys.exit() def update(self): if self.state == STATE.nextlevel: self.reset() return if self.capture_video: self.makeVideo() if self.timer == 0: self.state = STATE.scorescreen if self.state == STATE.logo: self.logoscreen.update() self.state = self.logoscreen.state if self.state == STATE.splashscreen: self.splashscreen.update() self.state = self.splashscreen.state elif self.state == STATE.controls: self.controls_screen.update() elif self.state == STATE.menu: self.menu.update() if self.game_music: self.game_music = False mixer.music.fadeout(2000) elif self.state == STATE.scorescreen: self.p1_scores[self.stage_number-1] = self.stage.level.p1_data self.p2_scores[self.stage_number-1] = self.stage.level.p2_data self.score_screen.p1_scores[self.stage_number-1].text = self.stage.level.p1_data self.score_screen.p2_scores[self.stage_number-1].text = self.stage.level.p2_data self.score_screen.update(self.stage_number, 1, self.hi_score) elif self.state == STATE.game: if not self.game_music: mixer.music.load(os.path.join('assets', 'music', 'cyberspine.ogg')) mixer.music.play(-1) self.game_music = True self.camera.update(self.stage.level.player1) if self.intro_countdown <= GAME.fps: self.intro = False self.intro_countdown = 0 if self.intro: self.countdownOverlay.update(self.intro_countdown) self.intro_countdown -= 1 else: self.stage.level.update() if self.stage.level.intro: self.timer = GAME.time if self.ticks > self.fps: self.ticks = 0 self.timer -= 1 else: self.ticks += 1 display_time = self.format_timer(self.timer) self.game_time.text = display_time if self.timer_red: self.animate_flash() else: self.game_time.color = COLOR.white self.game_time.update() self.p1_score.text = str(self.stage.level.p1_data) self.p1_score.update() self.p2_score.text = str(self.stage.level.p2_data) self.p2_score.update() self.bg_text.text = "0" + str(self.stage_number) self.bg_text.update() def draw(self): self.screen.fill(COLOR.black) if self.state == STATE.logo: self.logoscreen.draw(self.screen) elif self.state == STATE.splashscreen: self.splashscreen.draw(self.screen) elif self.state == STATE.scorescreen: self.score_screen.draw(self.screen) elif self.state == STATE.controls: self.controls_screen.draw(self.screen) elif self.state == STATE.game: self.screen.blit(SCREEN.bg, (0, 0)) self.bg_text.draw_to(self.screen) self.screen.blit(ASSET.score_bg, (0, 0)) self.stage.draw(self.screen) for particle in self.stage.level.particles: self.screen.blit(particle.image, self.camera.apply(particle)) self.game_time.draw_to(self.screen) self.p1_score.draw_to(self.screen) self.p2_score.draw_to(self.screen) if self.intro: self.countdownOverlay.draw(self.screen) elif self.state == STATE.menu: self.menu.draw(self.screen) if not self.firstrun: pass self.scanlines.draw(self.screen) def run_game(self, fps=30): self.fps = fps while True: self.handle_events() self.update() self.draw() pygame.display.update() pygame.display.set_caption("CleanerBots v0.1 - " + str(int(self.fpsClock.get_fps())) + " fps") self.fpsClock.tick(self.fps) def complex_camera(self, camera_rect, target_rect): x, y, dummy, dummy = target_rect dummy, dummy, w, h = camera_rect x, y = int(SCREEN.width/2)-x, int(SCREEN.height/2) - y x = min(0, x) x = max(-(camera_rect.width-SCREEN.width), x) y = max(-(camera_rect.height-SCREEN.height), y) y = min(0, y) return pygame.Rect(x, y, w, h) def format_timer(self, timer): self.timer_red = False minutes = timer/60 seconds = timer % 60 if minutes == 0 and seconds < 10: self.timer_red = True if seconds < 10: seconds = "0" + str(seconds) return str(minutes)+":"+str(seconds) def makeVideo(self): pygame.image.save(self.screen, os.path.join("screenshots", "screenshot%d.jpg" %self.screen_number)) self.screen_number += 1 def animate_flash(self): self.flash_timer += 1 if self.flash_timer < GAME.fps/4: self.game_time.color = COLOR.white elif self.flash_timer < GAME.fps/2: self.game_time.color = COLOR.red else: self.flash_timer = 0
class Game: all_sprites: Group def __init__(self): # Initialize pygame pygame.init() # Create variable to satisfy game loop self.running = True # Initialize game-pad / joystick[0] self.control = Control(self) # Set window title and icon pygame.display.set_caption('Zorlda') self.icon = pygame.image.load(WINDOW_ICON) pygame.display.set_icon(self.icon) # Set display size to match assets, create display, and scale # 'SCALED' flag seems to be an integer scalar that is in PyGame 2.0.0+ # without, game runs at original pixel resolution (currently at 320x180) self.screen = pygame.display.set_mode((ART_SCALE_X, ART_SCALE_Y), SCALED) # ~Sprite Groups~ # ALL sprites # group with all sprites for camera updates self.all_sprites = pygame.sprite.Group() # Walls group self.walls = pygame.sprite.Group() # Mobs group self.mobs = pygame.sprite.Group() # Animated sprites group self.anim_spr = pygame.sprite.Group() # EXPERIMENTAL Set up active sprite group, which sorts layering by Y axis value # self.sprite_draw_group = YSortedGroup() # Beeper group self.beepers = pygame.sprite.Group() # ~Levels/Maps # Load the map file self.map = TiledMap(MAP_FILE) self.map_img = self.map.make_map() self.map_rect = self.map_img.get_rect() # Load objects from map self.load_map_obj() # -Background objects - transparent layer on top of other sprites bushes, fountains, etc. self.bg_objects = BGObjects(self, 0, 0, BG_OBJECTS_IMG) # ~Clocks # Pygame clock self.clock = pygame.time.Clock() # # Delta time for movement # self.dt = 0 # Animation clock self.anim_clock = Animation() # ~Camera # IT'S MAGIC self.camera = Camera(self.map.width, self.map.height) # Testing self.show_fps = False self.draw_debug = False def load_map_obj(self): for tile_object in self.map.tmxdata.objects: if tile_object.name == 'player': # Place Player self.player = Player(self, tile_object.x, tile_object.y, PLAYER_SPRITESHEET) if tile_object.name == 'karel': # place Karels Karel(self, tile_object.x, tile_object.y, KAREL_SPRITESHEET) if tile_object.name == 'wall': # place wall, etc. bounding boxes Obstacle(self, tile_object.x, tile_object.y, tile_object.width, tile_object.height) def input_processing(self): self.control.get_input() def update(self): # Update ALL SPRITES # Sprite groups can ONLY call the update function and then use the functions *in there* XD self.all_sprites.update() # a Karel hits the Player(!) hits = pygame.sprite.spritecollide(self.player, self.mobs, False, collided=collide_hit_rect) for hit in hits: self.player.health -= 1 # hit.vel = vec(0, 0) if self.player.health <= 0: self.running = False if hits: # KNOCK-BACK # TODO: make this more responsive # ...camera moves too much to be comfortable at high velocities # solution might be to stop the mob and player's movement for a sec, freeze mob longer than player self.player.pos += hit.vel * 8 hit.pos = hit.pos - (hit.vel * 12) # a Karel hits a beeper hits = pygame.sprite.groupcollide(self.mobs, self.beepers, False, True) for hit in hits: hit.health -= 1 # Update camera self.camera.update(self.player.hit_rect) def render(self): # Render Map layers self.screen.blit(self.map_img, self.camera.apply_rect(self.map_rect)) # Render all sprites!! for sprite in self.all_sprites: self.screen.blit(sprite.image, self.camera.apply(sprite)) if self.draw_debug: pygame.draw.rect(self.screen, CYAN, self.camera.apply_rect(sprite.hit_rect), 1) # Testing functions # Show FPS in window title if self.show_fps: pygame.display.set_caption('Zorlda - FPS:{:.2f}'.format( self.clock.get_fps())) else: pygame.display.set_caption('Zorlda') # Show bounding boxes if self.draw_debug: for wall in self.walls: pygame.draw.rect(self.screen, CYAN, self.camera.apply_rect(wall.rect), 1) # HUD functions draw_player_health(self.screen, 10, 10, self.player.health) # Update display pygame.display.update() def run(self): while self.running: self.input_processing() self.update() self.render() # Frame-rate (essentially divides 1000 milliseconds(via PyGame clock) by FRAME_RATE) self.clock.tick(FRAME_RATE)
class Game(object): def __init__(self): pg.mixer.pre_init(44100, -16, 1, 512) pg.init() pg.mixer.init() pg.display.set_caption(TITLE) pg.mouse.set_visible(False) self.screen = pg.display.set_mode((WIDTH, HEIGHT)) self.clock = pg.time.Clock() # game self.running = True self.playing = False self.game_speed = 0 self.last_update = 0 self.dt = 0 self.cursor_pos = vec() self.last_mouse_pos = vec() self.dragging_camera = False self.dragging_camera = False # Groups self.all_sprites = [] self.items = [] self.imps = [] self.woods = [] # Switcher self.map = None self.camera = None self.pause = False self.mode = None self.modes = [ None, 'dig&cut', 'resource', 'imp', 'ladder', 'torch', 'shelf', 'bed' ] self.dragging = 0 # 0: False, 1: add, -1:remove # ----- load data ----- self.dir = path.dirname(__file__) self.img_dir = path.join(self.dir, 'img') self.snd_dir = path.join(self.dir, 'snd') self.map_dir = path.join(self.dir, 'map') # load font self.font_name = path.join(self.dir, 'old_evils.ttf') # load images self.img = { 'sky': pg.image.load(path.join(self.img_dir, 'Other/skybox_sideHills.png')).convert(), 'sky_top': pg.image.load(path.join(self.img_dir, 'Other/skybox_top.png')).convert(), 'sky_bottom': pg.image.load(path.join(self.img_dir, 'Other/skybox_bottom.png')).convert(), 'dig_mark': pg.image.load(path.join(self.img_dir, 'dig_mark.png')).convert_alpha(), 'dig_mark_hammer': pg.image.load(path.join(self.img_dir, 'dig_mark_hammer.png')).convert_alpha(), 'imp': pg.image.load(path.join(self.img_dir, 'imp.png')).convert_alpha(), 'wood': pg.image.load(path.join(self.img_dir, 'wood.png')).convert_alpha(), 'cursor': pg.image.load(path.join(self.img_dir, 'cursor.png')).convert_alpha(), 'axe_iron': pg.image.load(path.join(self.img_dir, 'Items/axe_iron.png')).convert_alpha(), } self.img['wood'].set_colorkey(BLACK) # load musics and sounds self.snd = { 'mark': pg.mixer.Sound(path.join(self.snd_dir, 'mark1.ogg')), 'unmark': pg.mixer.Sound(path.join(self.snd_dir, 'unmark1.ogg')), 'digging': list(), 'cut_tree': pg.mixer.Sound(path.join(self.snd_dir, 'qubodupImpactWood.ogg')), # 'dig_stone': [pg.mixer.Sound(path.join(self.snd_dir, 'qubodupImpactStone.ogg')), # pg.mixer.Sound(path.join(self.snd_dir, 'qubodupImpactMetal.ogg'))], 'shift': pg.mixer.Sound(path.join(self.snd_dir, 'UI_Click_Organic_mono.ogg')), 'tree_down': pg.mixer.Sound(path.join(self.snd_dir, 'crack01.mp3.flac')), 'build': [ pg.mixer.Sound( path.join(self.snd_dir, 'qubodupImpactMeat01.ogg')), pg.mixer.Sound( path.join(self.snd_dir, 'qubodupImpactMeat02.ogg')) ] } for i in range(1, 9): self.snd['digging'].append( pg.mixer.Sound(path.join(self.snd_dir, 'tool{}.ogg'.format(i)))) def new(self): self.dragging_camera = False self.all_sprites = pg.sprite.LayeredUpdates() self.items = pg.sprite.Group() self.imps = pg.sprite.Group() self.woods = pg.sprite.Group() self.map = Map(self) self.map.generate(200, 200) self.map.light(vec(10, 10), 20, 1) self.camera = Camera(self) self.game_speed = 200 self.pause = False self.mode = None self.dragging = 0 # 0: False, 1: add, -1:remove pg.mixer.music.load(path.join(self.snd_dir, 'ObservingTheStar.ogg')) Imp(self, vec(10, 10)) self.camera.focus(vec(10 * config.TILESIZE, 10 * config.TILESIZE)) self.resource = { 'woods': 0, 'iron': 0, } def run(self): pg.mixer.music.play(loops=-1) pg.mixer.music.set_volume(0.4) self.playing = True self.last_update = pg.time.get_ticks() while self.playing: self.dt = self.clock.tick(config.FPS) / 1000 self.events() self.update() self.draw() def update(self): if not self.pause: now = pg.time.get_ticks() if now - self.last_update > self.game_speed: self.last_update = now self.next_turn() for sprite in self.all_sprites: sprite.float_pos += sprite.v / ( (self.game_speed - 14) / 1000) / config.FPS sprite.rect.topleft = sprite.float_pos mouse_pos = vec(pg.mouse.get_pos()) self.cursor_pos = vec( vec2int((mouse_pos - self.camera.offset) / config.TILESIZE)) tile = self.map.data[vec2int(self.cursor_pos)] # drag camera if self.dragging_camera: mouse_vector = mouse_pos - self.last_mouse_pos self.camera.update(mouse_vector) # game stuff if self.map.in_bounds(self.cursor_pos) and self.map.in_view( self.cursor_pos): if self.mode == 'dig&cut' and tile and ( tile.in_group('destroyable') or tile.in_group('diggable') or tile.in_group('cuttable')): if self.dragging == 1: if not tile.in_group('dig&cut_mark'): tile.add_to_group('dig&cut_mark') self.snd['mark'].play() elif self.dragging == -1: if tile.in_group('dig&cut_mark'): tile.remove_from_group('dig&cut_mark') elif self.mode == 'ladder': if self.dragging == 1: if tile is None or isinstance(tile, BgTile): # Ladder(self.map, self.cursor_pos) BuildMark(self.map, self.cursor_pos, 'ladder') elif self.dragging == -1: if isinstance(tile, BuildMark) and tile.image_name == 'ladder': tile.kill() elif self.mode == 'shelf': if self.dragging == 1: if tile is None or isinstance(tile, BgTile): BuildMark(self.map, self.cursor_pos, 'shelf') elif self.dragging == -1: if isinstance(tile, BuildMark) and tile.image_name == 'shelf': tile.kill() elif self.mode == 'bed': if self.dragging == 1: if tile is None or isinstance(tile, BgTile): BuildMark(self.map, self.cursor_pos, 'bed') elif self.dragging == -1: if isinstance(tile, BuildMark) and tile.image_name == 'bed': tile.kill() elif self.mode == 'resource' and tile and tile.in_group('earth'): if self.dragging == 1: if not tile.in_group('resource_mark') and \ self.map.can_stand(tile.pos + (0, -1)): tile.add_to_group('resource_mark') self.snd['mark'].play() elif self.dragging == -1: if tile.in_group('resource_mark'): tile.remove_from_group('resource_mark') self.snd['unmark'].play() self.last_mouse_pos = mouse_pos def next_turn(self): # ----- 遍历标记,为标记雇佣 imp ----- for mark in union_dicts(self.map.groups['dig&cut_mark'], self.map.groups['build_mark_noworker']): tile = self.map.data[mark] neighbors = self.map.find_neighbors(tile.pos, (self.map.can_stand, )) found = False for dest in neighbors: if not found: path = self.map.path_finding(dest) for imp in self.imps: if not found: if imp.task is None and vec2int(imp.pos) in path: if tile and (tile.in_group('diggable') or tile.in_group('destroyable')): imp.task = Dig(self.map, tile.pos, dest) found = True elif tile and tile.in_group('cuttable'): imp.task = Cut(self.map, tile.pos, dest) found = True elif isinstance(tile, BuildMark): if (tile.image_name == 'torch') or \ (tile.image_name == 'ladder' and self.resource['woods'] >= 1) or \ (tile.image_name == 'shelf' and self.resource['woods'] >= 3) or \ (tile.image_name == 'bed' and self.resource['woods'] >= 4): imp.task = Build( self.map, tile.pos, dest) tile.worker = imp tile.remove_from_group( 'build_mark_noworker') found = True # # ----- 更新小弟目的地 ----- # for imp in self.imps: # if isinstance(imp.task, Dig) or isinstance(imp.task, Cut): # imp.task.path = {} # neighbors = self.map.find_neighbors(imp.task.target, (self.map.can_stand,)) # found = False # for dest in neighbors: # if not found: # path = self.map.path_finding(dest) # if vec2int(imp.pos) in path: # imp.task.path = path # found = True for wood in self.woods: tile_below = self.map.data[vec2int(wood.pos + (0, 1))] if not wood.owner and tile_below and not tile_below.in_group( 'resource_mark'): path = self.map.path_finding(wood.pos) found = False for imp in self.imps: if not found: if imp.task is None and vec2int(imp.pos) in path and \ len([i for i in imp.inventories if isinstance(i, Wood)]) < 1: imp.task = Carry(self.map, wood.pos, wood.pos, item_to_find=wood) for mark in self.map.groups['resource_mark']: path = self.map.path_finding(vec(mark) + (0, -1)) for wood in self.woods: if wood.owner and vec2int(wood.owner.pos) in path: wood.owner.task = Carry(self.map, vec(mark) + (0, -1), vec(mark) + (0, -1), item_to_find=None) self.all_sprites.update() self.map.groups['visible'] = {} for imp in self.imps: self.map.light(imp.pos) self.map.light_torch() def consume_woods(self, n): for i, wood_in_res in enumerate([ wood for wood in self.woods if vec2int(wood.pos + vec(0, 1)) in self.map.groups['resource_mark'] ]): if i < n: wood_in_res.kill() def events(self): tile = self.map.data[vec2int(self.cursor_pos)] for e in pg.event.get(): # ----- 退出事件 ----- if e.type == pg.QUIT: if self.playing: self.playing = False self.running = False # ----- 退出事件 ----- # ----- 鼠标按下事件 ----- if e.type == pg.MOUSEBUTTONDOWN: # e.button 1左键 2中键 3右键 4滚轮上 5滚轮下 if e.button == 1: if self.map.in_bounds( self.cursor_pos) and self.map.in_view( self.cursor_pos): if self.mode == 'imp': if self.map.can_stand(self.cursor_pos): Imp(self, self.cursor_pos) elif self.mode == 'shelf': if tile is None or isinstance(tile, BgTile): self.dragging = 1 elif isinstance( tile, BuildMark) and tile.image_name == 'ladder': self.dragging = -1 elif self.mode == 'bed': if tile is None or isinstance(tile, BgTile): self.dragging = 1 elif isinstance( tile, BuildMark) and tile.image_name == 'bed': self.dragging = -1 elif self.mode == 'ladder': if tile is None or isinstance(tile, BgTile): self.dragging = 1 elif isinstance( tile, BuildMark) and tile.image_name == 'ladder': self.dragging = -1 elif self.mode == 'dig&cut' and tile: if tile.in_group('dig&cut_mark'): self.dragging = -1 else: self.dragging = 1 elif self.mode == 'resource' and tile and tile.in_group( 'earth'): if tile.in_group('resource_mark'): self.dragging = -1 else: self.dragging = 1 elif self.mode == 'torch': if isinstance(tile, BgTile): BuildMark(self.map, tile.pos, 'torch') elif isinstance(tile, Torch): tile.kill() elif self.mode == 'remove' and tile is not None: tile.kill() if e.button == 3: self.dragging_camera = True if e.button == 4: self.mode = self.modes[(self.modes.index(self.mode) - 1) % len(self.modes)] self.snd['shift'].play() if e.button == 5: self.mode = self.modes[(self.modes.index(self.mode) + 1) % len(self.modes)] self.snd['shift'].play() # ----- 鼠标按下事件 ----- # ----- 鼠标放开事件 ----- if e.type == pg.MOUSEBUTTONUP: if e.button == 1: if self.dragging: self.dragging = False if e.button == 2: # debug pass if e.button == 3: self.dragging_camera = False # ----- 鼠标放开事件 ----- # ----- 键盘按下事件 ----- if e.type == pg.KEYDOWN: if e.key == pg.K_SPACE: self.pause = False if self.pause else True if e.key == pg.K_1: self.game_speed = 800 if e.key == pg.K_2: self.game_speed = 600 if e.key == pg.K_3: self.game_speed = 400 if e.key == pg.K_4: self.game_speed = 200 if e.key == pg.K_z: if config.TILESIZE == 48: config.TILESIZE = 32 self.camera.offset += (self.cursor_pos.x * 16, self.cursor_pos.y * 16) else: config.TILESIZE = 48 self.camera.offset -= (self.cursor_pos.x * 16, self.cursor_pos.y * 16) self.camera.repair() if e.key == pg.K_d: self.mode = 'dig&cut' if e.key == pg.K_i: self.mode = 'imp' if e.key == pg.K_l: self.mode = 'ladder' if e.key == pg.K_r: self.mode = 'resource' if e.key == pg.K_c: self.mode = 'torch' # ----- 键盘按下事件 ----- def draw(self): # draw debug HUD pg.display.set_caption("{:.2f}".format(self.clock.get_fps())) # pg.display.set_caption("camera({}, {})".format(self.camera.offset.x, self.camera.offset.y)) # pg.display.set_caption( # "({},{},{})".format(self.cursor_pos.x, self.cursor_pos.y, # (type(self.map.data[vec2int(self.cursor_pos)])))) self.screen.blit(pg.transform.scale(self.img['sky_top'], (WIDTH, 100)), (0, 0)) self.screen.blit(self.img['sky'], (0, 100)) self.screen.blit(self.img['sky'], (512, 100)) self.screen.blit( pg.transform.scale(self.img['sky_bottom'], (WIDTH, 512)), (0, 612)) tiles = self.map.draw(self.camera) # pg.display.set_caption(str(tiles)) # self.all_sprites.draw(self.screen) for sprite in self.all_sprites: if isinstance(sprite, Wood) and sprite.owner: # 隐藏被捡起来的木头 continue self.screen.blit(sprite.image, self.camera.apply(sprite)) # draw target box and mouse cursor target = pg.Rect( self.cursor_pos.x * config.TILESIZE + self.camera.offset.x, self.cursor_pos.y * config.TILESIZE + self.camera.offset.y, config.TILESIZE, config.TILESIZE) pg.draw.rect(self.screen, WHITE, target, 2) self.draw_mode_icon(self.mode) # draw game speed if self.pause: self.draw_text('PAUSE', 32, RED, vec(WIDTH / 2, 16), align='mid') else: self.draw_text('SPEED:', 32, WHITE, vec(WIDTH / 2 - 130, 16), align='mid') for i in range(1, 5): if 1000 - (200 * i) == self.game_speed: self.draw_text('x' + str(i), 38, BROWN, vec(WIDTH / 2 - 100 + 56 * i, 16), align='mid') else: self.draw_text('x' + str(i), 32, WHITE, vec(WIDTH / 2 - 100 + 56 * i, 16), align='mid') # draw resource # count woods self.resource['woods'] = 0 for wood in self.woods: if vec2int(wood.pos + vec(0, 1)) in self.map.groups['resource_mark']: self.resource['woods'] += 1 count_woods = self.resource['woods'] for bm in self.map.groups['build_mark']: bm = self.map.data[bm] if bm.image_name == 'ladder': count_woods -= 1 elif bm.image_name == 'shelf': count_woods -= 3 elif bm.image_name == 'bed': count_woods -= 4 self.screen.blit(pg.transform.scale(self.img['wood'], (24, 24)), (16, HEIGHT - 30)) if count_woods >= 0: self.draw_text('x' + str(count_woods), 24, WHITE, (40, HEIGHT - 24)) else: self.draw_text('x' + str(count_woods), 24, RED, (40, HEIGHT - 24)) self.screen.blit(self.img['cursor'], self.last_mouse_pos - (15, 10)) pg.display.flip() def draw_mode_icon(self, mode): if mode == 'dig&cut': image = self.img['axe_iron'] mode_name = 'Dig&Cut' elif mode == 'resource': image = self.map.image['greystone_sand'] mode_name = 'Set Resource Area' elif mode == 'imp': image = self.img['imp'] mode_name = 'Minion' elif mode == 'ladder': image = self.map.image['ladder'].copy() mode_name = 'Ladder' elif mode == 'torch': image = self.map.image['torch'] mode_name = 'Torch' elif mode == 'shelf': image = self.map.image['shelf'] mode_name = 'Library' elif mode == 'bed': image = self.map.image['bed'] mode_name = 'Bed' else: image = self.map.image['table'] mode_name = 'Nothing' self.screen.blit(pg.transform.scale(image, (64, 64)), vec(WIDTH - 96, HEIGHT - 96)) self.draw_text(mode_name, 46, WHITE, vec(WIDTH - 104, HEIGHT - 90), align='right') def draw_text(self, text, font_size, color, pos, align='left'): font = pg.font.Font(self.font_name, font_size) text_surface = font.render(text, True, color) text_rect = text_surface.get_rect() if align == 'left': text_rect.topleft = pos elif align == 'mid': text_rect.midtop = pos elif align == 'right': text_rect.topright = pos self.screen.blit(text_surface, text_rect) def zoom(self, n): config.TILESIZE += n if 32 <= config.TILESIZE <= 96: self.camera.offset -= (self.cursor_pos.x * n, self.cursor_pos.y * n) config.TILESIZE = max(32, config.TILESIZE) config.TILESIZE = min(96, config.TILESIZE) self.camera.repair()
class Game(): def __init__(self): self.map = self.load_map(Constants.MAP_FILE) self.player = PlayerSprite(Constants.PLAYER_IMAGES, self.player_start_position, self.map_bounds) self.bullet_group = pygame.sprite.Group() self.player_group = pygame.sprite.Group(self.player) self.cursor = CursorSprite(Constants.CURSOR_IMAGE) def load_map(self, map): # Load map f = open(map, 'r') contents = f.read() f.close() json_contents = json.loads(contents) map_array = json_contents['map'] blocks = [] y = 0 for row in map_array: x = 0 for entry in row: if entry == 0: image = 'grass.png' passable = True destroyable = False elif entry == 1: image = 'water.png' passable = False destroyable = True elif entry == 2: image = 'lava.png' passable = False destroyable = False elif entry == 3: image = 'dirt.png' passable = True destroyable = False else: print("map file corrupted") sys.exit(1) # add on a new sprite at x*box_size, y*box_size block = TileSprite(Constants.IMAGE_PATH + image, (x * Constants.BLOCK_SIZE, y * Constants.BLOCK_SIZE), passable, destroyable) blocks.append(block) x += 1 y += 1 self.total_level_width = len(map_array[0]) * Constants.BLOCK_SIZE # calculate size of level in pixels self.total_level_height = len(map_array) * Constants.BLOCK_SIZE # maybe make 32 an constant self.camera = Camera(Camera.complex_camera, self.total_level_width, self.total_level_height) self.tile_group = pygame.sprite.Group(*blocks) self.player_start_position = ( Constants.BLOCK_SIZE * json_contents['start'][0], Constants.BLOCK_SIZE * json_contents['start'][1]) self.map_bounds = (Constants.BLOCK_SIZE * len(map_array[0]), Constants.BLOCK_SIZE * len(map_array)) def add_bullet(self): self.bullet_group.add(BulletSprite(self.camera.apply(self.player).center, pygame.mouse.get_pos())) def update_bullets(self): for bullet in self.bullet_group: if not pygame.Rect(0, 0, self.total_level_width, self.total_level_height).contains(bullet.rect): self.bullet_group.remove(bullet) else: bullet.update(self, self.tile_group)
class Game: WIDTH = 720 HEIGHT = WIDTH/12*9 SIZE = (WIDTH, HEIGHT) MAP_WIDTH = 1980 MAP_HEIGHT = 1080 MAP_SIZE = (MAP_WIDTH, MAP_HEIGHT) FPS = 60 LOG_FILE = "gamelog.log" SAVE_FILE = "save.json" HAS_MAP = False HAS_HEALTH = True MAX_SCALES = 100 def __init__(self): self.create_logger() try: self.debug("Initializing pygame") pygame.init() except Exception as e: self.debug("Init Error: "+str(e)) self.music = None self.bg_vol = 0.4 self.name = None self.entities = None self.map_layer = None self.collisions = [] self.transport_rects = {} try: self.shop = Shop(self) self.manager = LevelManager(self) self.rsc = resources.ResourceManager(self) self.scenes = CutScenes(self) except Exception as e: self.debug("Manager Error: "+str(e)) def init(self, classname="Crystal"): # Create window os.environ['SDL_VIDEO_CENTERED'] = '1' # center screen self.screen = pygame.display.set_mode(self.SIZE) pygame.display.set_caption("Dragon TakeOver") # Load levels try: self.debug("Loading levels...") self.manager.load_all_levels() except Exception as e: self.debug("Level.All Error: " + str(e)) # Add icon ico_path = os.path.join("resources","images","icon.png") ico_surf = self.rsc.load_image(ico_path,(32,32),colors.WHITE) pygame.display.set_icon(ico_surf) # create camera, fps, and game var self.clock = pygame.time.Clock() self.running = True self.game_dead = False self.camera = Camera(self.SIZE, self.MAP_SIZE) self.name = str(classname).lower() # load game try: self.debug("loading resources") font = pygame.font.Font(None, 48) self.load_text = font.render("Loading...",1,colors.WHITE) self.load_rect = self.load_text.get_rect() self.load_rect.centerx = self.screen.get_rect().centerx self.load_rect.centery = self.screen.get_rect().centery self.IS_LOADING = True load_thread = self.create_thread(self.loading_screen) self.rsc.load_resources() self.IS_LOADING = False self.debug("waiting for loading thread to stop...") load_thread.join() self.debug("loading thread killed") except Exception as e: self.debug("Resource error: " + str(e)) try: self.debug("loading shop resources") self.shop.init() except Exception as e: self.debug("Shop.init Error: " + str(e)) self.create_sprites() self.load_save() ### Load Game Save file def load_save(self): save_data = None try: self.debug("loading save data") if os.path.exists(self.SAVE_FILE): with open(self.SAVE_FILE, 'r') as f: save_data = json.loads(f.read()) self.name = save_data['player'] self.scenes.reset_scenes() self.create_player() if os.path.exists(self.SAVE_FILE): self.manager.load_level(save_data['level']) self.load_player_info(save_data) except Exception as e: self.debug("Save data Error: " + str(e)) ### Create/Overwrite Game save file def write_save(self): self.debug("writing save") save = {} save['level'] = self.manager.level save['player'] = self.name save['max_hp'] = self.player.MAX_HP save['max_ap'] = self.player.MAX_AP save['attack'] = self.player.attack save['scales'] = self.player.scales save['boss_scales']= self.player.boss_scales save['party_hp'] = self.player.party_health save['party_atk'] = self.player.party_attack with open(self.SAVE_FILE, 'w') as f: f.write(json.dumps(save, indent=4, sort_keys=True)) ### Create Debug/Game log def create_logger(self): # delete existing log file if os.path.exists(self.LOG_FILE): os.remove(self.LOG_FILE) # create logger logging.basicConfig(filename=self.LOG_FILE, level=logging.DEBUG) ### Create game sprites def create_sprites(self): self.debug("creating sprites") self.background = Block(self.MAP_SIZE) self.background.block_id = "bg" self.entities = pygame.sprite.Group() self.entities.add( self.background ) def create_player(self): self.tests = [] try: self.debug("Creating party..") # spawn player self.player = Player(self, self.name) self.player.block_id = "player" self.entities.add( self.player ) # choose ally bots bot_options = ["crystal","nathan","jack"] bot_options.remove(self.name.lower()) # spawn bots self.bots = [] for bot_name in bot_options: self.debug("Creating bot: "+bot_name) if bot_name == "crystal": bot = CrystalBot(self, bot_name) elif bot_name == "jack": bot = JackBot(self, bot_name) else: bot = NathanBot(self, bot_name) bot.rect.x = self.player.rect.x + 50 bot.rect.y = self.player.rect.y - 50 self.bots.append( bot ) self.entities.add( bot ) except Exception as e: self.debug("Party Creation Error: " + str(e)) ### Load player info from save file def load_player_info(self, info): self.player.MAX_HP = info['max_hp'] self.player.MAX_AP = info['max_ap'] self.player.attack = info['attack'] self.player.scales = info['scales'] self.player.boss_scales = info['boss_scales'] self.player.party_attack = info['party_atk'] self.player.party_health = info['party_hp'] """ EVENT LOOP FUNCTIONS """ def draw(self): for event in pygame.event.get(): if event.type == pygame.QUIT: self.running = False self.player.update_stop(event) self.clock.tick(self.FPS) self.screen.fill(colors.BLACK) self.draw_sprites() self.draw_player_info() self.entities.update() pygame.display.flip() def draw_sprites(self, isScene=False): self.camera.update(self.player) for e in self.entities.sprites(): if e.block_id not in ["player","bot"]: self.screen.blit(e.image, self.camera.apply(e.rect)) # prioritize drawing of player and bots for bot in self.bots: self.screen.blit(bot.image, self.camera.apply(bot.rect)) self.screen.blit(self.player.image, self.camera.apply(self.player.rect)) # do collision for sprite in self.entities.sprites(): if sprite.block_id in ["player","bot"]: if sprite.rect.collidelist(self.collisions) > -1: sprite.move_back() # check transport if not isScene: for name in self.transport_rects: rect = self.transport_rects[name] if self.player.rect.colliderect(rect): print str(name) if name == "void": if self.player.boss_scales < 3: self.player.rect.y -= 30 self.player.h_decel, self.player.v_decel = True, True self.scenes.load_scene(3) spawn = self.manager.levels["village"]["spawn"] self.player.set_pos(spawn[0], spawn[1]) break else: self.manager.load_level(name) break else: pass for x in self.tests: self.screen.blit(x[1], self.camera.apply(x[0])) def draw_bars(self, sprite): _mid = (sprite.MAX_HP*60/100) _low = (sprite.MAX_HP*30/100) bar_width = sprite.bar_width # get length of health percent_left = (sprite.HP * bar_width) / (sprite.MAX_HP * 1.0) percent_lost = ((sprite.MAX_HP - sprite.HP) * bar_width) / (sprite.MAX_HP * 1.0) # get length of ap ap_left = (sprite.AP * bar_width) / (sprite.MAX_AP * 1.0) ap_lost = ((sprite.MAX_AP - sprite.AP) * bar_width) / (sprite.MAX_AP * 1.0) # calculate color if sprite.HP > _mid: color = colors.H_GREEN elif sprite.HP > _low: color = colors.H_YELLOW else: color = colors.H_RED # draw player health if sprite.block_id == "player": bar_x, bar_y = 40, 10 bar_height = 15 # draw HP left = (bar_x+3,bar_y+3, percent_left, bar_height) lost = (bar_x+percent_left+3, bar_y+3, percent_lost, bar_height) pygame.draw.rect(self.screen, color, left) pygame.draw.rect(self.screen, (10, 10, 10), lost) # draw ap left = (bar_x + 3, bar_y + 30, ap_left, bar_height) lost = (bar_x + ap_left+3, bar_y + 30, ap_lost, bar_height) pygame.draw.rect(self.screen, colors.AP_COLOR, left) pygame.draw.rect(self.screen, (10, 10, 10), lost) # draw boss health elif sprite.block_id == "boss": pass # draw mob health else: hp_rect = self.camera.apply(sprite.rect) x, y = hp_rect.x, hp_rect.y start_x = x + (sprite.WIDTH/2) start_y = y - sprite.hp_evel bar_height = 5 left = (start_x, start_y, percent_left, bar_height) lost = (start_x+percent_left, start_y, percent_lost, bar_height) pygame.draw.rect(self.screen, color, left) pygame.draw.rect(self.screen, (10,10,10), lost) def draw_player_info(self): # draw face face = self.player.face self.screen.blit(face, (5,5)) # draw scales scale_text = self.rsc.scale_nums[str(self.player.scales)] boss_text = self.rsc.scale_nums[str(self.player.boss_scales)] self.screen.blit(self.rsc.scale, (5, 65)) self.screen.blit(self.rsc.boss_scale, (105, 65)) self.screen.blit(scale_text, (35, 65)) self.screen.blit(boss_text, (135, 65)) # draw all entity health bars for e in self.entities.sprites(): if e.IS_ALIVE: self.draw_bars(e) #### Other def draw_loading(self): self.clock.tick(self.FPS) self.screen.fill(colors.BLACK) self.screen.blit(self.load_text, self.load_rect) pygame.display.flip() def run(self): while self.running: self.draw() self.exit() def exit(self): self.write_save() pygame.quit() sys.exit() def loading_screen(self): while self.IS_LOADING: self.draw_loading() def create_thread(self, func, *args): t = threading.Thread(target=func, args=args) t.daemon = True t.start() return t def debug(self, text, debug=True): _log = text starter = "> " if not isinstance(text, basestring): _log = repr(text) if debug: logging.debug(starter + _log) else: logging.info(starter + _log) print _log
class Deadline(): def __init__( self, level, player, game_width, game_height, fire_speed, game_over_func=None, gravity=False, fire_list_coords=None, theme=pygame_menu.themes.THEME_BLUE, fire_delay=None): self.timer = pygame.time.Clock() self.entities = pygame.sprite.Group() # Все объекты self.run = True self.paused = False self.fire_list_coords = [] # Window size self.WIN_SIZE = self.WIN_WIDTH, self.WIN_HEIGHT = game_width, game_height # Группируем ширину и высоту в одну переменную self.DISPLAY = (self.WIN_WIDTH, self.WIN_HEIGHT) # Game self.level = level self.fire_speed = fire_speed # Delay for fire spreading self.fire_counter = 0 # Delay for starting level if fire_delay is None: self.fire_delay = 300 else: self.fire_delay = fire_delay self.game_over_func = game_over_func self.platforms = [] self.seed = 0 self.x = self.y = 0 # координаты self.player = player self.entities.add(self.player) if fire_list_coords is not None: self.fire_list_coords = fire_list_coords else: self.fire_list_coords = [FIRE_START] # Высчитываем фактическую ширину уровня self.total_level_width = len(self.level[0]) * PLATFORM_WIDTH self.total_level_height = len(self.level) * PLATFORM_HEIGHT # высоту # Camera for player self.camera = Camera( self._camera_configure, self.total_level_width, self.total_level_height) # Pause menu for level self.PAUSE_MENU = pygame_menu.Menu( self.WIN_WIDTH // 3, self.WIN_HEIGHT // 3, 'Paused', theme=theme) self.PAUSE_MENU.add_button('Continue', action=self._continue_game) self.PAUSE_MENU.add_button('Save game', action=self._return_game_val) self.PAUSE_MENU.add_button( 'Quit to menu', action=self._stop_level) def run_game(self, gravity): ''' Main cycle of the game. ''' # Initialize pygame for this level self.screen = pygame.display.set_mode(self.WIN_SIZE) pygame.display.set_caption("DEADLINE") bg = Surface(self.WIN_SIZE) bg.fill(Color(BACKGROUND_COLOR)) # Directions of the player left = right = False up = False flag = True down = gravity self.start = False # все анимированные объекты, за исключением героя animatedEntities = pygame.sprite.Group() b1, b2 = -1, -1 for row in self.level: # вся строка b1 += 1 for col in row: # каждый символ b2 += 1 self.seed += 1 if col == "#": pf = Platform(self.x, self.y) self.entities.add(pf) self.platforms.append(pf) if col == "!": bd = BlockDie(self.x, self.y) self.entities.add(bd) self.platforms.append(bd) self.fire_list_coords.append([b1, b2]) if col == "C": pf = ClosedDoor(self.x, self.y) self.entities.add(pf) self.platforms.append(pf) if col == "E": pf = Door(self.x, self.y) self.entities.add(pf) self.platforms.append(pf) if col == 0: pf = Space(self.x, self.y) self.entities.add(pf) self.x += PLATFORM_WIDTH # блоки платформы ставятся на ширине блоков b2 = -1 self.y += PLATFORM_HEIGHT # то же самое и с высотой self.x = 0 # на каждой новой строчке начинаем с нуля running = False pygame.mixer.Channel(0).set_volume(0.85) pygame.mixer.Channel(0).play( pygame.mixer.Sound( get_data_path( 'fb_medium.ogg', 'music')), loops=-1) self.exit_code = 0 self.start_time = 0 while self.run: # Основной цикл программы self.timer.tick(60) if not self.paused: self.start_time += 1 if self.start and self.start_time > self.fire_delay: self._fire_cycle() events = pygame.event.get() for e in events: # Обрабатываем события if e.type == QUIT: self.run = False # Player died if not self.player.life: self.run = False self.exit_code = 2 # Player ended this level if self.player.end: self.run = False self.exit_code = 3 if e.type == KEYDOWN and e.key == K_ESCAPE: self.paused = not self.paused if e.type == KEYDOWN and e.key == K_LEFT: left = True self.start = True if e.type == KEYDOWN and e.key == K_RIGHT: right = True self.start = True if e.type == KEYDOWN and e.key == K_UP: up = True self.start = True if e.type == KEYDOWN and e.key == K_DOWN: down = True self.start = True if e.type == KEYUP and e.key == K_UP: up = False self.start = True if e.type == KEYUP and e.key == K_RIGHT: right = False self.start = True if e.type == KEYUP and e.key == K_LEFT: left = False self.start = True if e.type == KEYUP and e.key == K_DOWN: down = False self.start = True if e.type == KEYDOWN and e.key == K_LSHIFT: running = True self.start = True if e.type == KEYUP and e.key == K_LSHIFT: running = False self.start = True if self.paused: self.PAUSE_MENU.update(events) if not self.paused: self.player.update( left, right, up, down, self.platforms, running) else: self.player.update( False, False, False, False, self.platforms, False) # First - backgorund drawing self.screen.blit(bg, (0, 0)) # Next - drawing objects if not self.paused: animatedEntities.update() self.entities.update( left, right, up, down, self.platforms, running) # Centralize camera on player self.camera.update(self.player) for e in self.entities: self.screen.blit(e.image, self.camera.apply(e)) if self.paused: self.PAUSE_MENU.draw(self.screen) pygame.display.update() if self.game_over_func is not None: self.game_over_func() pygame.mixer.Channel(0).stop() pygame.mixer.Channel(1).stop() pygame.mixer.Channel(2).stop() # 1 - leaved from menu ; 2 - died ; 3 - finished return self.exit_code def get_endgame_score(self): pass def _return_game_val(self): ''' Function for saving the game status ''' self.exit_code = 7 self.run = False def _continue_game(self): self.paused = False def _stop_level(self): self.paused = False self.run = False self.exit_code = 1 def _fire_cycle(self): self.fire_counter += 1 self.y = 0 if self.fire_counter == self.fire_speed: for y_new, x_new in self.fire_list_coords: f = Fire(x_new, y_new) f.update(self.level, self.fire_list_coords) self.fire_counter = 0 for row in self.level: # вся строка for col in row: # каждый символ self.seed += 1 if col == "!": bd = BlockDie(self.x, self.y) self.entities.add(bd) self.platforms.append(bd) self.x += PLATFORM_WIDTH # блоки платформы ставятся на ширине блоков self.y += PLATFORM_HEIGHT # то же самое и с высотой self.x = 0 # на каждой новой строчке начинаем с нуля def _camera_configure(self, camera, target_rect): ''' Creating Rect for moving camera ''' left, top, _, _ = target_rect _, _, width, height = camera left, top = -left + self.WIN_WIDTH / 2, -top + self.WIN_HEIGHT / 2 # Left walls left = min(0, left) # Right walls left = max(-(camera.width - self.WIN_WIDTH), left) # Top walls top = max(-(camera.height - self.WIN_HEIGHT), top) top = min(0, top) return Rect(left, top, width, height) def get_level(self): return self.level
class Game: def __init__(self): """Initialize everything needed to run the game.""" pg.init() self.screen = pg.display.set_mode((WIDTH, HEIGHT)) pg.display.set_caption(TITLE) self.clock = pg.time.Clock() pg.key.set_repeat(500, 100) def new(self): """ Initialize everything needed for a new game.""" self.background = self.create_layer(Tile) # Holds all layers. self.layers = [self.background] self.player_sprite = pg.sprite.Group() self.player = Player(self, 0, 0) self.camera = Camera(self.background.width, self.background.height) def create_layer(self, object_type): """Create a layer and populate it with the appropriate object.""" layer = Grid(object_type) layer.init_chunks() layer.init_objects() return layer def run(self): """Runs pygame.""" while True: self.dt = self.clock.tick(FPS) / 1000 self.events() self.update() self.draw() def events(self): """Catch all events here.""" for event in pg.event.get(): if event.type == pg.QUIT: pg.quit() sys.exit() if event.type == pg.KEYDOWN: if event.key == pg.K_ESCAPE: pg.quit() sys.exit() # Moves the player and camera. if event.key == pg.K_LEFT: self.player.move(dx=-1) if event.key == pg.K_RIGHT: self.player.move(dx=1) if event.key == pg.K_UP: self.player.move(dy=-1) if event.key == pg.K_DOWN: self.player.move(dy=1) def update(self): """Everything that needs to be updated is done here.""" # Update player sprite. self.player_sprite.update() self.camera.update(self.player) # Uses player position to know which chunks to render around it. for layer in self.layers: layer.render = layer.render_chunks(*self.player.get()) # Set new limits for the camera. self.camera._update_max_size(self.background) def draw(self): """Draws images and displays it on the screen.""" # Covers previous screen. Essentially wipes it. self.screen.fill(BGCOLOR) # Get fps of the game. pg.display.set_caption("{:.2f}".format(self.clock.get_fps())) for layer in self.layers: for chunk in layer.render: for tile in chunk: self.screen.blit(tile[0], self.camera.apply_rect(tile[1])) for sprite in self.player_sprite: self.screen.blit(sprite.image, self.camera.apply(sprite)) pg.display.flip()
font = pygame.font.Font(None, 30) while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False elif event.type == pygame.KEYDOWN or event.type == pygame.KEYUP: player_group.update(event) prev_dy = camera.dy camera.update(player) if prev_dy != camera.dy: for sprite in obstacles_group: camera.apply(sprite) if randint(1, 130) % 40 == 0: Enemy(enemies_group, player_bullets_group, enemies_bullets_group, player) screen.fill(pygame.Color(0, 0, 0)) screen.blit(background, (0, camera.dy - HEIGHT // 2)) enemies_group.update() enemies_bullets_group.update() player_bullets_group.update() player_group.update() enemies_group.draw(screen) enemies_bullets_group.draw(screen)
class DunGen: """ This is the main class that initializes everything. """ def __init__(self, width=1000, height=600): pygame.init() # set the window dimensions self.window_width = width self.window_height = height # create the screen self.screen = pygame.display.set_mode((self.window_width, self.window_height)) pygame.display.set_caption("Dun-Gen") # noinspection PyArgumentList self.background = pygame.Surface((self.window_width, self.window_height)) # generate the map self.map = TheMap(LAND_WIDTH, LAND_HEIGHT) # probability of enemy appearing self.enemy_prob = 0 # creates the clock self.clock = pygame.time.Clock() self.time = pygame.time.get_ticks() # init player self.player = Player() self.player.rect.left = self.map.player_start_loc[0] self.player.rect.top = self.map.player_start_loc[1] self.player_sprites = pygame.sprite.RenderPlain(self.player) # create the camera self.camera = Camera(complex_camera, self.map.width << 5, self.map.height << 5, self.window_width, self.window_height) # debugging self.debug_mode = False self.god_mode = False # used for demo self.seen_first_key = False self.seen_first_stairs = False def main_loop(self): """ This initializes everything and starts the main-loop. """ # allows key-strokes to repeat if they're held down pygame.key.set_repeat(10, 30) # clear the background: black self.background = self.background.convert() self.background.fill((0, 0, 0)) while 1: self.clock.tick(60) # displays 60 max-fps self.controller() self.view() def controller(self): """ Handles all of the events-functionality: keys-pressed, etc. """ now = pygame.time.get_ticks() for e in pygame.event.get(): if e.type == KEYDOWN: if (e.key == K_RIGHT) or (e.key == K_LEFT) or (e.key == K_UP) or (e.key == K_DOWN): self.player.move(self.map.landscape, self.map.map_objects["other"], e.key) elif e.key == K_SPACE: # determine if keys are around; remove the key if found if pygame.sprite.spritecollide(self.player, self.map.map_objects["keys"], True): self.seen_first_key = True # determine if all keys have been collected and player's at a stairwell if len(self.map.map_objects["keys"]) == 0 and pygame.sprite.spritecollide(self.player, self.map.map_objects[ "stairs"], False): self.seen_first_stairs = True self.load_new_map() elif e.key == K_d and now - self.time > 250: # enter debug-mode self.debug_mode = not self.debug_mode if self.god_mode: self.god_mode = not self.god_mode self.time = now elif self.debug_mode and e.key == K_g and now - self.time > 250: # enter god-mode self.god_mode = not self.god_mode self.time = now elif e.key == K_ESCAPE: quit() # debug mode doesn't allow the map to grow # probability of enemies appearing still increases if self.debug_mode: if e.key == K_s: self.map.width -= 2 self.map.height -= 2 self.load_new_map() elif e.type == QUIT: quit() # move the enemies towards the player, if player is near enough for enemy_sprite in self.map.enemies_lst: if pygame.sprite.collide_circle(enemy_sprite, self.player): # player-radius: 6, enemy-radius: 4 enemy_sprite.move_towards_player(self.map.landscape, self.player.rect, self.map.map_objects["other"]) def view(self): """ Handles all of the display functionality. """ # draw scene and objects self.draw_walls_floors_to_screen() self.draw_objects_to_screen() # draw enemies, if near player or in god-mode for sprite in self.map.enemies_lst: if pygame.sprite.collide_circle(sprite, self.player) or self.god_mode: self.screen.blit(sprite.image, self.camera.apply(sprite)) # draw player for sprite in self.player_sprites: self.screen.blit(sprite.image, self.camera.apply(sprite)) # finally, draw text self.keys_remaining_msg() self.draw_demo_msg() self.draw_debug_msg() # present changes to window pygame.display.flip() def load_new_map(self): """ Loads a new map. Displays a loading message for 6 seconds and generates a new map. """ self.clock.tick() # initialize a counter self.screen.blit(self.background, (0, 0)) self.display_text_to_screen(LOADING_MSG_FONT_SIZE, "Loading...") self.display_text_to_screen(RANDOM_LOADING_MSG_FONT_SIZE, random.choice(RANDOM_LOADING_MSGS), pos_y=(self.background.get_height() >> 1) + 35, rgb_color=(255, 25, 25)) pygame.display.update() # display loading page # generate a new game self.map = TheMap(self.map.width + 2, self.map.height + 2) self.player.rect.left, self.player.rect.top = self.map.player_start_loc # 15 is the boundary; afterwards, the probability of enemy appearing where key is, is 100% if self.enemy_prob < 15: self.enemy_prob += 1 self.map.probability_enemy_appears = self.enemy_prob # readjust the camera self.camera = Camera(complex_camera, self.map.width << 5, self.map.height << 5, self.window_width, self.window_height) t1 = self.clock.tick() time_to_wait = 6000 - t1 # provide 6 seconds (or more) to read loading msg pygame.time.wait(time_to_wait) def display_text_to_screen(self, font_size, msg, pos_x=None, pos_y=None, rgb_color=(255, 255, 255)): """ displays some text to the screen :param font_size: (int) font size :param msg: (str) message to display :param pos_x: (int) x-coordinate to display at :param pos_y: (int) y-coordinate to display at :param rgb_color: (tuple) (r,g,b) """ if pygame.font: if not pos_x: pos_x = self.window_width >> 1 if not pos_y: pos_y = self.window_height >> 1 font = pygame.font.Font(None, font_size) text = font.render(msg, 1, rgb_color) text_pos = text.get_rect(centerx=pos_x, centery=pos_y) self.screen.blit(text, text_pos) def draw_walls_floors_to_screen(self): """ Draws the walls and the floor if it is some X distance from the player. Uses PyGame's circle collision to detect what wall/floor to light up. """ self.camera.update(self.player) # clear the background self.screen.blit(self.background, (0, 0)) # shifts all objects and creates camera motion-effect (also, performance booster) cam_x1 = -1 * self.camera.state.x >> 5 cam_y1 = -1 * self.camera.state.y >> 5 cam_x2 = (-1 * self.camera.state.x + self.window_width + 32) >> 5 cam_y2 = (-1 * self.camera.state.y + self.window_height + 32) >> 5 for x in range(cam_x1, cam_x2): for y in range(cam_y1, cam_y2): sprite = self.map.landscape[y][x] if pygame.sprite.collide_circle(sprite, self.player) or self.god_mode: near_viewable = True and not sprite.block_sight else: near_viewable = False if near_viewable or sprite.visited: # light sprites nearby and shadow visited sprites if not sprite.block_sight: sprite.visited = True if near_viewable: self.screen.blit(sprite.image, self.camera.apply(sprite)) else: self.screen.blit(sprite.drk_image, self.camera.apply(sprite)) def draw_objects_to_screen(self): """ Draws all map-objects: keys, stairs, and other (objects). """ for object_groups in self.map.map_objects: # unpacks the lists for sprite in self.map.map_objects[object_groups]: # unpacks the sprites if pygame.sprite.collide_circle(sprite, self.player) or self.god_mode: near_viewable = True and not sprite.block_sight else: near_viewable = False if near_viewable or sprite.visited: # light sprites nearby and shadows visited but not nearby sprites if not sprite.block_sight: sprite.visited = True if near_viewable: self.screen.blit(sprite.image, self.camera.apply(sprite)) else: self.screen.blit(sprite.drk_image, self.camera.apply(sprite)) def keys_remaining_msg(self): """ Displays a message, indicating how many keys remain to be collected """ remaining_keys = len(self.map.map_objects["keys"]) pos_y = self.background.get_height() - 30 if remaining_keys > 0: if remaining_keys == 1: msg = "Collect the last key" else: msg = "Collect %s Keys" % remaining_keys self.display_text_to_screen(36, msg, pos_y=pos_y) else: self.display_text_to_screen(36, "Climb the stairs!", rgb_color=(255, 0, 0), pos_y=pos_y) def draw_debug_msg(self): """ Displays debug information at the top right of the screen """ text_pos_x = self.window_width - 100 # x-coord to place msg text_pos_y = 30 # y-coord to place msg text_offset_y = 14 # offset y-coord for next lines if self.debug_mode: self.display_text_to_screen(16, "Debug mode(d): on", pos_x=text_pos_x, pos_y=text_pos_y) if self.god_mode: self.display_text_to_screen(16, "God mode(g): on", pos_x=text_pos_x, pos_y=text_pos_y + text_offset_y) else: self.display_text_to_screen(16, "God mode(g): off", pos_x=text_pos_x, pos_y=text_pos_y + text_offset_y) self.display_text_to_screen(16, "Skip level key: s", pos_x=text_pos_x, pos_y=text_pos_y + (text_offset_y << 1)) else: self.display_text_to_screen(16, "Debug mode(d): off", pos_x=text_pos_x, pos_y=text_pos_y) # display msg if enemy is trying to attack enemy_lst = pygame.sprite.spritecollide(self.player, self.map.enemies_lst, False) if enemy_lst: self.display_text_to_screen(16, "This is when he realizes he hasn't been programmed any weapons", pos_y=(self.window_height >> 1) + 40) def draw_demo_msg(self): """ Displays a message the first time the player is on a key or stairway. """ # key if not self.seen_first_key: color = (255, 255, 0) # yellow key_lst = pygame.sprite.spritecollide(self.player, self.map.map_objects["keys"], False) if key_lst: self.display_text_to_screen(32, "Press the SPACE BAR to collect the key", rgb_color=color) # stair if not self.seen_first_stairs: color = (255, 255, 0) # yellow stair_lst = pygame.sprite.spritecollide(self.player, self.map.map_objects["stairs"], False) if stair_lst: if len(self.map.map_objects["keys"]) == 0: self.display_text_to_screen(32, "Press the SPACE BAR to climb the stairs", rgb_color=color) else: self.display_text_to_screen(32, "Collect all of the keys and then come back", rgb_color=color)
class Gaming(engine.State): def init(self): P_Graph, R_Graph, M_Graph, doors, _map, room_init, room_end = run( debugger=conf.debugger) # Saving variables: self.room_end = room_end self.M_Graph = M_Graph self.R_Graph = R_Graph self.switch = False # Note: After X time of not receiving any damage health will be recorvered to some Y level at Z speed self.time_damage = time.time() # Tiles: self.tile_group = py.sprite.Group() self.mini_map = py.sprite.Group() # User Minimap: self.user_minimap = UserMiniMap(conf.user_image_minimap) # Lifebar: self.lifebar = Lifebar(conf.lifebar_image) self.lifebar_background = LifebarBackground( conf.lifebar_background_image) # Weapons: self.weapon_group = py.sprite.Group() # Miniature Weapon: self.miniature_weapon = MiniatureWeapon(conf.weapon_dict['weapon_1']) # Doors: self.door_group = py.sprite.Group() # Enemies: self.enemy_group = py.sprite.Group() # Dynamic Obstacles: self.dynamic_group = py.sprite.Group() # Dynamic Obstacles (with ""user_pos""): self.dynamic_user_group = py.sprite.Group() # Loading [ Light // Pipeline ] Obstacle matrix for further use in the program: im = py.image.load(conf.dinamic_obtacles['light'][1]) mat_im_light = sprite_sheets.crea_matriu_imatges( im, *conf.dinamic_obtacles['light'][0]) im = py.image.load(conf.dinamic_obtacles['pipeline'][1]) mat_im_pipeline = sprite_sheets.crea_matriu_imatges( im, *conf.dinamic_obtacles['pipeline'][0]) im = py.image.load(conf.dinamic_obtacles['eyeBox'][1]) mat_im_eyeBox = sprite_sheets.crea_matriu_imatges( im, *conf.dinamic_obtacles['eyeBox'][0]) im = py.image.load(conf.dinamic_obtacles['teletransporter'][1]) mat_im_teletransporter = sprite_sheets.crea_matriu_imatges( im, *conf.dinamic_obtacles['teletransporter'][0]) del (im) # Background Image: self.game_background = Background(conf.game_background) for row in range(len(_map)): for col in range(len(_map[row, :])): # Floor Tile: if _map[row, col] == 0: tile = Tile(conf.floor_image if np.random. choice(2, 1, p=[0.1, 0.9])[0] == 1 else conf.floor_broken_image) tile.rect.center = (col * conf.tile_size, row * conf.tile_size) self.tile_group.add(tile) # Minimap: tile_minimap = TileMiniMap(conf.floor_image_minimap) tile_minimap.rect.center = (col * conf.tile_size_mini_map + conf.position_mini_map[0], row * conf.tile_size_mini_map + conf.position_mini_map[1]) self.mini_map.add(tile_minimap) # Internal Wall Tile / Edge Tile / External Wall Tile: elif _map[row, col] == 1: _type = type_detector((row, col), _map) if not _type: ValueError( 'No type for this tile {}:{} (row, col)'.format( row, col)) _type = -1 # Note: Creating Wall Tile specific to type / "_type" image = '{}{}.png'.format(conf.root_wall_image, _type + 1) tile = Tile(image) tile.rect.center = (col * conf.tile_size, row * conf.tile_size) self.tile_group.add(tile) # Minimap: tile_minimap = TileMiniMap(conf.wall_image_minimap) tile_minimap.rect.center = (col * conf.tile_size_mini_map + conf.position_mini_map[0], row * conf.tile_size_mini_map + conf.position_mini_map[1]) self.mini_map.add(tile_minimap) # Obstacles elif _map[row, col] in [2, 3, 4, 5, 10, -1]: if _map[row, col] == 2: tile = Tile(rd.choice(conf.static_obstacles_images)) tile.rect.center = (col * conf.tile_size, row * conf.tile_size) self.tile_group.add(tile) elif _map[row, col] == 3: tile = DinamicTileLight(mat_im_light) tile.rect.center = (col * conf.tile_size, row * conf.tile_size) self.dynamic_group.add(tile) elif _map[row, col] == 4: tile = DinamicTileEyeBox(mat_im_eyeBox) tile.rect.center = (col * conf.tile_size, row * conf.tile_size) self.dynamic_user_group.add(tile) elif _map[row, col] == 5: tile = DinamicTilePipeline(mat_im_pipeline) tile.rect.center = (col * conf.tile_size, row * conf.tile_size) self.dynamic_group.add(tile) # Here we add the initial and final platform: elif _map[row, col] == -1: tile = DinamicTileEyeBox(mat_im_teletransporter) tile.rect.center = (col * conf.tile_size, row * conf.tile_size) self.dynamic_user_group.add(tile) _map[row, col] = 0 elif _map[row, col] == 10: tile = Tile(conf.floor_image if np.random. choice(2, 1, p=[0.1, 0.9])[0] == 1 else conf.floor_broken_image) tile.rect.center = (col * conf.tile_size, row * conf.tile_size) self.tile_group.add(tile) # Minimap: # Note: Here we need to handle the -1 tag of ""room_init"" and ""room_end"" if _map[row, col] != 0: tile_minimap = TileMiniMap(conf.obstacle_image_minimap) tile_minimap.rect.center = ( col * conf.tile_size_mini_map + conf.position_mini_map[0], row * conf.tile_size_mini_map + conf.position_mini_map[1]) self.mini_map.add(tile_minimap) else: tile_minimap = TileMiniMap(conf.init_end_image_minimap) tile_minimap.rect.center = ( col * conf.tile_size_mini_map + conf.position_mini_map[0], row * conf.tile_size_mini_map + conf.position_mini_map[1]) self.mini_map.add(tile_minimap) # Doors for door in doors: tile = Door(conf.door_close_image, door.orientation) tile.rect.center = (door.col * conf.tile_size, door.row * conf.tile_size) self.door_group.add(tile) # User im = py.image.load(conf.sprite_sheet_personatge) self.grup = py.sprite.Group() # grup de Sprites mat_im = sprite_sheets.crea_matriu_imatges( im, *conf.mides_sprite_sheet_personatge) self.heroi = Character( mat_im, tuple(coord * conf.tile_size for coord in room_init.center)[::-1], _map, self.door_group) self.grup.add(self.heroi) # Camera: self.camera = Camera(conf.screen_size[0], conf.screen_size[1]) # Enemies: if conf.allow_enemies: for room in self.R_Graph.R.nodes(): # Note: We don't want to have enemies in the initial and final rooms if room == room_end or room == room_init: continue enemies = list(conf.enemy_dict.keys()) enemies_number = room.size * conf.enemy_density while enemies_number > 0: # Chose random position: row, col = np.where( _map[room.topleft.row:room.bottomleft.row, room.topleft.col:room.topright.col] == 0) i = np.random.randint(len(row)) row, col = (row[i] + room.topleft.row, col[i] + room.topleft.col) del (i) position = [row * conf.tile_size, col * conf.tile_size][::-1] # Chose random enemy: enemy = conf.enemy_dict[np.random.choice( enemies, p=conf.probablity_enemies)] # Count enemy weight in room density: enemies_number -= enemy['weight'] enemy_params = [ enemy['selected_weapon'], enemy['velocity'], enemy['attack_perimeter'], enemy['follow_perimeter'], enemy['life'], enemy['size'], enemy['desfase'], enemy['follow_perimeter_secondary'] ] enemy = Enemy(enemy['sprite'], position, _map, M_Graph, enemy_params, self.door_group) self.enemy_group.add(enemy) # The paint method is called once. If you call repaint(), it # will be called again. def paint(self, screen): self.update(screen) # Every time an event occurs, event is called. If the event # method returns a value, it will become the new state. def event(self, event): if event.type == KEYDOWN or event.type == KEYUP: key = py.key.get_pressed() w, a, s, d, shift, space, e, q, esc = (key[py.K_w], key[py.K_a], key[py.K_s], key[py.K_d], key[py.K_LSHIFT], key[K_SPACE], key[K_e], key[K_q], key[K_ESCAPE]) # Mouvement: if any((w, s, a, d)): # Firts we test advenced mouvements if all((w, d)): self.heroi.canvia_estat(self.heroi.VES_AMUNT_DRETA) elif all((w, a)): self.heroi.canvia_estat(self.heroi.VES_AMUNT_ESQUERRA) elif all((s, d)): self.heroi.canvia_estat(self.heroi.VES_AVALL_DRETA) elif all((s, a)): self.heroi.canvia_estat(self.heroi.VES_AVALL_ESQUERRA) # If none of above statements are true we test basic mouvements elif w: self.heroi.canvia_estat(self.heroi.VES_AMUNT) elif s: self.heroi.canvia_estat(self.heroi.VES_AVALL) elif d: self.heroi.canvia_estat(self.heroi.VES_DRETA) elif a: self.heroi.canvia_estat(self.heroi.VES_ESQUERRA) else: self.heroi.canvia_estat(self.heroi.VES_STOP) # Actions: # Speed: if shift: self.heroi.velocity = conf.velocity_low else: self.heroi.velocity = conf.velocity_fast # Attack: if space: self.heroi.attack = True else: self.heroi.attack = False # Change Weapon: if e: self.heroi.change_weapon() # Open Door: if q: self.heroi.open = True else: self.heroi.open = False # Pause Menu: if esc: return self.game.change_state('PAUSE') # Go to next level: if self.action(self.heroi.rect.center) and not self.switch: self.switch = True self.clock = time.time() self.heroi.canvia_estat(self.heroi.VES_STOP) if self.switch: self.heroi.canvia_estat(self.heroi.VES_STOP) if time.time() - self.clock >= conf.wait_time: if self.game.count != conf.number_levels - 1: return self.game.change_state('NEXT_LEVEL') else: return self.game.change_state('MISSION_ACCOMPLISHED') # Subfunction: def action(self, user_pos): # Position user next level trap cercle_row, cercle_col = [ coord * conf.tile_size for coord in self.room_end.center ] perimeter = lambda x, y: (x - cercle_row)**2 + (y - cercle_col)**2 return perimeter(user_pos[1], user_pos[0]) <= ( conf.room_transporter_detection_perimeter * conf.tile_size)**2 # Loop is called once a frame. It should contain all the logic. # If the loop method returns a value it will become the new state. def loop(self): enemies_remove = dict() enemies_pos = list((sprite._id, sprite.rect.center, sprite.size) for sprite in self.enemy_group if sprite.state != sprite.DEAD) weapon = self.heroi.update(py.mouse.get_pos()) if weapon: self.weapon_group.add(weapon) # Detect end on cycle of a weapon: for weapon in self.weapon_group: _del = weapon.update(enemies_pos, self.heroi.rect.center, self.heroi._id) # Note: This if statement is true is the user shots a weapon to an enemy if type( _del ) == uuid.UUID and weapon.active_damage and weapon._id == self.heroi._id: if _del in enemies_remove: enemies_remove[_del].append(weapon.damage) else: enemies_remove[_del] = [weapon.damage] weapon.active_damage = False # Note: This if statement is true is the enemy shots to the user: elif type( _del ) == uuid.UUID and weapon.active_damage and weapon._id != self.heroi._id: if not conf.immortality: move_lifebar = int( (conf.lifebar_size[0] / conf.user_life) * weapon.damage) self.heroi.life -= (conf.user_life / conf.lifebar_size[0]) * move_lifebar weapon.active_damage = False self.lifebar.update(move_lifebar) self.time_damage = time.time() # Note: This if statement is true is the weapon ends he's life cycle elif type(_del) == bool: self.weapon_group.remove(weapon) # Nothing happens: elif type(_del) == type(None): pass else: pass # Weapon miniature on Lifebar Background: if not self.miniature_weapon == conf.weapon_dict[ self.heroi.inventory_weapons[self.heroi.selected_weapon]]: self.miniature_weapon = MiniatureWeapon(conf.weapon_dict[ self.heroi.inventory_weapons[self.heroi.selected_weapon]]) self.camera.update(self.heroi) self.user_minimap.update(self.heroi.rect.center) self.door_group.update() # Enemies: for enemy in self.enemy_group: # Damage enemies: if enemy._id in enemies_remove.keys(): enemy.life -= sum(enemies_remove[enemy._id]) enemy.state = enemy.DAMAGE enemies_pos = list((sprite._id, sprite.rect.center, sprite.size + conf.security_area) for sprite in self.enemy_group if sprite.state != sprite.DEAD) weapon = enemy.update(self.heroi.rect.center, enemies_pos) if weapon: self.weapon_group.add(weapon) # Dynamic Obstacles: self.dynamic_group.update() # Dynamic Obstacles (with ""user_pos""): self.dynamic_user_group.update(self.heroi.rect.center) # Health Recover Mecanism: if time.time( ) - self.time_damage > conf.life_recovery_waiting_time and self.heroi.life < conf.life_recovery_limit: move_lifebar = int( (conf.lifebar_size[0] / conf.user_life) * conf.life_recovery) self.heroi.life += (conf.user_life / conf.lifebar_size[0]) * move_lifebar self.lifebar.update(-move_lifebar) # Update is called once a frame. It should update the display. def update(self, screen): screen.fill(conf.background_color) # Background Image: screen.blit(self.game_background.image, self.game_background.rect) # Tiles for sprite in self.tile_group: screen.blit(sprite.image, self.camera.apply(sprite)) # Dynamic Obstacles: for sprite in self.dynamic_group: screen.blit(sprite.image, self.camera.apply(sprite)) # Dynamic Obstacles (with ""user_pos""): for sprite in self.dynamic_user_group: screen.blit(sprite.image, self.camera.apply(sprite)) # Doors for sprite in self.door_group: screen.blit(sprite.image, self.camera.apply(sprite)) # Enemies # Note: Dead enemies must be printed first for sprite in self.enemy_group: if sprite.state == sprite.DEAD: screen.blit(sprite.image, self.camera.apply(sprite)) for sprite in self.enemy_group: if sprite.state != sprite.DEAD: screen.blit(sprite.image, self.camera.apply(sprite)) # User for sprite in self.grup: screen.blit(sprite.image, self.camera.apply(sprite)) # Weapon for sprite in self.weapon_group: screen.blit(sprite.image, self.camera.apply(sprite)) # Minimap # Tiles self.mini_map.draw(screen) # User screen.blit(self.user_minimap.image, self.user_minimap.rect) # Lifebar screen.blit(self.lifebar.image, self.lifebar.rect) screen.blit(self.lifebar_background.image, self.lifebar_background.rect) # Weapon Miniature: screen.blit(self.miniature_weapon.image, self.miniature_weapon.rect) py.display.flip() # Dead Screen logic: if self.heroi.life <= 0: return self.game.change_state('GAMEOVER')
class Game(object): def __init__(self, w, h): pygame.init() self.size = w, h self.screen = pygame.display.set_mode(self.size) pygame.display.set_caption(TITLE) pygame.display.flip() self.hero_is_died = pygame.sprite.Sprite() self.hero_is_died.image = pygame.image.load("data/hero_died.png") self.hero_is_died.rect = self.hero_is_died.image.get_rect() self.hero_is_win = pygame.sprite.Sprite() self.hero_is_win.image = pygame.image.load("data/win.png") self.hero_is_win.rect = self.hero_is_died.image.get_rect() self.dead = pygame.sprite.Group() self.win_sp = pygame.sprite.Group() self.hero_is_win.add(self.win_sp) self.hero_is_died.add(self.dead) self.camera = Camera(w, h) self.win_m, self.dead_m = False, False self.music = [ pygame.mixer.Sound("data/background_music_1.ogg"), pygame.mixer.Sound("data/background_music_2.ogg"), pygame.mixer.Sound("data/background_music_3.ogg") ] self.menu_music = pygame.mixer.Sound("data/music/main_menu.ogg") self.victory_music = pygame.mixer.Sound("data/Victory.wav") self.dead_music = pygame.mixer.Sound("data/dead.wav") self.menu_music.play(-1) self.hero_sprite = pygame.sprite.Group() self.enemy_sprites = pygame.sprite.Group() self.boss_sprite = pygame.sprite.Group() self.platform_sprites = pygame.sprite.Group() self.all_sprites = pygame.sprite.Group() self.princess_sprite = pygame.sprite.Group() self.info_sprites = pygame.sprite.Group() self.background_sprite = pygame.sprite.Group() self.buttons = pygame.sprite.Group() self.level_names = ["intro", "1", "2", "final"] self.level_state = 0 self.new_game_btn = Button(self.buttons, "new_game_btn.png", "new_game_btn_2.png", 208, 93, "bookFlip2.ogg", "new_game") self.hero = Hero(self.hero_sprite, 60, 60, Sounds().return_dict_of_sounds()) self.hero.add(self.all_sprites) self.cursor_group = pygame.sprite.Group() self.cursor = Cursor(self.cursor_group) self.main_menu = True self.bg = Background(self.background_sprite) self.main_img = pygame.image.load("data/main_menu.png") pygame.mouse.set_visible(False) self.clock = pygame.time.Clock() self.fps = 40 self.just_music = None self.left_state, self.up_state, self.attack = None, None, None self.running = True def draw(self): self.screen.fill(pygame.Color("black")) for event in pygame.event.get(): if event.type == pygame.QUIT: self.running = False if self.main_menu: self.screen.blit(self.main_img, (0, 0)) self.buttons.draw(self.screen) self.cursor_group.draw(self.screen) for event in pygame.event.get(): if event.type == pygame.QUIT: self.running = False if event.type == pygame.MOUSEBUTTONDOWN: self.buttons.update(event) for sprite in self.buttons: if sprite.state(): if sprite.button_name == "new_game": self.main_menu = False draw_level(self.level_names[0], 46, 46, [ self.platform_sprites, self.all_sprites, self.hero_sprite, self.princess_sprite, self.info_sprites, self.boss_sprite, self.enemy_sprites ]) self.camera.update(self.hero) sprite.pressed = False self.menu_music.stop() self.just_music = choice(self.music) self.just_music.play(-1) break if event.type == pygame.KEYDOWN: if event.key == 32: draw_level(self.level_names[0], 46, 46, [ self.platform_sprites, self.all_sprites, self.hero_sprite, self.princess_sprite, self.info_sprites, self.boss_sprite, self.enemy_sprites ]) self.camera.update(self.hero) self.main_menu = False self.menu_music.stop() self.just_music = choice(self.music) self.just_music.play(-1) if event.type == pygame.MOUSEMOTION: self.buttons.update(event) self.cursor.rect.x, self.cursor.rect.y = event.pos else: if not self.hero.dead and not self.hero.win: if pygame.key.get_pressed()[pygame.K_SPACE]: self.up_state = -1 if pygame.key.get_pressed()[pygame.K_a]: self.left_state = -1 if pygame.key.get_pressed()[pygame.K_d]: self.left_state = 1 if pygame.key.get_pressed()[pygame.K_TAB]: self.level_state = 1 if pygame.key.get_pressed()[pygame.K_r]: self.reload_level() sleep(1) if pygame.key.get_pressed()[pygame.K_ESCAPE]: self.reload() sleep(1) if pygame.key.get_pressed()[pygame.K_f]: self.attack = True self.update() self.left_state, self.up_state, self.attack = None, None, None elif self.hero.win: if not self.win_m: self.just_music.stop() self.victory_music.play(-1) self.win_m = True self.win_sp.draw(self.screen) self.camera.update(self.hero_is_win) if pygame.key.get_pressed()[pygame.K_SPACE]: self.reload() else: if not self.dead_m: self.just_music.stop() self.dead_music.play(-1) self.dead_m = True self.dead.draw(self.screen) self.camera.update(self.hero_is_died) if pygame.key.get_pressed()[pygame.K_SPACE]: self.reload() self.clock.tick(self.fps) pygame.display.flip() def reload(self): self.level_state = 0 for el in self.platform_sprites: self.all_sprites.remove(el) self.platform_sprites.remove(el) for el in self.info_sprites: self.all_sprites.remove(el) self.info_sprites.remove(el) for sprite in self.princess_sprite: self.all_sprites.remove(sprite) self.princess_sprite.remove(sprite) for sprite in self.boss_sprite: self.all_sprites.remove(sprite) self.boss_sprite.remove(sprite) for sprite in self.enemy_sprites: self.all_sprites.remove(sprite) self.enemy_sprites.remove(sprite) self.hero.reload() self.main_menu = True self.dead_m, self.win_m = False, False self.just_music.stop() self.dead_music.stop() self.victory_music.stop() self.menu_music.play(-1) def reload_level(self): for el in self.platform_sprites: self.all_sprites.remove(el) self.platform_sprites.remove(el) for el in self.info_sprites: self.info_sprites.remove(el) self.all_sprites.remove(el) for sprite in self.princess_sprite: self.princess_sprite.remove(sprite) self.all_sprites.remove(self) for sprite in self.boss_sprite: self.boss_sprite.remove(sprite) self.all_sprites.remove(self) for sprite in self.enemy_sprites: self.all_sprites.remove(sprite) self.enemy_sprites.remove(sprite) self.hero.reload_level([ self.platform_sprites, self.all_sprites, self.hero_sprite, self.princess_sprite, self.info_sprites, self.boss_sprite, self.enemy_sprites ], self.level_names[self.level_state]) def check_for_next_level(self): for sprite in self.platform_sprites: if pygame.sprite.collide_rect(self.hero, sprite) and isinstance( sprite, LevelPlatform): self.level_state = (self.level_state + 1) % len( self.level_names) return True return False def next_level(self): self.just_music.stop() self.just_music = choice(self.music) self.just_music.play(-1) self.reload_level() sleep(1) def update(self): for sprite in self.all_sprites: self.camera.apply(sprite) self.background_sprite.draw(self.screen) self.all_sprites.draw(self.screen) self.hero_sprite.update([ self.platform_sprites, self.all_sprites, self.enemy_sprites, self.princess_sprite ], self.screen, self.left_state, self.up_state, self.attack) self.princess_sprite.update(self.platform_sprites) self.boss_sprite.update(self.platform_sprites, self.hero_sprite, self.screen) self.enemy_sprites.update(self.platform_sprites, self.hero_sprite, self.screen) self.platform_sprites.update(self.boss_sprite) self.camera.update(self.hero) if self.check_for_next_level(): self.next_level()