pythonpygamespritebullet

I have problem with bullet motion in pygame


When i shot i can control bullet in a fly. How can i avoid it. I want to bullet moved and i can't control it. Maybe i should to fix my code. But i can't solved it. For example bullet fly to right but when i pressed keys K_LEFT the bullet changes route.

import pygame
pygame.init()
#Frames
FPS = 60
#Colors
WHITE = (255, 255, 255)
GREY = (105, 105, 105)
BLACK = (0, 0, 0)
GREEN = (0, 225, 0)
#Screen size
W = 1280
H = 680
#Player_img
p_up = pygame.image.load('Assets/tanks/green/up1.png')
p_d = pygame.image.load('Assets/tanks/green/down1.png')
p_r = pygame.image.load('Assets/tanks/green/right1.png')
p_l = pygame.image.load('Assets/tanks/green/left1.png')
#Scale_img
player_up = pygame.transform.scale(p_up, (40, 40))
player_d = pygame.transform.scale(p_d, (40, 40)) 
player_r = pygame.transform.scale(p_r, (40, 40))
player_l = pygame.transform.scale(p_l, (40, 40))
#Screen
sf = pygame.display.set_mode((W, H))
pygame.display.set_caption('TanksX')
sf.fill(WHITE)
#Clock
clock = pygame.time.Clock()
#For Game
Run = True
last_move = 0
#Sprites init
class Player(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = player_up
        self.rect = self.image.get_rect()
        self.rect.centerx = W // 2
        self.rect.y = H // 2
        self.speedy = 2
        self.speedx = 2
        self.shoot_delay = 1000
        self.last_shot = pygame.time.get_ticks()
    def update(self):
        global last_move
        if keys[pygame.K_UP]:
            self.image = pygame.transform.rotate(player_up, 360)
            self.rect.y -= self.speedy
            last_move = 1
        elif keys[pygame.K_DOWN]:
            self.image = pygame.transform.rotate(player_up, 180)
            self.rect.y += self.speedy
            last_move = 2
        elif keys[pygame.K_RIGHT]:
            self.image = pygame.transform.rotate(player_up, -90)
            self.rect.x += self.speedx
            last_move = 3
        elif keys[pygame.K_LEFT]:
            self.image = pygame.transform.rotate(player_up, 90)
            self.rect.x -= self.speedx
            last_move = 4

        if keys[pygame.K_SPACE]:
            self.shoot()
    def shoot(self):
        now = pygame.time.get_ticks()
        if now - self.last_shot > self.shoot_delay:
            self.last_shot = now
            bullet1 = Bullet(self.rect.centerx, self.rect.centery)
            all_sprites.add(bullet1)
            bullets.add(bullet1)

class Bullet(pygame.sprite.Sprite):
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        a = 10
        b = 10
        self.image = pygame.Surface((a, b))
        self.rect = self.image.get_rect()
        self.rect.centerx = x
        self.rect.centery = y
        self.speedy = 10
        self.speedx = 10
    def update(self):
        global last_move
        if self.rect.x > W or self.rect.x < 0 or self.rect.y > H or self.rect.y < 0:
            self.kill()
        if last_move == 1:
            self.rect.y -= self.speedy
        if last_move == 2:
            self.rect.y += self.speedy
        if last_move == 3:
            self.rect.x += self.speedx
        if last_move == 4:
            self.rect.x -= self.speedx
#Groups
all_sprites = pygame.sprite.Group()
players = pygame.sprite.Group()
bullets = pygame.sprite.Group()
#Sprites
player1 = Player()
#Add Sprites to Groups
all_sprites.add(player1)
players.add(player1)
#Game
while Run:
    keys = pygame.key.get_pressed()
    for i in pygame.event.get():
        if i.type == pygame.QUIT:
            exit()

    all_sprites.draw(sf)
    all_sprites.update()
    pygame.display.flip()
    sf.fill(WHITE)
    clock.tick(FPS)

Please help me i will be very gratefull. I'm new to a python and pygame. Thankyou


Solution

  • The movement of the bullet is not affected by the current movement of the player. Add the arguments speedx and speedy to the class Bullet:

    class Bullet(pygame.sprite.Sprite):
        def __init__(self, x, y, speedx, speedy):
            pygame.sprite.Sprite.__init__(self)
            a = 10
            b = 10
            self.image = pygame.Surface((a, b))
            self.rect = self.image.get_rect()
            self.rect.centerx = x
            self.rect.centery = y
            self.speedx = speedx
            self.speedy = speedy
        def update(self):
            if self.rect.x > W or self.rect.x < 0 or self.rect.y > H or self.rect.y < 0:
                self.kill()
            self.rect.x += self.speedx
            self.rect.y += self.speedy
    

    The movement of bullet depends on the direction of the player when the bullet is shot. Determine the movement of the bullet (speedx, speedy) in Player.shoot, dependent on last_move and pass the movement to the constructor of Bullet:

    class Player(pygame.sprite.Sprite):
        # [...]
    
        def shoot(self):
            now = pygame.time.get_ticks()
            if now - self.last_shot > self.shoot_delay:
                speedx, speedy = 10, 0
                if last_move == 1:
                    speedx, speedy = 0, -10
                if last_move == 2:
                    speedx, speedy = 0, 10
                if last_move == 3:
                    speedx, speedy = 10, 0
                if last_move == 4:
                    speedx, speedy = -10, 0
                self.last_shot = now
                bullet1 = Bullet(self.rect.centerx, self.rect.centery, speedx, speedy)
                all_sprites.add(bullet1)
                bullets.add(bullet1)