playing with forced perspective pygame. A start.

update progress 6-15-18:
I'll get the new code into a new post when I'm done with the experiment.





I hope I explain it well,  My plan is to try and incorporate some kind of 3D effect with old fashioned art known as Forced Perspective.

I definitely need some more research to how it's accomplished, I only really know of what I learned in 10th grade art class, and that was back when dinosaurs roamed the earth.  (This works as a reference to when Jurrasic Park came out too!)

It's slightly off center on purpose.





Here's the code:  enjoy, explore, have fun!
As always, drop me a comment, improvements, critiques and hero worship are welcomed.  (Or tell me some python jokes, those are fun)



#!usr/bin/python3
# -*- coding: utf-8 -*-

import pygame as pg
from sys import exit
from time import sleep


class SkullGlobals(object):
    """ class container for globally used variables """
    def __init__(self):
        self.WIDTH = 800
        self.HEIGHT = 800
        self.CENTER_SCREEN_X = 0 + self.WIDTH//12
        self.CENTER_SCREEN_Y = 0 + self.HEIGHT//12
        self.CENTER_SCREEN_H = self.HEIGHT - self.HEIGHT//6
        self.CENTER_SCREEN_W = self.WIDTH - self.WIDTH//6
        self.background_color = (110, 100, 110)
        self.BLUE = (40, 60, 200)
        self.LBLUE = (100, 100, 255)
        self.BORDER = (self.WIDTH + self.HEIGHT)//200
        self.left_y = 0 + self.HEIGHT//100
        self.left_x = 0 + self.WIDTH//100
        self.right_y = self.HEIGHT - self.left_y
        self.right_x = self.WIDTH - self.left_x
        self.small_height = self.left_y * 5
        self.small_width = self.left_x * 10
        self.left_upper_y = 0 + (self.HEIGHT//10)
        self.left_upper_x = 0 + (self.WIDTH//10)
        self.left_upper_right_y = self.HEIGHT - self.BORDER
        self.right_lower_x = self.WIDTH - (self.WIDTH//10)
        self.right_lower_y = self.HEIGHT - (self.HEIGHT//10)
        self.CENTER = (self.WIDTH//2, self.HEIGHT//2)
        self.FULL_SIZE = (self.WIDTH//4 + self.HEIGHT//4)//2
        self.SMALL_SIZE = (self.WIDTH//50 + self.HEIGHT//50)//2
        self.RED = (230, 50, 50)
        self.GREEN = (50, 230, 50)
        self.D_WHITE = (200,200,200)
        self.base_color = 150
        self.menu_bar_color = (90, 100, 80)

############   background  coordinates chart #########
"""
        polygon sides = P1, P2, P3, P4
               -----------------------------
            |A   \     [P1]       //  B |
            |      \            //      |
            |        W---------X        |
            |        |         |        |
            | [P2]   |         |  [P4]  |
            |        Y_________Z        |
            |      //           \       |
            |C   //      [P3]    \    D |
            -----------------------------

"""

# tip:  Courier is Monospace, good for transferring ascii art/diagrams
##########################################


class BackgroundBox(object):

    def __init__(self, my_screen, globals):
        self.screen = my_screen
        self.globals = globals
        self.HEIGHT = self.globals.HEIGHT
        self.WIDTH = self.globals.WIDTH
        self.box_w = self.WIDTH//4
        self.box_h = self.HEIGHT//4
        self.diff_box_w = (self.box_w//2 * 3)
        self.diff_box_h = (self.box_h//2 * 3)
        self.A = (0, 0)
        self.B = (self.WIDTH, 0)
        self.C = (0, self.HEIGHT)
        self.D = (self.WIDTH, self.HEIGHT)
        self.W = (self.box_w, self.box_h)
        self.X = (self.box_w + self.diff_box_w, self.box_h)
        self.Y = (self.box_w, self.box_h + self.diff_box_h)
        self.Z = (self.box_w + self.diff_box_w, self.box_h + self.diff_box_h)

    def draw_back(self):
        """
         globals base color = 150  a ligther grey with (150, 150, 150)
         back rect will be positioned at self.W, with
         width = self.diff_box_x
         height = self.diff_box_y
         pygame rect = (top left x, top left y, width, height) pg.draw.rect(screen/surface, color(R, G, B), (pygame rect), thickness/edge 0=fill)
        """

        color = self.globals.base_color
        darker = (color - 70, color - 70, color - 70)
        darker_light = (color - 20, color - 20, color - 20)
        edge = 8  ######### should replace with globals
        diff_edge = 5  ######  replace with globals and edge local variable
        box_rect = (self.W[0], self.W[1], self.diff_box_w, self.diff_box_h)
        inner_box = (self.W[0] + diff_edge, self.W[1] + diff_edge, self.diff_box_w - (diff_edge * 2), self.diff_box_h - (diff_edge * 2))

        pg.draw.rect(self.screen, darker, box_rect, edge)
        pg.draw.rect(self.screen, darker_light, inner_box, 0)

    def draw_lines(self):
        """
        point A --> W (thicker)
        point B --> X
        point C --> Y (thicker)
        point D --> Z
        pygame draw line (screen/surface, color, start_pos, end_pos, width)

        # currently not visible ,  Undecided how needed they are
        """

        color = self.globals.base_color
        darker = (color - 70, color - 70, color - 70)
        pg.draw.line(self.screen, darker, self.A, self.W, 5)
        pg.draw.line(self.screen, darker, self.B, self.X, 3)
        pg.draw.line(self.screen, darker, self.C, self.Y, 5)
        pg.draw.line(self.screen, darker, self.D, self.Z, 3)

    def color_walls(self):
        """ create polygons for walls, coordinates in example
            P1 = [A, W, X, B]    * below *
            P2 = [A, C, Y, W]
            P3 = [C, D, Z, Y]
            P4 = [D, Z, X, B]
                --------------
            |A          B|
            |            |
            |W          X|
            --------------

            pygame draw polygon (screen/surface, Points list (P1), thick/fill=0)
        """

        color = self.globals.base_color
        darker = (color - 65, color - 65, color - 65)
        lighter = (color - 75, color - 75, color - 75)
        P1 = [self.A, self.W, self.X, self.B]
        P2 = [self.A, self.C, self.Y, self.W]
        P3 = [self.C, self.D, self.Z, self.Y]
        P4 = [self.D, self.Z, self.X, self.B]
        pg.draw.polygon(self.screen, lighter, P1, 0)
        pg.draw.polygon(self.screen, darker, P2, 0)
        pg.draw.polygon(self.screen, lighter, P3, 0)
        pg.draw.polygon(self.screen, darker, P4, 0)

class PyDrawObjects(object):
    def __init__(self, screen, globals):
        self.screen = screen
        self.globals = globals
        self.box =  BackgroundBox(self.screen, self.globals)

    def run_objects(self):
        self.box.draw_back()
        self.box.draw_lines()
        self.box.color_walls()

def start_pygame():
    """ start all pygame dependants return screen"""
    pg.init()  # Not sure the proper place to put this
    globals = SkullGlobals()
    screen = pg.display.set_mode((globals.WIDTH, globals.HEIGHT))
    pg.display.set_caption(('Pygame Display'))
    screen.fill(globals.background_color)
    animation_timer = pg.time.Clock()
    pg.display.flip()

    return screen, animation_timer



def pygame_loop():
    """
        The loop that will run drawing and responding to events
    """

    #  pg.init()  could go here instead of in the start_pygame()
    globals = SkullGlobals()
    w = globals.WIDTH
    h = globals.HEIGHT
    screen, timer = start_pygame()
    screen.fill(globals.background_color)
    back_drop = PyDrawObjects(screen, globals)
    running = True

    while running:
        screen.fill(globals.background_color)
        timer.tick(60)  ##  WITHOUT TIMER  < MY CPU runs as fast as it can >!!!!
        events = pg.event.get()
        for event in events:
            if event.type == pg.QUIT:
                running = False
                pg.QUIT
                exit(0)

        back_drop.run_objects()
        pg.display.update()


pygame_loop()









Comments

Popular posts from this blog

JavaScript Ascii animation with while loops and console.log

playing with trigonometry sin in pygame

JavaScript and a Matrix