####################################### # Code coded by Mike Doty # Visit my site at www.PsyguyGames.com # if you like to play games! # # If you want trackball checking, you will # have to code it yourself. Sorry! # # Oh, and it just grabs the first joystick. # Yes, that makes me lazy. # # Released February 8, 2008. # # I'm releasing this under the # "The I Really Could Care Less About You Public License." # Read it here: http://www.revinc.org/pages/license # # I'll stop now before the header becomes # longer than the code itself. :P # ####################################### import pygame from pygame.locals import * import os import time SCREEN_WIDTH = 800 SCREEN_HEIGHT = 600 def intersect(r1, r2): if ( (r2[0] >= (r1[0] + r1[2])) or ( (r2[0] + r2[2]) <= r1[0] ) or \ (r2[1] >= (r1[1] + r1[3])) or ( (r2[1] + r2[3]) <= r1[1] ) ): return False return True class ImageBox: def __init__(self): self.list = [] self.width = 0 self.scroll = 0 self.load_images() def load_images(self): self.list = [] files = os.listdir("tilesheets") for each in files: if (each.lower().endswith( (".png", ".bmp") )): self.load_thumbnail(os.path.join("tilesheets", each)) def load_thumbnail(self, source): surface = pygame.image.load(source) (width, height) = (surface.get_width(), surface.get_height()) thumb_height = 100 ratio = float( float(width) / float(height)) thumb_width = int(ratio * thumb_height) if (thumb_width > self.width): self.width = thumb_width print "%s -> (%d, %d)" % (source, thumb_width, thumb_height) thumbnail_surface = pygame.surface.Surface( (thumb_width, thumb_height) ) self.list.append( (pygame.transform.scale(surface, (thumb_width, thumb_height)), source) ) def draw(self, where): y_marker = 0 for i in range(0, len(self.list)): (surface, name) = self.list[i] my_rect = (0, y_marker - self.scroll, surface.get_width(), surface.get_height()) if (my_rect[0] + my_rect[2] > 0 and my_rect[0] < (self.scroll + SCREEN_HEIGHT)): where.blit(surface, (0, my_rect[1])) if (intersect( (pygame.mouse.get_pos()[0], pygame.mouse.get_pos()[1], 1, 1), my_rect )): pygame.draw.rect(where, (255, 255, 255), my_rect, 2) return name y_marker += surface.get_height() return "" def process(self): if (pygame.key.get_pressed()[K_UP]): if (self.scroll > 0): self.scroll -= 2 elif (pygame.key.get_pressed()[K_DOWN]): self.scroll += 2 class Tilesheet: def __init__(self, source, x, y): self.surface = pygame.image.load(source) self.x = x self.y = y self.width = self.surface.get_width() self.height = self.surface.get_height() self.x_offset = 0 self.y_offset = 0 self.current_tile = None def get_rect(self): return (self.x, self.y, 320, 240) def process(self): if (intersect( (pygame.mouse.get_pos()[0], pygame.mouse.get_pos()[1], 1, 1), self.get_rect()) ): if (pygame.key.get_pressed()[K_UP]): self.y_offset -= 5 if (self.y_offset < 0): self.y_offset = 0 elif (pygame.key.get_pressed()[K_DOWN]): self.y_offset += 5 if (self.y_offset > self.height - 240): self.y_offset = self.height - 240 elif (pygame.key.get_pressed()[K_LEFT]): self.x_offset -= 5 if (self.x_offset < 0): self.x_offset = 0 elif (pygame.key.get_pressed()[K_RIGHT]): self.x_offset += 5 if (self.x_offset > self.width - 320): self.x_offset = self.width - 320 def draw(self, where, tile_width, tile_height): where.blit(self.surface, (self.x, self.y), (self.x_offset, self.y_offset, 320, 240)) pygame.draw.rect(where, (255, 255, 255), (self.x, self.y, 320, 240), 2) if (intersect( (pygame.mouse.get_pos()[0], pygame.mouse.get_pos()[1], 1, 1), self.get_rect()) ): pygame.draw.rect(where, (255, 255, 0), self.get_rect(), 2) tx = ( (pygame.mouse.get_pos()[0] - self.x) / tile_width) * tile_width ty = ( (pygame.mouse.get_pos()[1] - self.y) / tile_height) * tile_height pygame.draw.rect(where, (255, 255, 255), (self.x + tx, self.y + ty, tile_width, tile_height), 1) return (tx, ty) return None class Canvas: def __init__(self, x, y): self.surface = pygame.surface.Surface( (320, 240) ) self.x = x self.y = y self.width = self.surface.get_width() self.height = self.surface.get_height() self.x_offset = 0 self.y_offset = 0 def get_rect(self): return (self.x, self.y, 320, 240) def process(self): if (intersect( (pygame.mouse.get_pos()[0], pygame.mouse.get_pos()[1], 1, 1), self.get_rect()) ): if (pygame.key.get_pressed()[K_UP]): self.y_offset -= 5 if (self.y_offset < 0): self.y_offset = 0 elif (pygame.key.get_pressed()[K_DOWN]): self.y_offset += 5 if (self.y_offset > self.height - 240): self.y_offset = self.height - 240 elif (pygame.key.get_pressed()[K_LEFT]): self.x_offset -= 5 if (self.x_offset < 0): self.x_offset = 0 elif (pygame.key.get_pressed()[K_RIGHT]): self.x_offset += 5 if (self.x_offset > self.width - 320): self.x_offset = self.width - 320 def draw(self, where, tile_width, tile_height, tile): where.blit(self.surface, (self.x, self.y), (self.x_offset, self.y_offset, 320, 240)) pygame.draw.rect(where, (255, 255, 255), (self.x, self.y, 320, 240), 2) if (intersect( (pygame.mouse.get_pos()[0], pygame.mouse.get_pos()[1], 1, 1), self.get_rect()) ): pygame.draw.rect(where, (255, 255, 0), self.get_rect(), 2) tx = ( (pygame.mouse.get_pos()[0] - self.x) / tile_width) * tile_width ty = ( (pygame.mouse.get_pos()[1] - self.y) / tile_height) * tile_height #pygame.draw.rect(where, (255, 255, 255), (self.x + tx, self.y + ty, tile_width, tile_height), 1) if (tile): where.blit(tile, (self.x + tx, self.y + ty)) if (pygame.mouse.get_pressed()[0]): self.surface.blit(tile, (tx, ty)) class App: def __init__(self): pygame.init() pygame.display.set_caption("Super Awesome Mega Ultra Tile Map Editor") self.screen = pygame.display.set_mode( (SCREEN_WIDTH, SCREEN_HEIGHT) ) pygame.mouse.set_visible(False) self.font = pygame.font.SysFont("Courier", 24) self.mouse_sprite = pygame.image.load(os.path.join("data", "mouse.bmp")).convert() self.mouse_sprite.set_colorkey((0,0,0)) self.image_box = ImageBox() self.tile_width = 40 self.tile_height = 40 self.tile_surface = None self.tilesheet = None if (len(self.image_box.list) > 0): self.tilesheet = Tilesheet(self.image_box.list[0][1], SCREEN_WIDTH - 320 - 10, 50) self.canvas = Canvas(SCREEN_WIDTH - 320 - 10, 300) if (not (os.path.exists("saved"))): os.mkdir("saved") def draw_text_button(self, where, coords, text): surface = self.font.render(text, True, (255, 255, 255), (0, 0, 0)) if (intersect( (pygame.mouse.get_pos()[0], pygame.mouse.get_pos()[1], 1, 1), (coords[0], coords[1], surface.get_width(), surface.get_height() ))): surface = self.font.render(text, True, (255, 0, 0), (0, 0, 0)) where.blit(surface, coords) return True else: where.blit(surface, coords) return False def draw_text(self, text, x, y, color, align_right=False): surface = self.font.render(text, True, color, (0, 0, 0)) surface.set_colorkey( (0, 0, 0) ) self.screen.blit(surface, (x, y)) def center_text(self, text, x, y, color): surface = self.font.render(text, True, color, (0, 0, 0)) surface.set_colorkey( (0, 0, 0) ) self.screen.blit(surface, (x - surface.get_width() / 2, y)) def check_width(self, text): surface = self.font.render(text, True, (255, 255, 255), (0, 0, 0)) return surface.get_width() def main(self): while (True): self.g_keys = pygame.event.get() self.screen.fill(0) buttons_clicked = [] for event in self.g_keys: if (event.type == KEYDOWN and event.key == K_ESCAPE): self.quit() return elif (event.type == QUIT): self.quit() return if (event.type == MOUSEBUTTONDOWN): buttons_clicked.append(event.button) if (event.type == KEYDOWN and event.key == K_s): pygame.image.save(self.canvas.surface, os.path.join("saved", "%d.png" % time.time())) self.image_box.process() file_clicked = self.image_box.draw(self.screen) if (file_clicked != "" and (1 in buttons_clicked)): self.tilesheet = Tilesheet(file_clicked, SCREEN_WIDTH - 320 - 10, 50) if (self.tilesheet): self.tilesheet.process() tile_hovered = self.tilesheet.draw(self.screen, self.tile_width, self.tile_height) if (tile_hovered and (1 in buttons_clicked)): self.tile_surface = self.tilesheet.surface.subsurface( (tile_hovered[0], tile_hovered[1], self.tile_width, self.tile_height) ) self.canvas.draw(self.screen, self.tile_width, self.tile_height, self.tile_surface) position1 = self.image_box.width + 10 position2 = self.image_box.width + 160 self.center_text("%d" % self.tile_width, position1 + self.check_width("<") + ( (position1 + 50) - (position1 + self.check_width("<")) ) / 2, 10, (255, 255, 255)) self.center_text("Tile Width", position1 + self.check_width("<") + ( (position1 + 50) - (position1 + self.check_width("<")) ) / 2, 30, (255, 255, 255)) if (self.draw_text_button(self.screen, (position1, 10), "<") and 1 in buttons_clicked): if (self.tile_width > 8): self.tile_width -= 1 if (self.draw_text_button(self.screen, (position1 + 50, 10), ">") and 1 in buttons_clicked): self.tile_width += 1 self.center_text("%d" % self.tile_height, position2 + self.check_width("<") + ( (position2 + 50) - (position2 + self.check_width("<")) ) / 2, 10, (255, 255, 255)) self.center_text("Tile Height", position2 + self.check_width("<") + ( (position2 + 50) - (position2 + self.check_width("<")) ) / 2, 30, (255, 255, 255)) if (self.draw_text_button(self.screen, (position2, 10), "<") and 1 in buttons_clicked): if (self.tile_height > 8): self.tile_height -= 1 if (self.draw_text_button(self.screen, (position2 + 50, 10), ">") and 1 in buttons_clicked): self.tile_height += 1 self.screen.blit(self.mouse_sprite, (pygame.mouse.get_pos())) pygame.display.flip() def quit(self): pygame.display.quit() app = App() app.main()