代码之家  ›  专栏  ›  技术社区  ›  ScalaBoy

如何在PyGame中模拟真实速度?

  •  2
  • ScalaBoy  · 技术社区  · 6 年前

    worker 物体。我该怎么做?

    目前我有参数 speed 在密码里。此参数初始化为 randint(2, 4) -介于2和4之间的随机整数。但这个值并没有映射到真实的比例。

    在我的例子中,1像素表示 0.038

    METERS_PER_PIXEL = 0.038370147
    AVG_WALK_SPEED = 1.4 # meters per second
    MIN_RUN_SPEED = 2.0  # meters per second
    MAX_RUN_SPEED = 5.0  # meters per second
    

    有了这些常量,我想再引入一个名为 human_speed . 例如,我想初始化 人的速度 属于 工人 等于 1.4 . 我怎样才能转换 速度 以便 pygame 我需要 人的速度 一些后端计算。

    import pygame, random
    import sys
    
    WHITE = (255, 255, 255)
    GREEN = (20, 255, 140)
    GREY = (210, 210 ,210)
    
    SCREENWIDTH=1000
    SCREENHEIGHT=578  
    
    
    class Background(pygame.sprite.Sprite):
        def __init__(self, image_file, location, *groups):
            self._layer = -1
            pygame.sprite.Sprite.__init__(self, groups)
    
            self.image = pygame.transform.scale(pygame.image.load(image_file).convert(), (SCREENWIDTH, SCREENHEIGHT))
            self.rect = self.image.get_rect(topleft=location)
    
    
    class Worker(pygame.sprite.Sprite):
        def __init__(self, image_file, location, *groups):
    
            self._layer = 1
            pygame.sprite.Sprite.__init__(self, groups)
            self.image = pygame.transform.scale(pygame.image.load(image_file).convert_alpha(), (40, 40))
            self.rect = self.image.get_rect(topleft=location)
            self.change_direction()
            self.speed = random.randint(2, 4)
    
    
        def change_direction(self):
    
            self.direction = pygame.math.Vector2(random.randint(-100, 100), random.randint(-100, 100))
    
            while self.direction.length() == 0:
                self.direction = pygame.math.Vector2(random.randint(-100, 100), random.randint(-100, 100)) 
    
            self.direction = self.direction.normalize()
    
    
        def update(self, screen):
    
            if random.uniform(0,1)<0.005:
                self.change_direction()
    
            vec = [int(v) for v in self.direction * self.speed]
            self.rect.move_ip(*vec)
    
            if not screen.get_rect().contains(self.rect):
                self.change_direction()
            self.rect.clamp_ip(screen.get_rect())
    
    pygame.init()
    
    all_sprites = pygame.sprite.LayeredUpdates()
    workers = pygame.sprite.Group()
    
    screen = pygame.display.set_mode((SCREENWIDTH, SCREENHEIGHT))
    pygame.display.set_caption("TEST")
    
    # create multiple workers
    for pos in ((0,0), (100, 100), (200, 100)):
        Worker("worker.png", pos, all_sprites, workers)
    
    Background("background.jpg", [0,0], all_sprites)
    
    carryOn = True
    clock = pygame.time.Clock()
    
    while carryOn:
        for event in pygame.event.get():
            if event.type==pygame.QUIT:
                carryOn = False
    
        all_sprites.update(screen)
        all_sprites.draw(screen)
    
        pygame.display.flip()
    
        clock.tick(20)
    
    1 回复  |  直到 6 年前
        1
  •  2
  •   sloth JohnnBlade    6 年前

    如果你这样做了 1.4 0.038 米是 1 1.4 / 0.038 = 36.8 每秒像素数。

    如果你的帧率是20,那就意味着你的普通工人应该搬家 1/20 其中 36.8 像素,导致 1.84

    这很简单,因为有些问题,比如:

    • Sprite 在一个 Rect 矩形 只能处理整数,不能处理浮点数。但是你可以创造一个 Vector2 以存储精确的位置,并在每次移动时环绕坐标,并将其存储在 矩形

    • 如果仅依靠固定的目标帧率来计算要移动的距离,则可能会出现不一致的移动。通常您使用一种称为delta time的方法,这基本上意味着您可以跟踪每帧运行的时间,并将该值传递给 update 函数并使用它计算距离。