diff --git a/main.py b/main.py index b5ae2e8..33de189 100644 --- a/main.py +++ b/main.py @@ -5,6 +5,69 @@ import numpy as np SCREEN_SIZE = (800,600) TICK_TIME = 0.5 +class Wolf(arcade.SpriteCircle): + ls = arcade.SpriteList() + def __init__(self,parent=None): + super().__init__(radius=5, color=arcade.color.RED) + 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 = 8 + self.move_target = 0 + self.target_timer = 0 + Wolf.ls.append(self) + @classmethod + def update(cls): + if len(cls.ls) == 0: + Wolf() + for e in cls.ls: + e.age += 1 + if e.age >= 30: + cls.ls.remove(e) + continue + + if e.health >= 50 and e.age_to_bride < e.age: + Wolf(e) + e.health -= 30 + + hit_cow = arcade.check_for_collision_with_list(e,Cow.ls) + for c in hit_cow: + e.health += c.health + Cow.ls.remove(c) + else: + if e.target_timer <= 0: + e.move_target = Cow.get_near(e.center_x,e.center_y) + e.target_timer = 3 + if e.move_target: + vec = cls.get_vector(e.center_x,e.move_target.center_x, + e.center_y,e.move_target.center_y) + new_x = e.center_x + vec[0]*e.speed + new_y = e.center_y + vec[1]*e.speed + if 0 < new_x < SCREEN_SIZE[0] and 0 < new_y < SCREEN_SIZE[1]: + e.center_x = new_x + e.center_y = new_y + e.health -= 1 + if e.health <= 0: + cls.ls.remove(e) + + @classmethod + def draw(cls): + cls.ls.draw() + @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 Cow(arcade.SpriteCircle): ls = arcade.SpriteList() def __init__(self,parent=None): @@ -23,20 +86,31 @@ class Cow(arcade.SpriteCircle): self.target_timer = 0 Cow.ls.append(self) @classmethod + def get_near(cls,x,y): + dist_list = list() + for e in cls.ls: + dist_list.append((e,((e.center_x - x)**2 + (e.center_y - y)**2)**0.5)) + dist_list.sort(key=lambda x: x[1]) + if len(dist_list) == 0: + return None + return dist_list[0][0] + @classmethod def update(cls): + if len(cls.ls) == 0: + Cow() for c in cls.ls: c.age += 1 if c.age >= 30: cls.ls.remove(c) - if len(cls.ls) == 0: - Cow() continue + + if c.health >= 50 and c.age_to_bride < c.age: + Cow(c) + c.health -= 30 + 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: if c.target_timer <= 0: @@ -57,8 +131,6 @@ class Cow(arcade.SpriteCircle): @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]) @@ -89,21 +161,24 @@ class Plant(arcade.SpriteCircle): for p in cls.ls: dist_list.append((p,((p.center_x - x)**2 + (p.center_y - y)**2)**0.5 - p.width )) dist_list.sort(key=lambda x: x[1]) + if len(dist_list) == 0: + return None + if len(dist_list) < 3: + return dist_list[0][0] return dist_list[randint(0,3)][0] @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 + hit_list = arcade.check_for_collision_with_list(p,cls.ls) + 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] and 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 @@ -127,17 +202,15 @@ class MainView(arcade.View): print(f'Total plants: {len(Plant.ls)}, total cows: {len(Cow.ls)}') Plant.update() Cow.update() + Wolf.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() + Wolf.draw() if __name__ == '__main__':