简体   繁体   English

在pygame中使块从线反弹

[英]Making a block bounce off a line in pygame

Running the following code allows 3 squares to move about a screen, which are then supposed roam freely, bouncing off the edges, until they encounter a blue line. 运行以下代码,可以使3个正方形在屏幕上移动,然后假定它们可以自由漫游,从边缘弹起,直到遇到蓝线为止。 They are under strict orders to bounce off that line as well. 他们也受到严格命令才能跳出这条线。 I am able to do that when the block comes from the right and bounces off the line's right side, but not from the left and to bounce off the line's left side. 当块来自右侧并从线的右侧反弹,而不是从左侧并从线的左侧反弹时,我能够做到这一点。 Please see the code for more information. 请参阅代码以获取更多信息。

import pygame, sys, time
from pygame.locals import *

pygame.init()
WINDOWWIDTH = 200
WINDOWHEIGHT = 300
screen = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT), 0, 32)
pygame.display.set_caption('Animation')

DOWNLEFT = 1
DOWNRIGHT = 3
UPLEFT = 7
UPRIGHT = 9

MOVESPEED = 1

BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)


b1 = {'rect':pygame.Rect(0, 50, 25, 25), 'color':RED, 'dir':DOWNRIGHT}
b2 = {'rect':pygame.Rect(0, 100, 25, 25), 'color':GREEN, 'dir':DOWNRIGHT}
b3 = {'rect':pygame.Rect(0, 150, 25, 25), 'color':BLUE, 'dir':DOWNRIGHT}
blocks = [b1, b2, b3]

while True:
    # check for the closing of the 'x' button
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
    screen.fill(BLACK)
    pygame.draw.line(screen,BLUE,(150,0),(150,150),5)


    for b in blocks:
        #moves the blocks
        if b['dir'] == DOWNLEFT:
            b['rect'].left -= MOVESPEED
            b['rect'].top += MOVESPEED
        if b['dir'] == DOWNRIGHT:
            b['rect'].left += MOVESPEED
            b['rect'].top += MOVESPEED
        if b['dir'] == UPLEFT:
            b['rect'].left -= MOVESPEED
            b['rect'].top -= MOVESPEED
        if b['dir'] == UPRIGHT:
            b['rect'].left += MOVESPEED
            b['rect'].top -= MOVESPEED

        # check if the block has move out of the window
        if b['rect'].top < 0:
            # block has moved past the top
            if b['dir'] == UPLEFT:
                b['dir'] = DOWNLEFT
            if b['dir'] == UPRIGHT:
                b['dir'] = DOWNRIGHT
        if b['rect'].bottom > WINDOWHEIGHT:
            # block has moved past the bottom
            if b['dir'] == DOWNLEFT:
                b['dir'] = UPLEFT
            if b['dir'] == DOWNRIGHT:
                b['dir'] = UPRIGHT
        if b['rect'].left < 0:
            # block has moved past the left side
            if b['dir'] == DOWNLEFT:
                b['dir'] = DOWNRIGHT
            if b['dir'] == UPLEFT:
                b['dir'] = UPRIGHT
        if b['rect'].right > WINDOWWIDTH:
            # block has moved past the right side
            if b['dir'] == DOWNRIGHT:
                b['dir'] = DOWNLEFT
            if b['dir'] == UPRIGHT:
                b['dir'] = UPLEFT
        if b['rect'].left < 150 and b['rect'].top > 0 and b['rect'].top < 150:
            if b['dir'] == DOWNLEFT:
                b['dir'] = DOWNRIGHT
            if b['dir'] == UPLEFT:
                b['dir'] = UPRIGHT
##        if b['rect'].right > 150 and b['rect'].top > 0 and b['rect'].top < 150:
##            if b['dir'] == DOWNLEFT:
##                b['dir'] = DOWNRIGHT
##            if b['dir'] == UPLEFT:
##                b['dir'] = UPRIGHT
        print(b['rect'].right)
        pygame.draw.rect(screen, b['color'], b['rect'])

    pygame.display.update()
    time.sleep(0.0001)
