Advertisement
cookertron

Save the Queen (Python Pygame)

Sep 11th, 2019
440
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 27.03 KB | None | 0 0
  1. """
  2.  _____  ____  __ __    ___      ______  __ __    ___       ___   __ __    ___    ___  ____  
  3. / ___/ /    T|  T  |  /  _]    |      T|  T  T  /  _]     /   \ |  T  T  /  _]  /  _]|    \
  4. (   \_ Y  o  ||  |  | /  [_     |      ||  l  | /  [_     Y     Y|  |  | /  [_  /  [_ |  _  Y
  5. \__  T|     ||  |  |Y    _]    l_j  l_j|  _  |Y    _]    |  Q  ||  |  |Y    _]Y    _]|  |  |
  6. /  \ ||  _  |l  :  !|   [_       |  |  |  |  ||   [_     |     ||  :  ||   [_ |   [_ |  |  |
  7. \   ||  |  | \  / |     T      |  |  |  |  ||     T    l     |l     ||     T|     T|  |  |
  8.  \___jl__j__j  \_/  l_____j      l__j  l__j__jl_____j     \__,_j \__,_jl_____jl_____jl__j__j
  9. """
  10. # heading font http://patorjk.com/software/taag/#p=display&h=0&v=0&f=Crawford&t=testing
  11. # sub heading font http://patorjk.com/software/taag/#p=display&h=2&v=2&f=Small%20Slant&t=testing
  12.  
  13. # This game was inspired by Nishant in the Pygame Facebook group (fb.com/groups/pygame)
  14. # Shoot the enemies [LMB] before they touch the queen. If it's getting too much drop a bomb [RMB]!
  15. # Coding by Anthony Cook fb.com/anthony.cook78
  16.  
  17. import math, random, sys, time
  18. import pygame
  19. from pygame.locals import *
  20. from pygame import gfxdraw
  21.  
  22.  
  23. """
  24.   ___                      __              
  25.  / _ \_______  _______ ___/ /_ _________ ___
  26. / ___/ __/ _ \/ __/ -_) _  / // / __/ -_|_-<
  27. /_/  /_/  \___/\__/\__/\_,_/\_,_/_/  \__/___/
  28. """
  29. def quit():
  30.     for event in pygame.event.get():
  31.         if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
  32.             return True
  33.     return False
  34.  
  35. def threshold_table(size, steps, reverse = False, opposite = False):
  36.     t = 2.0 * size / (steps * (steps - 1))
  37.     a = 0
  38.     table = []
  39.     for i in range(steps):
  40.         a += t * i
  41.         if opposite: table.append(size - a)
  42.         else: table.append(a)
  43.     if reverse: table.reverse()
  44.     return table
  45.  
  46.  
  47. """
  48.  _____                 ____    __          
  49. / ___/__ ___ _  ___   / __/__ / /___ _____
  50. / (_ / _ `/  ' \/ -_) _\ \/ -_) __/ // / _ \
  51. \___/\_,_/_/_/_/\__/ /___/\__/\__/\_,_/ .__/
  52.                                     /_/    
  53. """
  54. # define display surface           
  55. W, H = 1280, 720
  56. HW, HH = W / 2, H / 2
  57.  
  58. # initialise display
  59. pygame.init()
  60. FONT = pygame.font.SysFont(None, 72)
  61. DS = pygame.display.set_mode((W, H))
  62. pygame.display.set_caption("Kill The Queen")
  63. pygame.mouse.set_visible(False)
  64.  
  65. # start FPS monitoring
  66. FPS = 120
  67. SPF = 1.00 / FPS
  68. FPSTime = time.time()
  69. FRAME_COUNT = 0
  70.  
  71.  
  72. """
  73.  _____     __          
  74. / ___/__  / /__  _______
  75. / /__/ _ \/ / _ \/ __(_-<
  76. \___/\___/_/\___/_/ /___/
  77. """
  78. FUCHSIA     = (255,   0, 255)
  79. PURPLE      = (128,   0, 128)
  80. TEAL        = (  0, 128, 128)
  81. LIME        = (  0, 255,   0)
  82. GREEN       = (  0, 128,   0)
  83. OLIVE       = (128, 128,   0)
  84. YELLOW      = (255, 255,   0)
  85. ORANGE      = (255, 165,   0)
  86. RED         = (255,   0,   0)
  87. MAROON      = (128,   0,   0)
  88. SILVER      = (192, 192, 192)
  89. GRAY        = (128, 128, 128)
  90. BLUE        = (  0,   0, 255)
  91. NAVY        = (  0,   0, 128)
  92. AQUA        = (  0, 255, 255)
  93. DARK_GRAY   = ( 25,  25,  25)
  94. WHITE       = (255, 255, 255)
  95. BLACK       = (  0,   0,   0)
  96.  
  97. VECTOR_TABLE = [[math.cos(math.radians(degrees)), math.sin(math.radians(degrees))] for degrees in range(360)]
  98.  
  99.  
  100. """
  101.   ____          __    ______       ______
  102.  / __/__  ___  / /_  / __/ /___ __/ _/ _/
  103. / _// _ \/ _ \/ __/ _\ \/ __/ // / _/ _/
  104. /_/  \___/_//_/\__/ /___/\__/\_,_/_//_/  
  105. """
  106. BLOCKY_FONT = {
  107.     'a' : "10 0 10 6 6 6 6 11 12 11 12 6 10 6 10 0 19 0 19 22 12 22 12 17 6 17 6 22 0 22 0 0",
  108.     'b' : "0 0 0 22 19 22 19 15 13 15 13 16 7 16 7 14 13 14 13 15 19 15 19 7 13 7 13 8 7 8 7 6 13 6 13 7 19 7 19 0",
  109.     'c' : "0 0 0 22 17 22 17 15 7 15 7 6 17 6 17 0",
  110.     'd' : "0 0 0 24 19 19 19 10 12 10 12 14 6 15 6 6 12 6 12 10 19 10 19 0",
  111.     'e' : "0 0 0 22 17 22 17 16 6 16 6 14 17 14 17 8 6 8 6 6 17 6 17 0",
  112.     'f' : "0 0 0 22 6 22 6 14 17 14 17 8 6 8 6 6 17 6 17 0",
  113.     'g' : "0 0 0 22 17 22 17 8 8 8 8 14 11 14 11 16 6 16 6 6 17 6 17 0",
  114.     'h' : "0 0 0 22 7 22 7 14 13 14 13 22 19 22 19 0 13 0 13 8 7 8 7 0",
  115.     'i' : "0 0 0 22 6 22 6 0",
  116.     'j' : "0 13 0 22 17 22 17 0 11 0 11 16 6 16 6 13",
  117.     'k' : "0 22 0 0 6 0 6 7 13 0 21 0 10 11 21 22 13 22 6 15 6 22",
  118.     'l' : "0 0 0 22 18 22 18 16 7 16 7 0",
  119.     'm' : "0 0 0 22 6 22 6 6 8 6 8 22 14 22 14 6 16 6 16 22 22 22 22 0",
  120.     'n' : "0 0 0 22 7 22 7 6 13 6 13 22 19 22 19 0",
  121.     'o' : "0 0 0 22 19 22 19 11 13 11 13 15 7 15 7 6 13 6 13 11 19 11 19 0",
  122.     'p' : "0 0 0 22 6 22 6 14 19 14 19 0 10 0 10 6 12 6 12 8 6 8 6 6 10 6 10 0",
  123.     'q' : "0 0 0 22 8 22 13 27 22 27 17 22 19 22 19 0 9 0 9 6 12 6 12 15 6 15 6 6 9 6 9 0",
  124.     'r' : "0 0 0 22 7 22 7 15 14 22 22 22 14 14 19 14 19 0 11 0 11 6 13 6 13 8 7 8 7 6 11 6 11 0",
  125.     's' : "0 0 0 14 11 14 11 16 0 16 0 22 17 22 17 8 6 8 6 6 17 6 17 0",
  126.     't' : "0 0 0 6 7 6 7 22 13 22 13 6 19 6 19 0",
  127.     'u' : "0 0 0 22 19 22 19 0 13 0 13 16 7 16 7 0",
  128.     'v' : "0 0 9 22 16 22 24 0 18 0 12 14 7 0",
  129.     'w' : "0 0 0 22 22 22 22 0 16 0 16 16 14 16 14 0 8 0 8 16 6 16 6 0",
  130.     'x' : "0 0 9 11 0 22 8 22 13 16 17 22 25 22 17 11 25 0 17 0 13 6 8 0",
  131.     'y' : "0 0 9 12 9 22 15 22 15 12 24 0 16 0 12 6 8 0",
  132.     'z' : "3 0 3 6 13 6 0 22 22 22 22 16 13 16 25 0",
  133.     '1' : "0 0 0 6 3 6 3 22 9 22 9 0",
  134.     '2' : "1 0 1 6 11 6 11 8 0 8 0 22 18 22 18 16 7 16 7 14 18 14 18 0",
  135.     '3' : "0 0 0 6 11 6 11 8 0 8 0 14 11 14 11 16 0 16 0 22 17 22 17 0",
  136.     '4' : "0 0 0 17 11 17 11 22 17 22 17 17 19 17 19 11 17 11 17 0 11 0 11 11 6 11 6 0",
  137.     '5' : "0 0 0 14 11 14 11 16 0 16 0 22 17 22 17 8 6 8 6 6 17 6 17 0",
  138.     '6' : "12 16 6 16 6 14 9 14 9 8 6 8 6 6 18 6 18 0 0 0 0 22 18 22 18 8 9 8 9 14 12 14",
  139.     '7' : "3 0 3 6 12 6 0 22 8 22 25 0",
  140.     '8' : "0 0 0 22 10 22 10 16 7 16 7 14 10 14 10 8 7 8 7 6 13 6 13 8 9 8 9 14 13 14 13 16 10 16 10 22 19 22 19 0",
  141.     '9' : "0 0 6 0 6 1 10 1 10 6 6 6 6 8 12 8 12 6 9 6 9 1 12 1 12 0 19 0 19 22 0 22 0 16 12 16 12 14 0 14",
  142.     '0' : "0 0 0 22 19 22 19 0 10 0 10 6 13 6 13 15 7 15 7 6 10 6 10 0",
  143.     '!' : "0 0 6 0 6 14 3 14 3 16 6 16 6 22 0 22 0 16 3 16 3 14 0 14",
  144.     '?' : "0 0 17 0 17 14 3 14 3 16 6 16 6 22 0 22 0 16 3 16 3 14 0 14 0 8 11 8 11 6 0 6",
  145.     ':' : "0 3 6 3 6 9 3 9 3 13 6 13 6 19 0 19 0 13 3 13 3 9 0 9",
  146. }                                      
  147.  
  148. class font:
  149.     def __init__(s, fontData, sizes = []):
  150.         s.font = s.convertRaw(fontData)
  151.  
  152.         s.rasterFonts = []
  153.         s.rasterFonts.append(s.rasterize())
  154.  
  155.         for sFactor in sizes:
  156.             s.rasterFonts.append(s.rasterize(sFactor))
  157.  
  158.     def rasterize(s, sFactor = 1):
  159.         global BLACK, WHITE
  160.  
  161.         font = {'width' : int(s.font['aw'] * sFactor), 'height' : int(s.font['ah'] * sFactor), 'sWidth' : int(s.font['fw'] * sFactor), 'sHeight' : int(s.font['fh'] * sFactor), 'surfaces' : {}}
  162.  
  163.         for char, data in s.font['f'].items():
  164.             font['surfaces'][char] = {'width' : int(data['w'] * sFactor), 'height' : int(data['h'] * sFactor)}
  165.             font['surfaces'][char]['surface'] = pygame.Surface((int(s.font['fw'] * sFactor) + 1, int(s.font['fh'] * sFactor) + 1))
  166.             font['surfaces'][char]['surface'].set_colorkey(BLACK, pygame.RLEACCEL)
  167.  
  168.             points = []
  169.             for p in s.font['f'][char]['p']:
  170.                 points.append([int(p[0] * sFactor), int(p[1] * sFactor)])
  171.  
  172.             pygame.draw.polygon(font['surfaces'][char]['surface'], WHITE, points)
  173.  
  174.         return font
  175.  
  176.     def stringSurface(s, t, color = None, sIndex = 0):
  177.         global BLACK
  178.  
  179.         surface = pygame.Surface((s.getSurfaceWidth(t, sIndex), s.rasterFonts[sIndex]['sHeight']))
  180.         if color:
  181.             surface2 = surface.copy()
  182.             surface2.fill(color)
  183.        
  184.         cx = 0
  185.         for char in t:
  186.             if char != " ":
  187.                 surface.blit(s.rasterFonts[sIndex]['surfaces'][char]['surface'], (cx, 0))
  188.                 if s.rasterFonts[sIndex]['surfaces'][char]['width'] > s.rasterFonts[sIndex]['width']: cx += int(s.rasterFonts[sIndex]['width'] * 1.4)
  189.                 else: cx += int(s.rasterFonts[sIndex]['width'] * 1.2)
  190.             else: cx += s.rasterFonts[sIndex]['width']
  191.        
  192.         if color:
  193.             surface.blit(surface2, (0, 0), None, pygame.BLEND_MULT)
  194.        
  195.         surface.set_colorkey(BLACK, pygame.RLEACCEL)
  196.         return surface
  197.    
  198.     def getSurfaceWidth(s, t, sIndex):
  199.         cx = 0
  200.         for char in t:
  201.             if char != " ":
  202.                 if s.rasterFonts[sIndex]['surfaces'][char]['width'] > s.rasterFonts[sIndex]['width']: cx += int(s.rasterFonts[sIndex]['width'] * 1.4)
  203.                 else: cx += int(s.rasterFonts[sIndex]['width'] * 1.2)
  204.             else: cx += s.rasterFonts[sIndex]['width']
  205.         return cx        
  206.  
  207.     def convertRaw(s, fD):
  208.         f = {}
  209.         p = []
  210.         ms = {'w' : {}, 'h' : {}}
  211.         fw, fh = 0, 0
  212.         for k, v in fD.items():
  213.             pL = []
  214.             w, h = 0, 0
  215.             for d in v.split(' '):
  216.                 c = int(d)
  217.                 p.append(int(d))
  218.                 if len(p) == 2:
  219.                     pL.append(list(p))
  220.                     p = []
  221.                     if c > h: h = c
  222.                 elif c > w: w = c
  223.             f[k] = {'p' : list(pL), 'w' : w, 'h' : h}
  224.             if w > fw: fw = w
  225.             if h > fh: fh = h
  226.             if w in ms['w']: ms['w'][w] += 1
  227.             else: ms['w'][w] = 1
  228.             if h in ms['h']: ms['h'][h] += 1
  229.             else: ms['h'][h] = 1
  230.         mw, mh = None, None
  231.         for k, v in ms['w'].items():
  232.             if not mw: mw = k
  233.             elif v > ms['w'][mw]: mw = k
  234.         for k, v in ms['h'].items():
  235.             if not mh: mh = k
  236.             if v > ms['h'][mh]: mh = k
  237.         return {'aw' : mw, 'ah' : mh, 'fh' : fh, 'fw' : fw, 'f' : f}
  238.  
  239. """
  240.   ____                      ___  _ __
  241.  / __/__  ___ __ _  __ __  / _ )(_) /_
  242. / _// _ \/ -_)  ' \/ // / / _  / / __/
  243. /___/_//_/\__/_/_/_/\_, / /____/_/\__/
  244.                   /___/              
  245. """
  246. ENEMY_SIZE = 20
  247. ENEMY_GROW_STEPS = 25
  248. ENEMY_SIZE_TABLE = threshold_table(ENEMY_SIZE, ENEMY_GROW_STEPS)
  249.  
  250. class enemy:
  251.     def __init__(s):
  252.         global HW, HH, WHITE
  253.         global VECTOR_TABLE
  254.  
  255.         s.color = WHITE
  256.  
  257.         degrees = random.randint(0, 359)
  258.        
  259.         dx = random.randint(HW - 50, HW)
  260.         s.x = HW + VECTOR_TABLE[degrees][0] * dx
  261.        
  262.         dy = random.randint(HH - 50, HH)
  263.         s.y = HH + VECTOR_TABLE[degrees][1] * dy
  264.  
  265.         s.angle = int(math.degrees(math.atan2(HH - s.y, HW - s.x))) % 360
  266.  
  267.         s.sizeIndex = 0
  268.        
  269.         s.dead = False
  270.         s.stopped = False
  271.        
  272.     def howClose(s):
  273.         global HW, HH
  274.         global QUEEN_SIZE, ENEMY_SIZE        
  275.         return int(math.hypot(s.x - HW, s.y - HH))
  276.  
  277.     def move(s):
  278.         global VECTOR_TABLE
  279.         if s.stopped: return
  280.  
  281.         if s.sizeIndex < ENEMY_GROW_STEPS - 1:
  282.             s.sizeIndex += 1
  283.             return
  284.  
  285.         s.x += VECTOR_TABLE[s.angle][0]
  286.         s.y += VECTOR_TABLE[s.angle][1]
  287.  
  288.     def draw(s):
  289.         global DS
  290.         global ENEMY_SIZE_TABLE
  291.         pygame.draw.circle(DS, s.color, (int(s.x), int(s.y)), int(ENEMY_SIZE_TABLE[s.sizeIndex]))
  292.  
  293. class enemies:
  294.     def reset(s):
  295.         global FRAME_COUNT
  296.         s.container = []
  297.         s.frameCounter = FRAME_COUNT
  298.         s.newTimer()
  299.  
  300.     def newTimer(s):
  301.         global FPS
  302.         s.nextEnemyTimer = random.randint(FPS/5, FPS)
  303.  
  304.     def do(s):
  305.         global HW, HH
  306.         global RED, WHITE
  307.         global FRAME_COUNT
  308.         global QUEEN_SHAKE_RADIUS, QUEEN_SIZE, ENEMY_SIZE
  309.         global queenHandler, crosshairHandler, explosionHandler
  310.  
  311.         queenHandler.shakeRadius = 0
  312.         deleteEnemies = []
  313.         for e in s.container:
  314.             if e.dead:
  315.                 deleteEnemies.append(e)
  316.                 continue
  317.             distanceToCrossHair = math.hypot(crosshairHandler.x - e.x, crosshairHandler.y - e.y)
  318.             if distanceToCrossHair <= ENEMY_SIZE:
  319.                 e.color = RED
  320.                 crosshairHandler.enemyInSight = e
  321.             elif crosshairHandler.enemyInSight == e:
  322.                 e.color = WHITE
  323.                 crosshairHandler.enemyInSight = None
  324.  
  325.             e.draw()
  326.             e.move()
  327.             distanceToQueen = e.howClose()
  328.             if distanceToQueen < QUEEN_SHAKE_RADIUS:
  329.                 queenHandler.shakeRadius = QUEEN_SHAKE_TABLE[distanceToQueen]
  330.  
  331.             if distanceToQueen < QUEEN_SIZE + ENEMY_SIZE and not queenHandler.dead:
  332.                 e.stopped = True
  333.                 queenHandler.dead = True
  334.                 explosionHandler.add(HW, HH, 32)
  335.  
  336.         for dead in deleteEnemies:
  337.             s.container.remove(dead)
  338.  
  339.         if FRAME_COUNT - s.frameCounter > s.nextEnemyTimer:
  340.             s.frameCounter = FRAME_COUNT
  341.             s.newTimer()
  342.             s.container.append(enemy())
  343.  
  344.  
  345. """
  346.  ____                      ___  _ __
  347. / __ \__ _____ ___ ___    / _ )(_) /_
  348. / /_/ / // / -_) -_) _ \ / _  / / __/
  349. \___\_\_,_/\__/\__/_//_/ /____/_/\__/
  350. """
  351. QUEEN_SIZE = 32
  352. QUEEN_SHAKE_RADIUS = 300
  353. QUEEN_SHAKE_SIZE = 10
  354. QUEEN_SHAKE_TABLE = threshold_table(QUEEN_SHAKE_SIZE, QUEEN_SHAKE_RADIUS, True)
  355.  
  356. class queen:
  357.     def reset(s):
  358.         global HW, HH
  359.         s.dead = False
  360.         s.shakeRadius = 0
  361.         s.x, s.y = HW, HH
  362.  
  363.     def draw(s):
  364.         global DS, HW, HH
  365.         global QUEEN_SIZE
  366.         if not s.dead: pygame.draw.circle(DS, ORANGE, (int(s.x), int(s.y)), QUEEN_SIZE)
  367.    
  368.     def move(s):
  369.         global HW, HH
  370.         global VECTOR_TABLE
  371.  
  372.         if s.shakeRadius == 0:
  373.             s.x, s.y = HW, HH
  374.             return
  375.         angle = random.randint(0, 359)
  376.         s.x = HW + VECTOR_TABLE[angle][0] * s.shakeRadius
  377.         s.y = HH + VECTOR_TABLE[angle][1] * s.shakeRadius
  378.  
  379.     def do(s):
  380.         s.move()
  381.         s.draw()        
  382.  
  383.  
  384. """
  385.  _____                 __        _       ___  _ __
  386. / ___/______  ___ ___ / /  ___ _(_)___  / _ )(_) /_
  387. / /__/ __/ _ \(_-<(_-</ _ \/ _ `/ / __/ / _  / / __/
  388. \___/_/  \___/___/___/_//_/\_,_/_/_/   /____/_/\__/
  389. """
  390. CROSS_HAIR_SIZE = 30
  391.  
  392. class crosshair:
  393.     def move(s):
  394.         s.x, s.y = pygame.mouse.get_pos()
  395.  
  396.     def reset(s):
  397.         s.enemyInSight = None
  398.         s.leftButtonStatus = False
  399.         s.rightButtonStatus = False
  400.         s.move()
  401.  
  402.     def draw(s):
  403.         global DS
  404.         global GREEN
  405.         global CROSS_HAIR_SIZE
  406.         pygame.gfxdraw.hline(DS, s.x - CROSS_HAIR_SIZE, s.x + CROSS_HAIR_SIZE, s.y, GREEN)
  407.         pygame.gfxdraw.vline(DS, s.x, s.y - CROSS_HAIR_SIZE, s.y + CROSS_HAIR_SIZE, GREEN)
  408.  
  409.     def trigger(s):
  410.         global HW, HH
  411.         global ENEMY_SIZE, QUEEN_SIZE, BULLET_HOLE_SIZE
  412.         global explosionHandler, bulletHoleHandler, enemyHandler, bombHandler, textHandler
  413.         global kills, started, scoreSurface
  414.  
  415.         mb = pygame.mouse.get_pressed()
  416.         if not s.rightButtonStatus and mb[2]:
  417.             s.rightButtonStatus = True
  418.             if started: bombHandler.useBomb()
  419.         elif s.rightButtonStatus and not mb[2]:
  420.             s.rightButtonStatus = False
  421.  
  422.         if not s.leftButtonStatus and mb[0]:
  423.             started = True
  424.             s.leftButtonStatus = True
  425.             if s.enemyInSight:
  426.                 explosionHandler.add(s.enemyInSight.x, s.enemyInSight.y, ENEMY_SIZE)
  427.                 enemyHandler.container.remove(s.enemyInSight)
  428.                 s.enemyInSight = None
  429.                 kills += 1
  430.                 scoreSurface = textHandler.stringSurface("score: {}".format(kills), None, 2)
  431.             else:
  432.                 distanceFromQueen = math.hypot(HW - s.x, HH - s.y)
  433.                 if distanceFromQueen > QUEEN_SIZE + BULLET_HOLE_SIZE:
  434.                     bulletHoleHandler.add(s.x, s.y)
  435.         elif s.leftButtonStatus and not mb[0]:
  436.             s.leftButtonStatus = False
  437.  
  438.     def do(s):
  439.         s.draw()
  440.         s.move()
  441.         s.trigger()
  442.  
  443.  
  444. """
  445.   ____           __         _                 ___  _ __
  446.  / __/_ __ ___  / /__  ___ (_)__  ___  ___   / _ )(_) /_
  447. / _/ \ \ // _ \/ / _ \(_-</ / _ \/ _ \(_-<  / _  / / __/
  448. /___//_\_\/ .__/_/\___/___/_/\___/_//_/___/ /____/_/\__/
  449.         /_/                                          
  450. """
  451. PARTICLE_SIZE = 10
  452.  
  453. PARTICLE_COUNT_TABLE = [1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 18, 20, 24, 30, 36, 40, 45, 60, 72, 90, 120, 180, 360]
  454. PARTICLE_COUNT_TABLE_INDEX = 13 # 20
  455. PARTICLE_SPAWN_RADIUS_PERCENT = 0.20
  456.  
  457. PARTICLE_MIN_DISTANCE = 25
  458. PARTICLE_MAX_DISTANCE = 200
  459. PARTILCE_DISTANCE_STEP = 25
  460. PARTICLE_DISOLVE_STEP = 20
  461.  
  462. PARTICLE_SHRINK_TABLE = threshold_table(PARTICLE_SIZE, PARTICLE_DISOLVE_STEP, True)
  463. PARTICLE_COLOR_TABLE = threshold_table(255, PARTICLE_DISOLVE_STEP, True)
  464.  
  465. PARTICLE_DISTANCE_TABLE = [threshold_table(particleDistance, PARTICLE_DISOLVE_STEP, True, True) for particleDistance in range(PARTICLE_MIN_DISTANCE, PARTICLE_MAX_DISTANCE + PARTILCE_DISTANCE_STEP, PARTILCE_DISTANCE_STEP)]
  466. PARTICLE_DISTANCE_TABLE_COUNT = len(PARTICLE_DISTANCE_TABLE) - 1
  467.  
  468. class particle:
  469.     def __init__(s, a, x, y):
  470.         global PARTICLE_DISTANCE_TABLE_COUNT
  471.  
  472.         s.angle = a
  473.         s.distance_index = random.randint(0, PARTICLE_DISTANCE_TABLE_COUNT)
  474.  
  475.         s.originX, s.originY = x, y
  476.         s.x, s.y = s.originX, s.originY
  477.  
  478.     def draw(s, index):
  479.         global DS, WHITE
  480.         global PARTICLE_SHRINK_TABLE, PARTICLE_COLOR_TABLE
  481.         color = (255, PARTICLE_COLOR_TABLE[index], 0)
  482.         pygame.draw.circle(DS, color, (int(s.x), int(s.y)), int(PARTICLE_SHRINK_TABLE[index]))
  483.  
  484.     def move(s, index):
  485.         global VECTOR_TABLE, PARTICLE_DISTANCE_TABLE
  486.         s.x = s.originX + VECTOR_TABLE[s.angle][0] * PARTICLE_DISTANCE_TABLE[s.distance_index][index]
  487.         s.y = s.originY + VECTOR_TABLE[s.angle][1] * PARTICLE_DISTANCE_TABLE[s.distance_index][index]
  488.  
  489.     def do(s, index):
  490.          s.draw(index)
  491.          s.move(index)
  492.  
  493. class explosion:
  494.     def __init__(s, x, y, group_radius_size):
  495.         global WHITE
  496.         global VECTOR_TABLE
  497.         global PARTICLE_COUNT_TABLE, PARTICLE_COUNT_TABLE_INDEX, PARTICLE_SPAWN_RADIUS_PERCENT
  498.  
  499.         s.dead = False
  500.        
  501.         s.disolveStepCount = 0
  502.  
  503.         minimum_group_radius = group_radius_size - int(group_radius_size * PARTICLE_SPAWN_RADIUS_PERCENT)
  504.         s.particles = []
  505.         for degrees in range(0, 359, PARTICLE_COUNT_TABLE[PARTICLE_COUNT_TABLE_INDEX]):
  506.             radius = random.randint(minimum_group_radius, group_radius_size)
  507.             px = x + VECTOR_TABLE[degrees][0] * radius
  508.             py = y + VECTOR_TABLE[degrees][1] * radius
  509.             s.particles.append(particle(degrees, px, py))
  510.        
  511.     def do(s):
  512.         global PARTICLE_DISOLVE_STEP
  513.         if s.dead: return
  514.  
  515.         for p in s.particles:
  516.             p.do(s.disolveStepCount)
  517.        
  518.         if s.disolveStepCount < PARTICLE_DISOLVE_STEP - 1:
  519.             s.disolveStepCount += 1
  520.         else:
  521.             s.dead = True
  522.  
  523. class explosions:
  524.     def reset(s):
  525.         s.container = []
  526.  
  527.     def do(s):
  528.         delete_list = []
  529.         for e in s.container:
  530.             e.do()
  531.             if e.dead:
  532.                 delete_list.append(e)
  533.         for dead in delete_list:
  534.             s.container.remove(dead)
  535.  
  536.     def add(s, x, y, size):
  537.         s.container.append(explosion(x, y, size))
  538.  
  539.  
  540. """
  541.   ___       ____    __    __ __     __          ___  _ __
  542.  / _ )__ __/ / /__ / /_  / // /__  / /__ ___   / _ )(_) /_
  543. / _  / // / / / -_) __/ / _  / _ \/ / -_|_-<  / _  / / __/
  544. /____/\_,_/_/_/\__/\__/ /_//_/\___/_/\__/___/ /____/_/\__/
  545.  
  546. """
  547. BULLET_HOLE_SIZE = 15
  548. BULLET_HOLE_DURATION = FPS / 4
  549. BULLET_HOLE_DISSOLVE_STEPS = FPS
  550. BULLET_HOLE_DISSOLVE_TABLE = threshold_table(BULLET_HOLE_SIZE, BULLET_HOLE_DISSOLVE_STEPS)
  551. BULLET_HOLE_COLOR = DARK_GRAY
  552.  
  553. class bulletHole:
  554.     def __init__(s, x, y):
  555.         global FRAME_COUNT
  556.  
  557.         s.x, s.y = x, y
  558.         s.spawnTime = FRAME_COUNT
  559.         s.dissolveIndex = 0
  560.         s.dead = False
  561.    
  562.     def draw(s):
  563.         global DS, BLACK
  564.         global BULLET_HOLE_COLOR, BULLET_HOLE_SIZE, BULLET_HOLE_DISSOLVE_TABLE
  565.  
  566.         pygame.draw.circle(DS, BULLET_HOLE_COLOR, (s.x, s.y), BULLET_HOLE_SIZE)
  567.         if s.dissolveIndex:
  568.             pygame.draw.circle(DS, BLACK, (s.x, s.y), int(BULLET_HOLE_DISSOLVE_TABLE[s.dissolveIndex]))
  569.    
  570.     def do(s):
  571.         global FRAME_COUNT
  572.         global BULLET_HOLE_DURATION, BULLET_HOLE_DISSOLVE_STEPS
  573.  
  574.         s.draw()
  575.  
  576.         if FRAME_COUNT - s.spawnTime >= BULLET_HOLE_DURATION:
  577.             s.dissolveIndex += 1
  578.             if s.dissolveIndex == BULLET_HOLE_DISSOLVE_STEPS: s.dead = True
  579.  
  580. class bulletHoles:
  581.     def reset(s):
  582.         s.container = []
  583.  
  584.     def add(s, x, y):
  585.         s.container.append(bulletHole(x, y))
  586.    
  587.     def do(s):
  588.         deleteBulletHole = []
  589.         for bh in s.container:
  590.             bh.do()
  591.             if bh.dead: deleteBulletHole.append(bh)
  592.         for dead in deleteBulletHole:
  593.             s.container.remove(dead)
  594.  
  595.  
  596. """
  597.   ___             __         ___  _ __
  598.  / _ )___  __ _  / /  ___   / _ )(_) /_
  599. / _  / _ \/  ' \/ _ \(_-<  / _  / / __/
  600. /____/\___/_/_/_/_.__/___/ /____/_/\__/
  601. """
  602. BOMB_ICON_SIZE = 10
  603. BOMB_SPACING = 20
  604. BOMB_COLOR = PURPLE
  605. BOMB_COUNT = 3
  606. BOMB_DISSOLVE_STEPS = FPS
  607. BOMB_DISSOLVE_TABLE = threshold_table(BOMB_ICON_SIZE, BOMB_DISSOLVE_STEPS, True)                                        
  608.  
  609. class bomb:
  610.     def __init__(s, x, y):
  611.         s.x, s.y = x, y
  612.         s.dissolveIndex = 0
  613.         s.spent = False
  614.         s.dead = False
  615.  
  616.     def draw(s):
  617.         global DS
  618.         global BOMB_COLOR, BOMB_ICON_SIZE, BOMB_DISSOLVE_TABLE
  619.         pygame.draw.circle(DS, BOMB_COLOR, (s.x, s.y), int(BOMB_DISSOLVE_TABLE[s.dissolveIndex]))
  620.  
  621. class bombs:
  622.     def reset(s):
  623.         global H
  624.         global BOMB_COUNT, BOMB_ICON_SIZE, BOMB_SPACING
  625.  
  626.         s.live = []
  627.         s.spent = []
  628.  
  629.         bpx = BOMB_SPACING + BOMB_ICON_SIZE
  630.         bpy = H - BOMB_ICON_SIZE - BOMB_SPACING
  631.         for index in range(BOMB_COUNT):
  632.             s.live.append(bomb(bpx, bpy))
  633.             bpx += BOMB_SPACING + BOMB_ICON_SIZE
  634.        
  635.     def useBomb(s):
  636.         global ENEMY_SIZE
  637.         global enemyHandler, explosionHandler, crosshairHandler, textHandler
  638.         global kills, scoreSurface
  639.  
  640.         if not s.live: return
  641.  
  642.         s.spent.append(s.live.pop())
  643.        
  644.         for e in enemyHandler.container:
  645.             explosionHandler.add(e.x, e.y, ENEMY_SIZE)
  646.             kills += 1
  647.         scoreSurface = textHandler.stringSurface("score: {}".format(kills), None, 2)
  648.         enemyHandler.container = []
  649.         crosshairHandler.enemyInSight = None
  650.  
  651.     def do(s):
  652.         global BOMB_DISSOLVE_STEPS
  653.         for b in s.live:
  654.             b.draw()
  655.         deadBomb = None
  656.         for sb in s.spent:
  657.             sb.draw()
  658.             sb.dissolveIndex += 1
  659.             if sb.dissolveIndex == BOMB_DISSOLVE_STEPS - 1:
  660.                 deadBomb = sb
  661.         if deadBomb: s.spent.remove(deadBomb)
  662.  
  663.  
  664. """
  665.  _____                 _   __         _      __   __      
  666. / ___/__ ___ _  ___   | | / /__ _____(_)__ _/ /  / /__ ___
  667. / (_ / _ `/  ' \/ -_)  | |/ / _ `/ __/ / _ `/ _ \/ / -_|_-<
  668. \___/\_,_/_/_/_/\__/   |___/\_,_/_/ /_/\_,_/_.__/_/\__/___/
  669. """
  670. enemyHandler = enemies()
  671. queenHandler = queen()
  672. crosshairHandler = crosshair()
  673. explosionHandler = explosions()
  674. bulletHoleHandler = bulletHoles()
  675. bombHandler = bombs()
  676. textHandler = font(BLOCKY_FONT, [3, 0.8])
  677.  
  678. GAME_TITLE = textHandler.stringSurface("save the queen!", ORANGE, 1)
  679. GAME_TITLE_WIDTH, GAME_TITLE_HEIGHT = GAME_TITLE.get_rect().size
  680. GAME_TITLE_X = -GAME_TITLE_WIDTH
  681. GAME_TITLE_STOP_POS_X = HW - GAME_TITLE_WIDTH / 2
  682. GAME_TITLE_TRAVEL_DISTANCE = GAME_TITLE_STOP_POS_X - GAME_TITLE_X
  683. GAME_TITLE_TRAVEL_TIME = float(FPS)
  684. GAME_TITLE_ACCELERATION_THRESHOLD = 2.0 * GAME_TITLE_TRAVEL_DISTANCE / (GAME_TITLE_TRAVEL_TIME * (GAME_TITLE_TRAVEL_TIME - 1))
  685.  
  686. SPACE_TITLE = textHandler.stringSurface("press space to start", DARK_GRAY, 0)
  687. SPACE_TITLE_WIDTH = SPACE_TITLE.get_rect().width
  688. SPACE_TITLE_X = HW - SPACE_TITLE_WIDTH / 2
  689. SPACE_TITLE_Y = 300
  690.  
  691. YOU_SCORED = textHandler.stringSurface("you scored:")
  692. YOU_SCORED_WIDTH = YOU_SCORED.get_rect().width
  693.  
  694. SPACE_CONTINUE = textHandler.stringSurface("press space to continue", DARK_GRAY)
  695. SPACE_CONTINUE_WIDTH = SPACE_CONTINUE.get_rect().width
  696.  
  697. """
  698.   __  ___     _        __              
  699.  /  |/  /__ _(_)__    / / ___  ___  ___
  700. / /|_/ / _ `/ / _ \ / /_/ _ \/ _ \/ _ \
  701. /_/  /_/\_,_/_/_//_/ /____|___/\___/ .__/
  702.                                  /_/  
  703. """
  704. while True:
  705.     gameTitleXOffset = 0
  706.     gameTitleAccelerationIndex = GAME_TITLE_TRAVEL_TIME
  707.     gameTitleDirection = -1
  708.     spacePressed = True
  709.     while True:
  710.         if quit():
  711.             pygame.quit()
  712.             sys.exit()
  713.  
  714.         frameTime = time.time() - FPSTime
  715.         if frameTime < SPF: continue
  716.         FPSTime += frameTime
  717.  
  718.         DS.blit(GAME_TITLE, (GAME_TITLE_X + gameTitleXOffset, 200))
  719.         DS.blit(SPACE_TITLE, (SPACE_TITLE_X, SPACE_TITLE_Y))
  720.         pygame.display.update()
  721.         DS.fill(BLACK)
  722.  
  723.         gameTitleXOffset += GAME_TITLE_ACCELERATION_THRESHOLD * gameTitleAccelerationIndex
  724.         gameTitleAccelerationIndex += gameTitleDirection
  725.  
  726.         if gameTitleAccelerationIndex == 0:
  727.             gameTitleDirection = 1
  728.         if gameTitleAccelerationIndex == GAME_TITLE_TRAVEL_TIME:
  729.             gameTitleXOffset = 0
  730.             gameTitleDirection = -1
  731.  
  732.         k = pygame.key.get_pressed()
  733.         if not k[pygame.K_SPACE]: spacePressed = False
  734.         if k[pygame.K_SPACE] and not spacePressed:
  735.             break
  736.    
  737.     DS.fill(BLACK)
  738.     bulletHoleHandler.reset()
  739.     queenHandler.reset()
  740.     enemyHandler.reset()
  741.     explosionHandler.reset()
  742.     crosshairHandler.reset()
  743.     bombHandler.reset()
  744.     scoreSurface = textHandler.stringSurface("score: 0", None, 2)
  745.     kills = 0    
  746.     backToTitle = False
  747.  
  748.     while True:
  749.         if quit():
  750.             backToTitle = True
  751.             break
  752.  
  753.         frameTime = time.time() - FPSTime
  754.         if frameTime < SPF: continue
  755.         FPSTime += frameTime
  756.         FRAME_COUNT += 1
  757.  
  758.         DS.blit(scoreSurface, (10, 10))
  759.  
  760.         bulletHoleHandler.do()
  761.         queenHandler.do()
  762.         enemyHandler.do()
  763.         explosionHandler.do()
  764.         crosshairHandler.do()
  765.         bombHandler.do()
  766.  
  767.         pygame.display.update()
  768.         DS.fill(BLACK)
  769.  
  770.         if queenHandler.dead and not explosionHandler.container: break
  771.    
  772.     if not backToTitle:
  773.         DS.fill(BLACK)
  774.         finalScore = textHandler.stringSurface("{}".format(kills), ORANGE, 1)
  775.         finalScoreWidth = finalScore.get_rect().width
  776.         spacePressed = True
  777.        
  778.         while True:
  779.             if quit():
  780.                 pygame.quit()
  781.                 sys.exit()
  782.  
  783.             DS.blit(YOU_SCORED, (HW - YOU_SCORED_WIDTH / 2, HH - 50))
  784.             DS.blit(finalScore, (HW - finalScoreWidth / 2, HH + 5))
  785.             DS.blit(SPACE_CONTINUE, (HW - SPACE_CONTINUE_WIDTH / 2, HH + 100))
  786.  
  787.             pygame.display.update()
  788.             DS.fill(BLACK)
  789.  
  790.             k = pygame.key.get_pressed()
  791.             if not k[pygame.K_SPACE]: spacePressed = False
  792.             if k[pygame.K_SPACE] and not spacePressed:
  793.                 break
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement