Reputation: 129
I am trying to make a pygame racing game. It involves a "car" which is just a quadrilateral and a track in a PNG form. Right now, the game is very basic, but what I want it to do, is when the car is even off the track by a single pixel, an event to be triggered. I have made a very simple version of the code which is below that I would like to fix, as well as the picture of the track, please can somebody help me with this?
import pygame
from pygame.math import Vector2
pygame.init()
clock = pygame.time.Clock()
WIDTH = 900
HEIGHT = 550
screen = pygame.display.set_mode((WIDTH, HEIGHT))
abc = pygame.image.load("trackimagelinkinthepost")
track = pygame.transform.scale(abc, (100,75))
thetrack = track
REDCAR_ORIGINAL = pygame.Surface((50, 30), pygame.SRCALPHA)
redangle = 180
redspeed = 3
x = 800
y = 500
pos_red = Vector2(x,y)
vel_red = Vector2(-redspeed,0)
redcar = REDCAR_ORIGINAL
pygame.draw.polygon(
REDCAR_ORIGINAL, (255, 0, 0), [(0, 30), (50, 20), (50, 10), (0, 0)])
redrect = redcar.get_rect(center=pos_red)
trackrect = thetrack.get_rect(topleft=(0,0))
mask_red = pygame.mask.from_surface(redcar)
track_mask = pygame.mask.from_surface(thetrack)
myevent = True
while myevent:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
redangle += 3
vel_red.rotate_ip(-3)
redcar = pygame.transform.rotate(REDCAR_ORIGINAL, redangle)
redrect = redcar.get_rect(center=redrect.center)
# We need a new mask after the rotation.
mask_red = pygame.mask.from_surface(redcar)
elif keys[pygame.K_RIGHT]:
redangle -= 3
vel_red.rotate_ip(3)
redcar = pygame.transform.rotate(REDCAR_ORIGINAL, redangle)
redrect = redcar.get_rect(center=redrect.center)
mask_red = pygame.mask.from_surface(redcar)
pos_red += vel_red
redrect.center = pos_red
offset = redrect[0] - trackrect[0], redrect[1] - trackrect[1]
offtrack = mask_red.overlap(track_mask, offset)
if not offtrack:
print("HI")
screen.fill((100,255,100))
screen.blit(abc,(0,-50))
screen.blit(redcar, redrect)
pygame.display.flip()
clock.tick(120)
pygame.quit()
Upvotes: 0
Views: 89
Reputation: 101052
Frst, you don't want to check if the car mask overlaps with the track mask. You want to check if the car mask overlaps with the not-track mask.
Also, your offset is wrong. You have to check not-track-mask.overlap(car-mask, car-position)
instead of car-mask.overlap(track-mask, car-position)
.
Here's an example how to fix it (I simplified some things, also):
import pygame
import pygame.freetype
from pygame.math import Vector2
pygame.init()
clock = pygame.time.Clock()
WIDTH = 900
HEIGHT = 550
screen = pygame.display.set_mode((WIDTH, HEIGHT))
track_image = pygame.image.load("trackimagelinkinthepost.png").convert_alpha()
REDCAR_ORIGINAL = pygame.Surface((50, 30), pygame.SRCALPHA)
redangle = 0
redspeed = 2
pos_red = Vector2(200, 200)
vel_red = Vector2(redspeed, 0)
redcar = REDCAR_ORIGINAL
pygame.draw.polygon(REDCAR_ORIGINAL, pygame.Color('dodgerblue'), [(0, 30), (50, 20), (50, 10), (0, 0)])
mask_red = pygame.mask.from_surface(redcar)
off_mask = pygame.mask.from_surface(track_image)
off_mask.invert()
font = pygame.freetype.SysFont(None, 42, True, True)
s=False
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
redangle += 3
vel_red.rotate_ip(-3)
redcar = pygame.transform.rotate(REDCAR_ORIGINAL, redangle)
mask_red = pygame.mask.from_surface(redcar)
elif keys[pygame.K_RIGHT]:
redangle -= 3
vel_red.rotate_ip(3)
redcar = pygame.transform.rotate(REDCAR_ORIGINAL, redangle)
mask_red = pygame.mask.from_surface(redcar)
pos_red += vel_red
redcar_pos = list(int(v) for v in pos_red)
offtrack = off_mask.overlap(mask_red, redcar_pos)
screen.fill(pygame.Color('grey12'))
screen.blit(track_image, (0, 0))
if offtrack:
font.render_to(screen, (250, 20), '!!! OFFTRACK !!!', pygame.Color('orange'))
screen.blit(redcar, redcar_pos)
pygame.display.flip()
clock.tick(60)
pygame.quit()
Upvotes: 1