Advertisement
Guest User

Untitled

a guest
Oct 6th, 2019
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 35.62 KB | None | 0 0
  1. import pygame as p
  2. import random as r
  3. from os import listdir
  4. from math import ceil
  5.  
  6. RED = (255,0,0)
  7. GREEN = (0,255,0)
  8. BLUE = (0,0,255)
  9. WHITE = (255,255,255)
  10. BLACK = (0,0,0)
  11. YELLOW = (255, 255, 0)
  12. ORANGE = (255,165,0)
  13. background_colour = BLUE
  14.  
  15. main_dir = ""
  16. gfx_dir = main_dir+"gfx/"
  17. sound_dir = main_dir+"sound/"
  18. data_dir = main_dir+"data/"
  19.  
  20. p.init()
  21. p.font.init()
  22. p.mixer.init()
  23.  
  24. WIDTH, HEIGHT = 700, 700
  25. screen = p.display.set_mode((WIDTH, HEIGHT))
  26.  
  27. entities = []
  28. pickups = []
  29. projectiles = []
  30. actions = []
  31. fires = []
  32.  
  33. game_mode = "start"
  34.  
  35. screen_start = p.transform.scale(p.image.load(gfx_dir+"screen_start.png").convert(), (WIDTH, HEIGHT))
  36. game_over_start = p.transform.scale(p.image.load(gfx_dir+"screen_game_over.png").convert(), (WIDTH, HEIGHT))
  37. pause_popup = p.image.load(gfx_dir+"pause_popup.png").convert_alpha()
  38. pause_popup_rect = pause_popup.get_rect()
  39. pause_popup_rect.center = (int(WIDTH/2), int(HEIGHT/2))
  40.  
  41. requirement_font = p.font.SysFont("Arial", 30)
  42. score_font = p.font.SysFont("Calibri", 60)
  43. score_font.set_underline(True)
  44. level_font = p.font.SysFont("Consolas", 60)
  45. time_font = p.font.SysFont("Consolas", 30)
  46.  
  47. game_over_score_font = p.font.SysFont("Arial", 100)
  48. game_over_level_font = p.font.SysFont("Arial", 100)
  49.  
  50. game_clock = p.time.Clock()
  51. MAX_TICK_RATE = 60
  52.  
  53. turn_length_log = []
  54. turn_length = 0
  55. turn_colour_intensity = 0
  56.  
  57. p.mixer.music.load(sound_dir+"main_music.ogg")
  58.  
  59. music_playing = False
  60. paused = False
  61.  
  62. p.display.set_icon(p.image.load(gfx_dir+"icon.png"))
  63. if r.randint(1,5) == 1:
  64.     p.display.set_caption("pan fried")
  65. else:
  66.     p.display.set_caption("Panic Shift")
  67.  
  68. sound_dict = {}
  69. for file in listdir(sound_dir):
  70.     name = file[:-4]
  71.     sound_object = p.mixer.Sound(sound_dir+file)
  72.     sound_dict.update({name:sound_object})
  73.  
  74. def play_sound(name):
  75.     sound_dict[name].play()
  76.  
  77. class Camera():
  78.     def __init__(self, rect):
  79.         self.rect = rect
  80.         self.set_scale()
  81.  
  82.     def set_scale(self):
  83.         self.scale_x = WIDTH/self.rect.w
  84.         self.scale_y = HEIGHT/self.rect.h
  85.  
  86.     def update(self):
  87.         self.set_scale()
  88.  
  89.     def reverse_transform_point(self, point):
  90.         x, y = point
  91.         x = (x/self.scale_x)+self.rect.x
  92.         y = (y/self.scale_y)+self.rect.y
  93.  
  94.         return x, y
  95.  
  96.     def reverse_transform_rect(self, rect):
  97.         x, y = self.reverse_transform_point(rect.topleft)
  98.         w = (rect.w)/self.scale_x
  99.         h = (rect.h)/self.scale_y
  100.         new_rect = p.Rect([x,y,w,h])
  101.         return new_rect
  102.  
  103.     def transform_point(self, point):
  104.         x, y = point
  105.         x = (x-self.rect.x)*self.scale_x
  106.         y = (y-self.rect.y)*self.scale_y
  107.         #x += (WIDTH/2)
  108.         #y += (HEIGHT/2)
  109.         return x, y
  110.  
  111.     def transform_rect(self, rect):
  112.         x, y = self.transform_point(rect.topleft)
  113.         w = (rect.w)*self.scale_x
  114.         h = (rect.h)*self.scale_y
  115.         new_rect = p.Rect([x,y,w,h])
  116.         return new_rect
  117.  
  118.     def draw_transformed_surface(self, surface, rect):
  119.         transformed_rect = self.transform_rect(rect)
  120.         x, y = transformed_rect.topleft
  121.         w = transformed_rect.w+2
  122.         h = transformed_rect.h+2
  123.         surface = p.transform.scale(surface, (w,h))
  124.         screen.blit(surface, (x,y))
  125.  
  126.     def draw_transformed_rect(self, rect, colour=RED, border=0):
  127.         transformed_rect = self.transform_rect(rect)
  128.  
  129.         if border:
  130.             border *= ceil((self.scale_x+self.scale_y)/2)
  131.         p.draw.rect(screen, colour, transformed_rect, border)
  132.  
  133. class Tile():
  134.     def __init__(self, level, tile_type, x, y):
  135.         self.level = level
  136.         self.tile_type = tile_type
  137.         self.x = x
  138.         self.y = y
  139.  
  140.         self.rect = p.Rect(self.x, self.y, 1, 1)
  141.        
  142.         self.rx = self.x*self.level.tw
  143.         self.ry = self.y*self.level.th
  144.         self.real_rect = p.Rect(self.rx, self.ry, self.level.tw, self.level.th)
  145.  
  146.         self.surface = p.image.load(gfx_dir+"tile_"+self.tile_type+".png").convert()
  147.  
  148.         self.spawning_timer = 0
  149.  
  150.         self.solid = False
  151.         if self.tile_type == "wall":
  152.             self.solid = True
  153.             self.max_spawning_timer = 5
  154.             self.spawning_timer = self.max_spawning_timer
  155.            
  156.             self.level.walls.append(self)
  157.  
  158.     def draw(self, camera):
  159.         if self.spawning_timer:
  160.             self.surface.set_alpha(0+(256/self.max_spawning_timer*(self.max_spawning_timer-self.spawning_timer)))
  161.         else:
  162.             self.surface.set_alpha(256)
  163.  
  164.         if self.solid:
  165.             camera.draw_transformed_rect(self.real_rect, border=2)
  166.         camera.draw_transformed_surface(self.surface, self.real_rect)
  167.        
  168.  
  169. class Level():
  170.     def __init__(self, tw, th):
  171.         self.tw = tw
  172.         self.th = th
  173.  
  174.         self.tiles = []
  175.         self.spawners = []
  176.         self.walls = []
  177.         self.exit = None
  178.  
  179.         self.level = 1
  180.         self.create(self.level)
  181.        
  182.  
  183.     def create(self, difficulty):
  184.         difficulty -= 1
  185.         self.width = 10+min(difficulty,12)
  186.         self.height = 10+min(difficulty,12)
  187.  
  188.         if difficulty == 0:
  189.             self.time = 60*MAX_TICK_RATE
  190.         elif difficulty < 4:
  191.             self.time = (40)*MAX_TICK_RATE
  192.         else:
  193.             self.time = (40+(5*difficulty))*MAX_TICK_RATE
  194.        
  195.         self.rect = p.Rect(0, 0, self.width, self.height)
  196.         self.real_rect = p.Rect(0, 0, self.width*self.tw, self.height*self.th)
  197.  
  198.         self.tiles.clear()
  199.         self.walls.clear()
  200.         for pickup in pickups.copy():
  201.             pickups.remove(pickup)
  202.             entities.remove(pickup)
  203.            
  204.         for x in range(self.width):
  205.             self.tiles.append([])
  206.             for y in range(self.height):
  207.                 tile = Tile(self, "floor", x, y)
  208.                 self.tiles[-1].append(tile)
  209.  
  210.         self.spawners.clear()
  211.         if self.exit:
  212.             entities.remove(self.exit)
  213.  
  214.         projectile_timer = 10-min(difficulty*2,8)
  215.         self.projectile_spawner = Projectile_Spawner(self, projectile_timer, 3)
  216.         if difficulty > 3:
  217.             self.second_projectile_spawner = Projectile_Spawner(self, projectile_timer, 3)
  218.         if difficulty > 7:
  219.             self.third_projectile_spawner = Projectile_Spawner(self, int(projectile_timer*3), 3)
  220.  
  221.         pickup_timer = 10+min(difficulty,8)
  222.         self.pickup_spawner = Pickup_Spawner(self, 10, 3, max_entities=5)
  223.  
  224.         wall_timer = 15-min(difficulty*2,12)
  225.        
  226.         if difficulty > 4:
  227.             self.wall_spawner = Wall_Spawner(self, wall_timer, 3, max_entities=int(self.width*self.height/6))
  228.             self.second_wall_spawner = Wall_Spawner(self, wall_timer, 3, max_entities=int(self.width*self.height/6))
  229.         else:
  230.             self.wall_spawner = Wall_Spawner(self, wall_timer, 3, max_entities=int(self.width*self.height/4))
  231.            
  232.         camera.rect = self.real_rect.copy().inflate((self.tw*2, self.th*2))
  233.  
  234.         self.exit = Exit(self, int(self.width/2), int(self.height/2), 4+min(difficulty,60))
  235.         if player:
  236.             player.x, player.y = int(self.width/2)*self.tw, (int(self.height/2)+1)*self.th
  237.  
  238.     def draw(self, camera):
  239.         for tile_strip in self.tiles:
  240.             for tile in tile_strip:
  241.                 tile.draw(camera)
  242.  
  243. class Action():
  244.     def __init__(self, entity, timer):
  245.         self.entity = entity
  246.        
  247.         self.max_timer = timer
  248.         self.timer = self.max_timer
  249.  
  250.         actions.append(self)
  251.         entity.actions.append(self)
  252.  
  253.     def update(self):
  254.         self.timer -= 1
  255.         if self.timer <= 0:
  256.             actions.remove(self)
  257.             self.entity.actions.remove(self)
  258.  
  259. class Move_Action(Action):
  260.     def __init__(self, entity, timer, x, y):
  261.  
  262.         Action.__init__(self, entity, timer)
  263.         self.x = x
  264.         self.y = y
  265.  
  266.     def update(self):
  267.         Action.update(self)
  268.         self.entity.x = self.entity.x+((self.x-self.entity.x)/self.max_timer*(self.max_timer-self.timer))
  269.         self.entity.y = self.entity.y+((self.y-self.entity.y)/self.max_timer*(self.max_timer-self.timer))
  270.        
  271.        
  272.  
  273. class Entity():
  274.     def __init__(self, level, x, y, width, height, solid, collision_settings={}, spawning_timer=1):
  275.         self.level = level
  276.         self.x = x
  277.         self.y = y
  278.         self.tx, self.ty = int(self.x/self.level.tw), int(self.y/self.level.th)
  279.         self.width = width
  280.         self.height = height
  281.         self.rect = p.Rect(self.x, self.y, self.width, self.height)
  282.  
  283.         self.solid = solid
  284.  
  285.         self.collision_settings = {"tiles":True, "entities":True, "border":True}
  286.         self.collision_settings.update(collision_settings)
  287.  
  288.         self.actions = []
  289.  
  290.         self.max_spawning_timer = spawning_timer
  291.         self.spawning_timer = self.max_spawning_timer
  292.  
  293.         entities.append(self)
  294.  
  295.     def check_projectile_collision(self):
  296.         for projectile in projectiles:
  297.             if projectile != self:
  298.                 if self.tx == projectile.tx and self.ty == projectile.ty:
  299.                     return projectile
  300.         return False
  301.  
  302.     def set_rect(self):
  303.         self.rect = p.Rect(self.x, self.y, self.width, self.height)
  304.  
  305.     def update(self):
  306.         self.set_rect()
  307.  
  308.     def update_turn(self):
  309.         if self.spawning_timer:
  310.             self.spawning_timer -= 1
  311.  
  312.  
  313.     def move(self, ax, ay, timer, test=False):
  314.         if not ax and not ay:
  315.             return
  316.        
  317.         steps = ceil(max(abs(ax), abs(ay)))
  318.         dx = ax/steps
  319.         dy = ay/steps
  320.  
  321.         nx, ny = 0,0
  322.         for step in range(steps):
  323.             if not self.check_collision(nx+dx, 0):
  324.                 nx += dx
  325.             if not self.check_collision(0, ny+dy):
  326.                 ny += dy
  327.  
  328.         if not test:
  329.             Move_Action(self, timer, self.x+nx, self.y+ny)
  330.             self.tx += int(nx/self.level.tw)
  331.             self.ty += int(ny/self.level.th)
  332.            
  333.         return self.x+nx, self.y+ny
  334.  
  335.     def move_t(self, ax, ay, timer, test=False):
  336.         nx, ny = self.move(ax*self.level.tw, ay*self.level.th, timer, test=test)
  337.         tx, ty = int(nx/self.level.tw), int(ny/self.level.th)
  338.         return tx, ty
  339.    
  340.     def check_collision(self, ax, ay):
  341.         nx = self.x+ax
  342.         ny = self.y+ay
  343.         check_rect = p.Rect(nx, ny, self.width, self.height)
  344.        
  345.         sx = max(min(int(nx/self.level.tw)-1, self.level.width),0)
  346.         sy = max(min(int(ny/self.level.th)-1, self.level.height),0)
  347.         ex = max(min(sx+int(self.width/self.level.tw)+2, self.level.width),0)
  348.         ey = max(min(sy+int(self.height/self.level.th)+2, self.level.height),0)
  349.  
  350.         if self.collision_settings["tiles"]:
  351.             for x in range(sx, ex):
  352.                 for y in range(sy, ey):
  353.                     tile = self.level.tiles[x][y]
  354.                    
  355.                     #if tile.solid:
  356.                     #    print(tile.real_rect, check_rect)
  357.                     #    camera.draw_transformed_rect(tile.real_rect, BLUE)
  358.                     #    p.display.flip()
  359.                     if tile.solid and tile.real_rect.colliderect(check_rect) and not tile.spawning_timer:
  360.                         #print("collided tile")
  361.                         return tile
  362.  
  363.         if self.collision_settings["entities"]:
  364.             for entity in entities:
  365.                 if entity != self:
  366.                     if entity.solid and entity.rect.colliderect(check_rect):
  367.                         return entity
  368.  
  369.         if self.collision_settings["border"]:
  370.             if not self.level.real_rect.contains(check_rect):
  371.                 return "border"
  372.  
  373.        
  374.         return False
  375.  
  376. class Package(Entity):
  377.     def __init__(self, player):
  378.         self.player = player
  379.         Entity.__init__(self, self.player.level, 0, 0, 1*self.player.level.tw, 1*self.player.level.th, False, spawning_timer=0)
  380.        
  381.         self.surface = p.image.load(gfx_dir+"package.png").convert_alpha()
  382.  
  383.         old_package_count = len(self.player.packages)
  384.         self.player.packages.append(self)
  385.  
  386.         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:
  387.             play_sound("ready")
  388.        
  389.  
  390.         self.index = self.player.packages.index(self)
  391.        
  392.         self.tx, self.ty = self.player.move_log[self.index]
  393.         self.x = self.tx*self.player.level.tw
  394.         self.y = self.ty*self.player.level.th
  395.  
  396.         self.width = self.player.level.tw
  397.         self.height = self.player.level.th
  398.  
  399.         self.actions = []
  400.  
  401.         self.set_rect()
  402.  
  403.     def update_turn(self):
  404.         Entity.update_turn(self)
  405.  
  406.     def set_pos(self):
  407.         self.tx, self.ty = self.player.move_log[self.index]
  408.         Move_Action(self, self.player.action_speed, (self.tx*self.player.level.tw), (self.ty*self.player.level.th))
  409.  
  410.     def set_rect(self):
  411.         self.rect = p.Rect(self.x, self.y, self.width, self.height)
  412.  
  413.     def update(self):
  414.         self.tx = int(self.x/self.player.level.tw)
  415.         self.ty = int(self.y/self.player.level.th)
  416.  
  417.         self.set_rect()
  418.  
  419.         global game_mode
  420.         if self.check_projectile_collision():
  421.             game_mode = "game_over"
  422.             p.mixer.music.stop()
  423.             play_sound("damage")
  424.  
  425.     def draw(self, camera):
  426.         camera.draw_transformed_surface(self.surface, self.rect)
  427.         #rect = p.Rect(self.tx*self.player.level.tw, self.ty*self.player.level.th, self.player.level.tw, self.player.level.th)
  428.         #camera.draw_transformed_rect(rect)
  429.  
  430.        
  431. class Player(Entity):
  432.     def __init__(self, level, x, y):
  433.         Entity.__init__(self, level, x*level.tw, y*level.th, 1*level.tw, 1*level.th, False)
  434.  
  435.         self.action_speed = 15
  436.  
  437.         self.surfaces = {
  438.             "up":p.image.load(gfx_dir+"player_up.png").convert_alpha(),
  439.             "down":p.image.load(gfx_dir+"player_down.png").convert_alpha(),
  440.             "left":p.image.load(gfx_dir+"player_left.png").convert_alpha(),
  441.             "right":p.image.load(gfx_dir+"player_right.png").convert_alpha(),
  442.             }
  443.  
  444.         self.direction = "up"
  445.  
  446.         self.packages = []
  447.  
  448.         self.move_log = [(self.tx, self.ty)]
  449.  
  450.         self.score = Score(0)
  451.  
  452.     def update_turn(self):
  453.         Entity.update_turn(self)
  454.         up = self.p_move_t(0, -1, test=True)
  455.         down = self.p_move_t(0, 1, test=True)
  456.         left = self.p_move_t(-1, 0, test=True)
  457.         right = self.p_move_t(1, 0, test=True)
  458.  
  459.         global game_mode
  460.         if up == down == left == right:
  461.             game_mode = "game_over"
  462.             p.mixer.music.stop()
  463.             play_sound("timeup")
  464.  
  465.         for wall in self.level.walls:
  466.             if wall.x == self.tx and wall.y == self.ty and not wall.spawning_timer:
  467.                 game_mode = "game_over"
  468.                 p.mixer.music.stop()
  469.                 play_sound("damage")
  470.  
  471.     def update(self):
  472.         Entity.update(self)
  473.         self.score.update()
  474.  
  475.         for package in self.packages:
  476.             package.update()
  477.  
  478.         global game_mode
  479.         for entity in entities:
  480.             #print(self.tx, self.ty, projectile.tx, projectile.ty)
  481.             if entity.tx == self.tx and entity.ty == self.ty:  
  482.                 if type(entity) == Fire:
  483.                         game_mode = "game_over"
  484.                         p.mixer.music.stop()
  485.                         play_sound("damage")
  486.                        
  487.                 elif isinstance(entity,Pickup):
  488.                     entity.pickup()
  489.  
  490.                 elif type(entity) == Package:
  491.                     game_mode = "game_over"
  492.                     p.mixer.music.stop()
  493.                     play_sound("damage")
  494.  
  495.                 elif type(entity) == Exit:
  496.                     if self.packages:
  497.                         entity.give_packages(len(self.packages))
  498.  
  499.         package_multiplier = 1+((len(self.packages)-1)*0.5)
  500.         self.score.multiplier = max(1,package_multiplier)
  501.  
  502.         if game_mode == "main":
  503.             self.level.time -= 1
  504.             if self.level.time <= 0:
  505.                 game_mode = "game_over"
  506.                 p.mixer.music.stop()
  507.                 play_sound("timeup")
  508.  
  509.  
  510.     def p_move_t(self, ax, ay, test=False):
  511.         if not self.packages or ((self.tx+ax, self.ty+ay) != (self.packages[0].tx, self.packages[0].ty)):
  512.  
  513.             if not test:
  514.                 self.move_log.insert(0,(self.tx, self.ty))
  515.                 while len(self.move_log) > self.level.width*self.level.height:
  516.                     del self.move_log[-1]
  517.            
  518.             ox, oy = self.tx, self.ty
  519.  
  520.             if not test:
  521.                 if self.check_projectile_collision():
  522.                    self.check_projectile_collision().die()
  523.                    
  524.             tx, ty = self.move_t(ax, ay, self.action_speed, test=test)
  525.  
  526.             if not test:
  527.                 if self.check_projectile_collision():
  528.                    self.check_projectile_collision().die()
  529.  
  530.             if not test:
  531.                 if tx != ox or ty != oy:
  532.                     for package in self.packages:
  533.                         package.set_pos()
  534.                 else:
  535.                     del self.move_log[0]
  536.  
  537.             return tx, ty
  538.  
  539.         else:
  540.             return self.tx, self.ty
  541.  
  542.     def p_move(self, ax, ay, test=False):
  543.         nx, ny = self.move(ax, ay, self.action_speed, test=test)
  544.         return nx, ny
  545.  
  546.     def draw(self, camera):
  547.         #tile_rect = p.Rect(self.tx*self.level.tw, self.ty*self.level.th, self.level.tw, self.level.th)
  548.         #camera.draw_transformed_rect(tile_rect, colour=GREEN)
  549.        
  550.         camera.draw_transformed_surface(self.surfaces[self.direction], self.rect)
  551.         for package in self.packages:
  552.             package.draw(camera)
  553.  
  554. class Score():
  555.     def __init__(self, starting_score):
  556.         self.real_score = starting_score
  557.         self.score = self.real_score
  558.  
  559.         self.score_changes = []
  560.         self.new_score_change = True
  561.  
  562.         self.multiplier = 1
  563.  
  564.     def update(self):
  565.         if self.score_changes:
  566.             current_score_change = self.score_changes[0]
  567.            
  568.             if self.new_score_change:
  569.                 self.real_score += int(current_score_change[0]*current_score_change[3])
  570.                 self.new_score_change = False
  571.            
  572.             self.score += current_score_change[0]/current_score_change[2]*current_score_change[3]
  573.             current_score_change[1] -= 1            
  574.             if current_score_change[1] <= 0:
  575.                 del self.score_changes[0]
  576.                 self.new_score_change = True
  577.            
  578.         else:
  579.             self.new_score_change = True
  580.  
  581.     def change(self, amount, timer):
  582.         self.score_changes.append([amount, timer, timer, self.multiplier])
  583.  
  584.     def draw(self, x, y):
  585.         text = str(round(self.score))
  586.         if self.score_changes:
  587.             text += " +"+str(self.score_changes[0][0])
  588.  
  589.        
  590.  
  591.        
  592.  
  593.         rendered_text = score_font.render(text, True, BLACK)
  594.         rendered_text_width = rendered_text.get_width()
  595.        
  596.         screen.blit(rendered_text, (x, y))
  597.  
  598.         if not self.score_changes:
  599.             text = " x"+str(self.multiplier)
  600.             if self.multiplier == 1:
  601.                 colour = BLACK
  602.             else:
  603.                 colour = interpolate_colours(GREEN, RED, (1/5*(self.multiplier-1)))
  604.  
  605.             rendered_text = score_font.render(text, True, colour)
  606.             screen.blit(rendered_text, (x+rendered_text_width, y))
  607.        
  608.    
  609. class Pickup(Entity):
  610.     def __init__(self, level, x, y):
  611.         Entity.__init__(self, level, x*level.tw, y*level.th, 1*level.tw, 1*level.th, False, spawning_timer=2)
  612.         self.surface = p.image.load(gfx_dir+"pickup.png").convert()
  613.  
  614.         pickups.append(self)
  615.  
  616.     def update(self):
  617.         Entity.update(self)
  618.  
  619.     def pickup(self):
  620.         Package(player)
  621.         entities.remove(self)
  622.         pickups.remove(self)
  623.         self.level.pickup_spawner.entity_count -= 1
  624.         play_sound("pickup")
  625.  
  626.     def draw(self, camera):
  627.         if self.spawning_timer:
  628.             alpha = 64+(192/self.max_spawning_timer*(self.max_spawning_timer-self.spawning_timer))
  629.             self.surface.set_alpha(alpha)  
  630.         else:
  631.             self.surface.set_alpha(256)
  632.  
  633.         camera.draw_transformed_rect(self.rect, border=2, colour=GREEN)
  634.         camera.draw_transformed_surface(self.surface, self.rect)
  635.  
  636. class Fire(Entity):
  637.     def __init__(self, level, x, y):
  638.         Entity.__init__(self, level, x*level.tw, y*level.th, 1*level.tw, 1*level.th, False, spawning_timer=1)
  639.  
  640.         self.animation_speed = 1/60
  641.         self.animation_progress = 0
  642.  
  643.         self.animation_frames = []
  644.         for file in listdir(gfx_dir):
  645.             if file.startswith("fire"):
  646.                 frame = p.image.load(gfx_dir+file).convert_alpha()
  647.                 self.animation_frames.append(frame)
  648.  
  649.         fires.append(self)
  650.  
  651.     def update(self):
  652.         Entity.update(self)
  653.         self.animation_progress = (self.animation_progress+self.animation_speed )%1
  654.  
  655.     def draw(self, camera):
  656.         index = int(len(self.animation_frames)*self.animation_progress)
  657.         frame = self.animation_frames[index]
  658.  
  659.         camera.draw_transformed_surface(frame, self.rect)
  660.  
  661. class Projectile(Entity):
  662.     def __init__(self, level, x, y, direction):
  663.         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)
  664.         self.action_speed = 15
  665.  
  666.         self.direction = direction
  667.         if self.direction == "up":
  668.             self.vx, self.vy = (0,-1)
  669.         if self.direction == "down":
  670.             self.vx, self.vy = (0,1)
  671.         if self.direction == "left":
  672.             self.vx, self.vy = (-1,0)
  673.         if self.direction == "right":
  674.             self.vx, self.vy = (1,0)
  675.  
  676.         self.surface = p.image.load(gfx_dir+"projectile_"+self.direction+".png").convert_alpha()
  677.  
  678.         projectiles.append(self)
  679.  
  680.     def update(self):
  681.         Entity.update(self)
  682.         remove_self = False
  683.         if self.tx < -1 or self.ty < -1 or self.tx > self.level.width or self.ty > self.level.height:
  684.             self.die()
  685.  
  686.         if self.tx == player.tx and self.ty == player.ty:
  687.             self.die()
  688.             play_sound("hit")
  689.  
  690.     def die(self):
  691.         if self in projectiles:
  692.             projectiles.remove(self)
  693.         if self in entities:
  694.             entities.remove(self)
  695.  
  696.     def update_turn(self):
  697.         Entity.update_turn(self)
  698.         self.update()
  699.         self.p_move_t(self.vx, self.vy)
  700.         self.update()
  701.  
  702.     def p_move_t(self, ax, ay, test=False):
  703.         tx, ty = self.move_t(ax, ay, self.action_speed, test=test)
  704.         return tx, ty
  705.  
  706.     def p_move(self, ax, ay, test=False):
  707.         nx, ny = self.move_t(ax, ay, self.action_speed, test=test)
  708.  
  709.     def draw(self, camera):
  710.         #tile_rect = p.Rect(self.tx*self.level.tw, self.ty*self.level.th, self.level.tw, self.level.th)
  711.         #camera.draw_transformed_rect(tile_rect)
  712.         camera.draw_transformed_surface(self.surface, self.rect)
  713.  
  714. class Spawner():
  715.     def __init__(self, level, max_timer, variance, max_entities=None):
  716.         self.level = level
  717.         self.max_timer = max_timer
  718.         self.variance = variance
  719.         self.reset_timer()
  720.  
  721.         self.entity_count = 0
  722.         self.max_entities = max_entities
  723.  
  724.         self.level.spawners.append(self)
  725.  
  726.     def reset_timer(self):
  727.         self.timer = self.max_timer+r.randint(int(self.variance/2), int(self.variance/2))
  728.  
  729.     def update_turn(self):
  730.         self.timer -= 1
  731.         if self.timer <= 0:
  732.             self.reset_timer()
  733.             if not self.max_entities or self.entity_count < self.max_entities:
  734.                 self.entity_count += 1
  735.                 self.spawn()
  736.  
  737.     def spawn(self):
  738.         pass
  739.  
  740. def interpolate_colours(colour1, colour2, amount):
  741.     r1, g1, b1 = colour1
  742.     r2, g2, b2 = colour2
  743.  
  744.     dr, dg, db = r2-r1, g2-g1, b2-b1
  745.     r = max(min(int(r1+(dr*amount)),255),0)
  746.     g = max(min(int(g1+(dg*amount)),255),0)
  747.     b = max(min(int(b1+(db*amount)),255),0)
  748.     return (r,g,b)
  749.  
  750. class Exit(Entity):
  751.     def __init__(self, level, x, y, requirement):
  752.         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)
  753.         self.animation_speed = 1/60
  754.         self.animation_progress = 0
  755.  
  756.         self.animation_frames = []
  757.         for file in listdir(gfx_dir):
  758.             if file.startswith("exit"):
  759.                 frame = p.image.load(gfx_dir+file).convert_alpha()
  760.                 self.animation_frames.append(frame)
  761.  
  762.         self.requirement = requirement
  763.         self.packages = 0
  764.  
  765.         self.requirement_text = None
  766.  
  767.     def give_packages(self, amount):
  768.         self.packages += amount
  769.        
  770.         for i in range(amount):
  771.             package = player.packages[0]
  772.             player.packages.remove(package)
  773.             entities.remove(package)
  774.            
  775.             player.score.change(100, 15)
  776.  
  777.            
  778.            
  779.         if self.packages >= self.requirement:
  780.             time_bonus = int(self.level.time/2)
  781.             self.level.level += 1
  782.             self.level.create(self.level.level)
  783.             player.score.multiplier = 1
  784.             player.score.change(time_bonus, 45)
  785.             play_sound("complete")
  786.         else:
  787.             play_sound("give_package")
  788.  
  789.     def set_requirement_text(self):
  790.         total_packages = self.packages+len(player.packages)
  791.         if player.packages:
  792.             text = str(self.packages)+" +["+str(len(player.packages))+"] / "+str(self.requirement)
  793.         else:
  794.             text = str(self.packages)+" / "+str(self.requirement)
  795.            
  796.         if total_packages <= self.requirement:
  797.             colour = interpolate_colours(RED, GREEN, total_packages/self.requirement)
  798.         else:
  799.             colour = BLUE
  800.            
  801.         self.requirement_text = requirement_font.render(text, True, colour)
  802.         self.requirement_rect = self.requirement_text.get_rect()
  803.         self.requirement_rect.center = self.rect.center
  804.         self.requirement_rect.centery -= self.level.th
  805.        
  806.  
  807.     def update_turn(self):
  808.         self.set_requirement_text()
  809.        
  810.  
  811.     def update(self):
  812.         Entity.update(self)
  813.         self.animation_progress = (self.animation_progress+self.animation_speed )%1
  814.  
  815.     def draw(self, camera):
  816.         if not self.requirement_text:
  817.             self.set_requirement_text()
  818.         index = int(len(self.animation_frames)*self.animation_progress)
  819.         frame = self.animation_frames[index]
  820.  
  821.         camera.draw_transformed_surface(frame, self.rect)
  822.         camera.draw_transformed_surface(self.requirement_text, self.requirement_rect)
  823.  
  824.        
  825.  
  826. class Projectile_Spawner(Spawner):
  827.     def __init__(self, level, max_timer, variance):
  828.         Spawner.__init__(self, level, max_timer, variance)
  829.  
  830.     def spawn(self):
  831.         Spawner.spawn(self)
  832.         sides = ("top", "bottom", "left", "right")
  833.         side = r.choice(sides)
  834.  
  835.         if side == "top":
  836.             x = r.randint(0,self.level.width-1)
  837.             y = -1
  838.         if side == "bottom":
  839.             x = r.randint(0,self.level.width-1)
  840.             y = self.level.height
  841.         if side == "left":
  842.             x = -1
  843.             y = r.randint(0,self.level.height-1)
  844.         if side == "right":
  845.             x = self.level.width
  846.             y = r.randint(0,self.level.height-1)
  847.  
  848.         direction = ("down", "up", "right", "left")[sides.index(side)]
  849.  
  850.         Projectile(self.level, x, y, direction)
  851.  
  852. class Fire_Spawner(Spawner):
  853.     def __init__(self, level, max_timer, variance, max_entities=None):
  854.         Spawner.__init__(self, level, max_timer, variance, max_entities=max_entities)
  855.  
  856.     def spawn(self):
  857.         Spawner.spawn(self)
  858.         spawn_entity_in_blank_space(level, Fire)
  859.  
  860. class Pickup_Spawner(Spawner):
  861.     def __init__(self, level, max_timer, variance, max_entities=None):
  862.         Spawner.__init__(self, level, max_timer, variance, max_entities=max_entities)
  863.  
  864.     def spawn(self):
  865.         Spawner.spawn(self)
  866.         spawn_entity_in_blank_space(level, Pickup)
  867.  
  868. class Wall_Spawner(Spawner):
  869.     def __init__(self, level, max_timer, variance, max_entities=None):
  870.         Spawner.__init__(self, level, max_timer, variance, max_entities=max_entities)
  871.  
  872.     def spawn(self):
  873.         Spawner.spawn(self)
  874.         blank_space = find_blank_space(level)
  875.         if blank_space != False:
  876.             x, y = blank_space
  877.             level.tiles[x][y] = Tile(level, "wall", x, y)
  878.  
  879. def find_blank_space(level, border=False):
  880.     valid = False
  881.     attempts = 0
  882.     max_attempts = 10
  883.     while not valid and attempts < max_attempts:
  884.         attempts += 1
  885.         valid = True
  886.         if border:
  887.             x, y = r.randint(0,level.width-1), r.randint(0,level.width-1)
  888.         else:
  889.             x, y = r.randint(1,level.width-2), r.randint(1,level.width-2)
  890.        
  891.         for entity in entities:
  892.             if x == entity.tx and y == entity.ty:
  893.                 valid = False
  894.  
  895.         if level.tiles[x][y].solid:
  896.             valid = False
  897.                
  898.                
  899.     if attempts < max_attempts:
  900.         return x, y
  901.     else:
  902.         return False
  903.  
  904. def spawn_entity_in_blank_space(level, spawn_entity):
  905.     blank_space = find_blank_space(level)
  906.     if blank_space != False:
  907.         x, y = blank_space
  908.         return spawn_entity(level, x, y)
  909.        
  910.  
  911.     return False
  912.  
  913. def reset():
  914.     global player, level, camera
  915.     entities.clear()
  916.     projectiles.clear()
  917.     actions.clear()
  918.     pickups.clear()
  919.     fires.clear()
  920.  
  921.     camera = Camera(p.Rect(0,0,100,100))
  922.     player = None
  923.     level = Level(32, 32)
  924.    
  925.     level.pickup_spawner.spawn()
  926.    
  927.     player = Player(level, 5,6)
  928.    
  929.  
  930. def handle_input():
  931.     global game_mode
  932.     for event in p.event.get():
  933.         if event.type == p.KEYDOWN:
  934.             if game_mode == "main":
  935.  
  936.                 if event.key == p.K_ESCAPE:
  937.                     global paused
  938.                     paused = not paused
  939.                 elif not paused:
  940.                     if event.key in [p.K_w, p.K_s, p.K_a, p.K_d, p.K_SPACE]:
  941.                         update_turn()
  942.  
  943.                     #if event.key == p.K_q:
  944.                     #    camera.rect.inflate_ip((-100,-100))
  945.                     #elif event.key == p.K_z:
  946.                     #    camera.rect.inflate_ip((100,100))
  947.  
  948.                     if event.key == p.K_w:
  949.                         player.p_move_t(0,-1)
  950.                         player.direction = "up"
  951.                     elif event.key == p.K_s:
  952.                         player.p_move_t(0,1)
  953.                         player.direction = "down"
  954.                     elif event.key == p.K_a:
  955.                         player.p_move_t(-1,0)
  956.                         player.direction = "left"
  957.                     elif event.key == p.K_d:
  958.                         player.p_move_t(1,0)
  959.                         player.direction = "right"
  960.  
  961.                     elif event.key == p.K_m:
  962.                         global music_playing
  963.                         if music_playing:
  964.                             p.mixer.music.pause()
  965.                         else:
  966.                             p.mixer.music.unpause()
  967.                         music_playing = not music_playing
  968.  
  969.                
  970.                    
  971.             elif game_mode == "start":
  972.                 reset()
  973.                 game_mode = "main"
  974.                 p.mixer.music.play(-1)
  975.                 if not music_playing:
  976.                     p.mixer.music.pause()
  977.  
  978.             elif game_mode == "game_over":
  979.                 game_mode = "start"
  980.  
  981.         if event.type == p.QUIT:
  982.             p.display.quit()
  983.             exit()
  984.             quit()
  985.    
  986.  
  987. def update_turn():
  988.     if game_mode == "main":
  989.         global turn_length, turn_colour_intensity
  990.         turn_length = min(turn_length, 1*MAX_TICK_RATE)
  991.         turn_length_log.insert(0,turn_length)
  992.         turn_length = 0
  993.  
  994.         while len(turn_length_log) > 8:
  995.             del turn_length_log[-1]
  996.        
  997.         turn_colour_intensity = 1- ( sum(turn_length_log)/(MAX_TICK_RATE*len(turn_length_log)) )
  998.        
  999.         while actions:
  1000.             for action in actions:
  1001.                 action.update()
  1002.                 action.entity.update()
  1003.                
  1004.         player.update_turn()
  1005.         for package in player.packages:
  1006.             package.update_turn()
  1007.  
  1008.         for projectile in projectiles:
  1009.             projectile.update_turn()
  1010.  
  1011.         for wall in level.walls:
  1012.             if wall.spawning_timer:
  1013.                 if player.tx != wall.x or player.ty != wall.y:
  1014.                     wall.spawning_timer -= 1
  1015.  
  1016.         for pickup in pickups:
  1017.             pickup.update_turn()
  1018.  
  1019.         level.exit.update_turn()
  1020.        
  1021.         for spawner in level.spawners:
  1022.             spawner.update_turn()
  1023.  
  1024. def update():
  1025.     if game_mode == "main" and not paused:
  1026.         global turn_length, turn_colour_intensity, background_colour
  1027.         camera.update()
  1028.         for action in actions:
  1029.             action.update()
  1030.         for entity in entities:
  1031.             entity.update()
  1032.            
  1033.         turn_length += 1
  1034.         if turn_colour_intensity > 0:
  1035.             turn_colour_intensity -= 0.01
  1036.             background_colour = interpolate_colours(BLUE, RED, turn_colour_intensity)
  1037.  
  1038. def draw():
  1039.     if game_mode == "main":
  1040.         level.draw(camera)
  1041.         for fire in fires:
  1042.             fire.draw(camera)
  1043.         for pickup in pickups:
  1044.             pickup.draw(camera)
  1045.         for projectile in projectiles:
  1046.             projectile.draw(camera)
  1047.         player.draw(camera)
  1048.         level.exit.draw(camera)
  1049.         player.score.draw(0,0)
  1050.  
  1051.         rendered_level_text = level_font.render("Level "+str(level.level), True, WHITE)
  1052.         rendered_level_text_rect = rendered_level_text.get_rect()
  1053.         rendered_level_text_rect.topright = (WIDTH,0)
  1054.         screen.blit(rendered_level_text, rendered_level_text_rect)
  1055.  
  1056.         if level.time <= 10*MAX_TICK_RATE:
  1057.             colour = RED
  1058.         elif level.time <= 15*MAX_TICK_RATE:
  1059.             colour = ORANGE
  1060.         elif level.time <= 20*MAX_TICK_RATE:
  1061.             colour = YELLOW
  1062.         else:
  1063.             colour = GREEN
  1064.            
  1065.         rendered_time_text = time_font.render("Time: "+str(round(level.time/MAX_TICK_RATE,1))+"s", True, colour)
  1066.         rendered_time_text_rect = rendered_time_text.get_rect()
  1067.         rendered_time_text_rect.midtop = (int(WIDTH/2), 0)
  1068.         screen.blit(rendered_time_text, rendered_time_text_rect)
  1069.  
  1070.         if paused:
  1071.             screen.blit(pause_popup, pause_popup_rect)
  1072.                                              
  1073.     elif game_mode == "start":
  1074.         screen.blit(screen_start, (0,0))
  1075.     elif game_mode == "game_over":
  1076.         screen.blit(game_over_start, (0,0))
  1077.  
  1078.         rendered_score_text = game_over_score_font.render("Score:"+str(player.score.real_score), True, BLACK)
  1079.         rendered_level_text = game_over_score_font.render("Level "+str(level.level), True, BLACK)
  1080.  
  1081.         rendered_score_text_rect = rendered_score_text.get_rect()
  1082.         rendered_level_text_rect = rendered_level_text.get_rect()
  1083.  
  1084.         rendered_score_text_rect.center = (0.5*WIDTH, 0.4*HEIGHT)
  1085.         rendered_level_text_rect.center = (0.5*WIDTH, 0.8*HEIGHT)
  1086.  
  1087.         screen.blit(rendered_score_text, rendered_score_text_rect)
  1088.         screen.blit(rendered_level_text, rendered_level_text_rect)
  1089.  
  1090.  
  1091.  
  1092. RUNNING = True
  1093. while RUNNING:
  1094.     screen.fill(background_colour)
  1095.     handle_input()
  1096.     update()
  1097.     draw()
  1098.     p.display.flip()
  1099.     game_clock.tick(MAX_TICK_RATE)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement