delete tile
authorFrank DeMarco <if.self.end@gmail.com>
Thu, 21 Feb 2019 07:32:42 +0000 (02:32 -0500)
committerFrank DeMarco <if.self.end@gmail.com>
Thu, 21 Feb 2019 07:32:42 +0000 (02:32 -0500)
PictureProcessing.py

index f71ab0e..932643a 100644 (file)
@@ -1,4 +1,4 @@
-from os import makedirs, listdir
+from os import makedirs, listdir, remove
 from os.path import basename, join, exists
 from random import random, randrange, choice, randint
 from glob import glob
@@ -129,6 +129,10 @@ class Editor(GameChild):
     LABEL_SOLVED = "SOLVED"
     LABEL_LEFT = "\\27"
     LABEL_RIGHT = "\\26"
+    LABEL_TILE_LOAD = "LOAD"
+    LABEL_TILE_NEW = "NEW"
+    LABEL_TILE_DELETE = "DELETE"
+    LABEL_TILE_EDIT = "EDIT"
     HEADING_MARGIN = 60
     BUTTONS_MARGIN = 60
     VIEW_MARGIN = 120
@@ -139,6 +143,9 @@ class Editor(GameChild):
     TILE_BAR_SCALE = 3
     PALETTE_WIDTH = 100
     ZFILL_FILE = 5
+    TILE_MENU_CURSOR = "\\16"
+    TILE_MENU_SPACING = 16
+    ZFILL_TILE_PATH = 2
 
     def __init__(self, parent):
         GameChild.__init__(self, parent)
@@ -155,12 +162,14 @@ class Editor(GameChild):
         self.at_palette = False
         self.at_box = False
         self.at_test = False
+        self.at_tile_menu = False
         self.level_index = 0
         self.tile_index = 0
         self.palette_index = 0
         self.loaded = False
         self.menu_hidden = False
         self.paint_pressed = False
+        self.tile_menu_index = 0
 
     def reset(self):
         self.deactivate()
@@ -221,6 +230,10 @@ class Editor(GameChild):
             margin=self.VIEW_MARGIN)
         self.label_solved = self.get_label(self.LABEL_SOLVED)
         self.label_solved.location.bottomright = dsr.bottomright
+        self.label_tile_load = self.get_label(self.LABEL_TILE_LOAD)
+        self.label_tile_edit = self.get_label(self.LABEL_TILE_EDIT)
+        self.label_tile_new = self.get_label(self.LABEL_TILE_NEW)
+        self.label_tile_delete = self.get_label(self.LABEL_TILE_DELETE)
         self.arrow_tiles = self.get_label(self.LABEL_TILES)
         self.arrow_tiles.location.midtop = dsr.midtop
         self.arrow_play = self.get_label(self.LABEL_PLAY)
@@ -232,9 +245,18 @@ class Editor(GameChild):
         self.tile_bar = Sprite(self)
         bar_tile_height = self.get_current_level().original_tiles[0].get_width() * \
             self.TILE_BAR_SCALE
-        frame = Surface((dsr.w, bar_tile_height + self.TILE_BAR_PADDING * 2))
-        frame.fill(self.TILE_BAR_BACKGROUND)
-        self.tile_bar.add_frame(frame)
+        surface = Surface((dsr.w, bar_tile_height + self.TILE_BAR_PADDING * 2))
+        surface.fill(self.TILE_BAR_BACKGROUND)
+        self.tile_bar.add_frame(surface)
+        self.tile_menu_background = Sprite(self)
+        surface = Surface((dsr.w, self.label_tile_new.location.h))
+        surface.fill((0, 0, 0))
+        self.tile_menu_background.add_frame(surface)
+        self.tile_menu_background.location.top = self.tile_bar.location.bottom
+        self.label_tile_load.location.top = self.tile_menu_background.location.top
+        self.label_tile_edit.location.top = self.tile_menu_background.location.top
+        self.label_tile_new.location.top = self.tile_menu_background.location.top
+        self.label_tile_delete.location.top = self.tile_menu_background.location.top
         self.level_select_cursor = self.get_cursor(
             *self.get_current_level().preview.get_size())
         self.level_select_cursor.location.center = dsr.center
@@ -243,6 +265,8 @@ class Editor(GameChild):
         self.paint_cursor = self.get_cursor(*([self.CANVAS_SCALE] * 2))
         self.palette_cursor = self.get_cursor()
         self.box_cursor = self.get_cursor()
+        self.tile_menu_cursor = self.get_label(self.TILE_MENU_CURSOR)
+        self.tile_menu_cursor.location.top = self.tile_menu_background.location.top
         new_tile = self.new_tile = Surface([self.TILE_SIZE] * 2)
         new_tile.fill((255, 255, 255))
         for x in xrange(new_tile.get_width()):
@@ -334,15 +358,24 @@ class Editor(GameChild):
                 elif self.at_view:
                     self.menu_hidden = not self.menu_hidden
                 elif self.at_tile_bar:
-                    if self.add_tile_selected():
-                        tile = Surface([self.TILE_SIZE] * 2)
-                        tile.fill((0, 0, 0))
-                        self.get_current_level().add_tile(tile)
-                        if self.current_level_is_default:
-                            self.current_level_is_default = False
-                            self.add_default_level()
-                    self.at_tile_edit = True
+                    self.at_tile_menu = True
                     self.at_tile_bar = False
+                    self.tile_menu_index = 0
+                elif self.at_tile_menu:
+                    if self.tile_menu_index == 0:
+                        if self.add_tile_selected():
+                            tile = Surface([self.TILE_SIZE] * 2)
+                            tile.fill((0, 0, 0))
+                            self.get_current_level().add_tile(tile)
+                            if self.current_level_is_default:
+                                self.current_level_is_default = False
+                                self.add_default_level()
+                        self.at_tile_edit = True
+                        self.at_tile_menu = False
+                    elif self.tile_menu_index == 2:
+                        self.delete_tile(self.tile_index)
+                        self.at_tile_menu = False
+                        self.at_tile_bar = True
                 elif self.at_palette:
                     self.at_palette = False
                     self.at_tile_edit = True
@@ -357,6 +390,9 @@ class Editor(GameChild):
                 elif self.at_tile_bar:
                     self.at_tile_bar = False
                     self.at_view = True
+                elif self.at_tile_menu:
+                    self.at_tile_menu = False
+                    self.at_tile_bar = True
                 elif self.at_tile_edit:
                     self.at_tile_edit = False
                     self.at_tile_bar = True
@@ -380,6 +416,10 @@ class Editor(GameChild):
                     if self.tile_index == Interface.MAX_TILE_COUNT or \
                        self.tile_index > len(self.get_current_level().tiles):
                         self.tile_index = 0
+                if self.at_tile_menu:
+                    self.tile_menu_index += 1
+                    if self.tile_menu_index > 2:
+                        self.tile_menu_index = 0
                 if self.at_tile_edit or self.at_box:
                     dx = 1
                 if self.at_tile_edit:
@@ -418,6 +458,10 @@ class Editor(GameChild):
                         self.tile_index = min(
                             Interface.MAX_TILE_COUNT - 1,
                             len(self.get_current_level().tiles))
+                if self.at_tile_menu:
+                    self.tile_menu_index -= 1
+                    if self.tile_menu_index < 0:
+                        self.tile_menu_index = 2
                 if self.at_tile_edit or self.at_box:
                     dx = -1
                 if self.at_tile_edit:
@@ -466,6 +510,23 @@ class Editor(GameChild):
             elif self.palette_index < 0:
                 self.palette_index = self.get_palette_cell_count() - 1
 
+    def delete_tile(self, index):
+        level = self.get_current_level()
+        level.tiles.pop(index)
+        level.original_tiles.pop(index)
+        for ii in xrange(len(level.grid)):
+            for jj in xrange(len(level.grid[ii])):
+                if level.grid[ii][jj] == index:
+                    level.grid[ii][jj] = 0
+                elif level.grid[ii][jj] > index:
+                    level.grid[ii][jj] -= 1
+        if level.path is not None:
+            path = join(level.path, "%s.png" % str(index).zfill(self.ZFILL_TILE_PATH))
+            if exists(path):
+                remove(path)
+        level.set_preview()
+        self.save_level()
+
     def stamp(self):
         size = self.get_level_tile_size()
         x = self.box.location.left / size
@@ -476,7 +537,9 @@ class Editor(GameChild):
             for yi in xrange(y, y + h):
                 self.get_current_level().grid[xi][yi] = self.tile_index
         self.box.location.topleft = [size * coordinate for coordinate in self.box_corner]
-        self.get_current_level().set_preview()
+        level = self.get_current_level()
+        level.set_swap_status()
+        level.set_preview()
         self.save_level()
 
     def save_level(self):
@@ -506,7 +569,7 @@ class Editor(GameChild):
                 level_file.write(str(hex(grid[ii][jj]))[-1])
             level_file.write("\n")
         for ii, tile in enumerate(level.original_tiles):
-            save(tile, join(level.path, "%s.png" % str(ii).zfill(2)))
+            save(tile, join(level.path, "%s.png" % str(ii).zfill(self.ZFILL_TILE_PATH)))
 
     def set_box_anchor(self):
         size = self.get_level_tile_size()
@@ -621,8 +684,8 @@ class Editor(GameChild):
                     self.arrow_tiles.update()
                     self.arrow_play.update()
                     self.arrow_paint.update()
-                    self.arrow_music.update()
-            if self.at_tile_bar or self.at_tile_edit or self.at_palette:
+                    self.arrow_music.update()
+            if self.at_tile_bar or self.at_tile_edit or self.at_palette or self.at_tile_menu:
                 self.tile_bar.update()
                 tiles = self.get_current_level().original_tiles
                 if len(tiles) < Interface.MAX_TILE_COUNT:
@@ -645,6 +708,26 @@ class Editor(GameChild):
                         else:
                             self.tile_cursor.set_flashing(False)
                 self.label_back.update()
+                if self.at_tile_menu:
+                    self.tile_menu_background.update()
+                    if not self.add_tile_selected():
+                        labels = self.label_tile_edit, self.label_tile_load
+                        if len(self.get_current_level().tiles) > 1:
+                            labels += self.label_tile_delete,
+                    else:
+                        labels = self.label_tile_new, self.label_tile_load
+                    width = self.tile_menu_cursor.location.w * (len(labels) - 1) + \
+                        self.TILE_MENU_SPACING * (len(labels) - 1)
+                    for label in labels:
+                        width += label.location.w
+                    x = ds.get_width() / 2 - width / 2
+                    for label in labels:
+                        label.location.left = x
+                        x += label.location.w + self.tile_menu_cursor.location.w + self.TILE_MENU_SPACING
+                        label.update()
+                    self.tile_menu_cursor.location.right = labels[self.tile_menu_index].location.left
+                    self.tile_menu_cursor.update()
+                    self.label_select.update()
                 if not self.add_tile_selected():
                     tile = tiles[self.tile_index]
                     canvas = scale(tile, [self.CANVAS_SCALE * tile.get_width()] * 2)
@@ -978,6 +1061,7 @@ class Level(Animation):
         self.path = None
 
     def load(self, method=LOAD_DEFAULT, directory=None, title=None):
+        self.grid = []
         self.tiles = []
         self.original_tiles = []
         self.colored_tiles = {}
@@ -1061,10 +1145,13 @@ class Level(Animation):
         self.set_swap_status()
 
     def get_visible_tile_indicies(self):
-        indicies = set()
-        for row in self.grid:
-            for index in row:
-                indicies.add(index)
+        if not self.grid:
+            indicies = set((0,))
+        else:
+            indicies = set()
+            for row in self.grid:
+                for index in row:
+                    indicies.add(index)
         return indicies
 
     def set_entire_grid(self, index=None):
@@ -1173,7 +1260,7 @@ class Level(Animation):
 
     def set_swap_status(self, randomize=False):
         swap_status = self.swap_status = {}
-        if randomize and len(self.tiles) > 1:
+        if randomize and len(self.get_visible_tile_indicies()) > 1:
             swapped = False
             indicies = self.get_visible_tile_indicies()
             while not swapped:
@@ -1191,7 +1278,7 @@ class Level(Animation):
                         swapped = True
                         break
         else:
-            for index in xrange(len(self.tiles)):
+            for index in self.get_visible_tile_indicies():
                 swap_status[index] = index
 
     def stop_all_audio(self):