主函数中未调用函数

Joh*_*hon 3 python pygame

我对 python 相当陌生,我正在尝试用 Pygame 构建一个游戏。我一直遇到碰撞无法被识别的问题。这是我尝试过的代码

import pygame
pygame.init()

WIDTH, HEIGHT = (900, 500)
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption('Bong Pong')

FPS = 60
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
BORDER = pygame.Rect(WIDTH// 2 -5, 0, 10, HEIGHT)
VEL = 3
PLAYER_HEIGHT = 50
PLAYER_WIDTH = 15
BALL_HEIGHT = 15
BALL_WIDTH = 15


def draw_window(player_1, player_2, game_ball):
    WIN.fill(WHITE)
    pygame.draw.rect(WIN, BLACK, BORDER)
    pygame.draw.rect(WIN, BLACK, player_1)
    pygame.draw.rect(WIN, BLACK, player_2)
    pygame.draw.rect(WIN, RED, game_ball)
    pygame.display.update()


def player_1_movement(keys_pressed, player_1):
    if keys_pressed[pygame.K_w] and player_1.y - VEL > 0:
        player_1.y -= VEL
    if keys_pressed [pygame.K_s] and player_1.y + PLAYER_HEIGHT + VEL < 500:
        player_1.y += VEL
    
def player_2_movement(keys_pressed, player_2):
    if keys_pressed[pygame.K_UP] and player_2.y - VEL > 0:
        player_2.y -= VEL
    if keys_pressed [pygame.K_DOWN] and player_2.y + PLAYER_HEIGHT + VEL < 500:
        player_2.y += VEL


def player_collision(player_1, player_2, game_ball, ball_vel_x): 
    if game_ball.colliderect(player_1) or game_ball.colliderect(player_2):
        ball_vel_x *= -1
        
   
        
    
    

def main(): 
    clock = pygame.time.Clock()
    run = True

    player_1 = pygame.Rect(50, HEIGHT//2 - PLAYER_HEIGHT// 2, PLAYER_WIDTH, PLAYER_HEIGHT)
    player_2 = pygame.Rect(850, HEIGHT//2 - PLAYER_HEIGHT// 2, PLAYER_WIDTH, PLAYER_HEIGHT)
    game_ball = pygame.Rect(50 + PLAYER_WIDTH, HEIGHT//2 - BALL_HEIGHT// 2, BALL_WIDTH, BALL_HEIGHT)
    ball_vel_y = 2
    ball_vel_x = 2
    while run:
        clock.tick(FPS)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False 
                pygame.QUIT()
            
        keys_pressed = pygame.key.get_pressed()
        player_1_movement(keys_pressed, player_1)
        player_2_movement(keys_pressed, player_2)
        draw_window(player_1, player_2, game_ball)
        
        if game_ball.y - BALL_HEIGHT - VEL <= 0 or game_ball.y + BALL_HEIGHT + VEL >= 500:
            ball_vel_y *= -1
        
        game_ball.y -= ball_vel_y

      
        player_collision(player_1, player_2, game_ball, ball_vel_x)
         

        game_ball.x += ball_vel_x


    main()

if __name__ == '__main__':
    main()
     
Run Code Online (Sandbox Code Playgroud)

我也尝试过把

game_ball.x += ball_vel_x
Run Code Online (Sandbox Code Playgroud)

在player_collsion函数中,但它没有正确地反转它。

我已经通过将整个player_collision函数代码放入主函数中解决了这个问题,如下所示


def main(): 
    clock = pygame.time.Clock()
    run = True

    player_1 = pygame.Rect(50, HEIGHT//2 - PLAYER_HEIGHT// 2, PLAYER_WIDTH, PLAYER_HEIGHT)
    player_2 = pygame.Rect(850, HEIGHT//2 - PLAYER_HEIGHT// 2, PLAYER_WIDTH, PLAYER_HEIGHT)
    game_ball = pygame.Rect(50 + PLAYER_WIDTH, HEIGHT//2 - BALL_HEIGHT// 2, BALL_WIDTH, BALL_HEIGHT)
    ball_vel_y = 2
    ball_vel_x = 2
    while run:
        clock.tick(FPS)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False 
                pygame.QUIT()
            
        keys_pressed = pygame.key.get_pressed()
        player_1_movement(keys_pressed, player_1)
        player_2_movement(keys_pressed, player_2)
        draw_window(player_1, player_2, game_ball)
        
        if game_ball.y - BALL_HEIGHT - VEL <= 0 or game_ball.y + BALL_HEIGHT + VEL >= 500:
            ball_vel_y *= -1
        
        game_ball.y -= ball_vel_y

        if game_ball.colliderect(player_1) or game_ball.colliderect(player_2):
            ball_vel_x *= -1


        game_ball.x += ball_vel_x


    main()

Run Code Online (Sandbox Code Playgroud)

这正是我想要的,我只是想弄清楚为什么如果只是在主函数中调用而不是直接将其放入,这个函数将无法正常工作。

Rab*_*d76 6

Python 没有输入输出参数的概念。参数按值传递。如果在函数ball_vel_x中进行更改player_collision,则只有形参发生变化,但实参保持不变。ball_vel_x您必须从函数返回 的新值:

def player_collision(player_1, player_2, game_ball, ball_vel_x): 
    if game_ball.colliderect(player_1) or game_ball.colliderect(player_2):
        ball_vel_x *= -1
    return ball_vel_x 
Run Code Online (Sandbox Code Playgroud)
def main():
    # [...]

    while run:
        # [...]

        ball_vel_x = player_collision(player_1, player_2, game_ball, ball_vel_x)

        # [...]
Run Code Online (Sandbox Code Playgroud)

另一种可能性是将速度存储在对象中(例如gyame.math.Vector2)。变量存储对对象的引用,因此如果该变量是函数调用的参数,则可以在函数中更改对象的属性:

def player_collision(player_1, player_2, game_ball, ball_vel): 
    if game_ball.colliderect(player_1) or game_ball.colliderect(player_2):
        ball_vel.x *= -1 


def main(): 
    # [...]

    ball_vel = pygame.math.Vector2(2, 2)
    
    while run:
        # [...]
        
        if game_ball.y - BALL_HEIGHT - VEL <= 0 or game_ball.y + BALL_HEIGHT + VEL >= 500:
            ball_vel.y *= -1
        
        game_ball.y -= ball_vel.y
        player_collision(player_1, player_2, game_ball, ball_vel)
        game_ball.x += ball_vel.x
Run Code Online (Sandbox Code Playgroud)