Make a sprite move to the mouse click position step by step

前端 未结 1 459
天命终不由人
天命终不由人 2020-12-12 04:00

I\'m writing a little pirate game in Pygame. If you played sea battles in Empires Total War, you have an idea of what I would like to achieve:

The ship\'s sprite is

相关标签:
1条回答
  • 2020-12-12 04:47

    Say the current position is pos, and the point the player clicked is target_pos, then take the vector between pos and target_pos.

    Now you know how to get from pos to target_pos, but to move in constant speed (and not the entire distance at once), you have to normalize the vector, and apply a speed constant by scalar multiplication.

    That's it.


    Complete example: (the relevant code is in the Ship.update method)

    import pygame
    
    class Ship(pygame.sprite.Sprite):
    
        def __init__(self, speed, color):
            super().__init__()
            self.image = pygame.Surface((10, 10))
            self.image.set_colorkey((12,34,56))
            self.image.fill((12,34,56))
            pygame.draw.circle(self.image, color, (5, 5), 3)
            self.rect = self.image.get_rect()
    
            self.pos = pygame.Vector2(0, 0)
            self.set_target((0, 0))
            self.speed = speed
    
        def set_target(self, pos):
            self.target = pygame.Vector2(pos)
    
        def update(self):
            move = self.target - self.pos
            move_length = move.length()
    
            if move_length < self.speed:
                self.pos = self.target
            elif move_length != 0:
                move.normalize_ip()
                move = move * self.speed
                self.pos += move
    
            self.rect.topleft = list(int(v) for v in self.pos)
    
    def main():
        pygame.init()
        quit = False
        screen = pygame.display.set_mode((300, 300))
        clock = pygame.time.Clock()
    
        group = pygame.sprite.Group(
            Ship(1.5, pygame.Color('white')),
            Ship(3.0, pygame.Color('orange')),
            Ship(4.5, pygame.Color('dodgerblue')))
    
        while not quit:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    return 
                if event.type == pygame.MOUSEBUTTONDOWN:
                    for ship in group.sprites():
                        ship.set_target(pygame.mouse.get_pos())
    
            group.update()
            screen.fill((20, 20, 20))
            group.draw(screen)
            pygame.display.flip()
            clock.tick(60)
    
    if __name__ == '__main__':
        main()
    
    0 讨论(0)
提交回复
热议问题