class Ship: def __init__(self, app): self.screen = app.screen self.screen_rect = app.screen.get_rect() self.image = pygame.image.load("assets/images/dark_ship.png") self.rect = self.image.get_rect() self.rect.midbottom = self.screen_rect.midbottom self.speed = 0.15 self.acceleration = 0.05 self.x = float(self.rect.x) self.move_right = False self.move_left = False self.shoot_delay = 1000 self.last = pygame.time.get_ticks() self.weapon = Weapon() def draw(self): self.weapon.draw(self.screen) self.screen.blit(self.image, self.rect) def update(self): if self.move_right and self.rect.x + self.rect.width - 15 < self.screen_rect.width: print(self.speed) self.x += self.speed elif self.move_left and self.rect.x + 15 > 0: print(self.speed) self.x -= self.speed else: self.speed = 4 self.rect.x = self.x self.weapon.update() def shoot(self): now = pygame.time.get_ticks() if now - self.last > self.shoot_delay: self.last = now self.weapon.shoot(self.rect.x + 25, self.rect.y) def check_collision(self, object1, object2): if(object1.rect.x < object2.rect.x + object2.rect.width and object1.rect.x + object1.rect.width > object2.rect.x and object1.rect.y < object2.rect.y + object2.rect.height and object1.rect.y + object1.rect.height> object2.rect.y): return True
class Game(object): def __init__(self): # Settings pygame.mixer.init() pygame.mixer.music.load('latenight.ogg') pygame.mixer.music.play(0) self.WIDTH = 640 self.HEIGHT = 360 # Config self.tps_max = 100 # Initialization pygame.init() font = pygame.font.SysFont("Arial", 18) self.resolution = (self.screen_width, self.screen_height) = (self.WIDTH, self.HEIGHT) self.screen = pygame.display.set_mode(self.resolution, pygame.RESIZABLE) self.tps_clock = pygame.time.Clock() self.tps_delta = 0.0 self.scroll = Vector2(0, 0) self.map = Map(self) self.player = Player( self ) # przy inicjalizacji przekazuje playerowi wszystko Player(self) self.enemy = Enemy(self) self.weapon = Weapon(self) self.fire = Fire(self) self.physics = Physics(self) self.platforms = Platforms(self) self.collision = Collision(self) self.sprite = Sprite(self) self.menu = Menu(self) self.file_loader = FileLoader(self) self.sprite.load_images() def create_fonts(font_sizes_list): "Creates different fonts with one list" fonts = [] for size in font_sizes_list: fonts.append(pygame.font.SysFont("Arial", size)) return fonts def render(fnt, what, color, where): "Renders the fonts as passed from display_fps" text_to_show = fnt.render(what, 0, pygame.Color(color)) self.screen.blit(text_to_show, where) def display_fps(): "Data that will be rendered and blitted in _display" render(fonts[0], what=str(int(self.tps_clock.get_fps())), color="white", where=(0, 0)) fonts = create_fonts([32, 16, 14, 8]) while True: # Events for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit(0) elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE: ############# klik i cos sie dzieje raz sys.exit(0) # Ticking self.tps_delta += self.tps_clock.tick( ) / 1000.0 # zamieniam MS na sekundy while self.tps_delta > 1 / self.tps_max: self.tick() self.tps_delta -= 1 / self.tps_max # Rendering/Drawing self.screen.fill((0, 0, 0)) self.draw() display_fps() pygame.display.flip() def tick(self): self.player.tick() self.weapon.tick() self.fire.tick() self.enemy.tick() self.physics.tick() def draw(self): # self.menu.draw() self.map.draw() self.player.draw() self.enemy.draw() self.weapon.draw() self.fire.draw()
class Player(pygame.sprite.Sprite): def __init__(self, game): super().__init__() self.max_health = 300 self.health = self.max_health self.game = game self.image = pygame.image.load("assets/player2.png").convert_alpha() self.image_right = pygame.transform.flip(self.image, True, False).convert_alpha() self.image_left = self.image.copy().convert_alpha() self.rect = self.image.get_rect(x=game.screen.get_width() // 2 - 100, y=game.screen.get_height() // 2) self.velocity = 3 self.weapon = Weapon(self, game) self.all_plasma = pygame.sprite.Group() def draw(self): self.game.screen.blit(self.image, self.rect) prop_health = self.health / self.max_health * 100 prop_charge = self.weapon.charge / self.weapon.max_charge * 100 rect = pygame.Rect(self.rect.left - self.image.get_width() + 5, self.rect.top - 30, prop_health, 3) max_rect = pygame.Rect(self.rect.left - self.image.get_width() + 5, self.rect.top - 30, 100, 3) charge_rect = pygame.Rect(self.rect.left - self.image.get_width() + 5, self.rect.top - 25, prop_charge, 3) charge_max_rect = pygame.Rect( self.rect.left - self.image.get_width() + 5, self.rect.top - 25, 100, 3) pygame.draw.rect(self.game.screen, "#0e0e0e", max_rect) pygame.draw.rect(self.game.screen, "#e6d16a", rect) if self.weapon.charge != 1: pygame.draw.rect(self.game.screen, "#0e0e0e", charge_max_rect) pygame.draw.rect(self.game.screen, "#00ccff", charge_rect) self.weapon.draw() def move_y(self, direction): can_move = True if direction and self.rect.y > 0: for rect in self.game.map.down_rects: if rect.colliderect(self.rect): can_move = False if can_move: self.rect.y -= self.velocity elif (not direction and self.rect.y < self.game.screen.get_height() - self.image.get_height()): for rect in self.game.map.up_rects: if rect.colliderect(self.rect): can_move = False if can_move: self.rect.y += self.velocity def move_x(self, direction): can_move = True if not direction and self.rect.x > 0: for rect in self.game.map.right_rects: if rect.colliderect(self.rect): can_move = False if can_move: self.rect.x -= self.velocity self.image = self.image_left elif (direction and self.rect.x < self.game.screen.get_width() - self.image.get_width()): for rect in self.game.map.left_rects: if rect.colliderect(self.rect): can_move = False if can_move: self.rect.x += self.velocity self.image = self.image_right def shoot(self): self.all_plasma.add(Plasma(self.weapon)) Sounds.lazer.play() self.weapon.reset() def damage(self, amount): self.health -= amount if self.health <= 0: self.dead() self.game.game_over() def dead(self): self.health = self.max_health self.rect = self.image.get_rect(x=self.game.screen.get_width() // 2 - 100, y=self.game.screen.get_height() // 2) self.all_plasma = pygame.sprite.Group() self.weapon.charge = 0
class Gook(Thing): def __init__(self, bitmap, position, color, name, size, start_image, weapon='cannon'): super().__init__(bitmap, position, start_image, size) self.name = name self.color = color self.direction = 'right' self.x_speed = 0 # Только для перемещения без участия игрока! self.y_speed = 0 self.speed_decrease = 0.5 # Замедление self.hp = 100 self.angle = 0 self.move_img_delay = 0 self.is_weapon = False self.holding = False self.weapon = Weapon(bitmap, position, *WEAPONS[weapon], self.direction, self.angle) self.weapon_gen = itertools.cycle(self.get_next_weapon()) self.weapon_name = next(self.weapon_gen) def __str__(self): return self.name def draw(self, window): super().draw(window) font = pygame.font.Font(None, 30) hp_text = font.render(str(self.get_hp()), True, pygame.Color('green')) name_text = font.render(self.name, True, pygame.Color(self.color)) window.blit(hp_text, [self.position[0], self.position[1] - 10]) window.blit(name_text, [self.position[0], self.position[1] - 25]) if self.is_weapon: self.weapon.draw(window) def get_weapon(self): return self.weapon def get_weapon_name(self): return self.weapon_name def get_hp(self): return self.hp def get_next_weapon(self): for weapon_now in WEAPONS: yield weapon_now def get_place_for_filling(self, pos, res): return ((pos[0], pos[1] - 20), (res[0] + 30, res[1] + 20)) def change_direction(self, direction): if self.direction != direction: self.flip_x() self.weapon.flip_x() self.direction = direction self.get_weapon().direction = direction def change_weapon(self): self.weapon_name = next(self.weapon_gen) self.weapon = Weapon(self.bitmap, self.position, *WEAPONS[self.weapon_name], self.direction, self.angle) def key_move(self, move): last_pos = self.get_pos() if self.collision('down'): if move == 'D': self.x_speed = MOVEMENT_SPEED self.change_direction('right') collision_check = self.collision('right', self.x_speed) if collision_check: self.x_speed = collision_check - self.get_x( ) - self.size[0] if self.x_speed == 0: for i in range(1, 20): collision_check = self.collision('right', kx=1, ky=i) if not collision_check: self.move(1, -i) break else: self.x_speed = -MOVEMENT_SPEED self.change_direction('left') collision_check = self.collision('left', self.x_speed) if collision_check: self.x_speed = collision_check - self.get_x() if self.x_speed == 0: for i in range(1, 20): collision_check = self.collision('left', kx=1, ky=i, speed=-1) if not collision_check: self.move(-1, -i) break self.move(self.x_speed, 0) self.x_speed = 0 return last_pos def jump1(self): last_pos = self.get_pos() if self.collision('down'): self.move(-10, -20) if self.direction == 'left': self.change_speed((10, -20)) else: self.change_speed((-10, -20)) return last_pos def jump2(self): last_pos = self.get_pos() if self.collision('down'): self.move(15, -15) if self.direction == 'left': self.change_speed((-20, -15)) else: self.change_speed((20, -15)) return last_pos def change_get_angle(self, final_cords): fin_x, fin_y = final_cords st_x, st_y = self.get_x() + self.get_size()[0] // 2, self.get_y( ) + self.get_size()[1] // 2 self.angle = math.atan2((fin_y - st_y), (fin_x - st_x)) '''self.weapon.rotate(self.angle)''' return self.angle def shoot(self, final_cords, power): self.change_get_angle(final_cords) return Bullet(self.bitmap, (self.get_x() + self.get_size()[0] // 2, self.get_y() + self.get_size()[1] // 2), self.weapon_name, self.angle, power, self.direction) def change_image_state(self, image): super().change_image(image) if self.direction == 'left': self.flip_x() def change_move_image(self): if self.move_img_delay > 5: if self.image_name == MOVE2_IMG: self.change_image_state(MOVE1_IMG) else: self.change_image_state(MOVE2_IMG) self.move_img_delay = 0 else: self.move_img_delay += 1 def make_damage(self, dmg): self.hp -= dmg def check_state(self): if super().check_state() or not self.check_is_alive(): return 'del' def check_is_alive(self): return self.get_hp() > 0 def make_graveyard(self): return Gravestone(self.bitmap, self.get_pos(), GRAVESTONE_IMG, GRAVESTONE_RES)