Level editing
richard on 2008/03/31 10:53
of Flat Bot
— edited on 2008/03/31 06:14
Now I have a
level editor! The exact API needs a bit of work so it's not checked into Cocos yet. The code is below though. It's fired whenever I press "e" and saves the XML to "editor-save.xml" when I close the tile palette window.
@director.window.event
def on_text(s):
global editor
if s == 'e':
editor = TileEditorLayer(level, 'data/level-tiles.xml',
'level-tiles', lambda layer: scene.remove(layer))
scene.add(editor)
director.window.push_handlers(editor)
return True
class TileEditorLayer(cocos.layer.Layer):
def __init__(self, map_layer, filename, id, on_done):
super(TileEditorLayer, self).__init__()
self.map_layer = map_layer
tileset = cocos.tiles.load(filename)[id]
tilesets = [
(filename, ''),
]
self.selector = TileSetWidget(tileset)
@self.selector.window.event
def on_close():
self.map_layer.save_xml(tilesets)
director.window.pop_handlers()
self.selector.close()
self.selector = None
on_done(self)
return True
def on_mouse_press(self, x, y, buttons, modifiers):
x, y = self.map_layer.get_virtual_coordinates(x, y)
cell = self.map_layer.get(x, y)
cell.tile = self.selector.tileset[self.selector.current.tile_id]
self.map_layer.set_dirty()
class TileSetWidget(object):
def __init__(self, tileset):
self.window = pyglet.window.Window(width=64,height=256,
style=pyglet.window.Window.WINDOW_STYLE_TOOL)
self.window.push_handlers(self)
self.tileset = tileset
y = 0
self.batch = pyglet.graphics.Batch()
self.sprites = []
for n, k in enumerate(tileset):
s = pyglet.sprite.Sprite(tileset[k].image, y=y, batch=self.batch)
if not n:
self.current = s
s.color = (255, 200, 200)
s.tile_id = k
self.sprites.append(s)
s.scale = 32. / s.width
y += 32
def on_mouse_press(self, x, y, buttons, modifiers):
for s in self.sprites:
if x < s.x or x > s.x + s.width: continue
if y < s.y or y > s.y + s.height: continue
self.current.color = (255, 255, 255)
self.current = s
s.color = (255, 200, 200)
return True
def on_draw(self):
self.batch.draw()
def close(self):
self.window.pop_handlers()
self.window.close()
Oh, and see that dual-window thing going on there? pyglet
rocks :)