Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
457 views
in Technique[技术] by (71.8m points)

python - Pygame: colliding rectangles with other rectangles in the same list

I have a list of 10 drawn rectangles (referenced as cubes in my script) that are affected by gravity. I made a simple collision system for them to stop when they hit the ground. How can I make it so when 2 cubes collide they stop falling like they do with the ground?

import pygame
import time
import random
pygame.init()
clock = pygame.time.Clock()
wnx = 800
wny = 600
black = (0,0,0)
grey = (75,75,75)
white = (255,255,255)
orange = (255,100,30)
wn = pygame.display.set_mode((wnx, wny))
wn.fill(white)
def cube(cx,cy,cw,ch):
    pygame.draw.rect(wn, orange, [cx, cy, cw, ch])
def floor(fx,fy,fw,fh):
    pygame.draw.rect(wn, grey, [fx, fy, fw, fh])
def main():
    floory = 550    
    number = 30
    cubex = [0] * number
    cubey = [0] * number
    cubew = 10                          
    cubeh = 10
    for i in range(len(cubex)):
        cubex[i] = (random.randrange(0, 80)*10)
        cubey[i] = (random.randrange(2, 5)*10)
    gravity = -10
    exit = False

    while not exit:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                exit = True
        for i in range(len(cubex)): #i want to check here if it collides with an other cube
            if not (cubey[i] + 10) >= floory:
                cubey[i] -= gravity

        wn.fill(white)
        floor(0,floory,800,50)

        for i in range(len(cubex)):
            cube(cubex[i], cubey[i], cubew, cubeh)

        pygame.display.update()
        clock.tick(5)
main()
pygame.quit()
quit()
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Use pygame.Rect.colliderect to check if to rectangles are intersecting.

Create an rectangle (pygame.Rect) which defines the next position (area) of the cube:

cubeR = pygame.Rect(cubex[i], cubey[i] + 10, cubew, cubeh)

Find all intersecting rectangles

cl = [j for j in range(len(cubey)) if j != i and cubeR.colliderect(pygame.Rect(cubex[j], cubey[j], cubew, cubeh))]

And don't move (let further "fall") the cube if there is any() collision:

if not any(cl):
    # [...]

The check may look like this:

for i in range(len(cubex)):
    cubeR = pygame.Rect(cubex[i], cubey[i] + 10, cubew, cubeh)
    cisect = [j for j in range(len(cubey)) if j != i and cubeR.colliderect(pygame.Rect(cubex[j], cubey[j], cubew, cubeh))]
    if not any(cisect) and not (cubey[i] + 10) >= floory:
        cubey[i] -= gravity

Note, since all the cubes are aligned to an 10*10 raster, it is sufficient to check if the origins of the cubes are equal:

for i in range(len(cubex)):
    cisect = [j for j in range(len(cubey)) if j != i and cubex[i] == cubex[j] and cubey[i]+10 == cubey[j]]
    if not any(cisect) and not (cubey[i] + 10) >= floory:
        cubey[i] -= gravity

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...