Advertisement
cookertron

Python Pygame - Laser Cannon

Feb 8th, 2020
382
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.68 KB | None | 0 0
  1. import pygame
  2. import pygame.gfxdraw
  3. import time
  4. import random
  5. import math
  6.  
  7. W, H = 1280, 720
  8. HW, HH = int(W / 2), int(H / 2)
  9.  
  10. FPS = 120
  11.  
  12. class ease:
  13.     def __init__(s, height, frames):
  14.         if frames < 2 or not height:
  15.             s.gravity = 0
  16.             s.velocity = 0
  17.         else:
  18.             s.gravity = 2 * height / (frames * (frames - 1))
  19.             s.velocity = s.gravity * (frames - 1)
  20.         s.iFrames = int(frames)
  21.         s.frames = frames
  22.  
  23.     def pv(s, index):
  24.         return s.gravity * index
  25.  
  26.     def nv(s, index):
  27.         return s.velocity - s.gravity * index
  28.  
  29. # game time
  30. class gTime:
  31.     def __init__(s, fps): # input = frames per second
  32.         s.fps = fps
  33.         s.tpf = 1 / fps * 1000000000
  34.         s.time = 0
  35.         s.timeStamp = time.time_ns()
  36.  
  37.     def tick(s):
  38.         while time.time_ns() - s.timeStamp < s.tpf:
  39.             pass
  40.         s.timeStamp = time.time_ns()
  41.         s.time += 1
  42.  
  43. # laser cannon settings
  44. LASER_CANNON_RADIUS = 15
  45. LASER_CANNON_RELOAD_DELAY = 15 # frames
  46. LASER_SPEED = 10 # pixels
  47. LASER_LENGTH = 20 # pixels
  48.  
  49. class laserCannon:
  50.     class laser:
  51.         def __init__(s, parent):
  52.             global LASER_CANNON_RADIUS
  53.             global TIME
  54.             s.p = parent # keep a parental reference
  55.  
  56.             # setup starting coords
  57.             s.x1 = s.x2 = s.p.x
  58.             s.y1 = s.y2 = s.p.y
  59.  
  60.             # get direction
  61.             mx, my = pygame.mouse.get_pos()
  62.             s.dx, s.dy = mx - s.x1, my - s.y1
  63.             s.d = math.sqrt((s.dx * s.dx) + (s.dy * s.dy))
  64.             if s.d < LASER_CANNON_RADIUS:
  65.                 s.dx = random.uniform(-1, 1)
  66.                 s.dy = random.uniform(-1, 1)
  67.             else:
  68.                 s.dx /= s.d
  69.                 s.dy /= s.d                
  70.  
  71.             s.ts = TIME.time
  72.             s.dead = False
  73.  
  74.         def draw(s):
  75.             global DS
  76.             pygame.gfxdraw.line(DS, int(s.x1), int(s.y1), int(s.x2), int(s.y2), [255, 255, 255])
  77.  
  78.         def do(s):
  79.             global LASER_SPEED
  80.             global TIME
  81.  
  82.             l = TIME.time - s.ts - 1
  83.             if l > 120: # laser exists for 120 frames
  84.                 s.dead = True
  85.                 return
  86.  
  87.             # move the laser
  88.             s.x1 += s.dx * LASER_SPEED
  89.             s.y1 += s.dy * LASER_SPEED
  90.            
  91.             # get the distance between the cannon and the front tip of the laser
  92.             # if the distance means there's an overlap between the laser and the cannon
  93.             # truncate the laser length
  94.             # this is to make sure the laser doesn't appear out of the back of the cannon
  95.             d = math.hypot(s.x1 - s.p.x, s.y1 - s.p.y)
  96.             if d - LASER_LENGTH < LASER_CANNON_RADIUS:
  97.                 ll = LASER_LENGTH - (LASER_LENGTH - d)
  98.             else:
  99.                 ll = LASER_LENGTH
  100.  
  101.             # calculate the end tip of the laser
  102.             s.x2 = s.x1 - s.dx * ll
  103.             s.y2 = s.y1 - s.dy * ll
  104.    
  105.     def __init__(s):
  106.         global LASER_CANNON_RADIUS
  107.         global TIME
  108.         global HW, HH
  109.  
  110.         # position the cannon
  111.         s.x = HW
  112.         s.y = -LASER_CANNON_RADIUS
  113.        
  114.         # cannon will drop into position
  115.         s.e = ease(HH + LASER_CANNON_RADIUS, 240)
  116.        
  117.         # set up a few variables
  118.         s.ts = TIME.time # timestamp to control rate of fire
  119.         s.triggerPressed = False # only fire when lmb released
  120.         s.reloadDelay = 0 # time delay before being allowed to fire another laser
  121.         s.mode = s.fallingIntoPosition # current mode of the cannon (falling/ready)
  122.  
  123.         s.laserContainer = [] # list of laser objects
  124.  
  125.     def draw(s):
  126.         global LASER_CANNON_RADIUS
  127.         global DS
  128.  
  129.         pygame.gfxdraw.filled_circle(DS, s.x, int(s.y), LASER_CANNON_RADIUS, [255, 255, 255])
  130.         for l in s.laserContainer:
  131.             l.draw()
  132.  
  133.     def do(s):
  134.         s.draw()
  135.         s.mode()
  136.  
  137.     def fallingIntoPosition(s):
  138.         global TIME
  139.         global HH
  140.  
  141.         l = TIME.time - s.ts - 1
  142.         if l == s.e.iFrames: # if the cannon has finished falling, move onto ready mode
  143.             s.mode = s.ready
  144.         else:
  145.             s.y += s.e.nv(l)
  146.  
  147.     def ready(s):
  148.         global LASER_CANNON_RELOAD_DELAY
  149.  
  150.         # if mouse button is pressed fire a laser
  151.         lmb = pygame.mouse.get_pressed()[0]
  152.         if lmb and not s.triggerPressed:
  153.             s.triggerPressed = True
  154.         elif not lmb and s.triggerPressed:
  155.             s.triggerPressed = False
  156.             if not s.reloadDelay:
  157.                 s.laserContainer.append(s.laser(s))
  158.                 s.reloadDelay = LASER_CANNON_RELOAD_DELAY # set re-fire delay
  159.        
  160.         # count down fire delay tp zero
  161.         if s.reloadDelay:
  162.             s.reloadDelay -= 1
  163.  
  164.         dead = [] # container for dead lasers
  165.         for l in s.laserContainer:
  166.             l.do()
  167.             if l.dead: dead.append(l) # add dead lasers to list
  168.         for dl in dead: # remove dead lasers from container
  169.             s.laserContainer.remove(dl)
  170.  
  171.         # move the cannon using wasd keys
  172.         k = pygame.key.get_pressed()
  173.         if k[pygame.K_w]:
  174.             s.y -= 2
  175.         elif k[pygame.K_s]:
  176.             s.y += 2
  177.         if k[pygame.K_d]:
  178.             s.x += 2
  179.         elif k[pygame.K_a]:
  180.             s.x -= 2
  181.  
  182. pygame.init()
  183. DS = pygame.display.set_mode((W, H))
  184. TIME = gTime(FPS)
  185.  
  186. L = laserCannon()
  187.  
  188. # press ESCAPE to exit demo
  189. while True:
  190.     e = pygame.event.get()
  191.     if pygame.key.get_pressed()[pygame.K_ESCAPE]: break
  192.  
  193.     DS.fill([0, 0, 0]) # clear screen
  194.     L.do() # call laser routine
  195.  
  196.     pygame.display.update()
  197.     TIME.tick() # halt program for tpf (time per frame)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement