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()
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.
Comments