[Python] How do i make the player in my shooter game rotate along with the mouse? [duplicate]

Discussão em 'Python' iniciado por Stack, Dezembro 18, 2024.

  1. Stack

    Stack Membro Participativo

    I wanted the player to follow the mouse direction as it moves so it can aim more than 4 directions.

    I did this code to rotate it but it didn't work.

    def rotate(self):
    mouse_pos = pygame.Vector2(pygame.mouse.get_pos())
    angle = degrees(atan2(mouse_pos.x, mouse_pos.y)) - 90
    self.image = pygame.transform.rotozoom(self.original_image, angle, 1)


    I struggled for a long time on this, but i couldn't seem to find the issue.

    main.py



    from settings import *
    from sprites import *
    from pytmx.util_pygame import load_pygame
    from support import *
    from groups import *

    class Game:
    def __init__(self):
    pygame.init()
    self.display_surface = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
    pygame.display.set_caption('Survivor')
    self.clock = pygame.time.Clock()
    self.running = True
    self.load_folder()

    # Groups
    self.all_sprites = AllSprites()
    self.collision_sprites = pygame.sprite.Group()

    self.cursor = pygame.transform.scale(pygame.image.load("cursor.png"), (32,32))


    pygame.mouse.set_visible(False)

    self.setup()



    def load_folder(self):
    self.characters = import_folder("characters")

    def setup(self):
    map = load_pygame("data/world.tmx")

    for x, y, image in map.get_layer_by_name("Main").tiles():
    Sprite((x * TILE_SIZE, y * TILE_SIZE), image, self.all_sprites)
    pass

    for x, y, image in map.get_layer_by_name("Collision").tiles():
    Sprite((x * TILE_SIZE, y * TILE_SIZE), image, (self.all_sprites, self.collision_sprites))

    for obj in map.get_layer_by_name("Entities"):
    if obj.name == "Player":
    self.player = Player((obj.x, obj.y), self.characters[0], self.all_sprites, self.collision_sprites)

    if obj.name == "Enemy":
    self.enemy1 = Enemy((obj.x, obj.y), self.characters[randint(0,20)], self.player,self.all_sprites,
    self.collision_sprites)

    if obj.name == "Enemy2":
    self.enemy2 = Enemy((obj.x, obj.y), self.characters[randint(0,20)], self.player,self.all_sprites, self.collision_sprites)
    def run(self):
    while self.running:
    dt = self.clock.tick(60) / 1000

    for event in pygame.event.get():
    if event.type == pygame.QUIT:
    self.running = False

    self.all_sprites.update(dt)

    self.display_surface.fill("black")
    self.all_sprites.draw(self.player.rect.center)

    pos = pygame.mouse.get_pos()

    self.display_surface.blit(self.cursor, pos)

    pygame.display.update()


    if __name__ == "__main__":
    game = Game()
    game.run()

    sprites.py


    from settings import *
    from math import atan2, degrees

    class Sprite(pygame.sprite.Sprite):
    def __init__(self, pos, surf, groups):
    super().__init__(groups)
    self.image = surf
    self.rect = self.image.get_frect(center= pos)

    class Bullet(pygame.sprite.Sprite):
    def __init__(self, surf, pos, direction, groups):
    super().__init__(groups)

    self.image = surf
    self.rect = self.image.get_rect(center=pos)

    self.direction = direction
    self.speed = 850

    self.image = pygame.transform.flip(self.image, direction==-1, False)

    def update(self, dt):
    self.rect.x += self.direction * self.speed*dt

    class Player(pygame.sprite.Sprite):
    def __init__(self, pos, surf,groups,collision_sprites):
    super().__init__(groups)
    self.all_sprites = groups
    surf = pygame.transform.scale(surf, (80, 53*2))
    self.original_image = pygame.transform.rotate(surf, 90)
    self.original_image = self.original_image
    self.image = self.original_image
    self.rect = self.image.get_rect(center= pos)
    self.rect = self.rect.inflate(-30,0)

    self.bullet_surf = pygame.image.load("bullets/player bullet.png")


    self.speed = 500
    self.direction = pygame.Vector2()
    self.collision_sprites = collision_sprites

    self.can_shoot = True
    self.duration = 400
    self.start_time = 0

    self.flipx = False
    self.flipy = False


    def collision(self, direction):
    for sprite in self.collision_sprites:
    if sprite.rect.colliderect(self.rect):
    if direction == "horizontal":
    if self.direction.x > 0:
    self.rect.right = sprite.rect.left
    if self.direction.x < 0:
    self.rect.left = sprite.rect.right
    else:
    if self.direction.y > 0:
    self.rect.bottom = sprite.rect.top
    if self.direction.y < 0:
    self.rect.top = sprite.rect.bottom

    def cooldown(self):
    if self.can_shoot == False:
    current_time = pygame.time.get_ticks()
    if current_time - self.start_time >= self.duration:
    self.can_shoot = True

    def input(self):
    keys = pygame.key.get_pressed()
    mouse = pygame.mouse.get_pressed()

    self.direction.x = int(keys[pygame.K_RIGHT]) - int(keys[pygame.K_LEFT])
    self.direction.y = int(keys[pygame.K_DOWN]) - int(keys[pygame.K_UP])
    self.direction = self.direction.normalize() if self.direction else self.direction

    if mouse[0] and self.can_shoot:
    self.can_shoot = False
    self.start_time = pygame.time.get_ticks()
    Bullet(self.bullet_surf, self.rect.center, -1 if self.flipx else 1, self.all_sprites)
    self.cooldown()


    # def flip_image(self):
    # if self.direction:
    # self.flipx = self.direction.x < 0
    # if self.direction.y > 0:
    # if self.direction.y < 0:
    #
    # self.image = pygame.transform.rotozoom(pygame.transform.flip(self.original_image, self.flipx, False))

    def rotate(self):
    mouse_pos = pygame.Vector2(pygame.mouse.get_pos())
    angle = degrees(atan2(mouse_pos.x, mouse_pos.y)) - 90
    self.image = pygame.transform.rotozoom(self.original_image, angle, 1)

    def move(self, dt):
    self.rotate()

    self.rect.x += self.direction.x * self.speed * dt
    self.collision("horizontal")
    self.rect.y += self.direction.y * self.speed * dt
    self.collision("vertical")

    def update(self, dt):
    self.input()
    self.move(dt)

    class Enemy(pygame.sprite.Sprite):
    def __init__(self, pos, surf, player, groups, collision_sprites):
    super().__init__(groups)
    surf = pygame.transform.scale(surf, (80, 53 * 2))
    self.original_image = pygame.transform.rotate(surf, 270)
    self.original_image = self.original_image
    self.image = self.original_image
    self.rect = self.image.get_rect(center=pos)
    self.rect = self.rect.inflate(-30, 0)
    self.speed = randint(300, 400)
    self.player = player
    self.direction = pygame.Vector2()
    self.collision_sprites = collision_sprites

    self.flip = False

    def collision(self, direction):
    for sprite in self.collision_sprites:
    if sprite.rect.colliderect(self.rect):
    if direction == "horizontal":
    if self.direction.x > 0:
    self.rect.right = sprite.rect.left
    if self.direction.x < 0:
    self.rect.left = sprite.rect.right
    else:
    if self.direction.y > 0:
    self.rect.bottom = sprite.rect.top
    if self.direction.y < 0:
    self.rect.top = sprite.rect.bottom

    def move(self, dt):
    player_pos = pygame.Vector2(self.player.rect.center)
    enemy_pos = pygame.Vector2(self.rect.center)

    distance = player_pos.distance_to(enemy_pos)

    if distance > 100:
    self.direction = (player_pos - enemy_pos).normalize()

    self.rect.x += self.direction.x * self.speed * dt
    self.collision("horizontal")
    self.rect.y += self.direction.y * self.speed * dt
    self.collision("vertical")

    self.flip = self.direction.x > 0
    self.image = pygame.transform.flip(self.original_image, self.flip, False)
    self.rect = self.image.get_rect(center=self.rect.center)

    def update(self, dt):
    self.move(dt)


    This is the code to main.py and sprites.py. I struggled to find any issues, but possible answers would be helpful

    Continue reading...

Compartilhe esta Página