samochód porusza się i zmienia kierunek, gdy uderza w krawędź okna [zamknięte]
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
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 speed
pomocą 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)