问题
The car is moving straight. When it hits the window edge it moves backwards then changes direction at an angle of 45 degrees clockwise and keeps moving straight. if it hit the edge of the window again, it would do the same
I've made the code below. I was only able to stop and reverse the car when it hits the edge of the window. How to change the direction of the car, make it go straight, and keep the program running and it will only stop if we close the window?
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
output
image source
回答1:
Never implement additional loops to control the game. You have the application loop. Use it!
Use pygame.math.Vector2 objects to define the position and movement of the player. The initial movement is (0, 0). Additionally define a speed for the player:
player_pos = pygame.math.Vector2(player_image.get_width() // 2, screen.get_height() // 2)
player_move = pygame.math.Vector2(0, 0)
speed = 10
As soon as the mouse is pressed, define the direction of movement and scale the length of the movement vector by the speed
with 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)
Add up the motion vector (player_move
) to the position of the player ( player_pos
) in the application loop:
while True:
# [...]
player_pos += player_move
Get the bounding rectangle of the player. I recommend to read Why is my collision test always returning 'true' and why is the position of the rectangle of the image always wrong (0, 0)?:
player_rect = player_image.get_rect(center = (round(player_pos.x), round(player_pos.y)))
Once the player reaches the edges of the window, reflect the player on the edges like a pool ball. See also How to make ball bounce off wall with 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)
Compute the angle of the movement vector and rotate the player around its center. See How do I rotate an image around its center using PyGame? and How to rotate an image(player) to the mouse direction?:
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)
Finally redraw the scene:
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()
Complete example: repl.it/@Rabbid76/PyGame-CarMovement
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)
来源:https://stackoverflow.com/questions/65001510/the-car-moves-and-changes-direction-when-it-hits-the-window-edge