[PyGame] Getting projectiles into pygame. - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: Game Development (https://python-forum.io/forum-11.html) +--- Thread: [PyGame] Getting projectiles into pygame. (/thread-26952.html) |
Getting projectiles into pygame. - Everett_ - May-19-2020 Hey all, I'm really new to Python, this is only really my 5th or 6th day using the language (or really any major language). When I was younger I used Scratch a lot so if I'm using the wrong terminology or I am being unclear I'm sorry I can clear things up if you would like me to:). Right now this I'm trying to create a space-invaders-type clone, this is my first project without the direct help of a guide. So I want to have bullets come out of my plane sprite. I'm trying to figure out how to do two things really, one is to get a 'clone' of the bullet sprite to spawn at an x and y relative to the plane. I know how to use .blit((x, y)) but I can't figure out how to get a clone of the sprite to spawn in so I can have multiple bullets coming out of the plane. The next thing I want to figure out is how to get that new spawned clone of the sprite to keep going towards y = 0 and stopping either when it gets there or collides with the enemy(ies) I've googled some guides and posts and I either can't figure out how it could apply to my project or I can't understand what is happening. I saw a lot of ideas including classes and lists and while I understand what lists are I don't see/understand how they apply here, I am also starting to understand the usefulness of classes but they still are a bit confusing to me. Thanks for any help:) # imports and initializations import pygame import random pygame.init() # game start running = True gametick = 100 px = 250 # player x and y py = 275 pvel = 25 # player velocity and bullet vel bvel = 40 mod = 1 clock = pygame.time.Clock() # window window_height = 600 window_width = 800 window = pygame.display.set_mode((window_width, window_height)) pygame.display.set_caption("Game") # sprite imports. playerImg = pygame.image.load("images\player.png") backgroundImg = pygame.image.load("images\Background.png") bulletImg = pygame.image.load("images\Bullet.png") # Definitions def player(px, py): window.blit(playerImg, (px, py)) pygame.transform.scale(playerImg, (10, 10)) def background(): window.blit(backgroundImg, (0, 0)) def borders(): global px if px <= 0: px = 0 elif px >= 704: px = 704 # Gameloop while running: clock.tick(30) # Stop command for event in pygame.event.get(): if event.type == pygame.QUIT: running = False # Showing sprites and background background() player(px, py) # bullets # nothing here yet # Controls keys = pygame.key.get_pressed() if keys[pygame.K_LEFT]: borders() px -= pvel * mod if keys[pygame.K_RIGHT]: borders() px += pvel * mod if keys[pygame.K_UP]: pass # this will be for the bullets pygame.display.update() RE: Getting projectiles into pygame. - michael1789 - May-19-2020 The short answer is to use the Pygame Sprite Class. class Player(pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self) self.image = pygame.transform.scale(player_img, (60, 48)) self.image.set_colorkey(black) self.rect = self.image.get_rect() self.radius = 25 self.rect.center = (width / 2, height - 30) self.speedx = 0 self.shield = 100 self.shoot_delay = 250 self.last_shot = pygame.time.get_ticks() self.lives = 1 self.hidden = False self.hide_timer = pygame.time.get_ticks() self.power = 1 self.power_time = pygame.time.get_ticks() def update(self): if self.power >= 2 and pygame.time.get_ticks() - self.power_time > POWERUP_TIME: self.power -= 1 self.power_time = pygame.time.get_ticks() if self.hidden and pygame.time.get_ticks() - self.hide_timer > 1000: self.hidden = False self.rect.center = (width / 2, height - 30) self.speedx = 0 keystate = pygame.key.get_pressed() self.rect.x += self.speedx if keystate[pygame.K_LEFT]: self.speedx = -10 if keystate[pygame.K_RIGHT]: self.speedx = 10 if keystate[pygame.K_SPACE]: self.shoot() self.rect.x += self.speedx if self.rect.right > width: self.rect.right = width if self.rect.left < 0: self.rect.left = 0 def powerup(self): self.power += 1 self.power_time = pygame.time.get_ticks() def shoot(self): now = pygame.time.get_ticks() if now - self.last_shot > self.shoot_delay: self.last_shot = now if self.power == 1: bullet = Bullet(self.rect.centerx, self.rect.top) all_sprites.add(bullet) bullets.add(bullet) shoot_sound.play() if self.power >= 2: bullet1 = Bullet(self.rect.left, self.rect.centery) bullet2 = Bullet(self.rect.right, self.rect.centery) all_sprites.add(bullet1) bullets.add(bullet1) all_sprites.add(bullet2) bullets.add(bullet2) shoot_sound.play() def hide(self): self.hidden = True self.hide_timer = pygame.time.get_ticks() self.rect.center = (width / 2, height + 200) class Bullet(pygame.sprite.Sprite): def __init__(self, x, y): pygame.sprite.Sprite.__init__(self) self.image = bullet_img self.image.set_colorkey(black) self.rect = self.image.get_rect() self.rect.bottom = y self.rect.centerx = x self.speedy = -50 def update(self): self.rect.y += self.speedy if self.rect.bottom < 0: self.kill()This is cut from a vertical shooter I made from a tutorial. Specifically Player.shoot() refers to what you ask. A great video about classes can be seen here. RE: Getting projectiles into pygame. - Windspar - May-21-2020 For now just use classes as container. There two level to a class. Class level for a single instance. Objects for multiply instances. Class is a namespace you use to access variables. player_x = 250 player_y = 270 player_velocity = 25You could just use a class level instance. Only one instance can be made this way. class Player: x = 250 y = 275 velocity = 25 # To access variable of class instance. You use the namespace print(Player.x) print(Player.y) print(Player.velocity)If you wanted many different players. Then you use class object instances. class Player: # Class object initializer def __init__(self, x, y, velocity): self.x = x self.y = y self.velocity = velocity # Create a player. Argument match the __init__ method. player_a = Player(250, 270, 25) # Now player_a point to are new player class object. # player_a will be are namespace to the object. print(player_a.x) # Create are second player player_b = Player(450, 470, 25) print(player_a.x) print(player_b.x)What does self mean in a class. It standard word that point to your object. Uses self.x create a variable x in your object. Bullets. Use a list to store bullets positions. Only need list if shooting more than on bullet. bullets = [] bullets_remover = [] bullet_next_tick = 0 bullet_interval = 100 # how fast it can shootUse pygame.time.get_ticks() to control bullet shooting speed. ticks = pygame.time.get_ticks() if keys[pygame.K_UP]: if ticks > bullet_next_tick: bullet_next_tick = ticks + bullet_interval bullets.append([px, py]) for bullet in bullets: # Move bullet bullet[1] -= 5 if bullet[y] < 0: bullet_remover.append(bullet) else: window.blit(bulletImg, bullet) for bullet in bullet_remover: bullets.remove(bullet) bullet_remover = [] RE: Getting projectiles into pygame. - lolloiltizio - May-22-2020 Wow I'm new in this forum but I love it, i had same problem since I got used to scratch clones... Thank you! Here my first try with pygame. RE: Getting projectiles into pygame. - Everett_ - May-23-2020 Thank you all this is really helpful! :) RE: Getting projectiles into pygame. - lolloiltizio - May-24-2020 Hey boys, I've successfully created a space invaders clone with pygame thanks to you! I've used the "list method" and if you want to use a Rect instead an Img with windows.blit, you have to write the for loop after the pygame.draw(things) like this (note I've used some variables like colors that are not declared!): screen.fill(bgcolor) pygame.draw.rect(screen, color, ship) for bullet in bullets: bullet.y -= 5 if bullet.y < 0: bullet_remover.append(bullet) else: pygame.draw.rect(screen, color, bullet pygame.display.flip() clock.tick(60)Put this after the whole thing This is the code for the bullets, but with enemies is the same. To CONTROL the bullet shoot, you can simply append a Rect to the list in the while loop like this: while True: ticks = pygame.time.get_ticks() for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.mixer.music.stop() pygame.quit() print('Thanks for playing Space invaders! \nclosing...') sys.exit() if event.type == pygame.KEYDOWN: if event.key == pygame.K_UP: if ticks > bullet_next_tick: bullet_next_tick = ticks + bullet_interval bullets.append(pygame.Rect(ship.x, ship.y, 5, 20)) if event.key == pygame.K_RIGHT: x_spid += 5 if event.key == pygame.K_LEFT: x_spid -= 5 if event.type == pygame.KEYUP: if event.key == pygame.K_RIGHT: x_spid -= 5 if event.key == pygame.K_LEFT: x_spid += 5Obviously you still need to remove bullets for bullet in bullet_remover: bullets.remove(bullet) bullet_remover = []I'm really happy and proud of that. Thank you. Relly, thank you. (Tell me if you'd like to see the project ;)) (May-24-2020, 04:41 PM)lolloiltizio Wrote: Hey boys, I've successfully created a space invaders clone with pygame thanks to you! *really |