0

So recently I have been trying to make my first big game but I'm stuck on the shooting phase. Basically, my problem is I want to make it so that I can shoot multiple bullets and move around while doing so, but I can't seem to figure it out.

Code:

import pygame
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((600,600))
pygame.display.set_caption("Shooter Game!")
#Variables
playerX = 5
playerY = 5
black = (0,0,0)
blue = (0,0,255)
red = (255,0,0)
clicking = False
bulletX = playerX
bulletY = playerY
#End Of Variables#
while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            exit()
    screen.fill(blue)
    player = pygame.image.load("Young_Link_2D.png").convert_alpha()
    screen.fill(blue)
    player1 = pygame.transform.scale(player, (100,100))
    screen.blit(player1,(playerX,playerY))
    keyPressed = pygame.key.get_pressed()
    #Controls
    if keyPressed[pygame.K_a]:
        playerX -= 1
        bulletX = playerX
    if keyPressed[pygame.K_d]:
        playerX += 1
        bulletX = playerX
    if keyPressed[pygame.K_w]:
        playerY -= 1
        bulletY = playerY
    if keyPressed[pygame.K_s]:
        playerY += 1
        bulletY = playerY
    #End of Controls
    
    #Shooting
    if event.type == pygame.MOUSEBUTTONUP:
        if event.button == 1:
            Bullet = pygame.draw.rect(screen, red, (bulletX+35,bulletY + 60,10,25))
            bulletY = bulletY + 1
    
    pygame.display.update()
Nimantha
  • 6,405
  • 6
  • 28
  • 69
Ravishankar D
  • 131
  • 10
  • The reason u cant shoot many bullets and only one bullet is because u only have one instance. You should add a Bullet class with the methods to create a new instance every time the user demands it. That means that when you shoot, the bullet eg travels but then u shoot again and u place the bullet back at the player. The SAME bullet. So instead u should create a new bullet for every time the user wants to shoot –  Jan 16 '22 at 13:37

2 Answers2

1

Here is what i meant by classes:

import pygame
import Bullet
from pygame.locals import *

pygame.init()
screen = pygame.display.set_mode((600, 600))
pygame.display.set_caption("Shooter Game!")
# Variables
playerX = 5
playerY = 5
black = (0, 0, 0)
blue = (0, 0, 255)
red = (255, 0, 0)
clicking = False
bulletX = playerX
bulletY = playerY
bullets = []
newBullet = False
# End Of Variables#
while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            exit()
    screen.fill(blue)
    player = pygame.image.load("100x100_logo.png").convert_alpha()
    screen.fill(blue)
    player1 = pygame.transform.scale(player, (100, 100))
    screen.blit(player1, (playerX, playerY))
    keyPressed = pygame.key.get_pressed()
    # Controls
    if keyPressed[pygame.K_a]:
        playerX -= 1
        bulletX = playerX
    if keyPressed[pygame.K_d]:
        playerX += 1
        bulletX = playerX
    if keyPressed[pygame.K_w]:
        playerY -= 1
        bulletY = playerY
    if keyPressed[pygame.K_s]:
        playerY += 1
        bulletY = playerY
    # End of Controls

    # Shooting
    if event.type == pygame.MOUSEBUTTONDOWN:
        if event.button == 1:
            bullets.append(Bullet.Bullet(bulletX + 35, bulletY + 60))

    for i in range(len(bullets)):
        bullets[i].draw(screen, (255, 0, 0))
        bullets[i].move(1)
    print(len(bullets))

    pygame.display.update()

Thats your main code. There is still a bug where there is no cooldown so multiple bullets are created consecutively when holding the mouse button.

import pygame

class Bullet:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def draw(self, win, colour):
        pygame.draw.rect(win, colour, (self.x, self.y, 10, 25))

    def move(self, speed):
        self.y += speed

and thats the bullet class to create multiple instances

  • If you dont want to use OOP, then u can just add a cooldown and move the bullet from out of the screen, once its travelled there, back to the player –  Jan 16 '22 at 14:04
  • But I am getting the error on the line "import Bullet" there's no module like that right? – Ravishankar D Jan 16 '22 at 16:44
  • well u need to make two files, one for the 'Bullet' and import the path but just put them in the same folder. Its basically your own module –  Jan 17 '22 at 19:34
0

See How do I stop more than 1 bullet firing at once? and How can i shoot a bullet with space bar?.

You need to manage the bullets in a list:

bullets = []

Add a new bullet to the list when the mouse click is detected. Use pygame.Rect objects to represent the bullets. The events must be handled in the event loop:

for event in pygame.event.get():
    # [...]

    if event.type == pygame.MOUSEBUTTONUP:
        if event.button == 1:
            bullets.append(pygame.Rect(playerX, playerY, 35, 60))

Move the bullets in a loop. Remove the bullets from the list, when they when they move off the screen. See How to remove items from a list while iterating?:

for bullet in bullets[:]:
    bullet.y += 5
    if bullet.top > 600:
        bullets.remove(bullet)

Draw all the bullets in the list in another loop:

for bullet in bullets:
    pygame.draw.rect(screen, red, bullet)

Complete example:

import pygame
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((600,600))
pygame.display.set_caption("Shooter Game!")
#Variables
player = pygame.image.load("Young_Link_2D.png").convert_alpha()
playerX, playerY = 5, 5
black = (0,0,0)
blue = (0,0,255)
red = (255,0,0)
clicking = False
bullets = []
#End Of Variables#
clock = pygame.time.Clock()
running = True
while running:
    clock.tick(100)
    for event in pygame.event.get():
        if event.type == QUIT:
            running = False
        if event.type == pygame.MOUSEBUTTONUP:
            if event.button == 1:
                bullets.append(pygame.Rect(playerX, playerY, 35, 60))
    
    keyPressed = pygame.key.get_pressed()
    playerX += keyPressed[pygame.K_d] - keyPressed[pygame.K_a]
    playerY += keyPressed[pygame.K_s] - keyPressed[pygame.K_w]

    for bullet in bullets[:]:
        bullet.y += 5
        if bullet.top > 600:
            bullets.remove(bullet)

    screen.fill(blue)
    player1 = pygame.transform.scale(player, (100,100))
    screen.blit(player1,(playerX,playerY))
    for bullet in bullets:
        pygame.draw.rect(screen, red, bullet)
    pygame.display.update()

pygame.quit()
exit()
Rabbid76
  • 202,892
  • 27
  • 131
  • 174