summaryrefslogtreecommitdiff
path: root/gui/tmxmap.py
diff options
context:
space:
mode:
Diffstat (limited to 'gui/tmxmap.py')
-rw-r--r--gui/tmxmap.py175
1 files changed, 175 insertions, 0 deletions
diff --git a/gui/tmxmap.py b/gui/tmxmap.py
new file mode 100644
index 0000000..800868e
--- /dev/null
+++ b/gui/tmxmap.py
@@ -0,0 +1,175 @@
+
+# import pytmx
+import zipfile
+from itertools import cycle, islice
+try:
+ import cPickle as pickle
+except ImportError:
+ import pickle
+
+from kivy.core.image import Image as CoreImage
+from kivy.uix.widget import Widget
+from kivy.uix.image import Image
+from kivy.graphics.texture import Texture
+from kivy.animation import Animation
+from kivy.properties import (StringProperty, ObjectProperty,
+ NumericProperty, DictProperty)
+from kivy.logger import Logger
+
+from pathfind import breadth_first_search
+import net.mapserv as mapserv
+
+
+def kivy_image_loader(filename, colorkey, **kwargs):
+ texture = CoreImage(filename).texture
+
+ def loader(rect, flags):
+ x, y, w, h = rect
+ t = texture.get_region(x,
+ texture.height - y - h,
+ w, h)
+
+ if flags.flipped_diagonally:
+ t.flip_horizontal()
+ t.flip_vertical()
+ elif flags.flipped_vertically:
+ t.flip_vertical()
+ elif flags.flipped_horizontally:
+ t.flip_horizontal()
+
+ return t
+
+ return loader
+
+
+def create_map_texture(map_data, tile_size=4):
+ map_size = len(map_data[0]), len(map_data)
+ texture = Texture.create(size=(map_size[0] * tile_size,
+ map_size[1] * tile_size),
+ colorfmt='rgb')
+
+ c = cycle('\x45\x46\x47')
+ s = islice(c, 3 * 4000)
+ buf = b''.join(s)
+
+ for y, row in enumerate(map_data):
+ for x, cell in enumerate(row):
+ if cell > 0:
+ continue
+
+ texture.blit_buffer(buf, size=(tile_size, tile_size),
+ colorfmt='rgb',
+ pos=(x * tile_size, y * tile_size))
+
+ texture.flip_vertical()
+
+ return texture
+
+
+class BeingWidget(Widget):
+ anim = ObjectProperty(None)
+ name = StringProperty()
+
+
+class MapWidget(Image):
+ tile_size = NumericProperty(32)
+ player = ObjectProperty()
+ collisions = ObjectProperty(None)
+ current_attacks = DictProperty()
+ beings = DictProperty()
+ maps = {}
+
+ def load_map(self, name, *args):
+ if name not in self.maps:
+ Logger.info("Caching map %s", name)
+ zf = zipfile.ZipFile('mapdb.zip', 'r')
+ self.maps[name] = pickle.load(zf.open(name + '.pickle'))
+ zf.close()
+ # m = pytmx.TiledMap(filename=filename)
+ # data = m.get_layer_by_name('Collision').data
+ texture = create_map_texture(self.maps[name]['collisions'],
+ self.tile_size)
+ self.texture = texture
+ self.size = texture.size
+ self.collisions = self.maps[name]['collisions']
+
+ def to_game_coords(self, pos):
+ ts = self.tile_size
+ height = len(self.collisions)
+ x = int(pos[0] // ts)
+ y = height - int(pos[1] // ts) - 1
+ return x, y
+
+ def from_game_coords(self, pos):
+ ts = self.tile_size
+ height = len(self.collisions)
+ x = pos[0] * ts
+ y = (height - pos[1] - 1) * ts
+ return x, y
+
+ def move_being(self, being, gx, gy, speed=150):
+ ts = self.tile_size
+ ox = int(being.x // ts)
+ oy = int(being.y // ts)
+ gy = len(self.collisions) - gy - 1
+
+ try:
+ path = breadth_first_search(self.collisions,
+ (ox, oy), (gx, gy))
+ except KeyError:
+ path = []
+
+ if being.anim:
+ being.anim.stop(being)
+
+ being.anim = Animation(x=being.x, y=being.y, duration=0)
+
+ for i in range(len(path) - 1):
+ cx, cy = path[i + 1]
+ px, py = path[i]
+ distance = max(abs(cx - px), abs(cy - py))
+ being.anim += Animation(x=cx * ts, y=cy * ts,
+ duration=distance * speed / 1000.)
+
+ being.anim.start(being)
+
+ def get_attack_points(self, *bind_args):
+ points = []
+ try:
+ player_id = mapserv.server.char_id
+ except AttributeError:
+ player_id = 0
+ for (id1, id2) in self.current_attacks:
+ try:
+ # Temporary workaround
+ if id1 == player_id:
+ x1, y1 = self.player.pos
+ else:
+ x1, y1 = self.beings[id1].pos
+ if id2 == player_id:
+ x2, y2 = self.player.pos
+ else:
+ x2, y2 = self.beings[id2].pos
+ points.extend([x1, y1, x2, y2])
+ except:
+ pass
+
+ return points
+
+ def get_attack_endpoints(self, *bind_args):
+ points = []
+ try:
+ player_id = mapserv.server.char_id
+ except AttributeError:
+ player_id = 0
+ for (_, target) in self.current_attacks:
+ try:
+ if target == player_id:
+ x, y = self.player.pos
+ else:
+ x, y = self.beings[target].pos
+ points.extend([x, y])
+ except:
+ pass
+
+ return points