Advertisement
cookertron

Bubble Asteroids - Python Pygame

Nov 19th, 2022 (edited)
716
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 21.87 KB | Source Code | 0 0
  1. import time, sys
  2. from random import randint, uniform, choice
  3. import pygame
  4. from pygame import gfxdraw
  5. from pygame import Vector2 as V, Rect as R, Color as C
  6. from pygame.locals import *
  7.  
  8. def ball(color, radius):
  9.     surface = pygame.Surface((300, 300))
  10.     surface.fill(WHITE)
  11.     pygame.draw.circle(surface, color, (150, 150), 150)
  12.     pygame.gfxdraw.filled_circle(surface, 200, 100, 150, (255, 255, 255, 50))
  13.     pygame.gfxdraw.filled_circle(surface, 200, 65, 35, color + (50,))
  14.     pygame.gfxdraw.filled_circle(surface, 200, 65, 30, (255, 255, 255, 100))
  15.     pygame.gfxdraw.filled_circle(surface, 225, 115, 20, color + (50,))
  16.     pygame.gfxdraw.filled_circle(surface, 225, 115, 15, (255, 255, 255, 100))
  17.     scaled = pygame.transform.scale(surface, (radius * 2, radius * 2))
  18.     scaled.set_colorkey(WHITE)
  19.     return scaled
  20.  
  21. def bang(radius, color):
  22.     surface = pygame.Surface((radius * 0.75 * 2, radius * 0.875 * 2))
  23.     surface.set_colorkey((0, 0, 0))
  24.     surface.fill(color)
  25.  
  26.     pivot = V(surface.get_rect().center)
  27.     for degrees in range(0, 359, 60):
  28.         pygame.draw.circle(surface, (0, 0, 0), pivot + V(1, 0).rotate(degrees) * radius, radius // 2)
  29.     return pygame.transform.scale(surface, V(pivot.x * 2))
  30.  
  31. def wrap(pos):
  32.     if pos.x > PDR.w:
  33.         pos.x -= PDR.w
  34.     elif pos.x < 0:
  35.         pos.x += PDR.w
  36.     if pos.y > PDR.h:
  37.         pos.y -= PDR.h
  38.     elif pos.y < 0:
  39.         pos.y += PDR.h
  40.  
  41. class section:
  42.     def __init__(s, pivot, distance_from_pivot, angle_offset, radius, graphic=None):
  43.         s.pivot = pivot
  44.         s.dist = distance_from_pivot
  45.         s.dist_offset = 0
  46.         s.angle_offset = angle_offset
  47.         s.radius = radius
  48.  
  49.         s.graphic = graphic
  50.         if type(s.graphic) == pygame.Surface:
  51.             s.draw_graphic = s.draw_surface
  52.             s.alpha = s.set_surface_alpha
  53.         else:
  54.             s.draw_graphic = s.draw_primitive
  55.             s.primitive_alpha = 255
  56.             s.alpha = s.set_primitive_alpha
  57.  
  58.         s.update()
  59.  
  60.     def update(s):
  61.         s.pos = s.pivot.pos + V(1, 0).rotate(s.pivot.angle + s.angle_offset) * (s.dist + s.dist_offset)
  62.  
  63.         s.dimensions = [s.pos]
  64.  
  65.         if s.pos.x < s.radius:
  66.             s.dimensions.append(s.pos + PDR.topright)
  67.             if s.pos.y < s.radius:
  68.                 s.dimensions.append(s.pos + PDR.bottomright)
  69.             elif s.pos.y > PDR.h - s.radius:
  70.                 s.dimensions.append(s.pos + (PDR.w, -PDR.h))
  71.         elif s.pos.x > PDR.w - s.radius:
  72.             s.dimensions.append(s.pos + (-PDR.w, 0))
  73.             if s.pos.y < s.radius:
  74.                 s.dimensions.append(s.pos + (-PDR.w, PDR.h))
  75.             elif s.pos.y > PDR.h - s.radius:
  76.                 s.dimensions.append(s.pos + (-PDR.w, -PDR.h))
  77.         if s.pos.y < s.radius:
  78.             s.dimensions.append(s.pos + PDR.bottomleft)
  79.         elif s.pos.y > PDR.h - s.radius:
  80.             s.dimensions.append(s.pos + (0, -PDR.h))
  81.  
  82.     def draw_primitive(s, pos):
  83.         if s.radius > 0:
  84.             pygame.gfxdraw.filled_circle(PDS, int(pos.x), int(pos.y), int(s.radius), s.graphic + (s.primitive_alpha, ))
  85.  
  86.     def set_primitive_alpha(s, value):
  87.         s.primitive_alpha = value
  88.  
  89.     def draw_surface(s, pos):
  90.         PDS.blit(s.graphic, pos - s.graphic.get_rect().center)
  91.  
  92.     def set_surface_alpha(s, value):
  93.         s.graphic.set_alpha(value)
  94.  
  95.     def get_rear(s, offset=0):
  96.         pos = s.pos + V(-1, 0).rotate(s.pivot.angle + s.angle_offset) * (s.radius + offset)
  97.         wrap(pos)
  98.         return pos
  99.  
  100.     def get_front(s, offset=0):
  101.         pos = s.pos + V(1, 0).rotate(s.pivot.angle + s.angle_offset) * (s.radius + offset)
  102.         wrap(pos)
  103.         return pos
  104.  
  105.     def draw(s):
  106.         for dim in s.dimensions:
  107.             s.draw_graphic(dim)
  108.  
  109. class pivot:
  110.     def __init__(s, pos, angle=0):
  111.         s.pos = V(pos)
  112.         s.angle = angle
  113.         s.sections = []
  114.  
  115.     def add(s, _section):
  116.         s.sections.append(_section)
  117.    
  118.     def rel_move(s, offset):
  119.         s.pos += offset
  120.         wrap(s.pos)
  121.    
  122.     def draw(s, debug=False):
  123.         for section in s.sections:
  124.             section.draw()
  125.             if debug: pygame.draw.circle(PDS, RED, section.pos, 5)
  126.  
  127.     def update(s):
  128.         for section in s.sections:
  129.             section.update()
  130.    
  131.     def collision(s, pivot):
  132.         for source in s.sections:
  133.             for sDim in source.dimensions:
  134.                 for target in pivot.sections:
  135.                     for tDim in target.dimensions:
  136.                         if not (sDim.distance_to(tDim) < source.radius + target.radius): continue
  137.                         return True
  138.         return False
  139.    
  140.     def collision_radius(s, pos, radius=0):
  141.         for source in s.sections:
  142.             for sDim in source.dimensions:
  143.                 if sDim.distance_to(pos) < radius + source.radius: return True
  144.         return False
  145.  
  146. class explosions:
  147.     class explosion:
  148.         def __init__(s, pos, radius):
  149.             s.pivot = pivot(pos)
  150.             s.pivot.add(section(s.pivot, 0, 0, radius, bang(radius, WHITE)))
  151.             s.timestamp = NOW
  152.             s.dead = False
  153.        
  154.         def draw(s):
  155.             s.pivot.draw()
  156.        
  157.         def update(s):
  158.             if NOW - s.timestamp >= EXPLOSION_DURATION: s.dead = True
  159.  
  160.     def __init__(s):
  161.         s.explosions = []
  162.    
  163.     def add(s, section):
  164.         s.explosions.append(s.explosion(section.pos, section.radius * 2))
  165.  
  166.     def draw(s):
  167.         for explosion in s.explosions:
  168.             explosion.draw()
  169.  
  170.     def update(s):
  171.         dead_explosions = []
  172.         for explosion in s.explosions:
  173.             explosion.update()
  174.             if explosion.dead:
  175.                 dead_explosions.append(explosion)
  176.         for explosion in dead_explosions:
  177.             s.explosions.remove(explosion)
  178.  
  179. class particles:
  180.     class particle:
  181.         def __init__(s, pos, color, velocity=V(), rVelocity=0, delay=0, alpha=255, speed=0.01):
  182.             s.pos = V(pos)
  183.             s.velocity = V(velocity)
  184.             s.rVelocity = rVelocity
  185.             s.speed = speed
  186.  
  187.             s.lerp = 1
  188.             s.color = color
  189.             s.alpha = alpha
  190.  
  191.  
  192.             s.delay = delay
  193.             s.timestamp = NOW
  194.        
  195.         def update(s):
  196.             if NOW - s.timestamp <= s.delay: return
  197.            
  198.             s.pos += (s.velocity * s.lerp) * DELTA_TIME
  199.             if s.pos.x > PDR.w:
  200.                 s.pos.x -= PDR.w
  201.             elif s.pos.x < 0:
  202.                 s.pos.x += PDR.w
  203.             if s.pos.y > PDR.h:
  204.                 s.pos.y -= PDR.h
  205.             elif s.pos.y < 0:
  206.                 s.pos.y += PDR.h
  207.            
  208.             s.velocity.rotate_ip(s.rVelocity * DELTA_TIME)
  209.            
  210.             s.lerp -= s.speed * DELTA_TIME
  211.             if s.lerp < 0:
  212.                 s.lerp = 0
  213.        
  214.         def draw(s):
  215.             if NOW - s.timestamp <= s.delay: return
  216.             pygame.gfxdraw.filled_circle(PDS, int(s.pos.x), int(s.pos.y), 2, s.color + (int(s.lerp * s.alpha),))
  217.  
  218.     def __init__(s):
  219.         s.particles = []
  220.    
  221.     def add(s, particle):
  222.         s.particles.append(particle)
  223.    
  224.     def draw(s):
  225.         for particle in s.particles:
  226.             particle.draw()
  227.  
  228.     def update(s):
  229.         dead_particles = []
  230.         for particle in s.particles:
  231.             particle.update()
  232.             if not particle.lerp: dead_particles.append(particle)
  233.         for particle in dead_particles:
  234.             s.particles.remove(particle)
  235.  
  236. class bullets:
  237.     class bullet:
  238.         def __init__(s, pos, velocity, color):
  239.             s.pos = pos
  240.             s.velocity = velocity
  241.             s.distance_travelled = V()
  242.             s.color = color
  243.             s.lerp = 1
  244.             s.dead = False
  245.  
  246.         def draw(s):
  247.             pygame.gfxdraw.filled_circle(PDS, int(s.pos.x), int(s.pos.y), 3, WHITE + (int(s.lerp * 255),))
  248.            
  249.         def update(s):
  250.             distance = s.velocity * DELTA_TIME
  251.             s.pos += distance
  252.             if s.pos.x > PDR.w:
  253.                 s.pos.x -= PDR.w
  254.             if s.pos.x < 0:
  255.                 s.pos.x += PDR.w
  256.             if s.pos.y > PDR.h:
  257.                 s.pos.y -= PDR.h
  258.             if s.pos.y < 0:
  259.                 s.pos.y += PDR.h
  260.             s.distance_travelled += distance
  261.             total_distance = s.distance_travelled.magnitude()
  262.             if total_distance > BULLET_MAX_DISTANCE * BULLET_FADE_OUT_MARGIN:
  263.                 s.lerp = (BULLET_MAX_DISTANCE - total_distance) / BULLET_LERP_FACTOR
  264.             if total_distance >= BULLET_MAX_DISTANCE:
  265.                 s.dead = True
  266.  
  267.     def __init__(s):
  268.         s.pBullets = []
  269.         s.eBullets = []
  270.    
  271.     def player_bullet(s, pos, velocity, color):
  272.         s.pBullets.append(s.bullet(pos, velocity, color))
  273.    
  274.     def enemy_bullet(s, pos, velocity, color):
  275.         s.eBullets.append(s.bullet(pos, velocity, color))
  276.    
  277.     def draw(s):
  278.         for bullet in s.pBullets + s.eBullets:
  279.             bullet.draw()
  280.    
  281.     def update_bullets(s, bullets):
  282.         dead_bullets = []
  283.         for bullet in bullets:
  284.             bullet.update()
  285.             if bullet.dead: dead_bullets.append(bullet)
  286.         for bullet in dead_bullets:
  287.             bullets.remove(bullet)
  288.        
  289.     def update(s):
  290.         s.update_bullets(s.pBullets)
  291.         s.update_bullets(s.eBullets)
  292.  
  293. class asteroids:
  294.     class asteroid:
  295.         def __init__(s, pos, radius):
  296.             s.pivot = pivot(pos)
  297.             s.radius = radius
  298.             s.pivot.add(section(s.pivot, 0, 0, radius, ball(choice(ASTEROID_COLORS), radius)))
  299.             s.velocity = V(ASTEROID_SPEED, 0).rotate(randint(0, 359))
  300.  
  301.         def draw(s):
  302.             s.pivot.draw()
  303.        
  304.         def update(s):
  305.             s.pivot.rel_move(s.velocity * DELTA_TIME)
  306.             s.pivot.update()
  307.  
  308.         def collision(s, target_asteroid):
  309.             for source in s.pivot.sections:
  310.                 for sDim in source.dimensions:
  311.                     for target in target_asteroid.pivot.sections:
  312.                         for tDim in target.dimensions:
  313.                             if not (sDim.distance_to(tDim) < source.radius + target.radius): continue
  314.                             vector = tDim - sDim
  315.                             if vector.magnitude() < source.radius + target.radius:
  316.                                 target_asteroid.pivot.rel_move(vector.normalize() * (source.radius + target.radius + 1 - vector.magnitude()))
  317.                                 target_asteroid.pivot.update()
  318.                                 s.velocity.reflect_ip(tDim - sDim)
  319.                                 target_asteroid.velocity.reflect_ip(sDim - tDim)                                
  320.  
  321.         def get_split(s, index):
  322.             return s.pivot.pos + V(1, 0).rotate(-90 + 120 * index) * s.radius / 2
  323.  
  324.     def __init__(s, sizes):
  325.         s.asteroid_belt = []
  326.         for index, size in enumerate(sizes):
  327.             for _ in range(size):
  328.                 while True:
  329.                     found_space = True
  330.                     new_asteroid = s.asteroid(V(randint(0, PDR.w), randint(0, PDR.h)), ASTEROID_SIZES[index])
  331.                     for asteroid in s.asteroid_belt:
  332.                         if new_asteroid.pivot.collision(asteroid.pivot):
  333.                             found_space = False
  334.                             break
  335.                     if found_space: break
  336.                 s.asteroid_belt.append(new_asteroid)
  337.         s.spread = True
  338.         s.spread_size = 0
  339.         s.spread_particle_timestamp = NOW - ASTEROID_SPREAD_PARTICLE_DELAY
  340.  
  341.     def draw(s):
  342.         for asteroid in s.asteroid_belt:
  343.             asteroid.draw()
  344.    
  345.     def update(s):
  346.         if s.spread:
  347.             if NOW - s.spread_particle_timestamp >= ASTEROID_SPREAD_PARTICLE_DELAY:
  348.                 s.spread_particle_timestamp = NOW
  349.                 new_particle = particles.particle(PDR.center, choice(ASTEROID_COLORS), V(3 + uniform(0, 2), 0).rotate(randint(0, 359)), delay=uniform(0, ASTEROID_SPREAD_PARTICLE_DELAY))
  350.                 PARTICLES.add(new_particle)
  351.             s.spread_size += ASTEROID_SPREAD_SPEED * DELTA_TIME
  352.  
  353.         intrusion = False
  354.  
  355.         for asteroid1 in s.asteroid_belt:
  356.             if s.spread:
  357.                 vector = asteroid1.pivot.pos - PDR.center
  358.                 normal = vector.normalize()                
  359.                 distance = vector.magnitude()
  360.                 if distance < ASTEROID_EXCLUSION_RADIUS: intrusion = True
  361.                 if distance < s.spread_size:
  362.                     asteroid1.pivot.rel_move(normal * (s.spread_size - distance) / 50 * DELTA_TIME)
  363.             asteroid1.update()
  364.             for asteroid2 in s.asteroid_belt:
  365.                 if asteroid1 == asteroid2: continue
  366.                 asteroid1.collision(asteroid2)
  367.        
  368.         if s.spread and not intrusion:
  369.             s.spread = False
  370.             s.spread_size = 0
  371.    
  372.     def split(s, asteroid):
  373.         EXPLOSIONS.add(asteroid.sections[0])
  374.         if asteroid.radius == ASTEROID_SIZES[2]:
  375.             pass
  376.            
  377. class ship:
  378.     def __init__(s):
  379.         s.update = s.moving
  380.         s.pivot = pivot(PDR.center, -90)
  381.         s.pivot.add(section(s.pivot, 20, -135, 10, ball(SHIP_COLOR1, 10)))
  382.         s.pivot.add(section(s.pivot, 20, 135, 10, ball(SHIP_COLOR1, 10)))
  383.         s.pivot.add(section(s.pivot, 18, 0, 10, ball(SHIP_COLOR2, 10)))
  384.         s.pivot.add(section(s.pivot, 0, 0, 20, ball(SHIP_COLOR3, 20)))
  385.         s.pivot.add(section(s.pivot, 17, 180, 0, SHIP_COLOR4))
  386.         s.pivot.add(section(s.pivot, 17, 180, 0, SHIP_COLOR4))
  387.  
  388.         s.extra_sections = s.pivot.sections[:3]
  389.         s.nose_section = s.pivot.sections[2]
  390.         s.thrust_sections = s.pivot.sections[-2:]
  391.         s.body_section = s.pivot.sections[3]
  392.  
  393.         s.velocity = V()
  394.  
  395.         s.thrust_offset = 0
  396.         s.contrail_timestamp = time.perf_counter()
  397.         s.bullet_timestamp = time.perf_counter() - SHIP_BULLET_DELAY
  398.  
  399.     def thrusters(s):
  400.         if KEYS[K_UP] and s.update != s.death:        
  401.             s.thrust_offset += SHIP_THRUST_EXPAND_RATE * DELTA_TIME
  402.             if s.thrust_offset > 1: s.thrust_offset = 1
  403.         else:            
  404.             s.thrust_offset -= SHIP_THRUST_CONTRACT_RATE * DELTA_TIME
  405.             if s.thrust_offset < 0: s.thrust_offset = 0        
  406.         s.thrust_sections[0].dist_offset = s.thrust_offset * SHIP_THRUST_RADIUS
  407.         s.thrust_sections[0].radius = s.thrust_offset * SHIP_THRUST_RADIUS
  408.         s.thrust_sections[1].dist_offset = s.thrust_sections[0].dist_offset + s.thrust_offset * SHIP_THRUST_RADIUS
  409.         s.thrust_sections[1].radius = s.thrust_offset * SHIP_THRUST_RADIUS // 2
  410.  
  411.     def contrail(s):
  412.         if NOW - s.contrail_timestamp >= SHIP_CONTRAIL_DELAY:
  413.             new_particle = particles.particle(s.thrust_sections[1].pos, SHIP_CONTRAIL_COLOR)
  414.             PARTICLES.add(new_particle)
  415.             s.contrail_timestamp = NOW
  416.  
  417.     def moving(s):
  418.         if KEYS[K_RIGHT]:
  419.             s.pivot.angle += SHIP_ROTATIONAL_SPEED * DELTA_TIME
  420.         elif KEYS[K_LEFT]:
  421.             s.pivot.angle -= SHIP_ROTATIONAL_SPEED * DELTA_TIME
  422.  
  423.         if KEYS[K_UP]:
  424.             s.contrail()
  425.             s.velocity += V(SHIP_VELOCITY, 0).rotate(s.pivot.angle) * DELTA_TIME
  426.        
  427.         if KEYS[K_SPACE]:
  428.             if NOW - s.bullet_timestamp >= SHIP_BULLET_DELAY:
  429.                 BULLETS.player_bullet(s.nose_section.get_front(), V(SHIP_BULLET_SPEED, 0).rotate(s.pivot.angle), WHITE)
  430.                 s.bullet_timestamp = NOW
  431.                  
  432.         s.thrusters()
  433.        
  434.         s.pivot.rel_move(s.velocity * DELTA_TIME)
  435.         s.pivot.update()
  436.  
  437.     def kill(s):
  438.         EXPLOSIONS.add(s.body_section)
  439.         s.body_section.alpha(0)
  440.         s.update = s.death
  441.         s.death_lerp = 1
  442.  
  443.     def death(s):
  444.         s.death_lerp -= 0.01 * DELTA_TIME
  445.         if s.death_lerp < 0: s.death_lerp = 0
  446.  
  447.         for section in s.extra_sections:
  448.             section.dist_offset += (s.death_lerp * 2) * DELTA_TIME
  449.             section.alpha(s.death_lerp * 255)
  450.        
  451.         s.thrusters()
  452.         s.pivot.update()
  453.  
  454.         if NOW - s.contrail_timestamp >= SHIP_CONTRAIL_DELAY:
  455.             for section in s.extra_sections:
  456.                 PARTICLES.add(particles.particle(section.get_rear(4), SHIP_CONTRAIL_COLOR, alpha=s.death_lerp * 255, speed=0.03))
  457.             s.contrail_timestamp = NOW
  458.  
  459.     def collision(s, pivot_objects):
  460.         if s.update == s.death: return
  461.         for obj in pivot_objects:
  462.             if s.pivot.collision(obj.pivot):
  463.                 s.kill()
  464.  
  465.     def bullet_collision(s):
  466.         dead_asteroids = []
  467.         dead_bullets = []
  468.         for bullet in BULLETS.pBullets:
  469.             for asteroid in ASTEROIDS.asteroid_belt:
  470.                 if not asteroid.pivot.collision_radius(bullet.pos): continue                
  471.                 EXPLOSIONS.add(asteroid.pivot.sections[0])
  472.                 dead_asteroids.append(asteroid)
  473.                 dead_bullets.append(bullet)
  474.                 for degrees in range(0, 359, 72):
  475.                     new_particle = particles.particle(asteroid.pivot.pos, WHITE, V(5, 0).rotate(degrees), uniform(-0.5, 0.5))
  476.                     PARTICLES.add(new_particle)
  477.                 if not (asteroid.radius <= ASTEROID_SIZES[2]):
  478.                     for i in range(3):
  479.                         new_asteroid = asteroids.asteroid(asteroid.get_split(i), asteroid.radius / 2)
  480.                         ASTEROIDS.asteroid_belt.append(new_asteroid)
  481.                 break
  482.         for bullet in dead_bullets:
  483.             BULLETS.pBullets.remove(bullet)
  484.         for asteroid in dead_asteroids:
  485.             ASTEROIDS.asteroid_belt.remove(asteroid)
  486.                
  487.     def draw(s):
  488.         s.pivot.draw()
  489.  
  490. class grid:
  491.     class line:
  492.         class point:
  493.             def __init__(s, pos):
  494.                 s.anchor = V(pos)
  495.                 s.pos = V(pos)
  496.        
  497.         def __init__(s, p1, p2, steps):
  498.             s.vectors = []
  499.             s.points = []
  500.             vector = V(p2) - p1
  501.             dest = vector.magnitude()
  502.             chunk = dest / steps
  503.             normal = vector.normalize()
  504.             for i in range(steps + 1):
  505.                 s.vectors.append(s.point(V(p1) + normal * chunk * i))
  506.                 s.points.append(s.vectors[-1].pos)
  507.  
  508.         def update(s, mass_point, mass_radius):
  509.             s.points = []
  510.             for v in s.vectors:
  511.                 v1 = v.pos - mass_point
  512.                 if v1 != V():a1 = v1.normalize()
  513.                 else: a1 = V()                
  514.                 d1 = v1.magnitude()
  515.                 if d1 < mass_radius:
  516.                     v.pos += (a1 * (mass_radius - d1) / 50) * DELTA_TIME
  517.                 v2 = v.anchor - v.pos
  518.                 if v2 != V():a2 = v2.normalize()
  519.                 else: a2 = V()
  520.                 d2 = v2.magnitude()
  521.                 v.pos += a2 * d2 / 50 * DELTA_TIME
  522.                 s.points.append(v.pos)
  523.  
  524.         def draw(s):
  525.             pygame.gfxdraw.bezier(PDS, s.points, 2, DARK_GRAY)
  526.  
  527.     def __init__(s, size):
  528.         s.lines = []
  529.         for x in range(size, PDR.w, size):
  530.             s.lines.append(s.line((x, 0), (x, PDR.h), 10))
  531.         for y in range(size, PDR.h, size):
  532.             s.lines.append(s.line((0, y), (PDR.w, y), 10))
  533.    
  534.     def update(s, mass_point):
  535.         for l in s.lines:
  536.             l.update(mass_point, GRID_FORCE_RADIUS)
  537.    
  538.     def draw(s):
  539.         for l in s.lines:
  540.             l.draw()
  541.  
  542. pygame.init()
  543. PDR = R(0, 0, 1280, 720)
  544. PDS = pygame.display.set_mode(PDR.size)#, FULLSCREEN | SCALED)
  545. FPS = 120
  546. NOW = time.perf_counter()
  547.  
  548. WHITE = (255, 255, 255)
  549. REAL_BLACK = (0, 0, 0)
  550. BLACK = (10, 10, 10)
  551. RED = (255, 0, 0)
  552. DARK_GRAY = (64, 64, 64)
  553.  
  554. ASTEROID_COLORS = [
  555.     (26, 28, 44),   #0
  556.     (93, 39, 93),   #1
  557.     (177, 62, 83),  #2
  558.     (239, 125, 87), #3
  559.     (56, 183, 100), #4
  560.     (37, 113, 121), #5
  561.     (41, 54, 111),  #6
  562.     (59, 93, 201),  #7
  563.     (65, 166, 246), #8
  564.     (86, 108, 134), #9
  565.     (51, 60, 87),   #10
  566. ]
  567. ASTEROID_SPEED = 1
  568. ASTEROID_SIZES = [140, 70, 35]
  569. ASTEROID_EXCLUSION_RADIUS = 300
  570. ASTEROID_SPREAD_SPEED = 1
  571. ASTEROID_SPREAD_PARTICLE_DELAY = 0.01
  572. GRID_FORCE_RADIUS = 200
  573.  
  574. EXPLOSION_DURATION = 0.1
  575.  
  576. BULLET_MAX_DISTANCE = PDR.h
  577. BULLET_FADE_OUT_MARGIN = 0.80
  578. BULLET_LERP_FACTOR = BULLET_MAX_DISTANCE * (1 - BULLET_FADE_OUT_MARGIN)
  579.  
  580. SHIP_COLOR1 = (15, 200, 87)
  581. SHIP_COLOR2 = (255, 120, 0)
  582. SHIP_COLOR3 = (203, 35, 35)
  583. SHIP_COLOR4 = (200, 234, 0)
  584. SHIP_CONTRAIL_COLOR = (219, 116, 2)
  585. SHIP_ROTATIONAL_SPEED = 2
  586. SHIP_VELOCITY = 0.05
  587. SHIP_THRUST_EXPAND_RATE = 0.01
  588. SHIP_THRUST_CONTRACT_RATE = 0.05
  589. SHIP_THRUST_RADIUS = 10
  590. SHIP_CONTRAIL_DELAY = 0.1
  591. SHIP_BULLET_DELAY = 0.5
  592. SHIP_BULLET_SPEED = V(5, 0)
  593.  
  594. GRID = grid(80)
  595. ASTEROIDS = asteroids([1, 4, 4])
  596. EXPLOSIONS = explosions()
  597. PARTICLES = particles()
  598. BULLETS = bullets()
  599. SHIP = ship()
  600.  
  601. dts = time.perf_counter()
  602. DELTA_TIME = 0
  603.  
  604. exit_demo = False
  605. while not exit_demo:
  606.     NOW = time.perf_counter()
  607.     DELTA_TIME = (NOW - dts) * FPS
  608.     dts = NOW
  609.  
  610.     for e in pygame.event.get():
  611.         if e.type == KEYUP:
  612.             if e.key == K_ESCAPE:
  613.                 exit_demo = True
  614.         if e.type == MOUSEBUTTONUP:
  615.             if e.button == 1:
  616.                 EXPLOSIONS.add(ASTEROIDS.asteroid_belt[0].pivot.sections[0])
  617.  
  618.     KEYS = pygame.key.get_pressed()
  619.  
  620.     PDS.fill(BLACK)
  621.     GRID.draw()
  622.     PARTICLES.draw()
  623.     ASTEROIDS.draw()
  624.     if not ASTEROIDS.spread:
  625.         SHIP.draw()
  626.     BULLETS.draw()
  627.     EXPLOSIONS.draw()
  628.     pygame.display.update()
  629.     PARTICLES.update()
  630.     EXPLOSIONS.update()
  631.     BULLETS.update()
  632.     if not ASTEROIDS.spread:
  633.         SHIP.update()
  634.     ASTEROIDS.update()
  635.     GRID.update(SHIP.pivot.pos)
  636.    
  637.     if not ASTEROIDS.spread:
  638.         SHIP.collision(ASTEROIDS.asteroid_belt)
  639.         SHIP.bullet_collision()
  640.  
  641.     if SHIP.update == SHIP.death:
  642.         if not SHIP.death_lerp:
  643.             ASTEROIDS.spread = True
  644.             SHIP = ship()
  645. pygame.quit()
  646. sys.exit()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement