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.
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.