fd47252b5cb861513a643d23a35666684266f56d
[koperkapel.git] / koperkapel / gamelib / tiles.py
1 """ Definitions for the various tile types """
2
3 import os
4 import random
5
6 from pygame.transform import rotate
7
8 from pgzero.loaders import images
9
10
11 class Tile:
12     IMG = None
13     TILESET = None
14
15     @classmethod
16     def image(cls, neighbors):
17         if cls.IMG is None or cls.TILESET is None:
18             raise NotImplementedError()
19         return images.load(os.path.join(cls.TILESET, cls.IMG))
20
21 class OrientatedTile(Tile):
22     ANGLE = None
23
24     @classmethod
25     def image(cls, neighbors):
26         if cls.IMG is None or cls.TILESET is None:
27             raise NotImplementedError()
28         img = images.load(os.path.join(cls.TILESET, cls.IMG))
29         if cls.ANGLE:
30             img = rotate(img, cls.ANGLE)
31         return img
32
33
34 class RandomizedTile(Tile):
35     IMGDIR = None
36     TILESET = None
37     ROTATE = True
38
39     @classmethod
40     def image(cls, neighbors):
41         if cls.IMGDIR is None or cls.TILESET is None:
42             raise NotImplementedError()
43
44         imgdir = os.path.join(os.path.dirname(__file__), '..', 'images',
45                 cls.TILESET, cls.IMGDIR)
46         imgpath = os.path.splitext(random.choice(os.listdir(imgdir)))[0]
47         img = images.load(os.path.join(cls.TILESET, cls.IMGDIR, imgpath))
48
49         if cls.ROTATE:
50             img = rotate(img, 90 * random.randint(0, 3))
51
52         return img
53
54 class Floor(RandomizedTile):
55     IMGDIR = "floor"
56
57 class Wall(RandomizedTile):
58     IMGDIR = "wall"
59
60 class Underground(RandomizedTile):
61     IMGDIR = "underground"
62
63 class Grate(Tile):
64     IMG = os.path.join('grate', 'grate')
65     TILESET = 'bunker'
66
67 class Tunnel(OrientatedTile):
68
69     @classmethod
70     def image(cls, neighbors):
71         connections = [True if 'crawl' in x['behaviour'] else False for x in neighbors]
72         conn_count = connections.count(True)
73         # simple cases
74         cls.ANGLE = 0
75         if conn_count == 0:
76             # return single point tunnel
77             cls.IMG = os.path.join('tunnel', 'tunnel_none')
78         elif conn_count == 4:
79             # crossroads
80             cls.IMG = os.path.join('tunnel', 'tunnel_crossroads')
81         elif conn_count == 1:
82             # 1 point connector, roatated correctly
83             cls.IMG = os.path.join('tunnel', 'tunnel_1way')
84             # because of the ordering of neighbors, we use this formulation
85             for x, angle in zip(connections, (90, 270, 0, 180)):
86                 if x:
87                     cls.ANGLE = angle
88                     break
89         elif conn_count == 3:
90             # 3 point connector, rotated correctly
91             cls.IMG = os.path.join('tunnel', 'tunnel_3way')
92             # find the missing connection.
93             for x, angle in zip(connections, (0, 180, 270, 90)):
94                 if not x:
95                     cls.ANGLE = angle
96                     break
97         elif conn_count == 2:
98             # Need to distinguish pass-through or corner, and
99             # rotate correctly
100             # neighbors is left, right then up, down
101             if connections[0] == connections[1]:
102                 cls.IMG = os.path.join('tunnel', 'tunnel_passthrough')
103                 if connections[0]:
104                     cls.ANGLE = 90
105             else:
106                 cls.IMG = os.path.join('tunnel', 'tunnel_corner')
107                 if connections[0]:
108                     if connections[2]:
109                         # left, up
110                         cls.ANGLE = 90
111                     else:
112                         # left, down
113                         cls.ANGLE = 180
114                 else:
115                     if connections[2]:
116                         # right, up
117                         cls.ANGLE = 0
118                     else:
119                         # right, down
120                         cls.ANGLE = 270
121
122         return super(Tunnel, cls).image(neighbors)
123