samochód porusza się i zmienia kierunek, gdy uderza w krawędź okna [zamknięte]

Nov 25 2020

Samochód jedzie prosto. Kiedy uderza w krawędź okna, porusza się do tyłu, a następnie zmienia kierunek pod kątem 45 stopni w prawo i porusza się prosto. gdyby ponownie uderzył w krawędź okna, zrobiłby to samo

Stworzyłem kod poniżej. Byłem w stanie zatrzymać i cofnąć samochód tylko wtedy, gdy uderzył w krawędź okna. Jak zmienić kierunek auta, sprawić, żeby jechał prosto, a program dalej działał, a zatrzyma się tylko wtedy, gdy zamkniemy okno?

import pygame, sys
from pygame.locals import *

def base(cX,cY):
    screen.fill(whitdull)
    pygame.draw.rect(screen,whitdull,[0,0,1050,600],4)
    
    screen.blit(text1,[150,230])
    
    # Copy image to screen:
    screen.blit(player_image, [cX,cY])
    
    pygame.display.flip()
    clock.tick(ct)


def carMovement(b0XX,b0YY,bDirection):
    sX = 5      # 5 pixel/clock  Direction right-left
    sY = 5      # 5 pixel/clock  Direction upward-downward
    
    while True:
        
        # Direction to the right
        pX = sX
        pY = 0
        
        b0XX = b0XX + pX
        b0YY = b0YY + pY
        if b0XX == 970:
            b0XX = 970 - sX
            backward(b0XX,b0YY,Direction)
            
        # Copy image to screen:
        base(b0XX,b0YY)

    return b0XX,b0YY

def backward(b0XX,b0YY,bDirection):
    sX = 5      # 5 pixel/clock  Direction right-left
    sY = 5      # 5 pixel/clock  Direction upward-downward
    
    while b0XX >= 900:
        
        # Direction to the right
        pX = sX
        pY = 0
        
        b0XX = b0XX - pX
        b0YY = b0YY - pY
        if b0XX == 900:
            b0XX = 900 + sX
            
            
        base(b0XX,b0YY)
    return b0XX, b0YY

# Initialize Pygame
pygame.init()

# Define some colors
white=(250,250,250);   whitdull=(247,247,247)
black=(70,70,70)   ;   blue =(45,127,184) 
gold  =(248,179,35);   green=(0,176,80)
yellow=(254,240,11);   gray=(208,206,206)

#Setting font-size
font1 = pygame.font.Font(None,150)

text1 = font1.render("Bom-bom  Car",True,white)


# preparing  the  screen
width = 1050 ; height = 600
screen = pygame.display.set_mode([width, height])
pygame.display.set_caption('Bom-bom Car')
screen.fill(whitdull) 


player_image = pygame.image.load("Car-2.jpeg").convert()
#rotasi = pygame.transform.rotate(player_image, -45)


#initial condition
b0X = 0; b0Y = 250; Direction = 2      # initial car position, Direction 2 = to the right

ct = 20
clock = pygame.time.Clock()


# program utama Pygame
while True:
        
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        if event.type == pygame.MOUSEBUTTONDOWN:
            b0X,b0Y = carMovement(b0X,b0Y,Direction)
            
    base(b0X,b0Y)
    
    # Get the current mouse position (x,y)
    player_position = pygame.mouse.get_pos()
    xm=player_position[0]
    ym=player_position[1]
       
#end program

wynik

Źródło obrazu

Odpowiedzi

Rabbid76 Nov 25 2020 at 18:10

Nigdy nie wdrażaj dodatkowych pętli do sterowania grą. Masz pętlę aplikacji. Użyj tego!

Użyj pygame.math.Vector2obiektów, aby określić pozycję i ruch gracza. Początkowy ruch to (0, 0). Dodatkowo określ prędkość dla gracza:

