Reputation: 107
I am a Beginner in Python and i was making a simple 2D game in Pygame. I am almost done except for the collision checking with the pygame.Rect function. I am trying to check for collision with car2 and car under the comment "collision detecting" but i am getting -- TypeError: Invalid rectstyle argument. I researched for quite a while for this but i just am not able to utilize it in my code. I would appreciate if someone helped fix this problem.
import pygame
import random
import math
pygame.init()
black = (0, 0, 0)
screen_width = 600
screen_length = 800
screen = pygame.display.set_mode((screen_length, screen_width))
clock = pygame.time.Clock()
FPS = 60
icon = pygame.image.load('car.png')
pygame.display.set_icon(icon)
#game caption
pygame.display.set_caption("Car game")
#Main car
car = pygame.image.load('car.png')
carX = 370
carY = 470
carX_change = 0
#second car
car2 = pygame.image.load('car2.png')
car2_rect = car.get_rect()
car2_X = random.randint(200, 600)
car2_Y = random.randint(-50, 0)
car2Y_speed = 13
#road side trees
tree1Img = pygame.image.load('tree1.png')
tree1_X = 70
tree1_Y = 30
tree2Img = pygame.image.load("tree2.png")
tree2_X = 700
tree2_Y = 300
tree3Img = pygame.image.load("tree3.png")
tree3_X = 70
tree3_Y = 400
tree4Img = pygame.image.load("tree4.png")
tree4_X = 700
tree4_Y = 50
#game functions
def car1(x, y):
screen.blit(car, car_rect, (x, y))
def car_2(x, y):
global car2_Y
global car2_X
screen.blit(car2, car2_rect, (x, y))
car2_Y += car2Y_speed
if car2_Y > screen_length:
car2_X = random.randint(200, 545)
car2_Y = random.randint(-50, 0)
def tree1(x, y):
global tree1_Y
screen.blit(tree1Img, (x, y))
tree1_Y += 10
if tree1_Y >= screen_width:
tree1_Y = -50
def tree2(x, y):
global tree2_Y
screen.blit(tree2Img, (x, y))
tree2_Y += 10
if tree2_Y >= screen_width:
tree2_Y = -50
def tree3(x, y):
global tree3_Y
screen.blit(tree2Img, (x, y))
tree3_Y += 10
if tree3_Y >= screen_width:
tree3_Y = -50
def tree4(x, y):
global tree4_Y
screen.blit(tree4Img, (x, y))
tree4_Y += 10
if tree4_Y >= screen_width:
tree4_Y = -50
# 1st Road marker's movement
rectangleX = 426
rectangleY = 100
def roadmarker_move():
global rectangleY
if running == True:
rectangleY += 10
if rectangleY == 610:
rectangleY = -50
#2nd road marker's movement
rectangle2_X = 426
rectangle2_Y = 410
def roadmarker2_move():
global rectangle2_Y
if running == True:
rectangle2_Y += 10
if rectangle2_Y == 610:
rectangle2_Y = -50
#Main game loop
running = True
while running:
screen.fill((119, 118, 110))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
carX_change = 48
if event.key == pygame.K_LEFT:
carX_change = -48
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
carX_change = 0
carX += carX_change
#drawing Road lines
pygame.draw.line(screen, black, (639, 0), (639, 600), 10)
pygame.draw.line(screen, black, (200, 0), (200, 600), 10)
#drawing the 1st road markers
rectangle = pygame.draw.rect(screen, black, (rectangleX, rectangleY, 15, 80))
roadmarker_move()
#drawing the 2nd road markers
rectangle = pygame.draw.rect(screen, black, (rectangle2_X, rectangle2_Y, 15, 80))
roadmarker2_move()
#setting boundries
if carX <= 170:
carX = 170
elif carX >= 547:
carX = 547
#collision detecting
car_rect = car.get_rect()
car_rect.topleft = (carX, carY)
car_rect.move_ip((carX_change, 0))
car2_rect = car2.get_rect()
car2_rect.topleft = (car2_X, car2_Y)
car2_rect.move_ip((car2Y_speed, 0))
if ( car_rect.colliderect(car2_rect) ):
print( "car hit tree" )
car1(carX, carY)
car_2(car2_X, car2_Y)
tree1(tree1_X, tree1_Y)
tree2(tree2_X, tree2_Y)
tree3(tree3_X, tree3_Y)
tree4(tree4_X, tree4_Y)
clock.tick(FPS)
pygame.display.update()
pygame.quit()
Upvotes: 1
Views: 74
Reputation: 211136
The name of the attribute is topleft
rather than top_left
. See pygame.Rect
.
Furthermore, move_ip
has to be applied to the pygame.Rect
object rather than to the Surface:
car.move_ip((carX_change, 0))
car_rect.move_ip((carX_change, 0))
Finally car_rect(x, y)
makes not any sens at all. It is sufficient to pass a tuple with the position of the car to the method blit
in the function car1
:
screen.blit(car, car_rect(x, y))
screen.blit(car, (x, y))
respectively in the function car_2
screen.blit(car2, car2_rect, (x, y))
screen.blit(car2, (x, y))
To improve the collision you have to ensure that the collision rectangle reflects the actual position of the cars. You wrongly move the collision rectangles. Remove this lines of code and do the collision test after the cars have been moved:
car1(carX, carY) # <--- INSERT
car_2(car2_X, car2_Y) # <--- INSERT
car_rect = car.get_rect()
car_rect.topleft = (carX, carY)
#car_rect.move_ip((carX_change, 0)) <--- DELETE
car2_rect = car2.get_rect()
car2_rect.topleft = (car2_X, car2_Y)
#car2_rect.move_ip((car2Y_speed, 0)) <--- DELETE
#car1(carX, carY) <--- DELETE
#car_2(car2_X, car2_Y) <--- DELETE
Complete example:
import pygame
import random
import math
pygame.init()
black = (0, 0, 0)
screen_width = 600
screen_length = 800
screen = pygame.display.set_mode((screen_length, screen_width))
clock = pygame.time.Clock()
FPS = 60
icon = pygame.image.load('car.png')
pygame.display.set_icon(icon)
#game caption
pygame.display.set_caption("Car game")
#Main car
car = pygame.image.load('car.png')
carX = 370
carY = 470
carX_change = 0
#second car
car2 = pygame.image.load('car2.png')
car2_rect = car.get_rect()
car2_X = random.randint(200, 600)
car2_Y = random.randint(-50, 0)
car2Y_speed = 13
#road side trees
tree1Img = pygame.image.load('tree1.png')
tree1_X = 70
tree1_Y = 30
tree2Img = pygame.image.load("tree2.png")
tree2_X = 700
tree2_Y = 300
tree3Img = pygame.image.load("tree3.png")
tree3_X = 70
tree3_Y = 400
tree4Img = pygame.image.load("tree4.png")
tree4_X = 700
tree4_Y = 50
#game functions
def car1(x, y):
screen.blit(car, (x, y))
def car_2(x, y):
global car2_Y
global car2_X
screen.blit(car2, (x, y))
car2_Y += car2Y_speed
if car2_Y > screen_length:
car2_X = random.randint(200, 545)
car2_Y = random.randint(-50, 0)
def tree1(x, y):
global tree1_Y
screen.blit(tree1Img, (x, y))
tree1_Y += 10
if tree1_Y >= screen_width:
tree1_Y = -50
def tree2(x, y):
global tree2_Y
screen.blit(tree2Img, (x, y))
tree2_Y += 10
if tree2_Y >= screen_width:
tree2_Y = -50
def tree3(x, y):
global tree3_Y
screen.blit(tree2Img, (x, y))
tree3_Y += 10
if tree3_Y >= screen_width:
tree3_Y = -50
def tree4(x, y):
global tree4_Y
screen.blit(tree4Img, (x, y))
tree4_Y += 10
if tree4_Y >= screen_width:
tree4_Y = -50
# 1st Road marker's movement
rectangleX = 426
rectangleY = 100
def roadmarker_move():
global rectangleY
if running == True:
rectangleY += 10
if rectangleY == 610:
rectangleY = -50
#2nd road marker's movement
rectangle2_X = 426
rectangle2_Y = 410
def roadmarker2_move():
global rectangle2_Y
if running == True:
rectangle2_Y += 10
if rectangle2_Y == 610:
rectangle2_Y = -50
#Main game loop
running = True
while running:
screen.fill((119, 118, 110))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
carX_change = 48
if event.key == pygame.K_LEFT:
carX_change = -48
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
carX_change = 0
carX += carX_change
#drawing Road lines
pygame.draw.line(screen, black, (639, 0), (639, 600), 10)
pygame.draw.line(screen, black, (200, 0), (200, 600), 10)
#drawing the 1st road markers
rectangle = pygame.draw.rect(screen, black, (rectangleX, rectangleY, 15, 80))
roadmarker_move()
#drawing the 2nd road markers
rectangle = pygame.draw.rect(screen, black, (rectangle2_X, rectangle2_Y, 15, 80))
roadmarker2_move()
#setting boundries
if carX <= 170:
carX = 170
elif carX >= 547:
carX = 547
car1(carX, carY)
car_2(car2_X, car2_Y)
#collision detecting
car_rect = car.get_rect()
car_rect.topleft = (carX, carY)
car2_rect = car2.get_rect()
car2_rect.topleft = (car2_X, car2_Y)
if ( car_rect.colliderect(car2_rect) ):
print( "car hit tree" )
tree1(tree1_X, tree1_Y)
tree2(tree2_X, tree2_Y)
tree3(tree3_X, tree3_Y)
tree4(tree4_X, tree4_Y)
clock.tick(FPS)
pygame.display.update()
pygame.quit()
Upvotes: 3