Jul-01-2021, 01:54 PM
I couldn't get internet formula to work. So I made my own. Still working on it.
Something I been playing around with. No real purpose. Just testing.
Something I been playing around with. No real purpose. Just testing.
import pygame import itertools from types import SimpleNamespace color = SimpleNamespace(**dict([(k, pygame.Color(v)) for k, v in pygame.color.THECOLORS.items()])) def create_box_image(color, size): size = size, size surface = pygame.Surface(size, pygame.SRCALPHA) surface.fill((0, 0, 0, 0)) pygame.draw.rect(surface, color, (0, 0, *size), 1) return surface def shift_image(image): w, h = image.get_size() size = w + h, h surface = pygame.Surface(size, pygame.SRCALPHA) for x in range(w): for y in range(h): color = image.get_at((x, y)) surface.set_at((x + y, y), color) return surface class TileMap: def __init__(self, tilemap, tilekey): self.tilemap = tilemap self.tilekey = tilekey self.hover = None self.hover2 = None def draw(self, camera, surface): for y, row in enumerate(self.tilemap): for x, key in enumerate(row): if key != 0: image = self.tilekey[key] if self.hover == self.hover2 and self.hover != None: if self.hover[0] == x and self.hover[1] == y: image = self.tilekey["hover3"] else: if self.hover: if self.hover[0] == x and self.hover[1] == y: image = self.tilekey["hover"] if self.hover2: if self.hover2[0] == x and self.hover2[1] == y: image = self.tilekey["hover2"] surface.blit(image, camera.map_to_screen((x, y))) class TileCamera: def __init__(self, worldsize, position, view, tilesize, map): self.map = map self.view = view self.position = position self.tile = pygame.Rect(0, 0, tilesize, tilesize) self.surface = pygame.Surface(worldsize, pygame.SRCALPHA) def draw(self, surface): self.surface.fill(color.gray40) self.map.draw(self, self.surface) surface.blit(self.surface, self.position) def map_to_screen(self, position): return self.view[0] + position[0] * self.tile.w, self.view[1] + position[1] * self.tile.h def iso_hover(self, position): self.map.hover = position[0] // self.tile.w, position[1] // self.tile.h class IsoCamera: def __init__(self, worldsize, position, view, tilesize, map): self.map = map self.view = view self.position = position self.tile = pygame.Rect(0, 0, tilesize * 2, tilesize) self.surface = pygame.Surface(worldsize, pygame.SRCALPHA) def draw(self, surface): self.surface.fill(color.gray30) self.map.draw(self, self.surface) surface.blit(self.surface, self.position) def get_position(self, mpos): return mpos[0] - self.view[0] - self.position[0], mpos[1] - self.view[1] - self.position[1] # Formula found on the net def real_screen_to_map(self, position): x = (position[0] - self.view[0] - self.position[0]) / self.tile.width y = (position[1] - self.view[1] - self.position[1]) / self.tile.height return int(x + y), int(y - x) # Formula I came up with def screen_to_map(self, position): # Remove all offset posx = position[0] - self.position[0] - self.view[0] posy = position[1] - self.position[1] - self.view[1] # Change to map position y = (posy - posx * 0.5 + self.tile.centery) x = (posx + y - self.tile.height) // self.tile.height y /= self.tile.height if y < 0: y -= 1 return int(x), int(y) # Formula found on the net def map_to_screen(self, position): x, y = position return (self.view[0] + (x - y) * self.tile.centerx, self.view[1] + (x + y) * self.tile.centery) class TileLabels: def __init__(self): pen = Pen(pygame.font.Font(None, 24), color.white) iso_ypos = itertools.count(10, 30) ypos = itertools.count(10, 30) self.labels = { "Mouse" : Label(pen, "Mouse Pos: ({}, {})", (0, 0), (10, next(iso_ypos)), "topleft"), "ISO Position" : Label(pen, "ISO Position: ({}, {})", (0, 0), (10, next(iso_ypos)), "topleft"), "Position" : Label(pen, "Position: ({}, {})", (0, 0), (410, next(ypos)), "topleft"), "Position2" : Label(pen, "Position: ({}, {})", (0, 0), (410, next(ypos)), "topleft"), } def draw(self, surface): for value in self.labels.values(): value.draw(surface) # Formula I came up with def update(self, mpos, iso_cam): self.labels["Mouse"].render(*mpos) ix, iy = iso_cam.get_position(mpos) self.labels["ISO Position"].render(ix, iy) y = iy - ix * 0.5 + iso_cam.tile.centery x = ix + y - iso_cam.tile.h self.labels["Position"].render(x, y) self.labels["Position2"].render(*iso_cam.screen_to_map(mpos)) return x, y class Pen: def __init__(self, font, color): self.font = font self.color = color def render(self, string): return self.font.render(string, 1, self.color) class Label: def __init__(self, pen, fstring, data, position, anchor): self.pen = pen self.fstring = fstring self.position = position self.anchor = anchor self.render(*data) def draw(self, surface): surface.blit(self.image, self.rect) def render(self, *data): text = self.fstring.format(*data) self.image = self.pen.render(text) self.rect = self.image.get_rect(**{self.anchor: self.position}) class Main: def __init__(self, caption, width, height, flags=0): pygame.display.set_caption(caption) self.surface = pygame.display.set_mode((width, height), flags) self.rect = self.surface.get_rect() self.clock = pygame.time.Clock() self.running = False self.delta = 0 self.fps = 60 self.tile_labels = TileLabels() tilesize = 32 worldsize = 400, 400 view = 150, 100 self.maptile = [[1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1]] self.tilekey = { "hover" : create_box_image(color.lawngreen, tilesize), "hover2" : create_box_image(color.firebrick, tilesize), "hover3" : create_box_image(color.dodgerblue, tilesize), 1 : create_box_image(color.snow, tilesize) } rotate = pygame.transform.rotate scale = pygame.transform.smoothscale self.isokey = { "hover" : scale(rotate(self.tilekey["hover"], 45), (64, 32)), "hover2" : scale(rotate(self.tilekey["hover2"], 45), (64, 32)), "hover3" : scale(rotate(self.tilekey["hover3"], 45), (64, 32)), 1 : scale(pygame.transform.rotate(self.tilekey[1], 45), (64, 32)) } self.tile_map = TileMap(self.maptile, self.tilekey) self.iso_map = TileMap(self.maptile, self.isokey) self.tile_camera = TileCamera(worldsize, (400, 100), view, tilesize, self.tile_map) self.iso_camera = IsoCamera(worldsize, (0, 100), view, tilesize, self.iso_map) self.inverse_mouse = None def draw(self): self.iso_camera.draw(self.surface) self.tile_camera.draw(self.surface) self.tile_labels.draw(self.surface) def mainloop(self): self.running = True while self.running: for event in pygame.event.get(): if event.type == pygame.MOUSEMOTION: self.iso_camera.map.hover2 = self.iso_camera.screen_to_map(event.pos) pos = self.tile_labels.update(event.pos, self.iso_camera) self.tile_camera.iso_hover(pos) self.iso_camera.map.hover = self.tile_camera.map.hover elif event.type == pygame.QUIT: self.running = False self.surface.fill(color.black) self.draw() pygame.display.flip() self.delta = self.clock.tick(self.fps) * 0.001 def main(): pygame.init() app = Main("IsoMetric", 800, 500) app.mainloop() pygame.quit() main()
99 percent of computer problems exists between chair and keyboard.