我正在制作一个自然选择模拟器程序。我想要发生的事情之一是当两个父对象发生碰撞时,要创建的后代对象随机地继承其某些父级特征。特别是,我希望传递int值的宽度和高度。问题是,我只想在它是后代时将宽度和高度传递给对象。我希望父对象的初始spawn具有完全随机化的值。
我的整个代码是:
import pygame, random
pygame.init()
map_width = 800
map_height = 800
size = [map_width, map_height]
screen = pygame.display.set_mode(size)
# pygame already defines a lot of colors, we we just use them
colors = pygame.color.THECOLORS
pygame.display.set_caption("Natural Selection Game")
done = False
clock = pygame.time.Clock()
# just a simple generator to generate an id for each object
def id_generator():
i = 0
while True:
i += 1
yield i
ids = id_generator()
# just a helper function that wraps pygame.sprite.collide_mask
# to prevent a sprite from colliding with itself
def collide(a, b):
if a.id == b.id:
return False
return pygame.sprite.collide_mask(a, b)
class Organism(pygame.sprite.Sprite):
def __init__(self, id, org_list, width, height, color = None):
pygame.sprite.Sprite.__init__(self, org_list)
self.org_list = org_list
self.id = id
# Speed and direction
self.change_x = random.randrange(0,6)
self.change_y = random.randrange(0,6)
# Dimensions
self.width = width or random.randrange(20,60)
self.height = height or random.randrange(20,60)
x = random.randrange(0 + width, map_width - width )
y = random.randrange(0 + height, map_height - height)
self.rect = pygame.rect.Rect(x, y, width, height)
self.image = pygame.surface.Surface((width, height))
self.image.fill(colors['hotpink2'])
self.image.set_colorkey(colors['hotpink2'])
# we either pass in the color, or create a random one
self.color = color or random.choice([colors['red'], colors['green'], colors['blue']])
pygame.draw.ellipse(self.image, self.color, [0, 0, width, height])
self.mask = pygame.mask.from_surface(self.image)
# we keep track of collisions currently happening
# so we only spawn one children for each collisions
self.collisions = set()
# just something to limit the number of organisms
self.age = 0
self.children = 0
# Initiate movement
def update(self):
self.age += 1
# we move by simply moving the rect
# the Group's draw function will look that the rect attribute
# to determine the position for drawing the image
self.rect.move_ip(self.change_x, self.change_y)
# we can make use of a lot of Rect's attributes to make
# this computation simpler
if self.rect.left < 0 or self.rect.right > map_width:
self.change_x *= -1
if self.rect.top < 0 or self.rect.bottom > map_height:
self.change_y *= -1
# only reproduce if we are at least 200 ticks old
# so newly created organisms spwan new ones at the
# very moment they spawned themself
if self.age < 200:
return
# just an arbitary limit so the screen does not get too full
if self.age > 500:
print (self.id, ' died of age')
# kill() removes the Sprite from all its Groups (which is only org_list at the moment)
self.kill()
return
# just an arbitary limit so the screen does not get too full
if self.children > 4:
print (self.id, ' died of too many children')
self.kill()
return
# check if we collided with another Sprite
collided = pygame.sprite.spritecollideany(self, self.org_list, collide)
# also check if this
# - is a new collision
# - the other organism is at least 200 ticks old
# - there are not too many organisms at the screen at the moment
if collided and not collided.id in self.collisions and collided.age > 200 and len(self.org_list) < 100:
# keep track of the current collision, so this code is not triggerd
# every frame while the colliding organisms move other each other
self.collisions.add(collided.id)
collided.collisions.add(self.id)
print (self.id, ' collided with ', collided.id)
# inherit parent dimensions
width = random.choice(self.width, collided.width)
height = random.choice(self.height, collided.height)
# let the dimensions mutate sometimes for fun
if random.randrange(0, 100) < 5:
width = random.randrange(5, 100)
print ('Offspring of', self.id, ' and ', collided.id, ' mutates a dimension change')
elif random.randrange(0, 100) < 5:
height = random.randrange(5, 100)
print ('Offspring of', self.id, ' and ', collided.id, ' mutates a dimension change')
elif random.randrange(0, 100) < 5:
width = random.randrange(5, 100)
height = random.randrange(5, 100)
print ('Offspring of', self.id, ' and ', collided.id, ' mutates a dimension change')
# let the color mutate sometimes for fun
if random.randrange(0, 100) < 5:
color[random.randrange(0, 3)] = random.randrange(0, 256)
print ('Offspring of', self.id, ' and ', collided.id, ' speciates')
# create the new child with the new color
Organism(next(ids), self.org_list, list(map(int, color)))
self.children += 1
collided.children += 1
else:
# if there are currently no collisions, we clear the collisions set
# so new collisions can happen
self.collisions = set()
# we use a Group for all the draw/update/collision magic
org_list = pygame.sprite.Group()
for _ in range(15):
Organism(next(ids), org_list)
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
# we just call update on the group so update is called
# an every sprite in the group
org_list.update()
screen.fill(colors['white'])
# same for drawing: just call draw on the group
org_list.draw(screen)
clock.tick(60)
pygame.display.flip()
pygame.quit()
再一次,具体来说,当有父母的宽度和高度时,我想要传递宽度和高度,但是在没有父母的初始创世句中,我希望这些值是随机生成的。 / p>