Pygame: Find empty space?

Sam Tubb

I am making a cave exploring esque game, where the computer generates a random cave, and then throws the player in to explore it. The problem is, I need the player to be creates some where within the cave where there isn't blocks. I tried this:

#do generation
px=0
py=0
for b in blocks:
    while b.rect.collidepoint(px,py):
        px=randrange(1,640)
        py=randrange(1,480)
        player=Player(px,py)

But this didn't seem to work, so does anyone have a suggestion?

Here is the code:

import pygame
from pygame.locals import *
from collections import namedtuple
from random import randrange,choice
pygame.init()
screen=pygame.display.set_mode((640,480))
Move = namedtuple('Move', ['up', 'left', 'right'])
max_gravity=50
class Block(object):
    def __init__(self,x,y):
        self.x=x
        self.y=y
        self.rect=pygame.Rect(self.x,self.y,16,16)
class CaveMaker(object):
    def __init__(self):
        self.active=1
        self.x=randrange(1,640)
        self.y=randrange(1,480)
        self.direction=(choice([25,0,-25]),choice([25,0,-25]))
        self.rect=pygame.Rect(self.x,self.y,60,60)
        self.timeout=choice([30,50,70,90,110])
        self.destroytime=randrange(200,360)
    def Update(self):
        if self.active==1:
            self.x+=self.direction[0]
            self.y+=self.direction[1]
            self.timeout-=1
            if self.timeout==0:
                self.direction=(choice([25,0,-25]),choice([25,0,-25]))
                self.timeout=choice([30,50,70,90,110])
            self.destroytime-=1
            if self.destroytime==0:
                self.active=0
            self.rect=pygame.Rect(self.x,self.y,60,60)
class Player(object):
    def __init__(self, x, y):
        self.rect = pygame.Rect(x,y,16,16)
        self.on_ground = True
        self.xvel = 0
        self.yvel = 0
        self.jump_speed = 7
        self.move_speed = 3

    def update(self, move, blocks):
        if move.up and self.on_ground:
            self.yvel -= self.jump_speed
        if move.left:
                self.xvel = -self.move_speed
        if move.right:
                self.xvel = self.move_speed
        if not self.on_ground:
            self.yvel += 0.3
            # but not too fast
            if self.yvel > max_gravity: self.yvel = max_gravity
        if not (move.left or move.right):
            self.xvel = 0
        self.rect.left += self.xvel
        self.collide(self.xvel, 0, blocks)
        self.rect.top += self.yvel
        self.on_ground = False;
        self.collide(0, self.yvel, blocks)

    def collide(self, xvel, yvel, blocks):
        for block in [blocks[i] for i in self.rect.collidelistall(blocks)]:
            if xvel > 0:
                    self.rect.right = block.rect.left
            if xvel < 0:
                    self.rect.left = block.rect.right

            if yvel > 0:
                self.rect.bottom = block.rect.top
                self.on_ground = True
                self.yvel = 0
            if yvel < 0: self.rect.top = block.rect.bottom;self.yvel=0
blocks=[]
cavemakes=[]
gen=1
genx=0
geny=0
cavemakes.append(CaveMaker());cavemakes.append(CaveMaker());cavemakes.append(CaveMaker());cavemakes.append(CaveMaker());
while True:
    key=pygame.key.get_pressed()
    if gen==1:
        blocks.append(Block(genx,geny))
        geny+=16
        if geny>480:
            geny=0
            genx+=16
            if genx>640:
                gen=2
    elif gen==2:
        screen.fill((5,80,200))
        for b in blocks:
            pygame.draw.rect(screen, (90,90,90), b.rect, 0)
        for c in cavemakes:
            if c.active==0:
                gen='done'
                player=Player(32,32)
            c.Update()
            for b in blocks:
                if b.rect.colliderect(c.rect):
                    blocks.remove(b) 
        pygame.display.flip()
    if gen=='done':
        screen.fill((5,80,200))
        for b in blocks:
            pygame.draw.rect(screen, (90,90,90), b.rect, 0)
        for e in pygame.event.get():
            if e.type==QUIT:
                exit()
        move = Move(key[K_w], key[K_a], key[K_d])
        player.update(move,blocks)
        pygame.draw.rect(screen, (5,200,5), player.rect, 3)
        pygame.display.flip()
jonrsharpe

Your code

for b in blocks:
    while b.rect.collidepoint(px,py):
        px=randrange(1,640)
        py=randrange(1,480)

Will loop through each block, making sure that the point doesn't overlap with only that block. So your eventual point doesn't collide with the last block, but may with others. Try:

while any(b.rect.collidepoint(px, py) for b in blocks): 

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related