From 947df85053af2704ce1a17daf1fab13e273f0cc5 Mon Sep 17 00:00:00 2001
From: Viljami Ilola <+@hix.fi>
Date: Sat, 23 Mar 2024 21:02:56 +0200
Subject: remove cross dependencies. moving logic towards game/...

---
 src/sliceitoff/enemies/enemies.py | 13 +++++++------
 src/sliceitoff/field/field.py     | 33 ++++++++++++++-------------------
 src/sliceitoff/game/gameplay.py   |  5 +++--
 src/sliceitoff/game/level.py      |  6 ++++--
 4 files changed, 28 insertions(+), 29 deletions(-)

(limited to 'src')

diff --git a/src/sliceitoff/enemies/enemies.py b/src/sliceitoff/enemies/enemies.py
index aaa41be..3f206c7 100644
--- a/src/sliceitoff/enemies/enemies.py
+++ b/src/sliceitoff/enemies/enemies.py
@@ -65,15 +65,16 @@ class Enemies(pygame.sprite.Group):
             enemy.force_left()
         if ( enemy.rect.y + enemy.rect.h >= field.rect.y + field.rect.h ):
             enemy.force_up()
-
-    def update(self, dt = 0):
-        """ Update sprites basis of dt. dt = milliseconds from last update """
-        super().update(dt = dt)
+    
+    def hit_walls(self, field_sprites):
+        """ Do actions on enemies that are only partly on the fields """
         for enemy in self.sprites():
-            for field in self.field.sprites():
+            for field in field_sprites:
+                # if enemy is completely inside any field do next enemy
                 if field.rect.contains(enemy):
                     break
             else:
-                for field in self.field.sprites():
+                # now find field that enemy is partly on
+                for field in field_sprites:
                     if field.rect.colliderect(enemy):
                         self.wall_hit(field, enemy)
diff --git a/src/sliceitoff/field/field.py b/src/sliceitoff/field/field.py
index 842b07a..9e04b4f 100644
--- a/src/sliceitoff/field/field.py
+++ b/src/sliceitoff/field/field.py
@@ -47,17 +47,15 @@ class Field(pygame.sprite.LayeredUpdates):
         super().__init__()
         self.add(FieldSprite( (0, 0, *__class__.initial_area) ))
         self.area_full = __class__.initial_area[0] * __class__.initial_area[1]
-        self.area_current = self.area_full
-        
 
-    def update_area(self):
+    def calculate_current_area(self):
+        return sum( s.area[2]*s.area[3] for s in self.active_sprites() )
+        
+    def update_stats(self):
         """ calculates remaining area and remaining percentage """
-        self.area_current = sum( s.area[2]*s.area[3] for s in self.sprites() )
-        Stats.percent = 100 * self.area_current / self.area_full
+        Stats.percent = 100 * self.calculate_current_area() / self.area_full
         if DEBUG:
-            print(
-                    f"FIELD: {self.area_full}/{self.area_current}, "
-                    f"{Stats.percent}")
+            print(f"FIELD: {Stats.percent}")
 
     def slice(
             self,
@@ -67,13 +65,16 @@ class Field(pygame.sprite.LayeredUpdates):
         """ Slice one area into two areas """
         
         # Slicing hits the area?
-        overlap = self.get_sprites_at(Scaling.scale_to_display(pos))
-        if not overlap:
+        for overlap in self.get_sprites_at(Scaling.scale_to_display(pos)):
+            if not overlap.dead:
+                break
+        else:
             return None
         
+        
         # Save the area information and remove the sprite
-        ax, ay, aw, ah = overlap[0].area
-        overlap[0].remove(self)
+        ax, ay, aw, ah = overlap.area
+        overlap.remove(self)
 
         # create new areas if there is any space
         if direction:
@@ -86,7 +87,6 @@ class Field(pygame.sprite.LayeredUpdates):
                 self.add(FieldSprite( (x1, ay, x2-x1, ah) ))
             if x4 > x3:
                 self.add(FieldSprite( (x3, ay, x4-x3, ah) ))
-            self.update_area()
 
             self.add(SliceSprite( (x2, ay, x3-x2, ah) ))
             return Scaling.area_to_rect((x2, ay, x3-x2, ah))
@@ -102,12 +102,11 @@ class Field(pygame.sprite.LayeredUpdates):
 
         self.add(SliceSprite( (ax, y2, aw, y3-y2) ))
 
-        self.update_area()
         return Scaling.area_to_rect((ax, y2, aw, y3-y2))
 
     def active_sprites(self):
         """ Returns all sprites that are not dead """
-        return (s for s in self.sprites() if not s.dead)
+        return [s for s in self.sprites() if not s.dead]
     
     def kill_if_not_colliding(self, sprites):
         """ If there is empty fields that are not yet dead kill them """
@@ -117,7 +116,3 @@ class Field(pygame.sprite.LayeredUpdates):
                     break
             else:
                 field.dead = True
-
-#    def update(self, dt):
-#        """---"""
-    
\ No newline at end of file
diff --git a/src/sliceitoff/game/gameplay.py b/src/sliceitoff/game/gameplay.py
index 6296a5a..e691b84 100644
--- a/src/sliceitoff/game/gameplay.py
+++ b/src/sliceitoff/game/gameplay.py
@@ -14,13 +14,14 @@ class Gameplay:
         self.status = status
         self.player = player
         self.field = field
-        self.field = enemies
+        self.enemies = enemies
         
     def fire(self):
         if self.player.fire_lazer():
-            field.kill_if_not_colliding(enemies.sprites())
             if Stats.lose_life():
                 return True
+        self.field.kill_if_not_colliding(self.enemies.sprites())
+        self.field.update_stats()
         return Stats.percent < 20
 
     def quit(self):
diff --git a/src/sliceitoff/game/level.py b/src/sliceitoff/game/level.py
index a417d8f..7c58b86 100644
--- a/src/sliceitoff/game/level.py
+++ b/src/sliceitoff/game/level.py
@@ -15,7 +15,7 @@ class Level:
         self.field = Field()
         self.enemies = Enemies(field = self.field)
         self.player = Player(field = self.field, enemies = self.enemies)
-        self.gameplay = Gameplay(player = self.player, status = self.status)
+        self.gameplay = Gameplay(player = self.player, status = self.status, field = self.field, enemies = self.enemies)
         self.obj_classes = (
                 self.status,
                 self.field,
@@ -26,8 +26,10 @@ class Level:
         for obj in self.obj_classes:
             obj.update(dt = dt)
             
-        Stats.update_bonus(dt)
+        self.enemies.hit_walls(self.field.active_sprites())
             
+        Stats.update_bonus(dt)
+        
         self.display.update( (
                 self.status.sprites,
                 self.field,
-- 
cgit v1.2.3