Browse Source

draw interiors

Bastien Sevajol 6 years ago
parent
commit
eb66b0093c

+ 2 - 2
config.yaml View File

@@ -13,5 +13,5 @@ game:
13 13
         run_ref_time: 1
14 14
         crawl_ref_time: 10
15 15
 global:
16
-    logging_level: DEBUG
17
-    debug: true
16
+    logging_level: ERROR
17
+    debug: false

+ 41 - 0
opencc/gui/base.py View File

@@ -1,13 +1,21 @@
1 1
 # coding: utf-8
2
+import io
2 3
 import os
3 4
 import random
4 5
 import typing
5 6
 
6 7
 import pyglet
8
+import time
9
+
10
+import tmx
11
+from PIL import Image
7 12
 from pyglet.window import key
8 13
 
9 14
 from cocos.actions import MoveTo as BaseMoveTo
10 15
 from cocos.audio.pygame.mixer import Sound
16
+
17
+from opencc.simulation.interior import InteriorManager
18
+from opencc.simulation.tmx import TileMap
11 19
 from opencc.user_action import UserAction
12 20
 from synergine2.config import Config
13 21
 from synergine2.log import SynergineLogger
@@ -34,6 +42,11 @@ class EditLayer(BaseEditLayer):
34 42
     def __init__(self, *args, **kwargs) -> None:
35 43
         super().__init__(*args, **kwargs)
36 44
 
45
+        # TODO BS 20171213: Into other layer !
46
+        self.last_interior_draw = 0
47
+        # FIXME BS: hardcoded (move into other layer)
48
+        self.interior_manager = InteriorManager(TileMap('opencc/maps/003/003.tmx'))
49
+
37 50
     def _on_key_press(self, k, m):
38 51
         if self.selection:
39 52
             if k == key.M:
@@ -45,6 +58,34 @@ class EditLayer(BaseEditLayer):
45 58
             if k == key.F:
46 59
                 self.user_action_pending = UserAction.ORDER_FIRE
47 60
 
61
+    def draw(self) -> None:
62
+        super().draw()
63
+        self.draw_interiors()
64
+
65
+    def draw_interiors(self):
66
+        # TODO BS 20171213: Into other layer !
67
+        now = time.time()
68
+        # FIXME: config
69
+        if now - self.last_interior_draw > 2:
70
+            self.last_interior_draw = now
71
+            subject_grid_positions = [
72
+                a.subject.position for a
73
+                in self.layer_manager.subject_layer.subjects_index.values()
74
+            ]
75
+            interiors = self.interior_manager.get_interiors(where_positions=subject_grid_positions)
76
+
77
+            if interiors:
78
+                # FIXME: hardcoded
79
+                image = Image.open('opencc/maps/003/background.png')
80
+                image_fake_file = io.BytesIO()
81
+                # FIXME: tile height/width !
82
+                self.interior_manager.update_image_for_interiors(image, interiors, 8, 8)
83
+                image.save(image_fake_file, format='PNG')
84
+                self.layer_manager.background_sprite.image = pyglet.image.load(
85
+                    'new_background.png',
86
+                    file=image_fake_file,
87
+                )
88
+
48 89
 
49 90
 class TileLayerManager(LayerManager):
50 91
     edit_layer_class = EditLayer

BIN
opencc/maps/003/background.png View File


BIN
opencc/maps/003/background_interiors.png View File


BIN
opencc/maps/003/background_interiors.xcf View File


+ 11 - 3
opencc/simulation/interior.py View File

@@ -36,6 +36,8 @@ class InteriorManager(object):
36 36
         layer_tiles = self.map.layer_tiles(self.configuration.layer_name)
37 37
         for tile_xy, tile in layer_tiles.items():
38 38
 
39
+            # FIXME: on se retrouve avec des tuiles Grass la ou l'on a pas mis de tuile interior/exterior.
40
+            # Faut pouvoir dire c'est tel tile la tile par defaut de tel layer
39 41
             if tile.property('id') == self.configuration.interior_id:
40 42
                 x, y = map(int, tile_xy.split('.'))
41 43
                 if not any([(x, y) in i for i in interiors]):
@@ -77,9 +79,9 @@ class InteriorManager(object):
77 79
 
