summaryrefslogtreecommitdiff
path: root/src/sliceitoff/field/field.py
blob: 842b07a6500bad54655c1a003d98f54412cab4ba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import os
import pygame

from display import Scaling, INTERNAL_WIDTH, INTERNAL_HEIGHT

from stats import Stats

DEBUG = os.getenv("DEBUG")


class FieldSprite(pygame.sprite.Sprite):
    def __init__(self, area: tuple):
        super().__init__()
        self.color = (0,255,0,255)
        self.dead = False
        self.area = area
        self.rect = Scaling.area_to_rect(self.area)
        self.image = pygame.Surface(self.rect.size, pygame.SRCALPHA)
        self.image.fill(self.color)

    def update(self, dt = 0):
        if dt and self.dead:
            self.color = (
                    self.color[0],
                    self.color[1],
                    self.color[2],
                    self.color[3] - dt/4)
            if self.color[3] <= 0:
                self.kill()
            else:
                self.image.fill(self.color)


class SliceSprite(FieldSprite):
    def __init__(self, area: tuple ):
        super().__init__(area)
        self.color = (255,255,0,255)
        self.image.fill(self.color)
        self.dead = True
        


class Field(pygame.sprite.LayeredUpdates):
    initial_area = (320_000, 220_000)

    def __init__(self):
        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):
        """ 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
        if DEBUG:
            print(
                    f"FIELD: {self.area_full}/{self.area_current}, "
                    f"{Stats.percent}")

    def slice(
            self,
            pos: tuple,
            direction: bool,
            thickness: int) -> pygame.Rect:
        """ Slice one area into two areas """
        
        # Slicing hits the area?
        overlap = self.get_sprites_at(Scaling.scale_to_display(pos))
        if not overlap:
            return None
        
        # Save the area information and remove the sprite
        ax, ay, aw, ah = overlap[0].area
        overlap[0].remove(self)

        # create new areas if there is any space
        if direction:
            x1 = ax
            x2 = pos[0] - thickness
            x3 = pos[0] + thickness
            x4 = ax + aw
            
            if x2 > x1:
                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))
        y1 = ay
        y2 = pos[1] - thickness
        y3 = pos[1] + thickness
        y4 = ay + ah

        if y2 > y1:
            self.add(FieldSprite( (ax, y1, aw, y2-y1) ))
        if y4 > y3:
            self.add(FieldSprite( (ax, y3, aw, y4-y3) ))

        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)
    
    def kill_if_not_colliding(self, sprites):
        """ If there is empty fields that are not yet dead kill them """
        for field in self.active_sprites():
            for enemy in sprites:
                if enemy.rect.colliderect(field.rect):
                    break
            else:
                field.dead = True

#    def update(self, dt):
#        """---"""