Open random335 opened 1 month ago
import pygame, random, time, math
global creatures
creatures = []
global plants
plants = []
global targeted
targeted = []
global cam_offset
cam_offset = [0, 0]
def angle_between(points):
return math.atan2(points[1][1] - points[0][1], points[1][0] - points[0][0])*180/math.pi
class PlantManager:
def __init__(self):
self.plants = [[random.randint(-450, win.get_width() + 450), random.randint(-450, win.get_height() + 450)] for i in range(80)]
self.delay = time.time()
def update(self):
for plant in self.plants:
pygame.draw.circle(win, [0, 185, 0], [plant[0] + cam_offset[0], plant[1] + cam_offset[1]], 6)
if time.time() - self.delay > 3:
self.plants = self.plants + [[random.randint(-450, win.get_width() + 450), random.randint(-450, win.get_height() + 450)] for i in range(30)]
self.delay = time.time()
class Organism:
def __init__(self, x, y, _type_, traits):
self.x = x
self.y = y
self.type = _type_
self.traits = traits
self.food_requirement = traits[2]
self.hunger = 6
self.delay = time.time()
self.vital_status = 1
self.vel = [0, 0]
self.speed = traits[3]
self.move_angle = random.randint(-180, 180)
self.move_delay = time.time()
self.rect = pygame.rect.Rect(x - self.traits[1], y - self.traits[1], self.traits[1]*2, self.traits[1]*2)
self.target = None
self.plant_target = None
def new(self):
if self.target == None:
dists = [[], []]
for count, creature in enumerate(creatures):
if creature.type == self.type and creature.vital_status == 1 and creature.hunger <= creature.food_requirement/2 and creature.__hash__() != self.__hash__():
dists[0].append(count)
dists[1].append(math.dist([self.x, self.y], [creature.x, creature.y]))
if dists[1] != []:
if creatures[dists[0][dists[1].index(min(dists[1]))]].__hash__() not in targeted:
self.target = dists[0][dists[1].index(min(dists[1]))]
creatures[dists[0][dists[1].index(min(dists[1]))]].target = creatures.index(self)
targeted.append(creatures[dists[0][dists[1].index(min(dists[1]))]].__hash__())
if self.target != None:
if self.target < len(creatures):
self.move_angle = angle_between([(self.x, self.y), (creatures[self.target].x, creatures[self.target].y)])
pygame.draw.line(win, [255, 255, 255], (self.x + cam_offset[0], self.y + cam_offset[1]), (creatures[self.target].x + cam_offset[0], creatures[self.target].y + cam_offset[1]), 8)
if self.rect.colliderect(creatures[self.target].rect):
new_color = [creatures[self.target].traits[0], self.traits[0]][random.randint(0, 1)]
new_radius = [creatures[self.target].traits[1], self.traits[1]][random.randint(0, 1)]
new_hunger = [creatures[self.target].traits[2], self.traits[2]][random.randint(0, 1)]
new_speed = [creatures[self.target].traits[3], self.traits[3]][random.randint(0, 1)]
to_vary = random.randint(0, 6)
if to_vary == 2:
variation = random.randint(0, 3)
if variation == 0:
new_color[0] += random.randint(-20, 20)
if variation == 1:
addon = random.randint(-2, 2)
while addon == 0:
addon = random.randint(-2, 2)
new_radius += addon * 2
new_hunger += addon
new_speed -= addon/5
if variation == 2:
addon = random.randint(-2, 2)
while addon == 0:
addon = random.randint(-2, 2)
new_hunger += addon
new_radius -= addon/2
new_speed -= addon/5
if variation == 3:
addon = random.randint(-2, 2)
while addon == 0:
addon = random.randint(-2, 2)
new_speed += addon/5
new_hunger -= addon/2
recombined_traits = [new_color, new_radius, new_hunger, new_speed]
child = Organism(self.x, self.y, self.type, recombined_traits)
creatures.append(child)
self.hunger += 5
creatures[self.target].hunger += 5
creatures[self.target].target = None
self.target = None
else:
self.target = None
def search_plants(self):
if self.plant_target == None:
dists = [math.dist((self.x, self.y), plant) for plant in plant_manager.plants]
self.plant_target = dists.index(min(dists))
else:
if self.plant_target < len(plant_manager.plants):
self.move_angle = angle_between([(self.x, self.y), plant_manager.plants[self.plant_target]])
if self.rect.colliderect(pygame.rect.Rect(plant_manager.plants[self.plant_target][0] - 6, plant_manager.plants[self.plant_target][1] - 6, 12, 12)):
plant_manager.plants.remove(plant_manager.plants[self.plant_target])
self.hunger -= 5
self.plant_target = None
else:
self.plant_target = None
def update(self):
pygame.draw.circle(win, self.traits[0], (self.x + cam_offset[0], self.y + cam_offset[1]), self.traits[1])
self.rect.x = self.x - self.traits[1]
self.rect.y = self.y - self.traits[1]
if time.time() - self.delay >= 2:
self.hunger += 1
self.delay = time.time()
if self.hunger > self.food_requirement:
self.vital_status = 0
if self.hunger <= self.food_requirement/2:
self.new()
else:
self.target = None
self.search_plants()
if time.time() - self.move_delay >= 0.25:
self.move_angle += random.randint(-5, 5)
self.vel = [self.speed*math.cos(math.radians(self.move_angle)), self.speed*math.sin(math.radians(self.move_angle))]
self.x += self.vel[0]
self.y += self.vel[1]
if self.x <= -500 or self.y <= -900:
self.move_angle -= 180
self.x -= self.vel[0]*2
self.y -= self.vel[1]*2
if self.x >= win.get_width() + 500 or self.y >= win.get_height() + 500:
self.move_angle -= 180
self.x -= self.vel[0]*2
self.y -= self.vel[1]*2
pygame.init()
#traits[1] is radius
#traits[2] is food requirement
#traits[3] is speed
win = pygame.display.set_mode([0,0], pygame.FULLSCREEN)
creatures = [Organism(random.randint(-450, win.get_width() + 450), random.randint(-450, win.get_height() + 450), random.randint(0, 2), [[125, 0, 0], 10, 15, 3.5]) for i in range(100)]
plant_manager = PlantManager()
clock = pygame.Clock()
while True:
win.fill((0, 0, 0))
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
plant_manager.update()
if pygame.key.get_pressed()[pygame.K_RIGHT]:
cam_offset[0] -= 4
if pygame.key.get_pressed()[pygame.K_LEFT]:
cam_offset[0] += 4
if pygame.key.get_pressed()[pygame.K_UP]:
cam_offset[1] += 4
if pygame.key.get_pressed()[pygame.K_DOWN]:
cam_offset[1] -= 4
[creature.update() for creature in creatures]
for count, creature in enumerate(creatures):
if creature.vital_status == 0:
creatures.pop(count)
pygame.display.update()