具有类的属性的计算速度

时间:2019-04-05 19:32:31

标签: python python-3.x performance pygame

我是法国人,请原谅我的语言错误。

我尝试用球状物理制作一些 pygame-zero 游戏。 所以我想及时精确地控制一个球形物体

我创建了一个Ball类,实现了内置的Rect对象(以防万一使用默认碰撞)。

import pygame

WIDTH = 300
HEIGHT = 300

class Color:
    WHITE = (255, 255, 255)
    RED = (255, 0, 0)
    GREEN = (0, 255, 0)
    BLUE = (0, 0, 255)

class Ball(pygame.Rect):
    def __init__(self, cx, cy, radius, color: Color = Color.WHITE):
        position = (cx - radius, cy - radius)
        size = (radius * 2, radius * 2)
        super(Ball, self).__init__(position, size)
        self.radius = radius
        self.color = color

    @property
    def cx(self):
        return self.x + self.radius

    @cx.setter
    def cx(self, cx):
        self.x = cx - self.radius

    @property
    def cy(self):
        return self.y + self.radius

    @cy.setter
    def cy(self, cy):
        self.y = cy - self.radius


    def draw(self):
        position = (self.cx, self.cy)
        screen.draw.filled_circle(position, self.radius, self.color);
        # screen.draw.rect(self, Color.RED) # draw hitbox

我实例化一个球对象,并希望使其在x位置0到300。(窗口的宽度)。

在更新功能中,我使用默认的增量时间(每帧1/60之间经过的时间,以毫秒为单位)。

以100像素*增量时间的速度,球将在3秒(逻辑)上穿越屏幕。

但这不是...经过一些操作后,我创建了第二个球(我切换了球的名称),而当我使用变量时,一切正常。

cl = 0 # get time elpased at launch
ball = Ball(0, 10, 10, Color.RED)
x = ball.cx
ball2 = Ball(0, 30, 10, Color.BLUE)
speed = 100

def draw():
    screen.clear()
    ball.draw()
    ball2.draw()
    screen.draw.text(f"{cl:7.2f}", (0, 150))

def update(dt):
    global cl, x
    if ball.cx <= WIDTH:
        cl += dt

        # the ball make 3 seconds exactly
        x += speed * dt
        ball.cx = x

        ball2.cx += speed * dt # don't make 3 seconds WHY ?

我的问题...为什么? 创建一个自定义属性,它比经典的变量定义要慢得多吗?

1 个答案:

答案 0 :(得分:1)

如果要确保时间精确的计算,则必须使用浮点值进行所有计算。仅在将对象绘制为整数像素位置时,才将坐标转换为整数数据类型。

.cx属性具有整数数据类型。每当位置增加时,相加的数字的小数部分都会丢失。这导致不准确性增加。该对象似乎比预期的慢。 请注意,如果帧速率更高,则如果每帧的步距小于1.0,则对象甚至将静止不动。值<1.0的整数部分为0。

注意

ball2.cx += speed * dt

相同
ball2.cx += int(speed * dt)

x变量是浮点值。它以完全精度递增。当将精确值赋给.cx属性时,该值将强制转换为int,但是不精确度始终小于1.0,因此几乎可以忽略不计。

x += speed * dt
ball.cx = x  

相同
x += speed * dt
ball.cx = int(x)