0

The weapon is supposed to rotate around the player like in this video https://www.youtube.com/watch?v=xgkPuKbVXl0 but it doesn't rotate it just moves in a circle here is my code

this is the Weapon class

#weapon class
import pygame
import math

from pygame import rect
from pygame import image
texture = pygame.image.load("Textures/frames/weapon_knight_sword.png")


class Weapon(pygame.sprite.Sprite):
    def __init__(self, texture=texture, scale=(12, 20), range=10):
        super().__init__()
        self.image = texture
        self.CurrentImage = texture
        self.angle = 0
        self.x = 0
        self.y = 0
        self.rect = self.CurrentImage.get_rect(center=(0, 0))
        self.listOfActions = [self.getRotationAngle, self.rotate]

    def getRotationAngle(self):
        mouse_x, mouse_y = pygame.mouse.get_pos()
        rel_x, rel_y = mouse_x - self.x, mouse_y - self.y
        self.angle = (180 / math.pi) * -math.atan2(rel_y, rel_x)

    def rotate(self):
        print(self.angle)
        image = pygame.transform.rotate(self.image, -self.angle)
        self.rect = image.get_rect(center=(self.x, self.y))

    def applyActions(self):
        for i in range(len(self.listOfActions)):
            self.listOfActions[i]()

The player takes a weapon object as an attribute and gives it its credentials every time it gets updated the player inherits from GenericEntity class which has some properties and methods in common with other mobs in the game

#player code
from os import X_OK
import pygame
from generic_entity import GenericEntity
from weapon import Weapon
run = [pygame.image.load('Textures/frames/knight_m_run_anim_f0.png'), pygame.image.load('Textures/frames/knight_m_run_anim_f1.png'),
       pygame.image.load('Textures/frames/knight_m_run_anim_f2.png'), pygame.image.load('Textures/frames/knight_m_run_anim_f3.png')]
sound = 'audio/Player/player_walk.wav'
idle = [pygame.image.load('Textures/frames/knight_m_idle_anim_f0.png'), pygame.image.load('Textures/frames/knight_m_idle_anim_f1.png'),
        pygame.image.load('Textures/frames/knight_m_idle_anim_f2.png'), pygame.image.load('Textures/frames/knight_m_idle_anim_f3.png')]


class Player(GenericEntity):
    """
    A class to represent the player
    which inherits from the GenericEntity class
    ...

    Attributes
    ----------
    Check the generic_entity class

    Methods
    -------
    move():takes input and transfroms it to speed in y or x
    """

    def __init__(self, weapon, x=500, y=500, running=run, idiling=idle, sounds='audio/Player/player_walk.wav', scale=(25, 40), speed=3, health=100):
        super().__init__(x, y, running, idiling, sounds, scale, speed, health)
        self.left_pressed = False
        self.right_pressed = False
        self.up_pressed = False
        self.down_pressed = False
        self.listOfActions = [self.move, self.applyMove, self.updateWeapon]
        self.weapon = weapon

    def dash(self):
        pass

    def attack(self):
        pass

    def move(self):
        flagX = 1
        flagY = 1
        if self.left_pressed and not self.right_pressed:
            self.velX = -self.speed
            flagX = 0
        if self.right_pressed and not self.left_pressed:
            self.velX = self.speed
            flagX = 0
        if self.up_pressed and not self.down_pressed:
            self.velY = -self.speed
            flagY = 0
        if self.down_pressed and not self.up_pressed:
            self.velY = self.speed
            flagY = 0
        if flagX:
            self.velX = 0
        if flagY:
            self.velY = 0

    def updateWeapon(self):
        self.weapon.x = self.x
        self.weapon.y = self.y
        self.weapon.applyActions()

and this is the main func

#main
import pygame
from player import Player
from generic_enemy import GenericEnemy
from sys import exit
from weapon import Weapon
# Starts & intiates pygame
pygame.init()
weaponO = Weapon()
playerO = Player(weaponO)
enemyO = GenericEnemy(playerO)
enemy = pygame.sprite.Group()
enemy.add(enemyO)
player = pygame.sprite.Group()
player.add(playerO, weaponO)
WIDTH = 1366
HEIGHT = 768
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption('Soup')
# You can also change the icon
clock = pygame.time.Clock()
floor_surface = pygame.image.load('Textures/frames/floor_1.png').convert()

    
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()
        # check for (W, A, S, D)
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_a:
                playerO.left_pressed = True
            if event.key == pygame.K_d:
                playerO.right_pressed = True
            if event.key == pygame.K_w:
                playerO.up_pressed = True
            if event.key == pygame.K_s:
                playerO.down_pressed = True
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_a:
                playerO.left_pressed = False
            if event.key == pygame.K_d:
                playerO.right_pressed = False
            if event.key == pygame.K_w:
                playerO.up_pressed = False
            if event.key == pygame.K_s:
                playerO.down_pressed = False
    # draw all out elements
    # Updates the display
    for i in range(0, HEIGHT, 16):
        for k in range(0, WIDTH, 16):
            screen.blit(floor_surface, (k, i))
    # debug purposes

    enemy.draw(screen)
    enemy.update()
    player.draw(screen)
    player.update()
    pygame.display.update()
    # Locks the frame rate at 60 fps
    clock.tick(60)
Talha Tayyab
  • 8,111
  • 25
  • 27
  • 44
SandStone
  • 161
  • 1
  • 7

1 Answers1

1

The problem appears to be that you are not storing the Weapon's rotated image, just the rectangle that it takes up:

def rotate(self):
    print(self.angle)
    image = pygame.transform.rotate(self.image, -self.angle)
    self.rect = image.get_rect(center=(self.x, self.y))

You need to set image to be the rotated image in the rotate method, just make sure that you add a new field to store the original un-rotated image for future rotations:

def rotate(self):
    print(self.angle)
    self.image = pygame.transform.rotate(self.orig_image, -self.angle)
    self.rect = self.image.get_rect(center=(self.x, self.y))
Harry Jones
  • 336
  • 3
  • 8
  • I'm using the default pygame.sprite.Group.draw() method. are you saying I should override it and implement my own? – SandStone Nov 24 '21 at 16:29
  • @SandStone No. You can store the original image and set the rotated image in `update` – Rabbid76 Nov 24 '21 at 16:32
  • @SandStone Ah right, in that case, you'll need to store the original image as a field and set image to be the rotated image, I'll update my answer. – Harry Jones Nov 24 '21 at 17:10