jsuarez/MapMaker.py (139 lines of code) (raw):

from pdb import set_trace as T from scipy.misc import imread from scipy.misc import imsave from sim.lib import Enums from sim.lib.Enums import Material import sys import numpy as np import pygame def readRGB(path): return imread(path)[:, :, :3] def pgRead(path, alpha=False, rot=90): try: img = readRGB(path) except FileNotFoundError: return None img = pygame.pixelcopy.make_surface(img) if alpha: img.set_colorkey((255, 255, 255)) return pygame.transform.rotate(img, rot) class TextureInitializer(): def __init__(self, sz, root='resource/'): self.width = sz self.statHeight = 2 self.material = readRGB(root+'Material/textures.png') self.material = self.textureTiles() self.entity = self.textureFromFile(Enums.Entity, root+'Entity/') def textureTiles(self): reverse = {} for mat in Material: mat = mat.value texCoords = mat.tex tex = self.getTile(*texCoords) tex = pygame.pixelcopy.make_surface(tex) mat.tex = pygame.transform.rotate(tex, 90) reverse[mat.index] = mat.tex return reverse def getTile(self, r, c): w = self.width tile = self.material[r*w:r*w+w, c*w:c*w+w, :] return tile def textureFromFile(self, enum, path, alpha=True, rot=270): reverse = {} for e in enum: texPath = path + e.name.lower() + '.png' tex = pgRead(texPath, alpha=alpha, rot=rot) e.value.tex = tex if type(e.value.data) == tuple: reverse[e.value.data[0]] = tex else: reverse[e.value.data] = tex return reverse class MapMaker: def __init__(self, w, h, res=16): self.W, self.H, self.res = w, h, res self.env = np.zeros((h, w), dtype=np.uint8) self.textures = TextureInitializer(self.res) self.setupScreen(self.W, self.H) self.zoom = 1 self.maxZoom = int(np.max(list(self.textures.material.keys()))) self.zoomDelta = 1 self.deltaX, self.deltaY = 0, 0 self.volDeltaX, self.volDeltaY = 0, 0 self.clicked = False self.rightClicked = False def getTile(self, rPx, cPx): return rPx//self.res, cPx//self.res def renderTile(self, r, c, tex): w = self.res self.buffer.blit(tex, (c*w, r*w)) def render(self): self.screen.fill((0, 0, 0)) #Draw if self.rightClicked: x, y = pygame.mouse.get_pos() x = x - self.deltaX y = y - self.deltaY c, r = self.getTile(x, y) tex = self.textures.material[self.zoom] self.env[r, c] = np.uint8(self.zoom) self.renderTile(r, c, tex) #Scale scaleX, scaleY = int(self.H), int(self.W) buff = pygame.transform.scale(self.buffer, (scaleX, scaleY)) #Translate deltaX = self.deltaX + self.volDeltaX - scaleX//2 + self.W//2 deltaY = self.deltaY + self.volDeltaY - scaleY//2 + self.H//2 #Render self.screen.blit(buff, (deltaX, deltaY)) pygame.display.flip() def setupScreen(self, envR, envC): self.W = envC * self.res self.H = envR * self.res pygame.init() self.screen = pygame.display.set_mode((self.W, self.H)) self.buffer = pygame.surface.Surface((self.W, self.H)) def update(self): self.processEvents(pygame.event.get()) self.updateMouse() imsave('resource/map/smallmap.png', self.env) self.render() def updateMouse(self): if self.clicked: volX, volY = self.volX, self.volY curX, curY = pygame.mouse.get_pos() self.volDeltaX = curX - volX self.volDeltaY = curY - volY def quit(self): pygame.quit() sys.exit() def mouseDown(self, button): if button == 1 and not self.clicked: self.volX, self.volY = pygame.mouse.get_pos() self.clicked = True if button == 3: self.rightClicked = True def mouseUp(self, button): if button == 1: if self.clicked: self.deltaX += self.volDeltaX self.deltaY += self.volDeltaY self.volDeltaX, self.volDeltaY = 0, 0 self.clicked = False elif button == 3: self.rightClicked = False elif button == 4: if self.zoom < self.maxZoom: self.zoom += self.zoomDelta elif button == 5: if self.zoom > 0: self.zoom -= self.zoomDelta def processEvents(self, events): for e in events: if e.type == pygame.QUIT: self.quit() elif e.type == pygame.MOUSEBUTTONDOWN: self.mouseDown(e.button) elif e.type == pygame.MOUSEBUTTONUP: self.mouseUp(e.button) if __name__ == '__main__': w, h = int(sys.argv[1]), int(sys.argv[2]) mapMaker = MapMaker(w, h) while True: mapMaker.update()