矢量运动中动作怪异的物体

2024-09-24 04:18:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我现在有一个游戏,我希望用户通过将鼠标从圆球拖动到任意位置来控制圆球,程序将通过向相反方向移动圆球来响应。方向很好,但是,我注意到当使用程序时,球体在左上方向的移动比右下方向的移动要少。我相信这可能是由于我对球体实施的重力缓慢造成的,然而,我无法确切地找到导致问题的原因

Main.py:

import pygame, sys, orb ...

def run_game():
    #Screen settings
    -snip-

    main_orb = Orb(screen)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.MOUSEBUTTONDOWN:
            main_orb.reset()
        elif event.type == pygame.MOUSEBUTTONUP:
            main_orb.release = True
            main_orb.calc_vector(mouse_pos)
        
    main_orb.update()
    main_orb.release_func(mouse_pos)
    main_orb.blitme()
    pygame.display.flip()

run_game()

圆球

import pygame, math ...

class Orb():
    def __init__(self,screen):
        self.screen = screen

        # Get self image&rect and center position
        -snip-

        # Physics properties
        self.velocity = 0
        self.acceleration = 0
        self.vector = pygame.Vector2(0,-1)
        self.g = -30
        self.release = False

        # Update flag
        self.dont_update = False

    def reset(self):
        self.acceleration = 0
        self.velocity = 0
    def update(self):
        if self.velocity < 0 or self.dont_update == True:
            self.acceleration = 0
            self.velocity = 0
            self.dont_update = True
        else:
            self.acceleration = self.acceleration + self.g/60/60
            self.velocity = self.velocity + self.acceleration
            self.rect.x = self.rect.x + self.vector[0] * self.velocity
            self.rect.y = self.rect.y + self.vector[1] * self.velocity

    def calc_vector(self, mouse_pos):
        self.vector = pygame.Vector2(mouse_pos[0] - self.rect.centerx, 
                                         mouse_pos[1] - self.rect.centery)
        self.vector.rotate_ip(180)
        self.vector.normalize_ip()


    def release_func(self,mouse_pos):
        if self.release == True:
            self.acceleration = 2/1000 * math.hypot((self.rect.x-mouse_pos[0]),(self.rect.y-mouse_pos[1]))
            self.dont_update = False
            self.release = False

    def blitme(self):
        self.screen.blit(self.image,self.rect)

(附言)我知道我使用了很多标志,因此如果有任何关于如何重构代码的建议,我将不胜感激


Tags: posrectselfeventreleasemaindefupdate
1条回答
网友
1楼 · 发布于 2024-09-24 04:18:09

问题的原因是^{}存储整数坐标:

The coordinates for Rect objects are all integers. [...]

执行以下操作时,self.vector[0] * self.velocityself.vector[1] * self.velocity的分数部分丢失:

self.rect.x = self.rect.x + self.vector[0] * self.velocity
self.rect.y = self.rect.y + self.vector[1] * self.velocity

另见Pygame doesn't let me use float for rect.move, but I need it


您必须以浮点精度进行计算。将类型为pygame.Vector2的属性self.pos添加到类:

class Orb():
    def __init__(self,screen):
        # [...]
        self.rect.center = self.screen_rect.center
        self.pos = pygame.Vector2(self.rect.center)

递增update中的属性并同步rect属性:

class Orb():
    # [...]

     def update(self):
        if self.velocity < 0 or self.dont_update == True:
            # [...]
        else:
            # [...]

            self.pos = self.pos + self.vector * self.velocity
            self.rect.center = round(self.pos.x), round(self.pos.y)

完整类Orb

class Orb():
    def __init__(self,screen):
        self.screen = screen

        # Get self image&rect and center position
        self.image = pygame.image.load('orb.bmp')
        self.rect = self.image.get_rect()
        self.screen_rect = screen.get_rect()
        self.rect.center = self.screen_rect.center
        self.pos = pygame.Vector2(self.rect.center)

        # physics properties
        self.velocity = 0
        self.acceleration = 0
        self.vector = pygame.Vector2(0,-1)
        self.collided = False
        self.g = -20
        self.release = False

        # Update flag
        self.dont_update = False

    def reset(self):
        self.acceleration = 0
        self.velocity = 0
    def update(self):
        if self.velocity < 0 or self.dont_update == True:
            self.acceleration = 0
            self.velocity = 0
            self.dont_update = True
        else:
            self.acceleration = self.acceleration + self.g/60/60
            self.velocity = self.velocity + self.acceleration
            print(self.vector)
            print(self.velocity)
            self.pos = self.pos + self.vector * self.velocity
            self.rect.center = round(self.pos.x), round(self.pos.y)

    def calc_vector(self, mouse_pos):
        self.vector = pygame.Vector2(mouse_pos[0] - self.pos.x, mouse_pos[1] - self.pos.y)
        self.vector.rotate_ip(180)
        self.vector.normalize_ip()


    def blitme(self):
        self.screen.blit(self.image,self.rect)

    def release_func(self,mouse_pos):
        if self.release == True:
            self.acceleration = 2/1000 * math.hypot((self.pos.x-mouse_pos[0]),(self.pos.y-mouse_pos[1]))
            self.dont_update = False
            self.release = False

    def collisioncheck(self):
        if self.rect.bottom >= self.screen_rect.bottom:
            self.collided = True
        elif self.rect.top <= self.screen_rect.top:
            self.collided = False
        elif self.rect.left <= self.screen_rect.left:
            self.collided = True
        elif self.rect.right >= self.screen_rect.right:
            self.collided = True
        else:
            self.collided = False

相关问题 更多 >