Reputation:
So I'm making this cool avoiding game and I've got everything done except for the collision. Since I'm a noob to the pygame module, I didn't do any classes, and I don't know how I would check if the player hitbox collides with the enemy hitbox. Also, I know a few people have asked this before, but the answers they gave are either unclear to me or are for sprites, not rectangles. Here's my code: https://hastebin.com/exaximafiy.py
#avoid game
#import
import pygame
from time import sleep
import os
import math
import random
import pygame.mixer
from pygame.locals import *
#intiate pygame
pygame.mixer.init()
pygame.init()
os.system("cls")
#set screen size
screen = pygame.display.set_mode((1024,768))
#set title
pygame.display.set_caption("Avoid")
def menu():
pygame.time.delay(100)
#set title
pygame.display.set_caption("Avoid - Menu Screen")
running = True
while running:
#close program if user clicked big X
if pygame.mixer.get_busy() != None:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running=False
pygame.quit()
break
#set bg
screen.fill((255,255,255))
menubg=pygame.image.load("menuScreen.png")
screen.blit(menubg,(0,0))
pygame.display.flip()
#detect button press (enter to play, h for instructions, q for options, esc to quit)
keys = pygame.key.get_pressed()
if keys[pygame.K_RETURN]:
game()
if keys[pygame.K_h]:
instructions()
if keys[pygame.K_ESCAPE]:
pygame.quit()
if keys[pygame.K_q]:
options()
pygame.quit()
def instructions():
running=False
#set title
pygame.display.set_caption("Avoid - Instructions")
running=True
while running:
#close program if user clicked big X
if pygame.mixer.get_busy() != None:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running=False
pygame.quit()
break
#set bg
screen.fill((255,255,255))
helpbg=pygame.image.load("instructions.png")
screen.blit(helpbg,(0,0))
pygame.display.flip()
#if esc pressed, go to menu
keys = pygame.key.get_pressed()
if keys[pygame.K_ESCAPE]:
pygame.time.delay(100)
menu()
def gameOver():
running=False
#set title
pygame.display.set_caption("Avoid - Game Over")
running=True
while running:
#close program if user clicked big X
if pygame.mixer.get_busy() != None:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running=False
pygame.quit()
break
#set bg
screen.fill((255,255,255))
menubg=pygame.image.load("gameOver.png")
screen.blit(menubg,(0,0))
pygame.display.flip()
#detect input
keys = pygame.key.get_pressed()
if keys[pygame.K_RETURN]:
game()
if keys[pygame.K_ESCAPE]:
pygame.quit()
def game():
running=False
#play music
song = pygame.mixer.Sound("song.wav")
song.play(-1)
#set title
pygame.display.set_caption("Avoid - Game Screen")
#set vars
#enemy x and y pos
randx = random.randint(17,1007)
randy = random.randint(17,751)
#time vars (time2 = enemyspawn, time = stopwatch, time3 = playersize time, time4 = playersize)
time2 = 0.5
time=0
time3 = 10
time4 = 1
#player x,y
x = 1024*0.5
y = 768*0.5
#enemy width,height
width = 50
height = 50
#colors
red=(255,0,0)
#speed
vel=10
#set player size
playerSize = 15
running = True
while running:
#pygame.time.delay(10)
#close program if user clicked big X
if pygame.mixer.get_busy() != None:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running=False
pygame.quit()
break
#set stopwatch
time=time+0.040
#movement
keys = pygame.key.get_pressed()
#arrow
if keys[pygame.K_DOWN] and y < 751:
y += vel
if keys[pygame.K_UP] and y > 17:
y -= vel
if keys[pygame.K_RIGHT] and x < 1007:
x += vel
if keys[pygame.K_LEFT] and x > 17:
x -= vel
#wasd
if keys[pygame.K_s] and y < 751:
y += vel
if keys[pygame.K_w] and y > 17:
y -= vel
if keys[pygame.K_d] and x < 1007:
x += vel
if keys[pygame.K_a] and x > 17:
x -= vel
#if esc quit, y - collide
if keys[pygame.K_ESCAPE]:
pygame.quit()
if keys[pygame.K_y]:
collision()
#shows what coords you on
print(x,y)
#set bg
screen.fill((255,255,255))
gamebg=pygame.image.load("gamebg.png")
screen.blit(gamebg,(0,0))
pygame.display.flip()
#time thing in middle
time1 = float('%.2f' % round(time,1))
myfont = pygame.font.SysFont('Arial', 35)
textsurface = myfont.render(("time: " +str(time1)), 1, (0,0,0))
screen.blit(textsurface,(455,384))
#load enemys
if time2 < time1:
time2 = (time2+0.5)
randx = random.randint(17,1007)
randy = random.randint(17,751)
#rainbow
enemy=pygame.image.load("red.png")
screen.blit(enemy,(randx,randy))
pygame.display.flip()
pygame.time.wait(1)
enemy=pygame.image.load("orange.png")
screen.blit(enemy,(randx,randy))
pygame.display.flip()
pygame.time.wait(1)
enemy=pygame.image.load("yellow.png")
screen.blit(enemy,(randx,randy))
pygame.display.flip()
pygame.time.wait(1)
enemy=pygame.image.load("green.png")
screen.blit(enemy,(randx,randy))
pygame.display.flip()
pygame.time.wait(1)
enemy=pygame.image.load("blue.png")
screen.blit(enemy,(randx,randy))
pygame.display.flip()
pygame.time.wait(1)
enemy=pygame.image.load("indigo.png")
screen.blit(enemy,(randx,randy))
pygame.display.flip()
pygame.time.wait(1)
enemy=pygame.image.load("violet.png")
screen.blit(enemy,(randx,randy))
pygame.display.flip()
#change size
if time3 < time1:
time3 = (time3+10.0)
playerSize = (playerSize + 15)
time4 = (time4 + 0.9)
#draw hitboxes
#player
playerHitbox=((x-(17.5*time4)),(y-(18*time4)),(35*time4),(35*time4))
#enemy
enemyHitbox=(randx,randy,50,50)
#draw
pygame.draw.rect(screen,red,playerHitbox,2)
pygame.draw.rect(screen,red,enemyHitbox,2)
#draw player (red circle)
player = pygame.draw.circle(screen, red, [int(x),int(y)], playerSize)
#update screen
pygame.display.update()
def collision():
song.stop()
pygame.time.delay(1000)
gameOver()
# def checkCollision(playerHitbox, enemyHitbox):
# col = playerHitbox.colliderect(enemyHitbox)
# if col == True:
# collision()
# checkCollision(playerHitbox,enemyHitbox)
if Rect.colliderect(enemyHitbox):
collision()
menu()
Any leads would be helpful and you can ask me to clarify in the comments below.
Upvotes: 1
Views: 95
Reputation: 498
Every Rect
object in Pygame has a method colliderect
which can test if that Rect
object collides (overlaps) with any other Rect
object. More info
To check if a rectangle at point (x1
,y1
) with a width w1
and height h1
collides with a rectangle at point (x2
, y2
) with a width w2
and height h2
, you can implement this like so:
pygame.Rect(x1,y1,w1,h1).colliderect(pygame.Rect(x2,y2,w2,h2))
In your specific example for example, you could implement what you are trying to do with:
def checkCollision(playerHitbox, enemyHitbox):
return pygame.Rect(*playerHitbox).colliderect(pygame.Rect(*enemyHitbox))
NB: the *
I used here unpacks the tuple into arguments. I.e: the first element is sent as the first argument, the second is sent as the second argument, etc. More info.
You were on the right track in your code, remember that this method operates on Rect
objects and not on tuples of the information itself. You therefore need to instantiate the necessary Rect
objects as shown above ^
Upvotes: 4