Rectangle Collision Detection Problem


Scarface9291

Still Fresh
Joined
Dec 10, 2012
Messages
1
I am trying to make a program where the objective is to dodge the many blocks swarming around you while you are a small block that you move with arrow keys. Once the small player collides with one of the other blocks it gets deleted. It is the same idea as this program. (http://www.pygame.org/project-Escape-661-.html)


import pygame, sys, random, time


from pygame.locals import *


# set up pygame


pygame.init()


mainClock = pygame.time.Clock()


# set up the window


WINDOWWIDTH = 1000


WINDOWHEIGHT = 1000


windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT), 0, 32)


pygame.display.set_caption('Final')


BLACK = (0, 0, 0)


WHITE = (255, 255, 255)


RED = (255, 0, 0)


NEWBLOCK = 40


BLOCKSIZE = 20


player = pygame.Rect(500, 500, 30, 30)


blocks = []


moveLeft = False


moveRight = False


moveUp = False


moveDown = False


MOVESPEED = 7


DOWNLEFT = 1


DOWNRIGHT = 3


UPLEFT = 7


UPRIGHT = 9


b1 ={'rect':pygame.Rect(1, 1, 50, 50), 'color':RED, 'dir':UPLEFT}


b2 ={'rect':pygame.Rect(925, 1, 50, 50), 'color':RED, 'dir':UPRIGHT}


b3 ={'rect':pygame.Rect(760, 760, 50, 50), 'color':RED, 'dir':UPLEFT}


b4 ={'rect':pygame.Rect(1, 925, 50, 50), 'color':RED, 'dir':UPRIGHT}


b5 ={'rect':pygame.Rect(1, 462, 50, 50), 'color':RED, 'dir':UPLEFT}


b6 ={'rect':pygame.Rect(462, 231, 50, 50), 'color':RED, 'dir':UPRIGHT}


b7 ={'rect':pygame.Rect(231, 462, 50, 50), 'color':RED, 'dir':UPLEFT}


b8 ={'rect':pygame.Rect(325, 325, 50, 50), 'color':RED, 'dir':UPLEFT}


b9 ={'rect':pygame.Rect(100, 625, 50, 50), 'color':RED, 'dir':UPLEFT}


b10 ={'rect':pygame.Rect(530, 1, 50, 50), 'color':RED, 'dir':UPLEFT}


blocks = [b1, b2, b3, b4, b5, b6, b7, b8, b9, b10]


while True:


# check for events


for event in pygame.event.get():


if event.type == QUIT:


pygame.quit()


sys.exit()


if event.type == KEYDOWN:


# change the keyboard variables


if event.key == K_LEFT or event.key == ord('a'):


moveRight = False


moveLeft = True


if event.key == K_RIGHT or event.key == ord('d'):


moveLeft = False


moveRight = True


if event.key == K_UP or event.key == ord('w'):


moveDown = False


moveUp = True


if event.key == K_DOWN or event.key == ord('s'):


moveUp = False


moveDown = True


if event.type == KEYUP:


if event.key == K_ESCAPE:


pygame.quit()


sys.exit()


if event.key == K_LEFT or event.key == ord('a'):


moveLeft = False


if event.key == K_RIGHT or event.key == ord('d'):


moveRight = False


if event.key == K_UP or event.key == ord('w'):


moveUp = False


if event.key == K_DOWN or event.key == ord('s'):


moveDown = False


for b in blocks:


# move the block data structure


if b['dir'] == DOWNLEFT:


b['rect'].left -= MOVESPEED


b['rect'].top += MOVESPEED


if b['dir'] == DOWNRIGHT:


b['rect'].left += MOVESPEED


b['rect'].top += MOVESPEED


if b['dir'] == UPLEFT:


b['rect'].left -= MOVESPEED


b['rect'].top -= MOVESPEED


if b['dir'] == UPRIGHT:


b['rect'].left += MOVESPEED


b['rect'].top -= MOVESPEED


# check if the block has move out of the window


if b['rect'].top < 0:


# block has moved past the top


if b['dir'] == UPLEFT:


b['dir'] = DOWNLEFT


if b['dir'] == UPRIGHT:


b['dir'] = DOWNRIGHT


if b['rect'].bottom > WINDOWHEIGHT:


# block has moved past the bottom


if b['dir'] == DOWNLEFT:


b['dir'] = UPLEFT


if b['dir'] == DOWNRIGHT:


b['dir'] = UPRIGHT


if b['rect'].left < 0:


# block has moved past the left side


if b['dir'] == DOWNLEFT:


b['dir'] = DOWNRIGHT


if b['dir'] == UPLEFT:


b['dir'] = UPRIGHT


if b['rect'].right > WINDOWWIDTH:


# block has moved past the right side


if b['dir'] == DOWNRIGHT:


b['dir'] = DOWNLEFT


if b['dir'] == UPRIGHT:


b['dir'] = UPLEFT


# draw the block onto the surface


pygame.draw.rect(windowSurface, b['color'], b['rect'])


pygame.display.update()


time.sleep(0.02)


windowSurface.fill(BLACK)


if moveDown and player.bottom < WINDOWHEIGHT:


player.top += MOVESPEED


if moveUp and player.top > 0:


player.top -= MOVESPEED


if moveLeft and player.left > 0:


player.left -= MOVESPEED


if moveRight and player.right < WINDOWWIDTH:


player.right += MOVESPEED


for b in blocks[:]:


if player.colliderect(players):


players.remove(player)


pygame.draw.rect(windowSurface, WHITE, player)

The collision detection is not working and it glitches to a blank screen. Without the collision detection it works fine.
 
I don't know Python or PyGame, so I can only hazard a (probably useless) guess -


Is an array going out of bounds (possibly due to there being no other/too many players on the screen)? eg array[-1] or array[1000+] (in a DIMensioned array of 1000)?


If you draw the blocks before placing the player, does that make a difference?
 
Last edited by a moderator:
Can a mod please sticky a topic already, saying "THIS IS NOT A GENERIC PYGAME FORUM" or something, so people who search "pygame forum" on Google and see this as the second result know this more readily? There's no way to force Google to be less stupid or the Pygame developers to start an actual Pygame forum, after all.


Anyway... like I said, Google lied to you (or, rather, it's just stupid); this forum is specifically about Python and Pygame on the OpenPandora handheld unit. A much better place for generic Pygame questions is the mailing list, which you can find on pygame.org easily enough.


Anyway, I haven't looked thoroughly at the code, but if the collision detection is what's causing it, I suspect an infinite loop somewhere. I don't see any while loops, so I doubt this. Maybe your collision detection checks are just wrong.


EDIT: Maybe a timing issue. I see you're not limiting the frame rate like you should; calling time.sleep is a really weird way to do it in Pygame. The normal way is to create a pygame.clock.Clock and call that object's tick method, passing the frame rate you want.


If you paste your code in a way that spacing isn't messed up (like PasteBin), I can help more.

Is an array going out of bounds due to there being no other players on the screen? eg array[-1] or array[1000] (in a DIMensioned array of 1000)?

Python doesn't cause silent errors. Lists (what you are calling "arrays"; actual arrays are rarely used in Python) throw an exception if you try to use an index that's too high. -1 is not out of range, actually; it is interpreted as the last index of the list (and -2 is the second-to-last, and so on).
 
Last edited by a moderator:
Back
Top