player_pos = pygame.math.Vector2(player_image.get_width() // 2, screen.get_height() // 2)
player_move = pygame.math.Vector2(0, 0)
speed = 10

Zaraz po naciśnięciu myszy określ kierunek ruchu i przeskaluj długość wektora ruchu za speedpomocą scale_to_length():

if event.type == pygame.MOUSEBUTTONDOWN:
    dx = event.pos[0] - player_pos.x
    dy = event.pos[1] - player_pos.y
    if dx != 0 or dY != 0:
        player_move = pygame.math.Vector2(dx, dy)
        player_move.scale_to_length(speed)

Dodaj wektor ruchu ( player_move) do pozycji player ( player_pos) w pętli aplikacji:

while True:
    # [...]

    player_pos += player_move

Uzyskaj prostokąt graniczny gracza. Polecam przeczytać: Dlaczego mój test kolizji zawsze zwraca „prawda” i dlaczego pozycja prostokąta obrazu jest zawsze nieprawidłowa (0, 0)? :

player_rect = player_image.get_rect(center = (round(player_pos.x), round(player_pos.y)))

Gdy gracz dotrze do krawędzi okna, odbij gracza na krawędziach jak piłka bilardowa. Zobacz także Jak sprawić, by piłka odbijała się od ściany za pomocą Pygame? :

if player_rect.left < 0:
    player_rect.left = 0 
    player_pos.x = player_rect.centerx
    player_move.x = abs(player_move.x)
if player_rect.right > screen.get_width():
    player_rect.right = screen.get_width()
    player_pos.x = player_rect.centerx
    player_move.x = -abs(player_move.x)
if player_rect.top < 0:
    player_rect.top = 0 
    player_pos.y = player_rect.centery
    player_move.y = abs(player_move.y)
if player_rect.bottom > screen.get_height():
    player_rect.bottom = screen.get_height()
    player_pos.y = player_rect.centery
    player_move.y = -abs(player_move.y)

Oblicz kąt wektora ruchu i obróć gracza wokół jego środka. Zobacz: Jak obrócić obraz wokół jego środka za pomocą PyGame? i jak obrócić obraz (odtwarzacz) w kierunku myszy? :

angle = player_move.angle_to((1, 0))
rotated_player = pygame.transform.rotate(player_image, angle)
rotated_rect = rotated_player.get_rect(center = player_rect.center)

Wreszcie przerysuj scenę:

screen.fill(whitdull)
pygame.draw.rect(screen, whitdull,[0,0,1050,600],4)
screen.blit(text1,[150,230])
screen.blit(rotated_player, rotated_rect)
pygame.display.flip()

Kompletny przykład:

import pygame, sys
from pygame.locals import *

# Initialize Pygame
pygame.init()
clock = pygame.time.Clock()

# Define some colors
white=(250,250,250);   whitdull=(247,247,247)
black=(70,70,70)   ;   blue =(45,127,184) 
gold  =(248,179,35);   green=(0,176,80)
yellow=(254,240,11);   gray=(208,206,206)

#Setting font-size
font1 = pygame.font.Font(None,150)
text1 = font1.render("Bom-bom  Car",True,white)

# preparing  the  screen
width, height = 1050, 600
screen = pygame.display.set_mode([width, height])
pygame.display.set_caption('Bom-bom Car')

player_image = pygame.image.load("Car-2.jpeg").convert()

#initial condition
ct = 20
player_pos = pygame.math.Vector2(player_image.get_width() // 2, screen.get_height() // 2)
player_move = pygame.math.Vector2(0, 0)
speed = 10

# program utama Pygame
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        if event.type == pygame.MOUSEBUTTONDOWN:
            dx = event.pos[0] - player_pos.x
            dy = event.pos[1] - player_pos.y
            if dx != 0 or dY != 0:
                player_move = pygame.math.Vector2(dx, dy)
                player_move.scale_to_length(speed)

    player_pos += player_move
    player_rect = player_image.get_rect(center = (round(player_pos.x), round(player_pos.y)))
    if player_rect.left < 0:
       player_rect.left = 0 
       player_pos.x = player_rect.centerx
       player_move.x = abs(player_move.x)
    if player_rect.right > screen.get_width():
       player_rect.right = screen.get_width()
       player_pos.x = player_rect.centerx
       player_move.x = -abs(player_move.x)
    if player_rect.top < 0:
       player_rect.top = 0 
       player_pos.y = player_rect.centery
       player_move.y = abs(player_move.y)
    if player_rect.bottom > screen.get_height():
       player_rect.bottom = screen.get_height()
       player_pos.y = player_rect.centery
       player_move.y = -abs(player_move.y)

    angle = player_move.angle_to((1, 0))
    rotated_player = pygame.transform.rotate(player_image, angle)
    rotated_rect = rotated_player.get_rect(center = player_rect.center)
    
    screen.fill(whitdull)
    pygame.draw.rect(screen, whitdull,[0,0,1050,600],4)
    screen.blit(text1,[150,230])
    screen.blit(rotated_player, rotated_rect)    
    pygame.display.flip()
    clock.tick(ct)