from pygame import * init() HEIGHT = 700 WIDTH = 1024 screen = display.set_mode((WIDTH, HEIGHT)) margin = 300 offset = 0 def blit_offset(sprite, rect): rect.centerx -= offset screen.blit(sprite, rect) rect.centerx += offset class AutoMover: def next_move(self): def get_closer(pos, seeknum): if pos < seeknum: return min(pos+self.speed, seeknum) if pos > seeknum: return max(pos-self.speed, seeknum) return seeknum sx, sy = self.path_points[self.seekpoint] new_x, new_y = get_closer(self.rect.centerx, sx), get_closer(self.rect.centery, sy) return new_x - self.rect.centerx, new_y - self.rect.centery def update_and_display(self): mx, my = self.next_move() new_x, new_y = self.rect.centerx + mx, self.rect.centery + my if new_x > self.rect.centerx: self.sprite = self.sprite_right else: self.sprite = self.sprite_left if (new_x, new_y) == self.path_points[self.seekpoint]: self.seekpoint += 1 if self.seekpoint >= len(self.path_points): self.seekpoint = 0 self.rect.centerx, self.rect.centery = new_x, new_y blit_offset(self.sprite, self.rect) class Enemy (AutoMover): def __init__(self, sprite_path_right, sprite_path_left, path_points, speed): self.sprite_right = image.load(sprite_path_right) self.sprite_left = image.load(sprite_path_left) self.sprite = self.sprite_right self.rect = self.sprite.get_rect() self.path_points = path_points self.rect.centerx, self.rect.centery = path_points[0] self.speed = speed self.seekpoint = 1 def die(self): self.speed = 0 self.rect.centerx = 10 self.rect.centery = 10 def check_collision(self, player): if not self.rect.colliderect(player.rect): return if player.rect.bottom < self.rect.top + 100: self.die() return player.rect.centerx = 10 player.rect.centery = 10 class PlayerCharacter: def __init__(self, sprite_path): self.sprite = image.load(sprite_path) self.rect = self.sprite.get_rect() self.velocity_x = 0 self.velocity_y = 0 def startright(self): self.velocity_x += 5 def startleft(self): self.velocity_x -= 5 def jump(self): self.rect.centery += 1 for wp in wall + wall_moving: if wp.rect.colliderect(self.rect): self.velocity_y = -30 self.rect.centery -= 1 def stop(self): self.velocity_x = 0 def update_and_display(self): self.rect.centery += self.velocity_y self.rect.centerx += self.velocity_x self.velocity_y += 1 for wp in wall+wall_moving: if wp.rect.colliderect(self.rect): if self.velocity_y > 0: self.rect.bottom = wp.rect.top elif self.velocity_y < 0: self.rect.top = wp.rect.bottom + 1 self.velocity_y = 1 try: wp.speed # This worked, so it's a MoveWall # Let's move where it's going mx, my = wp.next_move() self.rect.centerx += mx self.rect.centery += my except: # It's not a MoveWall break break global offset if self.rect.centerx + margin - offset >= WIDTH: offset = self.rect.centerx + margin - WIDTH elif self.rect.centerx < margin + offset: offset = self.rect.centerx - margin blit_offset(self.sprite, self.rect) class MoveWall(AutoMover): def __init__(self, sprite_path, path_points, speed): self.path_points = path_points self.sprite = image.load(sprite_path) self.rect = self.sprite.get_rect() self.speed = speed self.sprite_right = self.sprite self.sprite_left = self.sprite self.seekpoint = 0 self.rect.centerx, self.rect.centery = path_points[0] class WallPiece: def __init__(self, sprite_path, loc): self.sprite = image.load(sprite_path) self.rect = self.sprite.get_rect() self.rect.centerx = loc[0] self.rect.centery = loc[1] def display(self): blit_offset(self.sprite, self.rect) config_lines = open("config").read().strip().split("\n") configuration = {line.split()[0]: line.split()[1] for line in config_lines} character = PlayerCharacter(configuration["character"]) wall = [WallPiece(configuration["wall"], (i * 20, HEIGHT/2)) for i in range(20)] wall.extend([WallPiece(configuration["wall"], (i*20 + 300, HEIGHT/2 + 300)) for i in range(30)]) enemies = [Enemy(configuration["enemy_right"], configuration["enemy_left"], [(600,200), (900,200), (900, 400), (600, 400)], 3)] wall_moving = [MoveWall(configuration["wall"], [(i * 20 + 300, 50), (i * 20 + 1000, 50)], 5) for i in range(5)] wall_moving.extend([MoveWall(configuration["wall"], [(550+20*i,270), (850+20*i,270), (850+20*i, 470), (550+20*i, 470)], 3) for i in range(7)]) from time import sleep while True: for e in event.get(): if e.type == KEYDOWN: if e.key == K_RIGHT: character.startright() if e.key == K_LEFT: character.startleft() if e.key == K_SPACE: character.jump() if e.type == KEYUP: if e.key == K_RIGHT or e.key == K_LEFT: character.stop() if e.type == QUIT: from sys import exit exit() screen.fill((255,255,255)) character.update_and_display() for wp in wall: wp.display() for mw in wall_moving: mw.update_and_display() for enemy in enemies: enemy.check_collision(character) enemy.update_and_display() display.flip() sleep(0.01)