Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import pygame as p
- import random as r
- from os import listdir
- from math import ceil
- RED = (255,0,0)
- GREEN = (0,255,0)
- BLUE = (0,0,255)
- WHITE = (255,255,255)
- BLACK = (0,0,0)
- YELLOW = (255, 255, 0)
- ORANGE = (255,165,0)
- background_colour = BLUE
- main_dir = ""
- gfx_dir = main_dir+"gfx/"
- sound_dir = main_dir+"sound/"
- data_dir = main_dir+"data/"
- p.init()
- p.font.init()
- p.mixer.init()
- WIDTH, HEIGHT = 700, 700
- screen = p.display.set_mode((WIDTH, HEIGHT))
- entities = []
- pickups = []
- projectiles = []
- actions = []
- fires = []
- game_mode = "start"
- screen_start = p.transform.scale(p.image.load(gfx_dir+"screen_start.png").convert(), (WIDTH, HEIGHT))
- game_over_start = p.transform.scale(p.image.load(gfx_dir+"screen_game_over.png").convert(), (WIDTH, HEIGHT))
- pause_popup = p.image.load(gfx_dir+"pause_popup.png").convert_alpha()
- pause_popup_rect = pause_popup.get_rect()
- pause_popup_rect.center = (int(WIDTH/2), int(HEIGHT/2))
- requirement_font = p.font.SysFont("Arial", 30)
- score_font = p.font.SysFont("Calibri", 60)
- score_font.set_underline(True)
- level_font = p.font.SysFont("Consolas", 60)
- time_font = p.font.SysFont("Consolas", 30)
- game_over_score_font = p.font.SysFont("Arial", 100)
- game_over_level_font = p.font.SysFont("Arial", 100)
- game_clock = p.time.Clock()
- MAX_TICK_RATE = 60
- turn_length_log = []
- turn_length = 0
- turn_colour_intensity = 0
- p.mixer.music.load(sound_dir+"main_music.ogg")
- music_playing = False
- paused = False
- p.display.set_icon(p.image.load(gfx_dir+"icon.png"))
- if r.randint(1,5) == 1:
- p.display.set_caption("pan fried")
- else:
- p.display.set_caption("Panic Shift")
- sound_dict = {}
- for file in listdir(sound_dir):
- name = file[:-4]
- sound_object = p.mixer.Sound(sound_dir+file)
- sound_dict.update({name:sound_object})
- def play_sound(name):
- sound_dict[name].play()
- class Camera():
- def __init__(self, rect):
- self.rect = rect
- self.set_scale()
- def set_scale(self):
- self.scale_x = WIDTH/self.rect.w
- self.scale_y = HEIGHT/self.rect.h
- def update(self):
- self.set_scale()
- def reverse_transform_point(self, point):
- x, y = point
- x = (x/self.scale_x)+self.rect.x
- y = (y/self.scale_y)+self.rect.y
- return x, y
- def reverse_transform_rect(self, rect):
- x, y = self.reverse_transform_point(rect.topleft)
- w = (rect.w)/self.scale_x
- h = (rect.h)/self.scale_y
- new_rect = p.Rect([x,y,w,h])
- return new_rect
- def transform_point(self, point):
- x, y = point
- x = (x-self.rect.x)*self.scale_x
- y = (y-self.rect.y)*self.scale_y
- #x += (WIDTH/2)
- #y += (HEIGHT/2)
- return x, y
- def transform_rect(self, rect):
- x, y = self.transform_point(rect.topleft)
- w = (rect.w)*self.scale_x
- h = (rect.h)*self.scale_y
- new_rect = p.Rect([x,y,w,h])
- return new_rect
- def draw_transformed_surface(self, surface, rect):
- transformed_rect = self.transform_rect(rect)
- x, y = transformed_rect.topleft
- w = transformed_rect.w+2
- h = transformed_rect.h+2
- surface = p.transform.scale(surface, (w,h))
- screen.blit(surface, (x,y))
- def draw_transformed_rect(self, rect, colour=RED, border=0):
- transformed_rect = self.transform_rect(rect)
- if border:
- border *= ceil((self.scale_x+self.scale_y)/2)
- p.draw.rect(screen, colour, transformed_rect, border)
- class Tile():
- def __init__(self, level, tile_type, x, y):
- self.level = level
- self.tile_type = tile_type
- self.x = x
- self.y = y
- self.rect = p.Rect(self.x, self.y, 1, 1)
- self.rx = self.x*self.level.tw
- self.ry = self.y*self.level.th
- self.real_rect = p.Rect(self.rx, self.ry, self.level.tw, self.level.th)
- self.surface = p.image.load(gfx_dir+"tile_"+self.tile_type+".png").convert()
- self.spawning_timer = 0
- self.solid = False
- if self.tile_type == "wall":
- self.solid = True
- self.max_spawning_timer = 5
- self.spawning_timer = self.max_spawning_timer
- self.level.walls.append(self)
- def draw(self, camera):
- if self.spawning_timer:
- self.surface.set_alpha(0+(256/self.max_spawning_timer*(self.max_spawning_timer-self.spawning_timer)))
- else:
- self.surface.set_alpha(256)
- if self.solid:
- camera.draw_transformed_rect(self.real_rect, border=2)
- camera.draw_transformed_surface(self.surface, self.real_rect)
- class Level():
- def __init__(self, tw, th):
- self.tw = tw
- self.th = th
- self.tiles = []
- self.spawners = []
- self.walls = []
- self.exit = None
- self.level = 1
- self.create(self.level)
- def create(self, difficulty):
- difficulty -= 1
- self.width = 10+min(difficulty,12)
- self.height = 10+min(difficulty,12)
- if difficulty == 0:
- self.time = 60*MAX_TICK_RATE
- elif difficulty < 4:
- self.time = (40)*MAX_TICK_RATE
- else:
- self.time = (40+(5*difficulty))*MAX_TICK_RATE
- self.rect = p.Rect(0, 0, self.width, self.height)
- self.real_rect = p.Rect(0, 0, self.width*self.tw, self.height*self.th)
- self.tiles.clear()
- self.walls.clear()
- for pickup in pickups.copy():
- pickups.remove(pickup)
- entities.remove(pickup)
- for x in range(self.width):
- self.tiles.append([])
- for y in range(self.height):
- tile = Tile(self, "floor", x, y)
- self.tiles[-1].append(tile)
- self.spawners.clear()
- if self.exit:
- entities.remove(self.exit)
- projectile_timer = 10-min(difficulty*2,8)
- self.projectile_spawner = Projectile_Spawner(self, projectile_timer, 3)
- if difficulty > 3:
- self.second_projectile_spawner = Projectile_Spawner(self, projectile_timer, 3)
- if difficulty > 7:
- self.third_projectile_spawner = Projectile_Spawner(self, int(projectile_timer*3), 3)
- pickup_timer = 10+min(difficulty,8)
- self.pickup_spawner = Pickup_Spawner(self, 10, 3, max_entities=5)
- wall_timer = 15-min(difficulty*2,12)
- if difficulty > 4:
- self.wall_spawner = Wall_Spawner(self, wall_timer, 3, max_entities=int(self.width*self.height/6))
- self.second_wall_spawner = Wall_Spawner(self, wall_timer, 3, max_entities=int(self.width*self.height/6))
- else:
- self.wall_spawner = Wall_Spawner(self, wall_timer, 3, max_entities=int(self.width*self.height/4))
- camera.rect = self.real_rect.copy().inflate((self.tw*2, self.th*2))
- self.exit = Exit(self, int(self.width/2), int(self.height/2), 4+min(difficulty,60))
- if player:
- player.x, player.y = int(self.width/2)*self.tw, (int(self.height/2)+1)*self.th
- def draw(self, camera):
- for tile_strip in self.tiles:
- for tile in tile_strip:
- tile.draw(camera)
- class Action():
- def __init__(self, entity, timer):
- self.entity = entity
- self.max_timer = timer
- self.timer = self.max_timer
- actions.append(self)
- entity.actions.append(self)
- def update(self):
- self.timer -= 1
- if self.timer <= 0:
- actions.remove(self)
- self.entity.actions.remove(self)
- class Move_Action(Action):
- def __init__(self, entity, timer, x, y):
- Action.__init__(self, entity, timer)
- self.x = x
- self.y = y
- def update(self):
- Action.update(self)
- self.entity.x = self.entity.x+((self.x-self.entity.x)/self.max_timer*(self.max_timer-self.timer))
- self.entity.y = self.entity.y+((self.y-self.entity.y)/self.max_timer*(self.max_timer-self.timer))
- class Entity():
- def __init__(self, level, x, y, width, height, solid, collision_settings={}, spawning_timer=1):
- self.level = level
- self.x = x
- self.y = y
- self.tx, self.ty = int(self.x/self.level.tw), int(self.y/self.level.th)
- self.width = width
- self.height = height
- self.rect = p.Rect(self.x, self.y, self.width, self.height)
- self.solid = solid
- self.collision_settings = {"tiles":True, "entities":True, "border":True}
- self.collision_settings.update(collision_settings)
- self.actions = []
- self.max_spawning_timer = spawning_timer
- self.spawning_timer = self.max_spawning_timer
- entities.append(self)
- def check_projectile_collision(self):
- for projectile in projectiles:
- if projectile != self:
- if self.tx == projectile.tx and self.ty == projectile.ty:
- return projectile
- return False
- def set_rect(self):
- self.rect = p.Rect(self.x, self.y, self.width, self.height)
- def update(self):
- self.set_rect()
- def update_turn(self):
- if self.spawning_timer:
- self.spawning_timer -= 1
- def move(self, ax, ay, timer, test=False):
- if not ax and not ay:
- return
- steps = ceil(max(abs(ax), abs(ay)))
- dx = ax/steps
- dy = ay/steps
- nx, ny = 0,0
- for step in range(steps):
- if not self.check_collision(nx+dx, 0):
- nx += dx
- if not self.check_collision(0, ny+dy):
- ny += dy
- if not test:
- Move_Action(self, timer, self.x+nx, self.y+ny)
- self.tx += int(nx/self.level.tw)
- self.ty += int(ny/self.level.th)
- return self.x+nx, self.y+ny
- def move_t(self, ax, ay, timer, test=False):
- nx, ny = self.move(ax*self.level.tw, ay*self.level.th, timer, test=test)
- tx, ty = int(nx/self.level.tw), int(ny/self.level.th)
- return tx, ty
- def check_collision(self, ax, ay):
- nx = self.x+ax
- ny = self.y+ay
- check_rect = p.Rect(nx, ny, self.width, self.height)
- sx = max(min(int(nx/self.level.tw)-1, self.level.width),0)
- sy = max(min(int(ny/self.level.th)-1, self.level.height),0)
- ex = max(min(sx+int(self.width/self.level.tw)+2, self.level.width),0)
- ey = max(min(sy+int(self.height/self.level.th)+2, self.level.height),0)
- if self.collision_settings["tiles"]:
- for x in range(sx, ex):
- for y in range(sy, ey):
- tile = self.level.tiles[x][y]
- #if tile.solid:
- # print(tile.real_rect, check_rect)
- # camera.draw_transformed_rect(tile.real_rect, BLUE)
- # p.display.flip()
- if tile.solid and tile.real_rect.colliderect(check_rect) and not tile.spawning_timer:
- #print("collided tile")
- return tile
- if self.collision_settings["entities"]:
- for entity in entities:
- if entity != self:
- if entity.solid and entity.rect.colliderect(check_rect):
- return entity
- if self.collision_settings["border"]:
- if not self.level.real_rect.contains(check_rect):
- return "border"
- return False
- class Package(Entity):
- def __init__(self, player):
- self.player = player
- Entity.__init__(self, self.player.level, 0, 0, 1*self.player.level.tw, 1*self.player.level.th, False, spawning_timer=0)
- self.surface = p.image.load(gfx_dir+"package.png").convert_alpha()
- old_package_count = len(self.player.packages)
- self.player.packages.append(self)
- if old_package_count < self.level.exit.requirement-self.level.exit.packages and len(self.player.packages) >= self.level.exit.requirement-self.level.exit.packages:
- play_sound("ready")
- self.index = self.player.packages.index(self)
- self.tx, self.ty = self.player.move_log[self.index]
- self.x = self.tx*self.player.level.tw
- self.y = self.ty*self.player.level.th
- self.width = self.player.level.tw
- self.height = self.player.level.th
- self.actions = []
- self.set_rect()
- def update_turn(self):
- Entity.update_turn(self)
- def set_pos(self):
- self.tx, self.ty = self.player.move_log[self.index]
- Move_Action(self, self.player.action_speed, (self.tx*self.player.level.tw), (self.ty*self.player.level.th))
- def set_rect(self):
- self.rect = p.Rect(self.x, self.y, self.width, self.height)
- def update(self):
- self.tx = int(self.x/self.player.level.tw)
- self.ty = int(self.y/self.player.level.th)
- self.set_rect()
- global game_mode
- if self.check_projectile_collision():
- game_mode = "game_over"
- p.mixer.music.stop()
- play_sound("damage")
- def draw(self, camera):
- camera.draw_transformed_surface(self.surface, self.rect)
- #rect = p.Rect(self.tx*self.player.level.tw, self.ty*self.player.level.th, self.player.level.tw, self.player.level.th)
- #camera.draw_transformed_rect(rect)
- class Player(Entity):
- def __init__(self, level, x, y):
- Entity.__init__(self, level, x*level.tw, y*level.th, 1*level.tw, 1*level.th, False)
- self.action_speed = 15
- self.surfaces = {
- "up":p.image.load(gfx_dir+"player_up.png").convert_alpha(),
- "down":p.image.load(gfx_dir+"player_down.png").convert_alpha(),
- "left":p.image.load(gfx_dir+"player_left.png").convert_alpha(),
- "right":p.image.load(gfx_dir+"player_right.png").convert_alpha(),
- }
- self.direction = "up"
- self.packages = []
- self.move_log = [(self.tx, self.ty)]
- self.score = Score(0)
- def update_turn(self):
- Entity.update_turn(self)
- up = self.p_move_t(0, -1, test=True)
- down = self.p_move_t(0, 1, test=True)
- left = self.p_move_t(-1, 0, test=True)
- right = self.p_move_t(1, 0, test=True)
- global game_mode
- if up == down == left == right:
- game_mode = "game_over"
- p.mixer.music.stop()
- play_sound("timeup")
- for wall in self.level.walls:
- if wall.x == self.tx and wall.y == self.ty and not wall.spawning_timer:
- game_mode = "game_over"
- p.mixer.music.stop()
- play_sound("damage")
- def update(self):
- Entity.update(self)
- self.score.update()
- for package in self.packages:
- package.update()
- global game_mode
- for entity in entities:
- #print(self.tx, self.ty, projectile.tx, projectile.ty)
- if entity.tx == self.tx and entity.ty == self.ty:
- if type(entity) == Fire:
- game_mode = "game_over"
- p.mixer.music.stop()
- play_sound("damage")
- elif isinstance(entity,Pickup):
- entity.pickup()
- elif type(entity) == Package:
- game_mode = "game_over"
- p.mixer.music.stop()
- play_sound("damage")
- elif type(entity) == Exit:
- if self.packages:
- entity.give_packages(len(self.packages))
- package_multiplier = 1+((len(self.packages)-1)*0.5)
- self.score.multiplier = max(1,package_multiplier)
- if game_mode == "main":
- self.level.time -= 1
- if self.level.time <= 0:
- game_mode = "game_over"
- p.mixer.music.stop()
- play_sound("timeup")
- def p_move_t(self, ax, ay, test=False):
- if not self.packages or ((self.tx+ax, self.ty+ay) != (self.packages[0].tx, self.packages[0].ty)):
- if not test:
- self.move_log.insert(0,(self.tx, self.ty))
- while len(self.move_log) > self.level.width*self.level.height:
- del self.move_log[-1]
- ox, oy = self.tx, self.ty
- if not test:
- if self.check_projectile_collision():
- self.check_projectile_collision().die()
- tx, ty = self.move_t(ax, ay, self.action_speed, test=test)
- if not test:
- if self.check_projectile_collision():
- self.check_projectile_collision().die()
- if not test:
- if tx != ox or ty != oy:
- for package in self.packages:
- package.set_pos()
- else:
- del self.move_log[0]
- return tx, ty
- else:
- return self.tx, self.ty
- def p_move(self, ax, ay, test=False):
- nx, ny = self.move(ax, ay, self.action_speed, test=test)
- return nx, ny
- def draw(self, camera):
- #tile_rect = p.Rect(self.tx*self.level.tw, self.ty*self.level.th, self.level.tw, self.level.th)
- #camera.draw_transformed_rect(tile_rect, colour=GREEN)
- camera.draw_transformed_surface(self.surfaces[self.direction], self.rect)
- for package in self.packages:
- package.draw(camera)
- class Score():
- def __init__(self, starting_score):
- self.real_score = starting_score
- self.score = self.real_score
- self.score_changes = []
- self.new_score_change = True
- self.multiplier = 1
- def update(self):
- if self.score_changes:
- current_score_change = self.score_changes[0]
- if self.new_score_change:
- self.real_score += int(current_score_change[0]*current_score_change[3])
- self.new_score_change = False
- self.score += current_score_change[0]/current_score_change[2]*current_score_change[3]
- current_score_change[1] -= 1
- if current_score_change[1] <= 0:
- del self.score_changes[0]
- self.new_score_change = True
- else:
- self.new_score_change = True
- def change(self, amount, timer):
- self.score_changes.append([amount, timer, timer, self.multiplier])
- def draw(self, x, y):
- text = str(round(self.score))
- if self.score_changes:
- text += " +"+str(self.score_changes[0][0])
- rendered_text = score_font.render(text, True, BLACK)
- rendered_text_width = rendered_text.get_width()
- screen.blit(rendered_text, (x, y))
- if not self.score_changes:
- text = " x"+str(self.multiplier)
- if self.multiplier == 1:
- colour = BLACK
- else:
- colour = interpolate_colours(GREEN, RED, (1/5*(self.multiplier-1)))
- rendered_text = score_font.render(text, True, colour)
- screen.blit(rendered_text, (x+rendered_text_width, y))
- class Pickup(Entity):
- def __init__(self, level, x, y):
- Entity.__init__(self, level, x*level.tw, y*level.th, 1*level.tw, 1*level.th, False, spawning_timer=2)
- self.surface = p.image.load(gfx_dir+"pickup.png").convert()
- pickups.append(self)
- def update(self):
- Entity.update(self)
- def pickup(self):
- Package(player)
- entities.remove(self)
- pickups.remove(self)
- self.level.pickup_spawner.entity_count -= 1
- play_sound("pickup")
- def draw(self, camera):
- if self.spawning_timer:
- alpha = 64+(192/self.max_spawning_timer*(self.max_spawning_timer-self.spawning_timer))
- self.surface.set_alpha(alpha)
- else:
- self.surface.set_alpha(256)
- camera.draw_transformed_rect(self.rect, border=2, colour=GREEN)
- camera.draw_transformed_surface(self.surface, self.rect)
- class Fire(Entity):
- def __init__(self, level, x, y):
- Entity.__init__(self, level, x*level.tw, y*level.th, 1*level.tw, 1*level.th, False, spawning_timer=1)
- self.animation_speed = 1/60
- self.animation_progress = 0
- self.animation_frames = []
- for file in listdir(gfx_dir):
- if file.startswith("fire"):
- frame = p.image.load(gfx_dir+file).convert_alpha()
- self.animation_frames.append(frame)
- fires.append(self)
- def update(self):
- Entity.update(self)
- self.animation_progress = (self.animation_progress+self.animation_speed )%1
- def draw(self, camera):
- index = int(len(self.animation_frames)*self.animation_progress)
- frame = self.animation_frames[index]
- camera.draw_transformed_surface(frame, self.rect)
- class Projectile(Entity):
- def __init__(self, level, x, y, direction):
- Entity.__init__(self, level, x*level.tw, y*level.th, 1*level.tw, 1*level.th, False, collision_settings={"border":False, "tiles":False}, spawning_timer=1)
- self.action_speed = 15
- self.direction = direction
- if self.direction == "up":
- self.vx, self.vy = (0,-1)
- if self.direction == "down":
- self.vx, self.vy = (0,1)
- if self.direction == "left":
- self.vx, self.vy = (-1,0)
- if self.direction == "right":
- self.vx, self.vy = (1,0)
- self.surface = p.image.load(gfx_dir+"projectile_"+self.direction+".png").convert_alpha()
- projectiles.append(self)
- def update(self):
- Entity.update(self)
- remove_self = False
- if self.tx < -1 or self.ty < -1 or self.tx > self.level.width or self.ty > self.level.height:
- self.die()
- if self.tx == player.tx and self.ty == player.ty:
- self.die()
- play_sound("hit")
- def die(self):
- if self in projectiles:
- projectiles.remove(self)
- if self in entities:
- entities.remove(self)
- def update_turn(self):
- Entity.update_turn(self)
- self.update()
- self.p_move_t(self.vx, self.vy)
- self.update()
- def p_move_t(self, ax, ay, test=False):
- tx, ty = self.move_t(ax, ay, self.action_speed, test=test)
- return tx, ty
- def p_move(self, ax, ay, test=False):
- nx, ny = self.move_t(ax, ay, self.action_speed, test=test)
- def draw(self, camera):
- #tile_rect = p.Rect(self.tx*self.level.tw, self.ty*self.level.th, self.level.tw, self.level.th)
- #camera.draw_transformed_rect(tile_rect)
- camera.draw_transformed_surface(self.surface, self.rect)
- class Spawner():
- def __init__(self, level, max_timer, variance, max_entities=None):
- self.level = level
- self.max_timer = max_timer
- self.variance = variance
- self.reset_timer()
- self.entity_count = 0
- self.max_entities = max_entities
- self.level.spawners.append(self)
- def reset_timer(self):
- self.timer = self.max_timer+r.randint(int(self.variance/2), int(self.variance/2))
- def update_turn(self):
- self.timer -= 1
- if self.timer <= 0:
- self.reset_timer()
- if not self.max_entities or self.entity_count < self.max_entities:
- self.entity_count += 1
- self.spawn()
- def spawn(self):
- pass
- def interpolate_colours(colour1, colour2, amount):
- r1, g1, b1 = colour1
- r2, g2, b2 = colour2
- dr, dg, db = r2-r1, g2-g1, b2-b1
- r = max(min(int(r1+(dr*amount)),255),0)
- g = max(min(int(g1+(dg*amount)),255),0)
- b = max(min(int(b1+(db*amount)),255),0)
- return (r,g,b)
- class Exit(Entity):
- def __init__(self, level, x, y, requirement):
- Entity.__init__(self, level, x*level.tw, y*level.th, 1*level.tw, 1*level.th, False, collision_settings={"border":False, "tiles":False}, spawning_timer=0)
- self.animation_speed = 1/60
- self.animation_progress = 0
- self.animation_frames = []
- for file in listdir(gfx_dir):
- if file.startswith("exit"):
- frame = p.image.load(gfx_dir+file).convert_alpha()
- self.animation_frames.append(frame)
- self.requirement = requirement
- self.packages = 0
- self.requirement_text = None
- def give_packages(self, amount):
- self.packages += amount
- for i in range(amount):
- package = player.packages[0]
- player.packages.remove(package)
- entities.remove(package)
- player.score.change(100, 15)
- if self.packages >= self.requirement:
- time_bonus = int(self.level.time/2)
- self.level.level += 1
- self.level.create(self.level.level)
- player.score.multiplier = 1
- player.score.change(time_bonus, 45)
- play_sound("complete")
- else:
- play_sound("give_package")
- def set_requirement_text(self):
- total_packages = self.packages+len(player.packages)
- if player.packages:
- text = str(self.packages)+" +["+str(len(player.packages))+"] / "+str(self.requirement)
- else:
- text = str(self.packages)+" / "+str(self.requirement)
- if total_packages <= self.requirement:
- colour = interpolate_colours(RED, GREEN, total_packages/self.requirement)
- else:
- colour = BLUE
- self.requirement_text = requirement_font.render(text, True, colour)
- self.requirement_rect = self.requirement_text.get_rect()
- self.requirement_rect.center = self.rect.center
- self.requirement_rect.centery -= self.level.th
- def update_turn(self):
- self.set_requirement_text()
- def update(self):
- Entity.update(self)
- self.animation_progress = (self.animation_progress+self.animation_speed )%1
- def draw(self, camera):
- if not self.requirement_text:
- self.set_requirement_text()
- index = int(len(self.animation_frames)*self.animation_progress)
- frame = self.animation_frames[index]
- camera.draw_transformed_surface(frame, self.rect)
- camera.draw_transformed_surface(self.requirement_text, self.requirement_rect)
- class Projectile_Spawner(Spawner):
- def __init__(self, level, max_timer, variance):
- Spawner.__init__(self, level, max_timer, variance)
- def spawn(self):
- Spawner.spawn(self)
- sides = ("top", "bottom", "left", "right")
- side = r.choice(sides)
- if side == "top":
- x = r.randint(0,self.level.width-1)
- y = -1
- if side == "bottom":
- x = r.randint(0,self.level.width-1)
- y = self.level.height
- if side == "left":
- x = -1
- y = r.randint(0,self.level.height-1)
- if side == "right":
- x = self.level.width
- y = r.randint(0,self.level.height-1)
- direction = ("down", "up", "right", "left")[sides.index(side)]
- Projectile(self.level, x, y, direction)
- class Fire_Spawner(Spawner):
- def __init__(self, level, max_timer, variance, max_entities=None):
- Spawner.__init__(self, level, max_timer, variance, max_entities=max_entities)
- def spawn(self):
- Spawner.spawn(self)
- spawn_entity_in_blank_space(level, Fire)
- class Pickup_Spawner(Spawner):
- def __init__(self, level, max_timer, variance, max_entities=None):
- Spawner.__init__(self, level, max_timer, variance, max_entities=max_entities)
- def spawn(self):
- Spawner.spawn(self)
- spawn_entity_in_blank_space(level, Pickup)
- class Wall_Spawner(Spawner):
- def __init__(self, level, max_timer, variance, max_entities=None):
- Spawner.__init__(self, level, max_timer, variance, max_entities=max_entities)
- def spawn(self):
- Spawner.spawn(self)
- blank_space = find_blank_space(level)
- if blank_space != False:
- x, y = blank_space
- level.tiles[x][y] = Tile(level, "wall", x, y)
- def find_blank_space(level, border=False):
- valid = False
- attempts = 0
- max_attempts = 10
- while not valid and attempts < max_attempts:
- attempts += 1
- valid = True
- if border:
- x, y = r.randint(0,level.width-1), r.randint(0,level.width-1)
- else:
- x, y = r.randint(1,level.width-2), r.randint(1,level.width-2)
- for entity in entities:
- if x == entity.tx and y == entity.ty:
- valid = False
- if level.tiles[x][y].solid:
- valid = False
- if attempts < max_attempts:
- return x, y
- else:
- return False
- def spawn_entity_in_blank_space(level, spawn_entity):
- blank_space = find_blank_space(level)
- if blank_space != False:
- x, y = blank_space
- return spawn_entity(level, x, y)
- return False
- def reset():
- global player, level, camera
- entities.clear()
- projectiles.clear()
- actions.clear()
- pickups.clear()
- fires.clear()
- camera = Camera(p.Rect(0,0,100,100))
- player = None
- level = Level(32, 32)
- level.pickup_spawner.spawn()
- player = Player(level, 5,6)
- def handle_input():
- global game_mode
- for event in p.event.get():
- if event.type == p.KEYDOWN:
- if game_mode == "main":
- if event.key == p.K_ESCAPE:
- global paused
- paused = not paused
- elif not paused:
- if event.key in [p.K_w, p.K_s, p.K_a, p.K_d, p.K_SPACE]:
- update_turn()
- #if event.key == p.K_q:
- # camera.rect.inflate_ip((-100,-100))
- #elif event.key == p.K_z:
- # camera.rect.inflate_ip((100,100))
- if event.key == p.K_w:
- player.p_move_t(0,-1)
- player.direction = "up"
- elif event.key == p.K_s:
- player.p_move_t(0,1)
- player.direction = "down"
- elif event.key == p.K_a:
- player.p_move_t(-1,0)
- player.direction = "left"
- elif event.key == p.K_d:
- player.p_move_t(1,0)
- player.direction = "right"
- elif event.key == p.K_m:
- global music_playing
- if music_playing:
- p.mixer.music.pause()
- else:
- p.mixer.music.unpause()
- music_playing = not music_playing
- elif game_mode == "start":
- reset()
- game_mode = "main"
- p.mixer.music.play(-1)
- if not music_playing:
- p.mixer.music.pause()
- elif game_mode == "game_over":
- game_mode = "start"
- if event.type == p.QUIT:
- p.display.quit()
- exit()
- quit()
- def update_turn():
- if game_mode == "main":
- global turn_length, turn_colour_intensity
- turn_length = min(turn_length, 1*MAX_TICK_RATE)
- turn_length_log.insert(0,turn_length)
- turn_length = 0
- while len(turn_length_log) > 8:
- del turn_length_log[-1]
- turn_colour_intensity = 1- ( sum(turn_length_log)/(MAX_TICK_RATE*len(turn_length_log)) )
- while actions:
- for action in actions:
- action.update()
- action.entity.update()
- player.update_turn()
- for package in player.packages:
- package.update_turn()
- for projectile in projectiles:
- projectile.update_turn()
- for wall in level.walls:
- if wall.spawning_timer:
- if player.tx != wall.x or player.ty != wall.y:
- wall.spawning_timer -= 1
- for pickup in pickups:
- pickup.update_turn()
- level.exit.update_turn()
- for spawner in level.spawners:
- spawner.update_turn()
- def update():
- if game_mode == "main" and not paused:
- global turn_length, turn_colour_intensity, background_colour
- camera.update()
- for action in actions:
- action.update()
- for entity in entities:
- entity.update()
- turn_length += 1
- if turn_colour_intensity > 0:
- turn_colour_intensity -= 0.01
- background_colour = interpolate_colours(BLUE, RED, turn_colour_intensity)
- def draw():
- if game_mode == "main":
- level.draw(camera)
- for fire in fires:
- fire.draw(camera)
- for pickup in pickups:
- pickup.draw(camera)
- for projectile in projectiles:
- projectile.draw(camera)
- player.draw(camera)
- level.exit.draw(camera)
- player.score.draw(0,0)
- rendered_level_text = level_font.render("Level "+str(level.level), True, WHITE)
- rendered_level_text_rect = rendered_level_text.get_rect()
- rendered_level_text_rect.topright = (WIDTH,0)
- screen.blit(rendered_level_text, rendered_level_text_rect)
- if level.time <= 10*MAX_TICK_RATE:
- colour = RED
- elif level.time <= 15*MAX_TICK_RATE:
- colour = ORANGE
- elif level.time <= 20*MAX_TICK_RATE:
- colour = YELLOW
- else:
- colour = GREEN
- rendered_time_text = time_font.render("Time: "+str(round(level.time/MAX_TICK_RATE,1))+"s", True, colour)
- rendered_time_text_rect = rendered_time_text.get_rect()
- rendered_time_text_rect.midtop = (int(WIDTH/2), 0)
- screen.blit(rendered_time_text, rendered_time_text_rect)
- if paused:
- screen.blit(pause_popup, pause_popup_rect)
- elif game_mode == "start":
- screen.blit(screen_start, (0,0))
- elif game_mode == "game_over":
- screen.blit(game_over_start, (0,0))
- rendered_score_text = game_over_score_font.render("Score:"+str(player.score.real_score), True, BLACK)
- rendered_level_text = game_over_score_font.render("Level "+str(level.level), True, BLACK)
- rendered_score_text_rect = rendered_score_text.get_rect()
- rendered_level_text_rect = rendered_level_text.get_rect()
- rendered_score_text_rect.center = (0.5*WIDTH, 0.4*HEIGHT)
- rendered_level_text_rect.center = (0.5*WIDTH, 0.8*HEIGHT)
- screen.blit(rendered_score_text, rendered_score_text_rect)
- screen.blit(rendered_level_text, rendered_level_text_rect)
- RUNNING = True
- while RUNNING:
- screen.fill(background_colour)
- handle_input()
- update()
- draw()
- p.display.flip()
- game_clock.tick(MAX_TICK_RATE)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement