4 from erdslangetjie.constants import TILE_SIZE
6 from kivy.app import App
7 from kivy.uix.widget import Widget
8 from kivy.uix.floatlayout import FloatLayout
9 from kivy.graphics import Color, Rectangle
10 from kivy.uix.label import Label
11 from kivy.uix.popup import Popup
12 from kivy.utils import platform
13 from kivy.config import Config
15 from erdslangetjie.data import filepath, load
16 from erdslangetjie.level import (Level, WALL, GATE, BUTTON,
20 if platform() != 'android':
21 Config.set('graphics', 'width', '1326')
22 Config.set('graphics', 'height', '760')
35 class EditorWindow(FloatLayout):
37 def __init__(self, level):
38 super(EditorWindow, self).__init__(size=(1326, 760))
39 if os.path.exists(filepath(level)):
40 level_data = load(level)
42 elif os.path.exists(filepath('levels/' + level)):
43 level_data = load('levels/' + level)
44 self.level = 'levels/' + level
46 print 'Unable to find %s - treating this as a new level' % level
47 level_data = load('levels/blank.txt')
48 if 'levels/' in level:
51 self.level = 'levels/' + level
52 self.level_obj = Level(level_data, self.level)
54 self.level_obj.load_tiles()
57 self.tool_widgets = []
61 tiles = self.level_obj.get_tiles()
64 for tile_line in tiles:
66 for tile in tile_line:
67 self._draw_tile((bx, by), tile)
71 name = Label(text="Level: [color=00ffcc]%s[/color]" % self.level,
72 markup=True, font_size=24, pos=(500, 360))
76 self.draw_save_button()
78 def _draw_tile(self, tile_pos, tile):
79 if tile_pos in self.nodes:
80 self.remove_widget(self.nodes[tile_pos])
81 node = Widget(size=(TILE_SIZE, TILE_SIZE), pos=tile_pos)
82 node.bind(on_touch_down=self.change_node)
83 node.bind(on_touch_move=self.change_node)
86 Rectangle(pos=node.pos, size=node.size, texture=tile.texture)
88 self.nodes[tile_pos] = node
90 def draw_toolbar(self):
91 for widget in self.tool_widgets:
92 widget.unbind(on_ref_press=self.change_tool)
93 self.remove_widget(widget)
94 self.tool_widgets = []
96 for tool in sorted(tool_map):
101 tool_label = Label(text='[color=%s][ref=%s]%s[/ref][/color]' %
102 (color, tool, tool), markup=True, font_size=24,
105 tool_label.bind(on_ref_press=self.change_tool)
106 self.add_widget(tool_label)
107 self.tool_widgets.append(tool_label)
109 def draw_save_button(self):
110 save_label = Label(text='[color=ffffff][ref=save]Save[/ref][/color]',
111 markup=True, font_size=24, pos=(500, -100))
112 save_label.bind(on_ref_press=self.do_save)
113 self.add_widget(save_label)
115 def do_save(self, label, ref):
117 self.level_obj.validate()
118 except RuntimeError as err:
119 popup = Popup(title='Error',
120 content=Label(text='Level not valid: %s' % err),
124 save_data = self.level_obj.get_level_data()
125 savefile = file(filepath(self.level), 'w')
126 savefile.write(save_data)
129 popup = Popup(title='Success',
130 content=Label(text='Level saved to %s' % self.level),
134 def change_tool(self, label, ref):
138 def contained(self, node, pos):
139 if pos[0] < node.pos[0] or pos[0] > node.pos[0] + TILE_SIZE:
141 if pos[1] < node.pos[1] or pos[1] > node.pos[1] + TILE_SIZE:
145 def change_node(self, node, touch):
146 if self.tool and self.contained(node, touch.pos):
147 tile_pos = (node.pos[0] / TILE_SIZE, node.pos[1] / TILE_SIZE)
148 action = tool_map[self.tool]
149 if self.level_obj.get_tile_type(tile_pos) != action:
150 self.level_obj.set_tile_type(tile_pos, action)
151 for map_pos, new_tile in self.level_obj.get_changed_tiles():
152 node_pos = (map_pos[0] * TILE_SIZE, map_pos[1] * TILE_SIZE)
153 self._draw_tile(node_pos, new_tile)
156 class EditorApp(App):
158 title = "Bane's Befuddlement Level Editor"
160 def __init__(self, level):
162 super(EditorApp, self).__init__()
165 editor = EditorWindow(self.level)
171 if len(sys.argv) > 1:
175 EditorApp(level).run()
178 if __name__ == '__main__':