78 80
     def get_interiors(
79 81
         self,
80
-        where_positions: typing.List[typing.Tuple[int, int]]=None,
82
+        where_positions: typing.Iterable[typing.Tuple[int, int]]=None,
81 83
     ) -> typing.List[typing.List[typing.Tuple[int, int]]]:
82
-        if not where_positions:
84
+        if where_positions is None:
83 85
             return self.interiors
84 86
         interiors = []
85 87
 
@@ -95,6 +97,7 @@ class InteriorManager(object):
95 97
         interiors: typing.List[typing.List[typing.Tuple[int, int]]],
96 98
         tile_width: int,
97 99
         tile_height: int,
100
+        invert_y: bool=True,
98 101
     ) -> None:
99 102
         # TODO BS 20171213: Optimization can be done: keep in cache modifications on image instead change it entirely
100 103
         pixels = image.load()
@@ -105,4 +108,9 @@ class InteriorManager(object):
105 108
                 start_y = tile_y * tile_height
106 109
                 for x in range(start_x, start_x+tile_width):
107 110
                     for y in range(start_y, start_y+tile_height):
108
-                        pixels[x, y] = (0, 0, 0, 0)
111
+
112
+                        real_y = y
113
+                        if invert_y:
114
+                            real_y = image.height - 1 - y
115
+
116
+                        pixels[x, real_y] = (0, 0, 0, 0)

+ 4 - 0
opencc/simulation/tmx.py View File

@@ -11,6 +11,10 @@ class TerrainTile(XYZTile):
11 11
 
12 12
 class TileMap(TMXMap):
13 13
     xyz_tile_class = TerrainTile
14
+    default_layer_tilesets = {
15
+        'interiors': 'interiors',
16
+        'terrain': 'terrain',
17
+    }
14 18
 
15 19
     def get_default_tileset(self) -> tmx.Tileset:
16 20
         return self.tmx_tilesets['terrain']

BIN
tests/fixtures/complex_40x40.png View File


BIN
tests/fixtures/complex_corner_interior_40x40.png View File


BIN
tests/fixtures/complex_one_interior_40x40.png View File


+ 13 - 0
tests/fixtures/corner_interior.tmx View File

@@ -0,0 +1,13 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<map version="1.0" tiledversion="2017.07.26" orientation="orthogonal" renderorder="left-up" width="5" height="5" tilewidth="8" tileheight="8" nextobjectid="1">
3
+ <tileset firstgid="1" source="interiors.tsx"/>
4
+ <layer name="interiors" width="5" height="5">
5
+  <data encoding="csv">
6
+0,0,0,0,0,
7
+0,2,2,1,0,
8
+0,2,1,1,0,
9
+0,1,1,1,0,
10
+0,0,0,0,0
11
+</data>
12
+ </layer>
13
+</map>

BIN
tests/fixtures/white_40x40.png View File


BIN
tests/fixtures/white_corner_interior_40x40.png View File


BIN
tests/fixtures/white_one_interior_40x40.png View File


+ 22 - 0
tests/gui/test_interiors.py View File

@@ -141,3 +141,25 @@ def test_interiors_zones__make_image_transparent__just_replace():
141 141
 
142 142
     manager.update_image_for_interiors(image, interiors, 8, 8)
143 143
     assert after_image_bytes == image.tobytes()
144
+
145
+
146
+def test_interiors_zones__make_image_complex_transparent__just_replace():
147
+    map_ = TMXMap('tests/fixtures/one_interior.tmx')
148
+    manager = InteriorManager(map_)
149
+    interiors = manager.get_interiors()
150
+    image = Image.open('tests/fixtures/complex_40x40.png')
151
+    after_image_bytes = Image.open('tests/fixtures/complex_one_interior_40x40.png').tobytes()
152
+
153
+    manager.update_image_for_interiors(image, interiors, 8, 8)
154
+    assert after_image_bytes == image.tobytes()
155
+
156
+
157
+def test_interiors_zones__make_image_corner_transparent__just_replace():
158
+    map_ = TMXMap('tests/fixtures/corner_interior.tmx')
159
+    manager = InteriorManager(map_)
160
+    interiors = manager.get_interiors()
161
+    image = Image.open('tests/fixtures/white_40x40.png')
162
+    after_image_bytes = Image.open('tests/fixtures/white_corner_interior_40x40.png').tobytes()
163
+
164
+    manager.update_image_for_interiors(image, interiors, 8, 8)
165
+    assert after_image_bytes == image.tobytes()