How can i make a collision system in the simplest way in pygame, without using classes. I've been trying for a long time and none of the ways works, in my last attempt the code was like this: (Sorry if it's wrongly written, I'm a beginner in all this)
import pygame
from pygame.locals import *
from sys import exit
pygame.init()
G = 9.807 # GRAVITY
screen = pygame.display.set_mode((400, 400))
time = pygame.time.Clock()
y_speed = 0
playersize = [20, 20]
playerpos = [0, 0]
def move(dx):
playerpos[0] += dx
if player.colliderect(block):
if dx > 0:
playerpos[0] -= player.right - block.left
if dx < 0:
playerpos[0] -= player.left - block.right
while 1:
time.tick(30)
screen.fill((255,255,255))
player = pygame.draw.rect(screen, (255,0,0), (playerpos[0], playerpos[1], playersize[0], playersize[1]))
block = pygame.draw.rect(screen, (0,0,0), (100, 380, 20, 20))
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
exit()
if event.type == KEYDOWN:
if event.key == K_SPACE or event.key == K_UP or event.key == K_w:
if playerpos[1] == 380:
y_speed = -5
time = pygame.time.Clock()
else:
pass
T = time.get_time() / 1000
F = G * T
y_speed += F
playerpos[1] += y_speed
if playerpos[1] >= 380:
playerpos[1] = 380
y_speed = 0
time = pygame.time.Clock()
else:
pass
keys = pygame.key.get_pressed()
if keys[K_a] or keys[K_LEFT]:
move(-5)
if keys[K_d] or keys[K_RIGHT]:
move(5)
pygame.display.update()
You must create a pygame.Rect
object with the current position of the player before the collision test. If the player hits the block from the left, the player`s right must be set by the left of the block. If the player hits the block from the right, the player's right must be set by the left of the block:
def move(dx):
playerpos[0] += dx
player = pygame.Rect((playerpos[0], playerpos[1], playersize[0], playersize[1]))
if player.colliderect(block):
if dx > 0:
player.right = block.left
playerpos[0] = player.left
if dx < 0:
player.left = block.right
playerpos[0] = player.left
You can add the collision for the y-direction in a similar way. However, you must perform the collision detection in y direction before the collision detection in x direction:
def move(dx, dy):
playerpos[1] += dy
player = pygame.Rect((playerpos[0], playerpos[1], playersize[0], playersize[1]))
if player.colliderect(block):
if dy > 0:
player.bottom = block.top
playerpos[1] = player.top
playerpos[0] += dx
player = pygame.Rect((playerpos[0], playerpos[1], playersize[0], playersize[1]))
if player.colliderect(block):
if dx > 0:
player.right = block.left
playerpos[0] = player.left
if dx < 0:
player.left = block.right
playerpos[0] = player.left
Complete and working example:
import pygame
from pygame.locals import *
from sys import exit
pygame.init()
G = 9.807 # GRAVITY
screen = pygame.display.set_mode((400, 400))
time = pygame.time.Clock()
y_speed = 0
playersize = [20, 20]
playerpos = [0, 0]
def move(dx, dy):
playerpos[1] += dy
player = pygame.Rect((playerpos[0], playerpos[1], playersize[0], playersize[1]))
if player.colliderect(block):
if dy > 0:
player.bottom = block.top
playerpos[1] = player.top
playerpos[0] += dx
player = pygame.Rect((playerpos[0], playerpos[1], playersize[0], playersize[1]))
if player.colliderect(block):
if dx > 0:
player.right = block.left
playerpos[0] = player.left
if dx < 0:
player.left = block.right
playerpos[0] = player.left
block = pygame.Rect(150, 330, 20, 20)
ground_y = 350
run = True
while run:
time.tick(30)
for event in pygame.event.get():
if event.type == QUIT:
run = False
if event.type == KEYDOWN:#
if event.key == K_SPACE or event.key == K_UP or event.key == K_w:
if playerpos[1] == ground_y - playersize[1]:
y_speed = -5
keys = pygame.key.get_pressed()
move_left = keys[K_a] or keys[K_LEFT]
move_right = keys[K_d] or keys[K_RIGHT]
x_speed = (move_right - move_left) * 5
T = time.get_time() / 1000
F = G * T
y_speed += F
move(x_speed, y_speed)
if playerpos[1] >= ground_y - playersize[1]:
playerpos[1] = ground_y - playersize[1]
y_speed = 0
screen.fill((255,255,255))
pygame.draw.rect(screen, "gray", (0, ground_y, 400, 400-ground_y))
pygame.draw.rect(screen, (255,0,0), (playerpos[0], playerpos[1], playersize[0], playersize[1]))
pygame.draw.rect(screen, (0,0,0), block)
pygame.display.update()
pygame.quit()
exit()