0

私はスプライトを使っていくつかの基本的な物理演算を行っています。これは、理論的にはスプライトが画面の上端に静止するように、余分なドラッグを伴う重力です。ただし、問題は、スプライトが地面に近づくにつれて振動が速くなり、境界を越えて「圧迫」してしまうことです。

これを止める良い方法は何ですか?必要に応じてコードを pst することもできますが、何も変わったことはありません。静止に近づくにつれて速度を下げるための回避策が必要だと思います。

import pygame, math, random

pygame.init() 

class Circle(pygame.sprite.Sprite):
    def __init__(self, screen):
        pygame.sprite.Sprite.__init__(self)
        self.screen = screen
        self.dx = 0
        self.dy = 0
        self.ddx = 0
        self.ddx = 0
        self.forceX = 0
        self.forceY = 0
        self.x = random.randrange(20,self.screen.get_width())
        self.y = self.screen.get_height()/2
        self.radius = random.randrange(5,30)
        self.image = pygame.Surface((self.radius*2,self.radius*2))
        self.image.set_colorkey((0,0,0))
        self.image.set_alpha(120)
        self.mass = self.radius/15.0
        pygame.draw.circle(self.image, (175,255,0), (self.radius,self.radius), self.radius)
        self.image = self.image.convert_alpha()
        self.rect = self.image.get_rect()
        self.rect.center = (self.x, self.y)

    def update(self):
        self.calcPos()
        self.checkBounds()
        self.rect.centerx = self.x
        self.rect.centery = self.y
        self.forceX = 0
        self.forceY = 0


    def calcPos(self): 
        self.ddx = self.forceX
        self.ddy = self.forceY
        self.dy += self.ddy
        self.dx += self.ddx
        self.x += self.dx
        self.y += self.dy 

    def applyForce(self, force):
        self.forceX += force[0]/self.mass
        self.forceY += force[1]/self.mass

    def checkBounds(self):
        if self.y > self.screen.get_height():
            self.dy *= -1.05
        if self.x > self.screen.get_width(): 
            self.dx *= -1.05
        if self.y < 0: 
            self.dy *= -1.05
        if self.x < 0: 
           self.dx *= -1.05

def main():
    screen = pygame.display.set_mode((600,400))
    background = pygame.Surface((screen.get_size()))
    background.fill((150,150,150)) 
    background = background.convert()

    circleGRP = pygame.sprite.Group() #Add balls
    for x in range(10):
        circleGRP.add(Circle(screen))

    wind = (1, 0)
    gravity = (0, 1.0)

    clock = pygame.time.Clock()
    mainLoop = True

    while mainLoop: 
        clock.tick(30) #Clock
        for event in pygame.event.get(): #Key events
            if event.type == pygame.QUIT:
                mainLoop = False
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    mainLoop = False
            elif event.type == pygame.MOUSEBUTTONDOWN: #Add wind
                if pygame.mouse.get_pressed()[0]:
                    for circle in circleGRP:
                        circle.applyForce(wind)

#----------------------------------------------------------------------------                   
        for circle in circleGRP: #Add gravity
            gravity = (0, 1.0)
            gravity = tuple([each * circle.mass for each in gravity])
            circle.applyForce(gravity)

            circleX = circle.dx * -1 #Add friction
            circleY = circle.dy * -1
            friction = (circleX/80* circle.mass* (circle.radius/5), circleY/80* circle.mass* (circle.radius/5))
            circle.applyForce(friction)

 #----------------------------------------------------------------------------    
        circleGRP.update()  
        screen.blit(background, (0,0))
        circleGRP.draw(screen)
        pygame.display.flip()

    pygame.quit()

if __name__ == "__main__":
    main()    
4

1 に答える 1

0

私は本当にコードを見る必要がありますが、あなたが何を望んでいるかを正しく理解していれば、例えば y がスプライトの場所である場合、上部までの距離に基づいて速度を得ることができます:

ydir=y/50
y+=int(ydir)

編集:

def checkBounds(self):
    if self.y > self.screen.get_height():
        self.dy *= -1.05
        self.y=self.screen.get_height()

最後の行が唯一の必要な変更です。ループごとにボールが境界を少し超えて押し出され、ボールに上向きの力がない場合に問題が発生します。これにより、ボールが下限を通過できなくなります。同じことが他の人のために行われます。

于 2013-07-08T02:55:42.017 に答える