import pygame, sys, time
from pygame.locals import *

pygame.init()
WINDOWWIDTH = 200
WINDOWHEIGHT = 300
screen = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT), 0, 32)
pygame.display.set_caption('Animation')

DOWNLEFT = 1
DOWNRIGHT = 3
UPLEFT = 7
UPRIGHT = 9

MOVESPEED = 1

BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)


b1 = {'rect':pygame.Rect(0, 50, 25, 25), 'color':RED, 'dir':DOWNRIGHT}
b2 = {'rect':pygame.Rect(0, 100, 25, 25), 'color':GREEN, 'dir':DOWNRIGHT}
b3 = {'rect':pygame.Rect(0, 150, 25, 25), 'color':BLUE, 'dir':DOWNRIGHT}
blocks = [b1, b2, b3]


while True:
# check for the closing of the 'x' button
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
    screen.fill(BLACK)
    pygame.draw.line(screen,BLUE,(150,0),(150,150),5)


    for b in blocks:
    #moves the blocks
        if b['dir'] == DOWNLEFT:
            b['rect'].left -= MOVESPEED
            b['rect'].top += MOVESPEED
        if b['dir'] == DOWNRIGHT:
            b['rect'].left += MOVESPEED
            b['rect'].top += MOVESPEED
        if b['dir'] == UPLEFT:
            b['rect'].left -= MOVESPEED
            b['rect'].top -= MOVESPEED
        if b['dir'] == UPRIGHT:
            b['rect'].left += MOVESPEED
            b['rect'].top -= MOVESPEED

    # check if the block has move out of the window
        if b['rect'].top < 0:
        # block has moved past the top
            if b['dir'] == UPLEFT:
                b['dir'] = DOWNLEFT
            if b['dir'] == UPRIGHT:
                b['dir'] = DOWNRIGHT
        if b['rect'].bottom > WINDOWHEIGHT:
        # block has moved past the bottom
            if b['dir'] == DOWNLEFT:
                b['dir'] = UPLEFT
            if b['dir'] == DOWNRIGHT:
                b['dir'] = UPRIGHT
        if b['rect'].left < 0:
        # block has moved past the left side
            if b['dir'] == DOWNLEFT:
                b['dir'] = DOWNRIGHT
            if b['dir'] == UPLEFT:
                b['dir'] = UPRIGHT
        if b['rect'].right > WINDOWWIDTH:
        # block has moved past the right side
            if b['dir'] == DOWNRIGHT:
                b['dir'] = DOWNLEFT
            if b['dir'] == UPRIGHT:
                b['dir'] = UPLEFT
        if b['dir'] == UPLEFT or b['dir'] == DOWNLEFT: # In this case it's rather easy to check for the exact conditions when direction changes should be made. Being the movement speed is only 1, at some point the b['rect'].right/left will be exactly 150. It's easier to check for that than deal with greater than less than problems which tend to only work for one way. If movement was higher than one you'd have to switch to short ranges instead.
            if b['rect'].left == 150 and b['rect'].top > 0 and b['rect'].top < 150:
                if b['dir'] == DOWNLEFT:
                    b['dir'] = DOWNRIGHT
                if b['dir'] == UPLEFT:
                    b['dir'] = UPRIGHT

        if b['dir'] == DOWNRIGHT or b['dir'] == UPRIGHT:
            if b['rect'].right == 150 and b['rect'].top < 150:
                if b['dir'] == DOWNRIGHT:
                    b['dir'] = DOWNLEFT
                if b['dir'] == UPRIGHT:
                    b['dir'] = UPLEFT
        print(b['rect'].right)
        pygame.draw.rect(screen, b['color'], b['rect'])

    pygame.display.update()
    time.sleep(0.00001)

This corrected codes works more like you were hoping for I'm thinking. 经过更正的代码的工作方式就更像您希望我正在考虑的那样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM