Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
495 views
in Technique[技术] by (71.8m points)

python - How to move a sprite according to an angle in Pygame

I'm having trouble with moving sprites. I can move them in the x and y axis with no problem at all. What I can't figure out is how can I move them according to a certain angle. What I mean is, I'm trying to create a function which includes the object I'm trying to move, its speed, and its direction(which should be measured in degrees). Something like:

MovingObject(obj,speed,direction) #this is the function I'm trying to define

It's more like a "spawning function" rather than just movement... Take for example that I would like to create an object of the class "Bullet" and want it to follow certain direction (different from the x and y axis, of course) Actually I have no clear idea of how to do such thing and I would like some advice in order to achieve so. Thanks for reading this!

EDIT: @Joran Beasley I tried to do what you told me...but I guess I did it wrong...

import pygame, math, time
screen=pygame.display.set_mode((320,240))
clock=pygame.time.Clock()
pygame.init()
def calculate_new_xy(old_xy,speed,angle_in_radians):
    new_x = old_xy.x + (speed*math.cos(angle_in_radians))
    new_y = old_xy.y + (speed*math.sin(angle_in_radians))
    return new_x, new_y
class Bullet(pygame.sprite.Sprite):
    def __init__(self,x,y,direction,speed):        
            pygame.sprite.Sprite.__init__(self)
            self.image=pygame.Surface((16, 16))
            self.image.fill((255,0,0))
            self.rect=self.image.get_rect()
            self.rect.center=(x,y)
            self.direction=math.radians(direction)
            self.speed=speed
    def update(self):
            self.rect.center=calculate_new_xy(self.rect,self.speed,self.direction)
spr=pygame.sprite.Group()
bullet=Bullet(160,120,45,1); spr.add(bullet)
play=True
while play:
    clock.tick(60)
    for ev in pygame.event.get():
        if ev.type == pygame.QUIT:
            play=False
    screen.fill((0,0,0))
    spr.update()
    spr.draw(screen)
    pygame.display.flip()
pygame.quit()

The object moves but... not in the specified direction...

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

you just need a little basic trig

def calculat_new_xy(old_xy,speed,angle_in_radians):
    new_x = old_xy.X + (speed*math.cos(angle_in_radians))
    new_y = old_xy.Y + (speed*math.sin(angle_in_radians))
    return new_x, new_y

--- edit ---

Here is your code from above edited to work

import pygame, math, time
screen=pygame.display.set_mode((320,240))
clock=pygame.time.Clock()
pygame.init()
def calculate_new_xy(old_xy,speed,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
class Bullet(pygame.sprite.Sprite):
    def __init__(self,x,y,direction,speed):
            pygame.sprite.Sprite.__init__(self)
            self.image=pygame.Surface((16, 16))
            self.image.fill((255,0,0))
            self.rect=self.image.get_rect()
            self.rect.center=(x,y)
            self.direction=math.radians(direction)
            self.speed=speed
    def update(self):
            self.rect.center=calculate_new_xy(self.rect.center,self.speed,self.direction)
spr=pygame.sprite.Group()
bullet=Bullet(160,120,45,2); spr.add(bullet)
play=True
while play:
    clock.tick(60)
    for ev in pygame.event.get():
        if ev.type == pygame.QUIT:
            play=False
    screen.fill((0,0,0))
    spr.update()
    spr.draw(screen)
    pygame.display.flip()
pygame.quit()

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...