I have a character in PyGame which I want to move forward depending on its rotation. Currently it's very strange and wonky.
Here's all my code: https://www.toptal.com/developers/hastebin/enapuravet.lua
Here's the relevent code:
def rotate(self, amount):
self.rotation += amount
if self.rotation == 181:
self.rotation = -180
elif self.rotation == -181:
self.rotation = 180
print(self.rotation)
self.capybara = pygame.transform.rotate(self.base_capybara, self.rotation)
self.rect = self.capybara.get_rect(center = self.rect.center)
def move_forward(self, speed):
print(self.rotation)
new_coordinates = calculate_new_xy((self.x, self.y), 2, self.rotation*(math.pi/180))
self.x = new_coordinates[0]
self.y = new_coordinates[1]
self.rect = self.capybara.get_rect(center = (self.x, self.y))
def calculate_new_xy(old_xy,speed,angle_in_radians):
print(angle_in_radians)
new_x = old_xy[0] + (speed*math.cos(angle_in_radians))
new_y = old_xy[1] + (speed*math.sin(angle_in_radians))
return new_x, new_y
Here's what it does: https://gyazo.com/3b7bf1c5b2e760a53913b6d3acae6e67
I also tried some other x_y calculating functions like this:
move_vec = pygame.math.Vector2()
move_vec.from_polar((speed, angle_in_degrees))
return old_xy + move_vec
but they had the same/very similar results.
This is the capybara:
Since pygame.Rect
is supposed to represent an area on the screen, a pygame.Rect
object can only store integral data.
The coordinates for Rect objects are all integers. [...]
If you want to store object positions with floating point accuracy, you have to store the location of the object in separate variables respectively attributes and to synchronize the pygame.Rect
object.round
the coordinates and assign it to the location (eg .center
) of the rectangle.
The unit of the angle of math.sin
and math.cos
is Randian. You needs to convert the angle from degrees to radians with math.radians
:
class Capybara:
def __init__(self, size_multiplier):
# [...]
self.x, self.y = 300, 300
self.rect = self.capybara.get_rect(center = (round(self.x), round(self.y)))
def rotate(self, amount):
self.rotation += amount
ifv self.rotation > 360:
self.rotation -= 360
elif self.rotation < 0:
self.rotation += 360
self.capybara = pygame.transform.rotate(self.base_capybara, self.rotation)
self.rect = self.capybara.get_rect(center = (round(self.x), round(self.y)))
def move(self, move):
self.x += move * math.cos(math.radians(self.rotation + 90))
self.y -= move * math.sin(math.radians(self.rotation + 90))
See also Move Character with Vector , Image rotation while moving or How to turn the sprite in pygame while moving with the keys .
Minimal example:
import pygame, math
pygame.init()
size = width, height = 600, 600
green = 50, 168, 82
screen = pygame.display.set_mode(size)
class Capybara:
def __init__(self, size_multiplier):
self.capybara = pygame.image.load('capybara.png')
self.o_size = 92, 206
self.new_size = (self.o_size[0] * size_multiplier,self.o_size[1] * size_multiplier)
self.capybara = pygame.transform.scale(self.capybara, self.new_size)
self.base_capybara = self.capybara
self.rotation = 0
self.x, self.y = 300, 300
self.rect = self.capybara.get_rect(center = (round(self.x), round(self.y)))
def rotate(self, amount):
self.rotation += amount
if self.rotation > 360:
self.rotation -= 360
elif self.rotation < 0:
self.rotation += 360
self.capybara = pygame.transform.rotate(self.base_capybara, self.rotation)
self.rect = self.capybara.get_rect(center = (round(self.x), round(self.y)))
def move(self, move):
self.x += move * math.cos(math.radians(self.rotation + 90))
self.y -= move * math.sin(math.radians(self.rotation + 90))
capybara = Capybara(0.8)
fpsClock = pygame.time.Clock()
rotate_l = False
rotate_r = False
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
keys = pygame.key.get_pressed()
rotate = keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]
move = keys[pygame.K_DOWN] - keys[pygame.K_UP]
capybara.move(-move * 5)
capybara.rotate(-rotate)
screen.fill(green)
screen.blit(capybara.capybara, capybara.rect)
pygame.display.update()
fpsClock.tick(60)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.