Awesome code Kamilche. I really like it. I'm going to put it in my favorites
folder :)

/J

On Sat, Mar 8, 2008 at 5:51 AM, Kamilche <[EMAIL PROTECTED]> wrote:

> Here's a perspective test I wrote, that I thought others might find
> enjoyable. It illustrates a single-point perspective (a 'vanishing
> point'), and shows how a room with a floor, ceiling, door, and avatar
> changes as the vanishing point changes.
>
>
> import pygame, os, sys, urllib
>
> SCREENSIZE          = (1024, 768)
> BACKCOLOR           = (150, 150, 150)
> INVISIBLE           = (  0,   0,   0,   0)
> PERSPECTIVECOLOR    = (  0,   0,   0, 128)
> PERSPECTIVEWIDTH    = 2
> WALLCOLOR           = (255, 128,   0, 220)
> WINDOWCOLOR         = (  0,  64, 200, 100)
> DOORCOLOR           = (100,  64,  50, 200)
> CEILINGCOLOR        = (255, 255, 255, 255)
> FLOORCOLOR          = (121,  74,  81, 255)
> HORIZONCOLOR        = (  0, 128,   0, 200)
> VPCOLOR             = (255,   0,   0, 255)
> WALLDEPTH           = .35
>
> VANISHINGPOINT      = (SCREENSIZE[0]/2, SCREENSIZE[1]/2)
>
> bg = None
> temp = None
> girl = None
>
> def CalculatePoint(depth, point):
>     xa, ya = VANISHINGPOINT
>     xb, yb = point
>     xbb = xa + depth * (xb-xa)
>     ybb = ya + depth * (yb-ya)
>     return int(xbb), int(ybb)
>
> def Intersection(a,b,c,d):
>     Ax,Ay = a; Bx,By = b; Cx,Cy = c; Dx,Dy = d
>     u = float((Dx-Cx)*(Ay-Cy)-(Dy-Cy)*(Ax-Cx)) /
> float((Dy-Cy)*(Bx-Ax)-(Dx-Cx)*(By-Ay))
>     x = Ax + u*(Bx-Ax)
>     y = Ay + u*(By-Ay)
>     return int(x),int(y)
>
> def DrawWall():
>     w, h = SCREENSIZE
>     topleft = CalculatePoint(WALLDEPTH, (0, 0))
>     topright = CalculatePoint(WALLDEPTH, (w, 0))
>     bottomleft = CalculatePoint(WALLDEPTH, (0, h))
>     bottomright = CalculatePoint(WALLDEPTH, (w, h))
>     pos = topleft
>     wallwidth = int(topright[0]-topleft[0])
>     wallheight = int(bottomleft[1]-topleft[1])
>     temp.fill(WALLCOLOR)
>     bg.blit(temp, topleft, [0, 0, wallwidth, wallheight])
>     pygame.draw.lines(bg, PERSPECTIVECOLOR, 1, [topleft, topright,
> bottomright, bottomleft], PERSPECTIVEWIDTH)
>
> def DrawOrthogonals():
>     pygame.draw.line(bg, PERSPECTIVECOLOR, (0, 0), VANISHINGPOINT,
> PERSPECTIVEWIDTH)
>     pygame.draw.line(bg, PERSPECTIVECOLOR, (SCREENSIZE[0], 0),
> VANISHINGPOINT, PERSPECTIVEWIDTH)
>     pygame.draw.line(bg, PERSPECTIVECOLOR, (0, SCREENSIZE[1]),
> VANISHINGPOINT, PERSPECTIVEWIDTH)
>     pygame.draw.line(bg, PERSPECTIVECOLOR, SCREENSIZE, VANISHINGPOINT,
> PERSPECTIVEWIDTH)
>     pygame.draw.line(bg, HORIZONCOLOR, (0, VANISHINGPOINT[1]),
> (SCREENSIZE[0], VANISHINGPOINT[1]), PERSPECTIVEWIDTH)
>
> def DrawDoor():
>     w, h = SCREENSIZE
>     topleft = CalculatePoint(.9, (0, .25*h))
>     topright = CalculatePoint(.7, (0, .25*h))
>     bottomleft = CalculatePoint(.9, (0, h))
>     bottomright = CalculatePoint(.7, (0, h))
>     pos = topleft
>     windowwidth = int(topright[0]-topleft[0])
>     windowheight = int(bottomleft[1]-topleft[1])
>     lst = [topleft, topright, bottomright, bottomleft, topleft]
>     temp.fill(INVISIBLE)
>     pygame.draw.polygon(temp, DOORCOLOR, lst)
>     bg.blit(temp, [0, 0])
>     pygame.draw.circle(bg, DOORCOLOR, topleft, 5)
>     pygame.draw.circle(bg, DOORCOLOR, topright, 5)
>     pygame.draw.circle(bg, DOORCOLOR, bottomright, 5)
>     pygame.draw.circle(bg, DOORCOLOR, bottomleft, 5)
>
> def DrawCeiling():
>     w, h = SCREENSIZE
>     vx, vy = VANISHINGPOINT
>     numtiles = 8
>     for i in range(0, SCREENSIZE[0]+1, SCREENSIZE[0]/numtiles):
>         pygame.draw.line(bg, CEILINGCOLOR, (i, 0), VANISHINGPOINT, 1)
>
>     # Calculate horizontal lines
>     topright = CalculatePoint(WALLDEPTH, (w, 0))
>     for i in range(0, SCREENSIZE[0]+1, SCREENSIZE[0]/numtiles):
>         try:
>             x, y = Intersection((0, 0), topright, (i, 0), VANISHINGPOINT)
>             left = Intersection([0, y], [w, y], (0, 0), VANISHINGPOINT)
>             right = Intersection([0, y], [w, y], (w, 0), VANISHINGPOINT)
>             pygame.draw.line(bg, CEILINGCOLOR, left, right, 1)
>         except:
>             pass
>     #pygame.draw.line(bg, CEILINGCOLOR, (0, 0), topright, 1)
>
> def DrawFloor():
>     w, h = SCREENSIZE
>     factor = 4
>     for i in range(-w*factor, w*2*factor, 100):
>         pygame.draw.line(bg, FLOORCOLOR, (i, h), VANISHINGPOINT, 1)
>
> def DrawGirl():
>     w, h = SCREENSIZE
>     data = [(.8, (75, h)), (.9, (w/2+50, h)), (WALLDEPTH+.05, (150, h))]
>     data.sort()
>     for depth, dest in data:
>         pt = CalculatePoint(depth, dest)
>         resizedgirl = pygame.transform.rotozoom(girl, 0, depth)
>         bg.blit(resizedgirl, [pt[0]-resizedgirl.get_width()/2,
> pt[1]-resizedgirl.get_height()])
>         pygame.draw.circle(bg, (0, 0, 255), pt, 5)
>
> def Text(s, _font = []):
>     if len(_font) == 0:
>         font = pygame.font.Font(None, 24)
>         _font.append(font)
>     font = _font[0]
>     shadow = font.render(s, 1, (0, 0, 0))
>     color = font.render(s, 1, (255, 255, 0))
>     w, h = color.get_size()
>     pic = pygame.Surface((w, h), pygame.SRCALPHA, 32).convert_alpha()
>     pic.fill(INVISIBLE)
>     pic.blit(shadow, [1, 1])
>     pic.blit(color, [0, 0])
>     return pic
>
> def Draw():
>     bg.fill(BACKCOLOR)
>     DrawCeiling()
>     DrawFloor()
>     DrawOrthogonals()
>     DrawDoor()
>     DrawWall()
>     DrawGirl()
>     pygame.draw.circle(bg, VPCOLOR, VANISHINGPOINT, 5)
>
> def main():
>     global bg, temp, girl, VANISHINGPOINT, WALLDEPTH
>     pygame.init()
>     pygame.key.set_repeat(500, 30)
>     bg = pygame.display.set_mode(SCREENSIZE, 0, 32)
>     temp = pygame.Surface(SCREENSIZE, pygame.SRCALPHA, 32).convert_alpha()
>     filename = "posette.png"
>     if os.path.exists(filename):
>         girl = pygame.image.load(filename).convert_alpha()
>     else:
>         try:
>             url = "http://www.kamilche.org/webimages/posette.png";
>             urllib.urlretrieve(url, filename)
>             girl = pygame.image.load(filename).convert_alpha()
>         except:
>             girl = pygame.Surface((150, 300), pygame.SRCALPHA,
> 32).convert_alpha()
>             girl.fill((255, 0, 0, 128))
>
>     quit = 0
>     info1 = Text("Click to move vanishing point, arrow keys to move
> wall.")
>     caption = ""
>     while not quit:
>         Draw()
>         info2 = Text(caption)
>         bg.blit(info1, [5, 5])
>         bg.blit(info2, [5, info1.get_height()+5])
>         pygame.display.flip()
>         pygame.event.pump()
>         for event in pygame.event.get():
>             if event.type == pygame.QUIT:
>                 quit = 1
>                 break
>             elif (event.type == pygame.MOUSEBUTTONDOWN and event.button
> == 1) or (event.type == pygame.MOUSEMOTION and event.buttons[0] == 1):
>                 # Move vanishing point
>                 VANISHINGPOINT = event.pos
>                 caption = 'Vanishing point = %s' % str(VANISHINGPOINT)
>             elif event.type == pygame.KEYDOWN:
>                 # Move back wall
>                 if event.key in [pygame.K_LEFT, pygame.K_UP]:
>                     WALLDEPTH = max(0.01, WALLDEPTH - .05)
>                 elif event.key in [pygame.K_RIGHT, pygame.K_DOWN]:
>                     WALLDEPTH = min(1.0, WALLDEPTH + .05)
>
>     pygame.quit()
>
> main()
>

Reply via email to