Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 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. Did not work for me.
- 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()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement