Advertisement
Guest User

python self.kill not functioning

a guest
Aug 16th, 2022
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.54 KB | None | 0 0
  1. import pygame as pg
  2. import math
  3.  
  4.  
  5. SCREEN_WIDTH, SCREEN_HEIGHT = (1280, 720)
  6. HALF_WIDTH, HALF_HEIGHT = SCREEN_HEIGHT // 2, SCREEN_HEIGHT // 2
  7.  
  8. KEY_MAPPING = {
  9.     'left':  pg.K_a,
  10.     'right': pg.K_d,
  11.     'up':    pg.K_w,
  12.     'down':  pg.K_s,
  13.     'shoot': pg.MOUSEBUTTONDOWN
  14. }
  15.  
  16.  
  17. blue = (113, 221, 238)
  18.  
  19.  
  20. class Element(pg.sprite.Sprite):
  21.     """
  22.    Returns an image and a rectangle of self. Also has a function
  23.    which scales the image and rectangle when ever the screen
  24.    changes size.
  25.    """
  26.     def __init__(self, img, x, y):
  27.         pg.sprite.Sprite.__init__(self)
  28.         try:
  29.             self.default_image = self.image = pg.image.load(f"{img}.png").convert_alpha()
  30.         except FileNotFoundError:
  31.             self.default_image = self.image = img
  32.         self.rect = self.image.get_rect(center=(x, y))
  33.  
  34.         # DO NOT USE THESE ATTRIBUTES ! THEY ARE FOR RESIZING ONLY
  35.         self.resize_w = self.default_image.get_width()
  36.         self.resize_h = self.default_image.get_height()
  37.         self.resize_x = x
  38.         self.resize_y = y
  39.         all_elements.add(self)
  40.  
  41.     def update_size(self):
  42.         # NEVER CALL THIS METHOD OUTSIDE OF resize_display()
  43.         self.image, self.rect = image_rescaler(self.default_image, (self.resize_x, self.resize_y),
  44.                                                (self.resize_w, self.resize_h))
  45.  
  46.  
  47. class Entity(pg.sprite.Sprite):
  48.     def __init__(self, speed, group):
  49.         pg.sprite.Sprite.__init__(self)
  50.         self.speed = speed
  51.         group.add(self)
  52.  
  53.  
  54. class CameraGroup(pg.sprite.Group):
  55.     """
  56.    Tne class to contain all game sprites which are visible
  57.    when the game is active. This class creates a "camera"
  58.    which gives an effect of screen scrolling based on
  59.    the player.
  60.    """
  61.     def __init__(self):
  62.         super().__init__()
  63.         # camera offset
  64.         self.offset = pg.math.Vector2()
  65.  
  66.         # ground
  67.         self.ground_img = pg.image.load("ground.png").convert_alpha()
  68.         self.ground = Element(self.ground_img, 0, 0)
  69.         self.ground.rect.topleft = (0, 0)
  70.  
  71.     def center_target_camera(self, target):
  72.         # offset based on (player coordinate - half screen size) to center player.
  73.         self.offset.x = target.rect.centerx - HALF_WIDTH
  74.         self.offset.y = target.rect.centery - HALF_HEIGHT
  75.  
  76.     def custom_draw(self, target):
  77.         # call function to calculate offset
  78.         self.center_target_camera(target)
  79.  
  80.         # draw ground
  81.         ground_offset = self.ground.rect.topleft - self.offset
  82.         screen.blit(self.ground.image, ground_offset)
  83.  
  84.         # iterates through all sprites in the class CameraGroup, ordered by their y position (highest to smallest)
  85.         for sprite in sorted(self.sprites(), key=lambda sprite: sprite.rect.centery):
  86.             offset_pos = sprite.rect.topleft - self.offset
  87.             screen.blit(sprite.image, offset_pos)
  88.  
  89.  
  90. class Player(Element, Entity):
  91.     """
  92.    Player class
  93.    """
  94.     def __init__(self, x, y, image, speed, group):
  95.         Entity.__init__(self, speed, group)
  96.         Element.__init__(self, image, x, y)
  97.  
  98.         # Stores (x, y) of direction
  99.         self.direction = pg.math.Vector2()
  100.         # Boolean variables to check if the player is currently doing anything.
  101.         self.shooting = False
  102.         self.up = False
  103.         self.down = False
  104.         self.right = False
  105.         self.left = False
  106.  
  107.         self.shoot_cooldown = 200
  108.         self.start_time = self.last_shot_time = self.current_time = pg.time.get_ticks()
  109.  
  110.     def update(self):
  111.         # Calling methods to add player functionality and animation
  112.         self.move()
  113.  
  114.     def change_direction(self, k_pressed, boolean):
  115.         # Changes the player's direction by checking it against a dictionary. Useful for keybind changing
  116.  
  117.         # Retrieving the key of the value "k_pressed" if it exists in KEY_MAPPING, and assigning to key_press
  118.         if k_pressed in KEY_MAPPING.values():
  119.             key_press = [k for k, v in KEY_MAPPING.items() if v == k_pressed][0]
  120.         else:
  121.             key_press = ""
  122.         if key_press == "right":
  123.             self.right = boolean
  124.         if key_press == "left":
  125.             self.left = boolean
  126.         if key_press == "up":
  127.             self.up = boolean
  128.         if key_press == "down":
  129.             self.down = boolean
  130.  
  131.     def move(self):
  132.         # Changing the player direction based on the boolean variables in change_direction
  133.         self.direction.x = -1 if self.left else 1 if self.right else 0
  134.         self.direction.y = -1 if self.up else 1 if self.down else 0
  135.  
  136.         # Moving the player
  137.         self.rect.center += self.direction * self.speed
  138.  
  139.     def shoot(self, pos):
  140.         self.current_time = pg.time.get_ticks()
  141.         # Allow the player to shoot (but not continuously)
  142.         if not self.shooting and self.current_time - self.last_shot_time >= self.shoot_cooldown:
  143.             self.last_shot_time = self.current_time
  144.             # Setting self.shooting to True so that only one bullet is created
  145.             self.shooting = True
  146.             # Creating the bullet
  147.             bullet = Bullet(self.rect.centerx, self.rect.centery, "bullet", pos, 2, a_s.camera)
  148.  
  149.         # Reset self.shooting
  150.         self.shooting = False
  151.  
  152.  
  153. class Bullet(Element, Entity):
  154.     def __init__(self, x, y, image, pos, speed, group):
  155.         Entity.__init__(self, speed, group)
  156.         Element.__init__(self, image, x, y)
  157.         pg.sprite.Sprite.__init__(self)
  158.         # Creating image, fipping it on the x (for easier calculation later) and scaling it.
  159.         self.image = pg.transform.flip(self.image, True, False)
  160.         self.image = pg.transform.scale(self.image, (32, 16))
  161.  
  162.         self.x = x
  163.         self.y = y
  164.         self.mousepos = pos
  165.         # Calculating the angle of bullet, so we can rotate it depending on direction
  166.         self.angle = math.atan2(pos[1] - y, pos[0] - x)
  167.         self.angle_deg = (self.angle * (180 / math.pi))
  168.         self.image = pg.transform.rotate(self.image, self.angle_deg * -1)
  169.         # Calculating the velocity of the bullet in both directions
  170.         dx = self.mousepos[0] - x
  171.         dy = self.mousepos[1] - y
  172.         total = abs(dx) + abs(dy)
  173.         self.vel_x = (self.speed * (dx / total))
  174.         self.vel_y = (self.speed * (dy / total))
  175.         # Variables which allow us to kill the bullet after some time
  176.         self.start_time = pg.time.get_ticks()
  177.         # Lifetime of bullet before being killed, in ms
  178.         self.lifetime = 500
  179.  
  180.     def update(self):
  181.         # Killing the bullet after self.lifetime has passed
  182.         if pg.time.get_ticks() - self.start_time > self.lifetime:
  183.             self.kill()
  184.             print("Killing")
  185.         # Moving the bullet (accurately, self.x is float while self.rect.x can only be int)
  186.         self.x += self.vel_x
  187.         self.y += self.vel_y
  188.         self.rect.x = int(self.x)
  189.         self.rect.y = int(self.y)
  190.  
  191.  
  192. def get_font(size):
  193.     font = pg.font.Font(None, size)
  194.     return font
  195.  
  196.  
  197. class Scene(object):
  198.     """
  199.    The base Scene class.
  200.    Raises an error if a required method is missing.
  201.    """
  202.     def __init__(self):
  203.         # creating variables which are used in most scene classes
  204.         self.bg_colour = (179, 66, 245)
  205.         self.font_l = get_font(72)
  206.         self.font_m = get_font(48)
  207.         self.font_s = get_font(32)
  208.  
  209.     def render(self):
  210.         raise NotImplementedError
  211.  
  212.     def update(self):
  213.         raise NotImplementedError
  214.  
  215.     def handle_events(self, events):
  216.         raise NotImplementedError
  217.  
  218.  
  219. class GameScene(Scene):
  220.     """
  221.    Game Scene class to handle all game logic which occurs
  222.    when the game is active, such as movement and shooting.
  223.    """
  224.     def __init__(self):
  225.         super(GameScene, self).__init__()
  226.         # Create object instances
  227.         self.camera = CameraGroup()
  228.         self.player = Player(HALF_WIDTH, HALF_HEIGHT, "player", 5, self.camera)
  229.  
  230.     def render(self):
  231.         screen.fill(blue)
  232.         # Drawing all elements in self.camera so that they have a y-sort and the screen is centered on the player
  233.         self.camera.custom_draw(self.player)
  234.  
  235.     def update(self):
  236.         self.camera.update()
  237.  
  238.     def handle_events(self, events):
  239.         for e in events:
  240.             if e.type == KEY_MAPPING['shoot']:
  241.                 m_pos = pg.mouse.get_pos()
  242.                 pos = (m_pos[0] + self.camera.offset[0], m_pos[1] + self.camera.offset[1])
  243.                 self.player.shoot(pos)
  244.             if e.type == pg.KEYDOWN:
  245.                 if e.key == pg.K_ESCAPE:
  246.                     # go to main menu if escape i   s pressed
  247.                     self.manager.go_to(main_menu_scene)
  248.                 self.player.change_direction(e.key, True)
  249.  
  250.             if e.type == pg.KEYUP:
  251.                 self.player.change_direction(e.key, False)
  252.  
  253.  
  254. class SceneManager(object):
  255.     def __init__(self):
  256.         # Game begins on main_menu
  257.         #self.go_to(main_menu_scene)
  258.         self.go_to(game_scene)
  259.         #self.go_to(options_scene)
  260.  
  261.     def go_to(self, scene):
  262.         global a_s
  263.         # Changes self.scene, so we can access the current scene
  264.         self.scene = scene
  265.         # Allows us to use go_to() in the active scene to change scenes rather than accessing manager every time.
  266.         self.scene.manager = self
  267.         # Easier way to reference the current scene
  268.         a_s = self.scene
  269.  
  270.  
  271. def main():
  272.     # Initialising pygame, creating the game screen window and setting the frame rate
  273.     global screen, FPS, all_elements
  274.     global game_scene
  275.     pg.init()
  276.     clock = pg.time.Clock()
  277.     FPS = 60
  278.     screen = pg.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
  279.     pg.display.set_caption("Game")
  280.  
  281.     # loading assets and creating global requirements for running the game
  282.     all_elements = pg.sprite.Group()
  283.  
  284.     # creating scene instances to avoid manager.go_to(scene) creating new scenes every time.
  285.     game_scene = GameScene()
  286.  
  287.     manager = SceneManager()
  288.  
  289.     # main game loop
  290.     running = True
  291.     while running:
  292.         # set caption to display FPS
  293.         pg.display.set_caption(f"Game - {round(clock.get_fps(), 2)}")
  294.         clock.tick(FPS)
  295.  
  296.         # check if user quits program
  297.         if pg.event.get(pg.QUIT):
  298.             running = False
  299.  
  300.         # event handler, updating and rendering for the active scene.
  301.         manager.scene.handle_events(pg.event.get())
  302.         manager.scene.update()
  303.         manager.scene.render()
  304.         # updating the display
  305.         pg.display.update()
  306.  
  307.  
  308. if __name__ == "__main__":
  309.     main()
  310.     quit()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement