import arcade from random import randint import numpy as np SCREEN_SIZE = (800,600) TICK_TIME = 0.5 class Cow(arcade.SpriteCircle): ls = arcade.SpriteList() def __init__(self,parent=None): super().__init__(radius=5, color=arcade.color.BROWN) if parent: self.center_x = parent.center_x self.center_y = parent.center_y else: self.center_x = randint(1,SCREEN_SIZE[0]) self.center_y = randint(1,SCREEN_SIZE[1]) self.age = 0 self.age_to_bride = 3 self.health = 30 self.speed = 5 Cow.ls.append(self) @classmethod def update(cls): for c in cls.ls: c.age += 1 if c.age >= 30: cls.ls.remove(c) continue hit_plant = arcade.check_for_collision_with_list(c,Plant.ls) for p in hit_plant: c.health += p.width if c.health >= 50 and c.age_to_bride < c.age: Cow(c) c.health -= 30 Plant.ls.remove(p) else: near_plant = Plant.get_near(c.center_x,c.center_y) if near_plant: vec = cls.get_vector(c.center_x,near_plant.center_x, c.center_y,near_plant.center_y) new_x = c.center_x + vec[0]*randint(0,c.speed) new_y = c.center_y + vec[1]*randint(0,c.speed) if 0 < new_x < SCREEN_SIZE[0] and 0 < new_y < SCREEN_SIZE[1]: c.center_x = new_x c.center_y = new_y c.health -= 1 if c.health <= 0: cls.ls.remove(c) @classmethod def draw(cls): cls.ls.draw() for p in cls.ls: p.draw_hit_box() @staticmethod def get_vector(src_x,target_x,src_y,target_y): source = np.array([src_x, src_y]) target = np.array([target_x, target_y]) direction = target - source length = np.linalg.norm(direction) return direction / length class Plant(arcade.SpriteCircle): ls = arcade.SpriteList() def __init__(self,parent=None): super().__init__(radius=1, color=arcade.color.GREEN) if parent: self.center_x = parent.center_x + randint(-parent.fly_distance,parent.fly_distance) self.center_y = parent.center_y + randint(-parent.fly_distance,parent.fly_distance) else: self.center_x = randint(1,SCREEN_SIZE[0]) self.center_y = randint(1,SCREEN_SIZE[1]) self.age = 0 self.fly_distance = 100 self.age_to_plant = 10 if not arcade.check_for_collision_with_list(self,Plant.ls) and 0 < self.center_x < SCREEN_SIZE[0] and 0 < self.center_y < SCREEN_SIZE[1]: Plant.ls.append(self) @classmethod def get_near(cls,x,y): min_dist = SCREEN_SIZE[0] near_plant = None for p in cls.ls: dist = ((p.center_x - x)**2 + (p.center_y - y)**2)**0.5 if dist < min_dist: near_plant = p min_dist = dist return near_plant @classmethod def update(cls): for p in cls.ls: p.age += 1 if p.center_x - p.width//2 > 0 and p.center_x + p.width//2 < SCREEN_SIZE[0] and p.center_y - p.height//2 > 0 and p.center_y + p.width//2 < SCREEN_SIZE[1]: hit_list = arcade.check_for_collision_with_list(p,cls.ls) if not hit_list: p.width += 2 p.height += 2 else: for h in hit_list: if p.width < h.width: cls.ls.remove(p) break if p.age >= p.age_to_plant: Plant(p) @classmethod def draw(cls): cls.ls.draw() for p in cls.ls: p.draw_hit_box() class MainView(arcade.View): def __init__(self): super().__init__() self.background_color = (100,100,200) Plant() self.time = 0 self.cur_time = 0 self.text = None def on_update(self, delta_time): self.cur_time += delta_time if self.cur_time >= TICK_TIME: Plant.update() Cow.update() self.time += 1 self.cur_time = 0 if self.time == 30: Cow() #self.text = arcade.Text(f'Time: {self.time}',20,100,(255,255,255)) def on_draw(self): self.clear() Plant.draw() Cow.draw() #self.text.draw() if __name__ == '__main__': window = arcade.Window(*SCREEN_SIZE,"Игра про жизнь") view = MainView() window.show_view(view) arcade.run()