2017-10-28 66 views
1

Pygame模块中的形状不能把浮点值作为它们的参数吗?Pygame形状不能带非整数参数

这是由于我目前正在做一个相对基本的物理模拟,并使用pygame来完成图形这一事实而引发的,在物理模拟中,它很少/从不发生一个对象居中的情况,一个整数值。

我想知道这主要是否会对模拟的准确性有重大影响?

+0

我通常保存我的对象在['pygame.math.Vector2's]的实际位置(http://www.pygame.org/docs/ref/math.html#pygame.math.Vector2 ),因为'pygame.Rect'不能存储浮点数并导致不准确的运动。您可以将Vector2传递给'pygame.Surface.blit'或将其分配给矩形,但是如果您想将其用于例如'pygame.draw.circle',则必须先将矢量转换为整数。 – skrx

+0

我只使用Pygame来制作图形,因为我想了解制作(矢量和普通)类并将它们实现到引擎中的过程。因此,如果我只是将数值四舍五入到最接近的整数,那么在显示对象时,使用精确值进行进一步计算时,这足够准确吗?我的推理是因为这些形状的参数是它们的像素位置,所以在显示时,如果它最多偏离0.5 px,那么应该没有那么重要了。 – Bob

+0

是的,应该是准确的。只要实际位置准确,如果对象显示为向左或向右进一步0.5像素,则不会影响仿真。你甚至不需要自己将数字舍入,因为当你将它们传递给'.blit'或者将它们赋值给一个矩形时,pygame自动为你做这些。只有像'pygame.draw.circle'这样的函数不接受浮点数。 – skrx

回答

0

以仿真术语/准确性来说,您应始终保持数据为浮点型。你应该围绕它们,在你调用Pygame需要整数的函数的时候将它们转换为int。

就做这样的事情:

pygame.draw.rect(surface, color, (int(x), int(y), width, height)) 

绘制一个矩形,例如。

0

我通常建议将游戏对象的位置和速度存储为vectors(其中包含浮点数)以保持物理准确。然后,您可以首先将速度添加到位置矢量,然后更新用作blit位置的对象的矩形,并可用于碰撞检测。在将它分配给矩形之前,您不必将位置向量转换为整数,因为pygame会自动为您执行此操作。

下面是一个跟随鼠标的对象的小例子。

import pygame as pg 
from pygame.math import Vector2 


class Player(pg.sprite.Sprite): 

    def __init__(self, pos, *groups): 
     super().__init__(*groups) 
     self.image = pg.Surface((30, 30)) 
     self.image.fill(pg.Color('steelblue2')) 
     self.rect = self.image.get_rect(center=pos) 
     self.direction = Vector2(1, 0) 
     self.pos = Vector2(pos) 

    def update(self): 
     radius, angle = (pg.mouse.get_pos() - self.pos).as_polar() 
     self.velocity = self.direction.rotate(angle) * 3 
     # Add the velocity to the pos vector and then update the 
     # rect to move the sprite. 
     self.pos += self.velocity 
     self.rect.center = self.pos 


def main(): 
    screen = pg.display.set_mode((640, 480)) 
    clock = pg.time.Clock() 
    font = pg.font.Font(None, 30) 
    color = pg.Color('steelblue2') 
    all_sprites = pg.sprite.Group() 
    player = Player((100, 300), all_sprites) 

    done = False 

    while not done: 
     for event in pg.event.get(): 
      if event.type == pg.QUIT: 
       done = True 

     all_sprites.update() 
     screen.fill((30, 30, 30)) 
     all_sprites.draw(screen) 
     txt = font.render(str(player.pos), True, color) 
     screen.blit(txt, (30, 30)) 

     pg.display.flip() 
     clock.tick(30) 


if __name__ == '__main__': 
    pg.init() 
    main() 
    pg.quit()