1
\$\begingroup\$

I just want to preface this by saying I am very new to pygame.

At the moment I have calculated the angle that I need to apply to my character so he can rotate but I am unsure how to actually make him rotate (I understand the principle of it but not how to code it). I have tried to watch videos and look at other questions on here but I have only seen lots of different solutions that I can't implement into my own code.

I want to make it so that my character faces wherever my mouse is moving.

import pygame
import math
from random import randint

pygame.init()

screen = pygame.display.set_mode((600, 600))
screen_width = 600
screen_height = 600
pygame.display.set_caption("Mousey")
char = pygame.image.load('76011.png')
background = pygame.image.load('pygameback.png')
clock = pygame.time.Clock()


class Player:
    def __init__(self, x, y, width, height):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.velocity = 12.5
        self.original = pygame.image.load('76011.png')
        self.rotated = self.original
        self.rect = self.rotated.get_rect()
        self.angle = 0

    def draw(self, win):
        screen.blit(char, (self.x, self.y))



class Enemy(Player):
    def __init__(self, x, y, width, height):
        Player.__init__(self, x, y, width, height)

    def draw(self, win):
        pygame.draw.rect(win, (0, 255, 0), (jeff.x, jeff.y, jeff.width, jeff.height))


def drawWindow():
    screen.blit(background, (0, 0))
    mag.draw(screen)
    jeff.draw(screen)
    pygame.display.update()


def XOR(a, b):
    if bool(a) != bool(b):
        return True
    return False


mag = Player(300, 300, 60, 60)
jeff = Enemy(180, 180, 60, 60)
run = True
while run:
    clock.tick(40)

    keys = pygame.key.get_pressed()

    for e in pygame.event.get():
        if e.type == pygame.QUIT:
            run = False
        if e.type == pygame.MOUSEBUTTONDOWN:
            mouse_x, mouse_y = pygame.mouse.get_pos()

        if e.type == pygame.MOUSEMOTION:
            mouse_x, mouse_y = pygame.mouse.get_pos()
            rel_x, rel_y = mouse_x - mag.x, mouse_y - mag.y
            angle = math.atan2(rel_y, rel_x)


    if XOR(keys[pygame.K_a], keys[pygame.K_LEFT]) and mag.x > mag.velocity:
        mag.x -= mag.velocity
        right = False
        left = True
    elif XOR(keys[pygame.K_d], keys[pygame.K_RIGHT]) and mag.x < screen_height - mag.width - mag.velocity:
        mag.x += mag.velocity
        right = True
        left = False
    elif XOR(keys[pygame.K_w], keys[pygame.K_UP]) and mag.y > mag.velocity:
        mag.y -= mag.velocity
        right = False
        left = False
    elif XOR(keys[pygame.K_s], keys[pygame.K_DOWN]) and mag.y < screen_height - mag.height - mag.velocity:
        mag.y += mag.velocity
        right = False
        left = False

    drawWindow()

I was also confused about where I need to make the character rotate. By this I mean, do I make a method inside the class that calculates the angle and makes the character rotate OR do I do all the calculations down where they are now?

\$\endgroup\$
2
\$\begingroup\$

Take a look at the pygame.transform.rotate method. It allows you to transform the drawing surface temporarily (don't forget to transform it by the inverse rotation afterwards) so that anything you draw will be rotated.

Now, as far as calculating the angle to transform by, the pygame.transform.rotate method, unlike most rotate methods in libraries like this, requires that the argument supplied be in degrees, as opposed to radians. To calculate the angle needed to make your character face the mouse, first, make sure the image of your player is already facing the origin of PyGame's radial origin (usually, to the right), and then calculate the angle using the formula:

math.atan2((mouse.y - player.y), (mouse.x - player.x))

This will give you the angle in radians, which can then be converted to degrees using the following formula:

degs = radians * (180 / math.pi)

Note, if you're using Python 2.x, make sure to include the following import at the top of the module including this code:

from __future__ import division

This is so Python will use proper division instead of defaulting to integer division.

From there, just supply the degree value to the function like so:

pygame.transform.rotate(degs)
surface.draw(player)
pygame.transform.rotate(-degs)

You would do this wherever you do the rest of your rendering.

Hope that helps. Let me know if you need more help.

\$\endgroup\$
  • \$\begingroup\$ Great. I will give this a go. Thank you :) \$\endgroup\$ – domefist Mar 20 at 20:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.