diff --git a/BlazeSudio/graphics/GUI/elements.py b/BlazeSudio/graphics/GUI/elements.py index fc7b74b..2e2c4fb 100644 --- a/BlazeSudio/graphics/GUI/elements.py +++ b/BlazeSudio/graphics/GUI/elements.py @@ -695,6 +695,13 @@ def sur(self, newsur): self._sur = newsur self.cache = None + def set(self, newsur): + self.sur = newsur + self.centre() + + def get(self): + return self._sur + def reset(self): self.scroll = 1 self.offset = [self.size[0]/2, self.size[1]/2] @@ -735,8 +742,8 @@ def update(self, mousePos, events): scrolling = any(e.type == pygame.MOUSEWHEEL for e in events) for e in events: if e.type == pygame.MOUSEWHEEL: - self.scrollVel += e.y * 0.5 - self.scrollVel += e.x * 0.5 + self.scrollVel += e.y * 0.25 + self.scrollVel += e.x * 0.25 elif not scrolling and e.type == pygame.MOUSEBUTTONDOWN: self.lastMP = mousePos diff --git a/BlazeSudio/utils/genCollisions.py b/BlazeSudio/utils/genCollisions.py index 4a7b8b6..7ce7b3c 100644 --- a/BlazeSudio/utils/genCollisions.py +++ b/BlazeSudio/utils/genCollisions.py @@ -1,5 +1,37 @@ import BlazeSudio.collisions as colls +__all__ = [ + "bounding_box", + "approximate_polygon" +] + +def bounding_box(surface): + """ + Simplifies a polygon into 4 points. + + Args: + surface (pygame.Surface): The surface to simplify. + """ + width, height = surface.get_size() + points = [] + for x in range(width): + for y in range(height): + if surface.get_at((x, y)).a > 125: + points.append((x, y)) + if not points: + return None + + xs, ys = zip(*points) + x1 = min(xs) + x2 = max(xs) + y1 = min(ys) + y2 = max(ys) + if x2 == width-1: + x2 = width + if y2 == height-1: + y2 = height + return colls.Polygon((x1, y1), (x2, y1), (x2, y2), (x1, y2)) + def approximate_polygon(surface, tolerance=3, ratio=0.1): # TODO: Seriously boost performance """ Returns a concave polygon that approximates the non-transparent area of a Pygame surface. diff --git a/BlazeSudio/utils/wrap/warp.py b/BlazeSudio/utils/wrap/warp.py index 5fb0c49..cffa1bf 100644 --- a/BlazeSudio/utils/wrap/warp.py +++ b/BlazeSudio/utils/wrap/warp.py @@ -10,6 +10,7 @@ def lerp2d(p1, p2, f): def draw_quad(surface, quad, img): points = [] + pixel_array = pygame.surfarray.array3d(img) wid, hei = img.get_size() for i in range(hei+1): @@ -23,8 +24,9 @@ def draw_quad(surface, quad, img): for x in range(wid): for y in range(hei): + color = pixel_array[x, y] # (r, g, b) pygame.draw.polygon( surface, - img.get_at((x,y)), + color, [points[b][a] for a, b in [(x,y), (x,y+1), (x+1,y+1), (x+1,y)]] ) diff --git a/demoFiles/sampleTileset.png b/demoFiles/sampleTileset.png index 04458ac..6b4cac3 100644 Binary files a/demoFiles/sampleTileset.png and b/demoFiles/sampleTileset.png differ diff --git a/demos.py b/demos.py index 04ace09..945eca5 100644 --- a/demos.py +++ b/demos.py @@ -518,7 +518,7 @@ def resetBotSur(): ]) CCENTER = GO.PNEW((0.5, 0.5), (1, 0), (True, True)) - botF['Main'].append(GUI.Static(botF, CCENTER, pygame.Surface((0, 0)))) + botF['Main'].append(GUI.ImageViewer(botF, CCENTER, pygame.Surface((0, 0)), (800, 400))) self.makeSur() @@ -586,8 +586,6 @@ def load(slf): ) yield 'Finishing up' - - slf['surf'] = pygame.transform.scale(slf['surf'], (500, 500)) fin, outs = load() if fin: self.botF['Main'][-1].set(outs['surf']) @@ -596,6 +594,7 @@ def load(slf): def TsetCollDemo(): from BlazeSudio.graphics import Screen, Loading, options as GO, GUI + from BlazeSudio.utils import genCollisions as gen from functools import partial import pygame @@ -610,24 +609,45 @@ def getTile(self, idx): @Loading.decor def calcPoly(slf, self): - self.poly = [(0, 0), (32, 0), (32, 32), (0, 32)] + chosen = self.opts.index(self.chooser.get()) + if chosen == 0: + self.poly = None + elif chosen == 1: + self.poly = [(0, 0), (32, 0), (32, 32), (0, 32)] + elif chosen == 2: + self.poly = gen.bounding_box(self.tile) + elif chosen == 3: + self.poly = gen.approximate_polygon(self.tile) def __init__(self): self.getTile(0) + self.opts = [ + 'No collisions', + 'Cover entire shape', + 'Bounding box', + 'Trace shape' + ] super().__init__() + + def _Event(self, event): + if event.type == pygame.KEYDOWN: + if event.key == pygame.K_RETURN: + self.calcPoly(self) def _LoadUI(self): self.layers[0].add('Main') PCTOP = GO.PNEW((0.5, 0), (1, 0), (True, False)) - self.scale = GUI.NumInputBox(self, PCTOP, 100, GO.RNONE, start=None, empty=1, min=1, max=30, placeholder='Scale by size', decimals=2) + self.scale = GUI.NumInputBox(self, PCTOP, 100, GO.RNONE, start=None, empty=10, min=1, max=30, placeholder='Scale by size', decimals=2) chooser = GUI.DropdownButton(self, PCTOP, ['Tile %i'%i for i in range(tset.get_width()//32)], func=lambda i: self.getTile(i)) + self.chooser = GUI.DropdownButton(self, PCTOP, self.opts) goBtn = GUI.Button(self, GO.PCBOTTOM, GO.CGREEN, 'Go!', func=partial(self.calcPoly, self)) self['Main'].extend([ self.scale, chooser, + self.chooser, goBtn ]) @@ -642,7 +662,7 @@ def outPos(x, y): self.WIN.blit(pygame.transform.scale(self.tile, (32*scale, 32*scale)), outPos(0, 0)) if self.poly is not None: - pygame.draw.polygon(self.WIN, (0, 0, 0), [outPos(*p) for p in self.poly], 4) + pygame.draw.polygon(self.WIN, (125, 125, 125), [outPos(*p) for p in self.poly], 4) Main()()